send-email: also pick up cc addresses from -by trailers
[gitweb.git] / builtin / commit.c
index 3bc5dff2c00c9556e6c032381d5baf18246bf8dc..0d9828e29ebe89f037e68761d5cd5b407339cd48 100644 (file)
@@ -32,6 +32,7 @@
 #include "column.h"
 #include "sequencer.h"
 #include "mailmap.h"
+#include "help.h"
 
 static const char * const builtin_commit_usage[] = {
        N_("git commit [<options>] [--] <pathspec>..."),
@@ -43,31 +44,6 @@ static const char * const builtin_status_usage[] = {
        NULL
 };
 
-static const char implicit_ident_advice_noconfig[] =
-N_("Your name and email address were configured automatically based\n"
-"on your username and hostname. Please check that they are accurate.\n"
-"You can suppress this message by setting them explicitly. Run the\n"
-"following command and follow the instructions in your editor to edit\n"
-"your configuration file:\n"
-"\n"
-"    git config --global --edit\n"
-"\n"
-"After doing this, you may fix the identity used for this commit with:\n"
-"\n"
-"    git commit --amend --reset-author\n");
-
-static const char implicit_ident_advice_config[] =
-N_("Your name and email address were configured automatically based\n"
-"on your username and hostname. Please check that they are accurate.\n"
-"You can suppress this message by setting them explicitly:\n"
-"\n"
-"    git config --global user.name \"Your Name\"\n"
-"    git config --global user.email you@example.com\n"
-"\n"
-"After doing this, you may fix the identity used for this commit with:\n"
-"\n"
-"    git commit --amend --reset-author\n");
-
 static const char empty_amend_advice[] =
 N_("You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
@@ -91,7 +67,17 @@ N_("If you wish to skip this commit, use:\n"
 "Then \"git cherry-pick --continue\" will resume cherry-picking\n"
 "the remaining commits.\n");
 
-static GIT_PATH_FUNC(git_path_commit_editmsg, "COMMIT_EDITMSG")
+static const char *color_status_slots[] = {
+       [WT_STATUS_HEADER]        = "header",
+       [WT_STATUS_UPDATED]       = "updated",
+       [WT_STATUS_CHANGED]       = "changed",
+       [WT_STATUS_UNTRACKED]     = "untracked",
+       [WT_STATUS_NOBRANCH]      = "noBranch",
+       [WT_STATUS_UNMERGED]      = "unmerged",
+       [WT_STATUS_LOCAL_BRANCH]  = "localBranch",
+       [WT_STATUS_REMOTE_BRANCH] = "remoteBranch",
+       [WT_STATUS_ONBRANCH]      = "branch",
+};
 
 static const char *use_message_buffer;
 static struct lock_file index_lock; /* real index */
@@ -116,7 +102,7 @@ static int edit_flag = -1; /* unspecified */
 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
 static int config_commit_verbose = -1; /* unspecified */
 static int no_post_rewrite, allow_empty_message;
-static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
+static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
 static char *sign_commit;
 
 /*
@@ -132,7 +118,7 @@ static const char *cleanup_arg;
 static enum commit_whence whence;
 static int sequencer_in_use;
 static int use_editor = 1, include_status = 1;
-static int show_ignored_in_status, have_option_m;
+static int have_option_m;
 static struct strbuf message = STRBUF_INIT;
 
 static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED;
@@ -170,11 +156,21 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
        return 0;
 }
 
+static int opt_parse_rename_score(const struct option *opt, const char *arg, int unset)
+{
+       const char **value = opt->value;
+       if (arg != NULL && *arg == '=')
+               arg = arg + 1;
+
+       *value = arg;
+       return 0;
+}
+
 static void determine_whence(struct wt_status *s)
 {
-       if (file_exists(git_path_merge_head()))
+       if (file_exists(git_path_merge_head(the_repository)))
                whence = FROM_MERGE;
-       else if (file_exists(git_path_cherry_pick_head())) {
+       else if (file_exists(git_path_cherry_pick_head(the_repository))) {
                whence = FROM_CHERRY_PICK;
                if (file_exists(git_path_seq_dir()))
                        sequencer_in_use = 1;
@@ -188,9 +184,9 @@ static void determine_whence(struct wt_status *s)
 static void status_init_config(struct wt_status *s, config_fn_t fn)
 {
        wt_status_prepare(s);
+       init_diff_ui_defaults();
        git_config(fn, s);
        determine_whence(s);
-       init_diff_ui_defaults();
        s->hints = advice_status_hints; /* must come after git_config() */
 }
 
@@ -245,8 +241,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
 
        if (with_tree) {
                char *max_prefix = common_prefix(pattern);
-               overlay_tree_on_index(&the_index, with_tree,
-                                     max_prefix ? max_prefix : prefix);
+               overlay_tree_on_index(&the_index, with_tree, max_prefix);
                free(max_prefix);
        }
 
@@ -256,7 +251,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
 
                if (ce->ce_flags & CE_UPDATE)
                        continue;
-               if (!ce_path_match(ce, pattern, m))
+               if (!ce_path_match(&the_index, ce, pattern, m))
                        continue;
                item = string_list_insert(list, ce->name);
                if (ce_skip_worktree(ce))
@@ -416,13 +411,9 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
                if (active_cache_changed
                    || !cache_tree_fully_valid(active_cache_tree))
                        update_main_cache_tree(WRITE_TREE_SILENT);
-               if (active_cache_changed) {
-                       if (write_locked_index(&the_index, &index_lock,
-                                              COMMIT_LOCK))
-                               die(_("unable to write new_index file"));
-               } else {
-                       rollback_lock_file(&index_lock);
-               }
+               if (write_locked_index(&the_index, &index_lock,
+                                      COMMIT_LOCK | SKIP_IF_UNCHANGED))
+                       die(_("unable to write new_index file"));
                commit_style = COMMIT_AS_IS;
                ret = get_index_file();
                goto out;
@@ -527,7 +518,7 @@ static int is_a_merge(const struct commit *current_head)
 static void assert_split_ident(struct ident_split *id, const struct strbuf *buf)
 {
        if (split_ident_line(id, buf->buf, buf->len) || !id->date_begin)
-               die("BUG: unable to parse our own ident: %s", buf->buf);
+               BUG("unable to parse our own ident: %s", buf->buf);
 }
 
 static void export_one(const char *var, const char *s, const char *e, int hack)
@@ -694,7 +685,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                }
        }
 
