diff options
Diffstat (limited to 'builtin/commit.c')
-rw-r--r-- | builtin/commit.c | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/builtin/commit.c b/builtin/commit.c index c101f006f..6e2f12acc 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -25,6 +25,7 @@ #include "rerere.h" #include "unpack-trees.h" #include "quote.h" +#include "submodule.h" static const char * const builtin_commit_usage[] = { "git commit [options] [--] <filepattern>...", @@ -44,9 +45,9 @@ static const char implicit_ident_advice[] = " git config --global user.name \"Your Name\"\n" " git config --global user.email you@example.com\n" "\n" -"If the identity used for this commit is wrong, you can fix it with:\n" +"After doing this, you may fix the identity used for this commit with:\n" "\n" -" git commit --amend --author='Your Name <you@example.com>'\n"; +" git commit --amend --reset-author\n"; static const char empty_amend_advice[] = "You asked to amend the most recent commit, but doing so would make\n" @@ -68,7 +69,6 @@ static enum { static const char *logfile, *force_author; static const char *template_file; static char *edit_message, *use_message; -static char *author_name, *author_email, *author_date; static int all, edit_flag, also, interactive, only, amend, signoff; static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; static int no_post_rewrite, allow_empty_message; @@ -147,7 +147,7 @@ static struct option builtin_commit_options[] = { "terminate entries with NUL"), OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"), - { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, + { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, /* end commit contents options */ { OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL, @@ -343,9 +343,13 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int if (!pathspec || !*pathspec) { fd = hold_locked_index(&index_lock, 1); refresh_cache_or_die(refresh_flags); - if (write_cache(fd, active_cache, active_nr) || - commit_locked_index(&index_lock)) - die("unable to write new_index file"); + if (active_cache_changed) { + if (write_cache(fd, active_cache, active_nr) || + commit_locked_index(&index_lock)) + die("unable to write new_index file"); + } else { + rollback_lock_file(&index_lock); + } commit_style = COMMIT_AS_IS; return get_index_file(); } @@ -454,7 +458,7 @@ static int is_a_merge(const unsigned char *sha1) static const char sign_off_header[] = "Signed-off-by: "; -static void determine_author_info(void) +static void determine_author_info(struct strbuf *author_ident) { char *name, *email, *date; @@ -498,10 +502,8 @@ static void determine_author_info(void) if (force_date) date = force_date; - - author_name = name; - author_email = email; - author_date = date; + strbuf_addstr(author_ident, fmt_ident(name, email, date, + IDENT_ERROR_ON_NO_NAME)); } static int ends_rfc2822_footer(struct strbuf *sb) @@ -545,10 +547,21 @@ static int ends_rfc2822_footer(struct strbuf *sb) return 1; } +static char *cut_ident_timestamp_part(char *string) +{ + char *ket = strrchr(string, '>'); + if (!ket || ket[1] != ' ') + die("Malformed ident string: '%s'", string); + *++ket = '\0'; + return ket; +} + static int prepare_to_commit(const char *index_file, const char *prefix, - struct wt_status *s) + struct wt_status *s, + struct strbuf *author_ident) { struct stat statbuf; + struct strbuf committer_ident = STRBUF_INIT; int commitable, saved_color_setting; struct strbuf sb = STRBUF_INIT; char *buffer; @@ -632,14 +645,13 @@ static int prepare_to_commit(const char *index_file, const char *prefix, strbuf_release(&sb); - determine_author_info(); + /* This checks and barfs if author is badly specified */ + determine_author_info(author_ident); /* This checks if committer ident is explicitly given */ - git_committer_info(0); + strbuf_addstr(&committer_ident, git_committer_info(0)); if (use_editor && include_status) { - char *author_ident; - const char *committer_ident; - + char *ai_tmp, *ci_tmp; if (in_merge) fprintf(fp, "#\n" @@ -667,23 +679,21 @@ static int prepare_to_commit(const char *index_file, const char *prefix, if (only_include_assumed) fprintf(fp, "# %s\n", only_include_assumed); - author_ident = xstrdup(fmt_name(author_name, author_email)); - committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"), - getenv("GIT_COMMITTER_EMAIL")); - if (strcmp(author_ident, committer_ident)) + ai_tmp = cut_ident_timestamp_part(author_ident->buf); + ci_tmp = cut_ident_timestamp_part(committer_ident.buf); + if (strcmp(author_ident->buf, committer_ident.buf)) fprintf(fp, "%s" "# Author: %s\n", ident_shown++ ? "" : "#\n", - author_ident); - free(author_ident); + author_ident->buf); if (!user_ident_sufficiently_given()) fprintf(fp, "%s" "# Committer: %s\n", ident_shown++ ? "" : "#\n", - committer_ident); + committer_ident.buf); if (ident_shown) fprintf(fp, "#\n"); @@ -692,6 +702,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix, s->use_color = 0; commitable = run_status(fp, index_file, prefix, 1, s); s->use_color = saved_color_setting; + + *ai_tmp = ' '; + *ci_tmp = ' '; } else { unsigned char sha1[20]; const char *parent = "HEAD"; @@ -707,6 +720,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, else commitable = index_differs_from(parent, 0); } + strbuf_release(&committer_ident); fclose(fp); @@ -1069,6 +1083,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) status_format = STATUS_FORMAT_PORCELAIN; wt_status_prepare(&s); + gitmodules_config(); git_config(git_status_config, &s); in_merge = file_exists(git_path("MERGE_HEAD")); argc = parse_options(argc, argv, prefix, @@ -1085,9 +1100,11 @@ int cmd_status(int argc, const char **argv, const char *prefix) fd = hold_locked_index(&index_lock, 0); if (0 <= fd) { - if (!write_cache(fd, active_cache, active_nr)) + if (active_cache_changed && + !write_cache(fd, active_cache, active_nr)) commit_locked_index(&index_lock); - rollback_lock_file(&index_lock); + else + rollback_lock_file(&index_lock); } s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; @@ -1157,7 +1174,6 @@ static void print_summary(const char *prefix, const unsigned char *sha1) init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); - rev.abbrev = 0; rev.diff = 1; rev.diffopt.output_format = DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY; @@ -1239,6 +1255,7 @@ static int run_rewrite_hook(const unsigned char *oldsha1, int cmd_commit(int argc, const char **argv, const char *prefix) { struct strbuf sb = STRBUF_INIT; + struct strbuf author_ident = STRBUF_INIT; const char *index_file, *reflog_msg; char *nl, *p; unsigned char commit_sha1[20]; @@ -1266,7 +1283,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) /* Set up everything for writing the commit object. This includes running hooks, writing the trees, and interacting with the user. */ - if (!prepare_to_commit(index_file, prefix, &s)) { + if (!prepare_to_commit(index_file, prefix, &s, &author_ident)) { rollback_index_files(); return 1; } @@ -1345,11 +1362,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1, - fmt_ident(author_name, author_email, author_date, - IDENT_ERROR_ON_NO_NAME))) { + author_ident.buf)) { rollback_index_files(); die("failed to write commit object"); } + strbuf_release(&author_ident); ref_lock = lock_any_ref_for_update("HEAD", initial_commit ? NULL : head_sha1, |