Merge branch 'jc/maint-fix-mailinfo-strip'
[gitweb.git] / builtin-log.c
index 0c2fa0ae2dc3f23cd52d2e8d765805b07262a7d6..e0d5caa61bac72cb40272ab26aa9b2202d5bb3e8 100644 (file)
@@ -27,10 +27,15 @@ static int default_show_root = 1;
 static const char *fmt_patch_subject_prefix = "PATCH";
 static const char *fmt_pretty;
 
+static const char * const builtin_log_usage =
+       "git log [<options>] [<since>..<until>] [[--] <path>...]\n"
+       "   or: git show [options] <object>...";
+
 static void cmd_log_init(int argc, const char **argv, const char *prefix,
                      struct rev_info *rev)
 {
        int i;
+       int decoration_style = 0;
 
        rev->abbrev = DEFAULT_ABBREV;
        rev->commit_format = CMIT_FMT_DEFAULT;
@@ -45,8 +50,17 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
        if (default_date_mode)
                rev->date_mode = parse_date_format(default_date_mode);
 
+       /*
+        * Check for -h before setup_revisions(), or "git log -h" will
+        * fail when run without a git directory.
+        */
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage(builtin_log_usage);
        argc = setup_revisions(argc, argv, rev, "HEAD");
 
+       if (!rev->show_notes_given && !rev->pretty_given)
+               rev->show_notes = 1;
+
        if (rev->diffopt.pickaxe || rev->diffopt.filter)
                rev->always_show_header = 0;
        if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
@@ -57,13 +71,26 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
        for (i = 1; i < argc; i++) {
                const char *arg = argv[i];
                if (!strcmp(arg, "--decorate")) {
-                       load_ref_decorations();
-                       rev->show_decorations = 1;
+                       decoration_style = DECORATE_SHORT_REFS;
+               } else if (!prefixcmp(arg, "--decorate=")) {
+                       const char *v = skip_prefix(arg, "--decorate=");
+                       if (!strcmp(v, "full"))
+                               decoration_style = DECORATE_FULL_REFS;
+                       else if (!strcmp(v, "short"))
+                               decoration_style = DECORATE_SHORT_REFS;
+                       else
+                               die("invalid --decorate option: %s", arg);
                } else if (!strcmp(arg, "--source")) {
                        rev->show_source = 1;
+               } else if (!strcmp(arg, "-h")) {
+                       usage(builtin_log_usage);
                } else
                        die("unrecognized argument: %s", arg);
        }
+       if (decoration_style) {
+               rev->show_decorations = 1;
+               load_ref_decorations(decoration_style);
+       }
 }
 
 /*
@@ -257,7 +284,7 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)
        pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode,
                git_log_output_encoding ?
                git_log_output_encoding: git_commit_encoding);
-       printf("%s\n", out.buf);
+       printf("%s", out.buf);
        strbuf_release(&out);
 }
 
@@ -329,11 +356,14 @@ int cmd_show(int argc, const char **argv, const char *prefix)
                case OBJ_TAG: {
                        struct tag *t = (struct tag *)o;
 
+                       if (rev.shown_one)
+                               putchar('\n');
                        printf("%stag %s%s\n",
                                        diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
                                        t->tag,
                                        diff_get_color_opt(&rev.diffopt, DIFF_RESET));
                        ret = show_object(o->sha1, 1, &rev);
+                       rev.shown_one = 1;
                        if (ret)
                                break;
                        o = parse_object(t->tagged->sha1);
@@ -345,12 +375,15 @@ int cmd_show(int argc, const char **argv, const char *prefix)
                        break;
                }
                case OBJ_TREE:
+                       if (rev.shown_one)
+                               putchar('\n');
                        printf("%stree %s%s\n\n",
                                        diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
                                        name,
                                        diff_get_color_opt(&rev.diffopt, DIFF_RESET));
                        read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
                                        show_tree_object, NULL);
+                       rev.shown_one = 1;
                        break;
                case OBJ_COMMIT:
                        rev.pending.nr = rev.pending.alloc = 0;
@@ -537,7 +570,7 @@ static int reopen_stdout(struct commit *commit, struct rev_info *rev)
 
        get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
 
-       if (!DIFF_OPT_TST(&rev->diffopt, QUIET))
+       if (!DIFF_OPT_TST(&rev->diffopt, QUICK))
                fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
 
        if (freopen(filename.buf, "w", stdout) == NULL)
@@ -658,6 +691,10 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
        log_write_email_headers(rev, head, &subject_start, &extra_headers,
                                &need_8bit_cte);
 
+       for (i = 0; !need_8bit_cte && i < nr; i++)
+               if (has_non_ascii(list[i]->buffer))
+                       need_8bit_cte = 1;
+
        msg = body;
        pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
                     encoding);
@@ -863,6 +900,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        struct patch_ids ids;
        char *add_signoff = NULL;
        struct strbuf buf = STRBUF_INIT;
+       int use_patch_format = 0;
        const struct option builtin_format_patch_options[] = {
                { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
                            "use [PATCH n/m] even with a single patch",
@@ -894,6 +932,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                            "don't output binary diffs"),
                OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
                            "don't include a patch matching a commit upstream"),
+               { OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
+                 "show patch format instead of default (patch + stat)",
+                 PARSE_OPT_NONEG | PARSE_OPT_NOARG },
                OPT_GROUP("Messaging"),
                { OPTION_CALLBACK, 0, "add-header", NULL, "header",
                            "add email header", PARSE_OPT_NONEG,
@@ -938,7 +979,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
         */
        argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
                             builtin_format_patch_usage,
-                            PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
+                            PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
+                            PARSE_OPT_KEEP_DASHDASH);
 
        if (do_signoff) {
                const char *committer;
@@ -999,9 +1041,20 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        if (argc > 1)
                die ("unrecognized argument: %s", argv[1]);
 
-       if (!rev.diffopt.output_format
-               || rev.diffopt.output_format == DIFF_FORMAT_PATCH)
-               rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
+       if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
+               die("--name-only does not make sense");
+       if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
+               die("--name-status does not make sense");
+       if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
+               die("--check does not make sense");
+
+       if (!use_patch_format &&
+               (!rev.diffopt.output_format ||
+                rev.diffopt.output_format == DIFF_FORMAT_PATCH))
+               rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;
+
+       /* Always generate a patch */
+       rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
 
        if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
                DIFF_OPT_SET(&rev.diffopt, BINARY);
@@ -1036,7 +1089,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 
        /*
         * We cannot move this anywhere earlier because we do want to
-        * know if --root was given explicitly from the comand line.
+        * know if --root was given explicitly from the command line.
         */
        rev.show_root_diff = 1;
 
@@ -1209,6 +1262,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
                argv++;
        }
 
+       if (argc > 1 && !strcmp(argv[1], "-h"))
+               usage(cherry_usage);
+
        switch (argc) {
        case 4:
                limit = argv[3];
@@ -1276,8 +1332,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
 
                if (verbose) {
                        struct strbuf buf = STRBUF_INIT;
+                       struct pretty_print_context ctx = {0};
                        pretty_print_commit(CMIT_FMT_ONELINE, commit,
-                                           &buf, 0, NULL, NULL, 0, 0);
+                                           &buf, &ctx);
                        printf("%c %s %s\n", sign,
                               sha1_to_hex(commit->object.sha1), buf.buf);
                        strbuf_release(&buf);