-       if (have_option_m) {
+       if (have_option_m && !fixup_message) {
                strbuf_addbuf(&sb, &message);
                hook_arg1 = "message";
        } else if (logfile && !strcmp(logfile, "-")) {
@@ -724,22 +715,24 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                ctx.output_encoding = get_commit_output_encoding();
                format_commit_message(commit, "fixup! %s\n\n",
                                      &sb, &ctx);
+               if (have_option_m)
+                       strbuf_addbuf(&sb, &message);
                hook_arg1 = "message";
-       } else if (!stat(git_path_merge_msg(), &statbuf)) {
+       } else if (!stat(git_path_merge_msg(the_repository), &statbuf)) {
                /*
                 * prepend SQUASH_MSG here if it exists and a
                 * "merge --squash" was originally performed
                 */
-               if (!stat(git_path_squash_msg(), &statbuf)) {
-                       if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0)
+               if (!stat(git_path_squash_msg(the_repository), &statbuf)) {
+                       if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0)
                                die_errno(_("could not read SQUASH_MSG"));
                        hook_arg1 = "squash";
                } else
                        hook_arg1 = "merge";
-               if (strbuf_read_file(&sb, git_path_merge_msg(), 0) < 0)
+               if (strbuf_read_file(&sb, git_path_merge_msg(the_repository), 0) < 0)
                        die_errno(_("could not read MERGE_MSG"));
-       } else if (!stat(git_path_squash_msg(), &statbuf)) {
-               if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0)
+       } else if (!stat(git_path_squash_msg(the_repository), &statbuf)) {
+               if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0)
                        die_errno(_("could not read SQUASH_MSG"));
                hook_arg1 = "squash";
        } else if (template_file) {
@@ -820,8 +813,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                                        "       %s\n"
                                        "and try again.\n"),
                                whence == FROM_MERGE ?
-                                       git_path_merge_head() :
-                                       git_path_cherry_pick_head());
+                                       git_path_merge_head(the_repository) :
+                                       git_path_cherry_pick_head(the_repository));
                }
 
                fprintf(s->fp, "\n");
@@ -1011,6 +1004,19 @@ static const char *find_author_by_nickname(const char *name)
        die(_("--author '%s' is not 'Name <email>' and matches no existing author"), name);
 }
 
+static void handle_ignored_arg(struct wt_status *s)
+{
+       if (!ignored_arg)
+               ; /* default already initialized */
+       else if (!strcmp(ignored_arg, "traditional"))
+               s->show_ignored_mode = SHOW_TRADITIONAL_IGNORED;
+       else if (!strcmp(ignored_arg, "no"))
+               s->show_ignored_mode = SHOW_NO_IGNORED;
+       else if (!strcmp(ignored_arg, "matching"))
+               s->show_ignored_mode = SHOW_MATCHING_IGNORED;
+       else
+               die(_("Invalid ignored mode '%s'"), ignored_arg);
+}
 
 static void handle_untracked_files_arg(struct wt_status *s)
 {
@@ -1073,6 +1079,9 @@ static void finalize_deferred_config(struct wt_status *s)
                s->show_branch = status_deferred_config.show_branch;
        if (s->show_branch < 0)
                s->show_branch = 0;
+
+       if (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED)
+               s->ahead_behind_flags = AHEAD_BEHIND_FULL;
 }
 
 static int parse_and_validate_options(int argc, const char *argv[],
@@ -1119,8 +1128,8 @@ static int parse_and_validate_options(int argc, const char *argv[],
                f++;
        if (f > 1)
                die(_("Only one of -c/-C/-F/--fixup can be used."));
-       if (have_option_m && f > 0)
-               die((_("Option -m cannot be combined with -c/-C/-F/--fixup.")));
+       if (have_option_m && (edit_message || use_message || logfile))
+               die((_("Option -m cannot be combined with -c/-C/-F.")));
        if (f || have_option_m)
                template_file = NULL;
        if (edit_message)
@@ -1187,27 +1196,14 @@ static int dry_run_commit(int argc, const char **argv, const char *prefix,
        return commitable ? 0 : 1;
 }
 
+define_list_config_array_extra(color_status_slots, {"added"});
+
 static int parse_status_slot(const char *slot)
 {
-       if (!strcasecmp(slot, "header"))
-               return WT_STATUS_HEADER;
-       if (!strcasecmp(slot, "branch"))
-               return WT_STATUS_ONBRANCH;
-       if (!strcasecmp(slot, "updated") || !strcasecmp(slot, "added"))
+       if (!strcasecmp(slot, "added"))
                return WT_STATUS_UPDATED;
-       if (!strcasecmp(slot, "changed"))
-               return WT_STATUS_CHANGED;
-       if (!strcasecmp(slot, "untracked"))
-               return WT_STATUS_UNTRACKED;
-       if (!strcasecmp(slot, "nobranch"))
-               return WT_STATUS_NOBRANCH;
-       if (!strcasecmp(slot, "unmerged"))
-               return WT_STATUS_UNMERGED;
-       if (!strcasecmp(slot, "localBranch"))
-               return WT_STATUS_LOCAL_BRANCH;
-       if (!strcasecmp(slot, "remoteBranch"))
-               return WT_STATUS_REMOTE_BRANCH;
-       return -1;
+
+       return LOOKUP_CONFIG(color_status_slots, slot);
 }
 
 static int git_status_config(const char *k, const char *v, void *cb)
@@ -1273,11 +1269,31 @@ static int git_status_config(const char *k, const char *v, void *cb)
                        return error(_("Invalid untracked files mode '%s'"), v);
                return 0;
        }
+       if (!strcmp(k, "diff.renamelimit")) {
+               if (s->rename_limit == -1)
+                       s->rename_limit = git_config_int(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "status.renamelimit")) {
+               s->rename_limit = git_config_int(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "diff.renames")) {
+               if (s->detect_rename == -1)
+                       s->detect_rename = git_config_rename(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "status.renames")) {
+               s->detect_rename = git_config_rename(k, v);
+               return 0;
+       }
        return git_diff_ui_config(k, v, NULL);
 }
 
 int cmd_status(int argc, const char **argv, const char *prefix)
 {
+       static int no_renames = -1;
+       static const char *rename_score_arg = (const char *)-1;
        static struct wt_status s;
        int fd;
        struct object_id oid;
@@ -1289,6 +1305,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                         N_("show branch information")),
                OPT_BOOL(0, "show-stash", &s.show_stash,
                         N_("show stash information")),
+               OPT_BOOL(0, "ahead-behind", &s.ahead_behind_flags,
+                        N_("compute full ahead/behind values")),
                { OPTION_CALLBACK, 0, "porcelain", &status_format,
                  N_("version"), N_("machine-readable output"),
                  PARSE_OPT_OPTARG, opt_parse_porcelain },
@@ -1301,12 +1319,18 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                  N_("mode"),
                  N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
                  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
-               OPT_BOOL(0, "ignored", &show_ignored_in_status,
-                        N_("show ignored files")),
+               { OPTION_STRING, 0, "ignored", &ignored_arg,
+                 N_("mode"),
+                 N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"),
+                 PARSE_OPT_OPTARG, NULL, (intptr_t)"traditional" },
                { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
                  N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
                  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
                OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
+               OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
+               { OPTION_CALLBACK, 'M', "find-renames", &rename_score_arg,
+                 N_("n"), N_("detect renames, optionally set similarity index"),
+                 PARSE_OPT_OPTARG, opt_parse_rename_score },
                OPT_END(),
        };
 
@@ -1321,8 +1345,12 @@ int cmd_status(int argc, const char **argv, const char *prefix)
        finalize_deferred_config(&s);
 
        handle_untracked_files_arg(&s);
-       if (show_ignored_in_status)
-               s.show_ignored_files = 1;
+       handle_ignored_arg(&s);
+
+       if (s.show_ignored_mode == SHOW_MATCHING_IGNORED &&
+           s.show_untracked_files == SHOW_NO_UNTRACKED_FILES)
+               die(_("Unsupported combination of ignored and untracked-files arguments"));
+
        parse_pathspec(&s.pathspec, 0,
                       PATHSPEC_PREFER_FULL,
                       prefix, argv);
@@ -1342,6 +1370,14 @@ int cmd_status(int argc, const char **argv, const char *prefix)
        s.ignore_submodule_arg = ignore_submodule_arg;
        s.status_format = status_format;
        s.verbose = verbose;
+       if (no_renames != -1)
+               s.detect_rename = !no_renames;
+       if ((intptr_t)rename_score_arg != -1) {
+               if (s.detect_rename < DIFF_DETECT_RENAME)
+                       s.detect_rename = DIFF_DETECT_RENAME;
+               if (rename_score_arg)
+                       s.rename_score = parse_rename_score(&rename_score_arg);
+       }
 
        wt_status_collect(&s);
 
@@ -1355,98 +1391,6 @@ int cmd_status(int argc, const char **argv, const char *prefix)
        return 0;
 }
 
-static const char *implicit_ident_advice(void)
-{
-       char *user_config = expand_user_path("~/.gitconfig", 0);
-       char *xdg_config = xdg_config_home("config");
-       int config_exists = file_exists(user_config) || file_exists(xdg_config);
-
-       free(user_config);
-       free(xdg_config);
-
-       if (config_exists)
-               return _(implicit_ident_advice_config);
-       else
-               return _(implicit_ident_advice_noconfig);
-
-}
-
-static void print_summary(const char *prefix, const struct object_id *oid,
-                         int initial_commit)
-{
-       struct rev_info rev;
-       struct commit *commit;
-       struct strbuf format = STRBUF_INIT;
-       const char *head;
-       struct pretty_print_context pctx = {0};
-       struct strbuf author_ident = STRBUF_INIT;
-       struct strbuf committer_ident = STRBUF_INIT;
-
-       commit = lookup_commit(oid);
-       if (!commit)
-               die(_("couldn't look up newly created commit"));
-       if (parse_commit(commit))
-               die(_("could not parse newly created commit"));
-
-       strbuf_addstr(&format, "format:%h] %s");
-
-       format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
-       format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
-       if (strbuf_cmp(&author_ident, &committer_ident)) {
-               strbuf_addstr(&format, "\n Author: ");
-               strbuf_addbuf_percentquote(&format, &author_ident);
-       }
-       if (author_date_is_interesting()) {
-               struct strbuf date = STRBUF_INIT;
-               format_commit_message(commit, "%ad", &date, &pctx);
-               strbuf_addstr(&format, "\n Date: ");
-               strbuf_addbuf_percentquote(&format, &date);
-               strbuf_release(&date);
-       }
-       if (!committer_ident_sufficiently_given()) {
-               strbuf_addstr(&format, "\n Committer: ");
-               strbuf_addbuf_percentquote(&format, &committer_ident);
-               if (advice_implicit_identity) {
-                       strbuf_addch(&format, '\n');
-                       strbuf_addstr(&format, implicit_ident_advice());
-               }
-       }
-       strbuf_release(&author_ident);
-       strbuf_release(&committer_ident);
-
-       init_revisions(&rev, prefix);
-       setup_revisions(0, NULL, &rev, NULL);
-
-       rev.diff = 1;
-       rev.diffopt.output_format =
-               DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
-
-       rev.verbose_header = 1;
-       rev.show_root_diff = 1;
-       get_commit_format(format.buf, &rev);
-       rev.always_show_header = 0;
-       rev.diffopt.detect_rename = 1;
-       rev.diffopt.break_opt = 0;
-       diff_setup_done(&rev.diffopt);
-
-       head = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
-       if (!head)
-               die_errno(_("unable to resolve HEAD after creating commit"));
-       if (!strcmp(head, "HEAD"))
-               head = _("detached HEAD");
-       else
-               skip_prefix(head, "refs/heads/", &head);
-       printf("[%s%s ", head, initial_commit ? _(" (root-commit)") : "");
-
-       if (!log_tree_commit(&rev, commit)) {
-               rev.always_show_header = 1;
-               rev.use_terminator = 1;
-               log_tree_commit(&rev, commit);
-       }
-
-       strbuf_release(&format);
-}
-
 static int git_commit_config(const char *k, const char *v, void *cb)
 {
        struct wt_status *s = cb;
@@ -1500,6 +1444,7 @@ int run_commit_hook(int editor_is_used, const char *index_file, const char *name
 
 int cmd_commit(int argc, const char **argv, const char *prefix)
 {
+       const char *argv_gc_auto[] = {"gc", "--auto", NULL};
        static struct wt_status s;
        static struct option builtin_commit_options[] = {
                OPT__QUIET(&quiet, N_("suppress summary after successful commit")),
@@ -1535,6 +1480,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
                            STATUS_FORMAT_SHORT),
                OPT_BOOL(0, "branch", &s.show_branch, N_("show branch information")),
+               OPT_BOOL(0, "ahead-behind", &s.ahead_behind_flags,
+                        N_("compute full ahead/behind values")),
                OPT_SET_INT(0, "porcelain", &status_format,
                            N_("machine-readable output"), STATUS_FORMAT_PORCELAIN),
                OPT_SET_INT(0, "long", &status_format,
@@ -1617,7 +1564,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                if (!reflog_msg)
                        reflog_msg = "commit (merge)";
                pptr = commit_list_append(current_head, pptr);
-               fp = xfopen(git_path_merge_head(), "r");
+               fp = xfopen(git_path_merge_head(the_repository), "r");
                while (strbuf_getline_lf(&m, fp) != EOF) {
                        struct commit *parent;
 
@@ -1628,14 +1575,14 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                }
                fclose(fp);
                strbuf_release(&m);
-               if (!stat(git_path_merge_mode(), &statbuf)) {
-                       if (strbuf_read_file(&sb, git_path_merge_mode(), 0) < 0)
+               if (!stat(git_path_merge_mode(the_repository), &statbuf)) {
+                       if (strbuf_read_file(&sb, git_path_merge_mode(the_repository), 0) < 0)
                                die_errno(_("could not read MERGE_MODE"));
                        if (!strcmp(sb.buf, "no-ff"))
                                allow_fast_forward = 0;
                }
                if (allow_fast_forward)
-                       parents = reduce_heads(parents);
+                       reduce_heads_replace(&parents);
        } else {
                if (!reflog_msg)
                        reflog_msg = (whence == FROM_CHERRY_PICK)
@@ -1677,8 +1624,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                append_merge_tag_headers(parents, &tail);
        }
 
-       if (commit_tree_extended(sb.buf, sb.len, active_cache_tree->oid.hash,
-                        parents, oid.hash, author_ident.buf, sign_commit, extra)) {
+       if (commit_tree_extended(sb.buf, sb.len, &active_cache_tree->oid,
+                                parents, &oid, author_ident.buf, sign_commit,
+                                extra)) {
                rollback_index_files();
                die(_("failed to write commit object"));
        }
@@ -1691,25 +1639,33 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                die("%s", err.buf);
        }
 
-       unlink(git_path_cherry_pick_head());
-       unlink(git_path_revert_head());
-       unlink(git_path_merge_head());
-       unlink(git_path_merge_msg());
-       unlink(git_path_merge_mode());
-       unlink(git_path_squash_msg());
+       unlink(git_path_cherry_pick_head(the_repository));
+       unlink(git_path_revert_head(the_repository));
+       unlink(git_path_merge_head(the_repository));
+       unlink(git_path_merge_msg(the_repository));
+       unlink(git_path_merge_mode(the_repository));
+       unlink(git_path_squash_msg(the_repository));
 
        if (commit_index_files())
-               die (_("Repository has been updated, but unable to write\n"
-                    "new_index file. Check that disk is not full and quota is\n"
-                    "not exceeded, and then \"git reset HEAD\" to recover."));
+               die(_("repository has been updated, but unable to write\n"
+                     "new_index file. Check that disk is not full and quota is\n"
+                     "not exceeded, and then \"git reset HEAD\" to recover."));
 
        rerere(0);
+       run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
        run_commit_hook(use_editor, get_index_file(), "post-commit", NULL);
        if (amend && !no_post_rewrite) {
                commit_post_rewrite(current_head, &oid);
        }
-       if (!quiet)
-               print_summary(prefix, &oid, !current_head);
+       if (!quiet) {
+               unsigned int flags = 0;
+
+               if (!current_head)
+                       flags |= SUMMARY_INITIAL_COMMIT;
+               if (author_date_is_interesting())
+                       flags |= SUMMARY_SHOW_AUTHOR_DATE;
+               print_commit_summary(prefix, &oid, flags);
+       }
 
        UNLEAK(err);
        UNLEAK(sb);