Skip to content

Commit 4c28e4a

Browse files
committed
commit: die before asking to edit the log message
When determine_author_info() returns to the calling prepare_to_commit(), we already know the pieces of information necessary to determine what author ident will be used in the final message, but deferred making a call to fmt_ident() before the final commit_tree(). Most importantly, we would open the editor to ask the user to compose the log message before it. As one important side effect of fmt_ident() is to error out when the given information is malformed, this resulted in us spawning the editor first and then refusing to commit due to error, even though we had enough information to detect the error before starting the editor, which was annoying. Move the fmt_ident() call to the end of determine_author_info() where we have final determination of author info to rectify this. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4579bb4 commit 4c28e4a

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

builtin/commit.c

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ static enum {
6969
static const char *logfile, *force_author;
7070
static const char *template_file;
7171
static char *edit_message, *use_message;
72-
static char *author_name, *author_email, *author_date;
7372
static int all, edit_flag, also, interactive, only, amend, signoff;
7473
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
7574
static int no_post_rewrite, allow_empty_message;
@@ -459,7 +458,7 @@ static int is_a_merge(const unsigned char *sha1)
459458

460459
static const char sign_off_header[] = "Signed-off-by: ";
461460

462-
static void determine_author_info(void)
461+
static void determine_author_info(struct strbuf *author_ident)
463462
{
464463
char *name, *email, *date;
465464

@@ -503,10 +502,8 @@ static void determine_author_info(void)
503502

504503
if (force_date)
505504
date = force_date;
506-
507-
author_name = name;
508-
author_email = email;
509-
author_date = date;
505+
strbuf_addstr(author_ident, fmt_ident(name, email, date,
506+
IDENT_ERROR_ON_NO_NAME));
510507
}
511508

512509
static int ends_rfc2822_footer(struct strbuf *sb)
@@ -550,10 +547,21 @@ static int ends_rfc2822_footer(struct strbuf *sb)
550547
return 1;
551548
}
552549

550+
static char *cut_ident_timestamp_part(char *string)
551+
{
552+
char *ket = strrchr(string, '>');
553+
if (!ket || ket[1] != ' ')
554+
die("Malformed ident string: '%s'", string);
555+
*++ket = '\0';
556+
return ket;
557+
}
558+
553559
static int prepare_to_commit(const char *index_file, const char *prefix,
554-
struct wt_status *s)
560+
struct wt_status *s,
561+
struct strbuf *author_ident)
555562
{
556563
struct stat statbuf;
564+
struct strbuf committer_ident = STRBUF_INIT;
557565
int commitable, saved_color_setting;
558566
struct strbuf sb = STRBUF_INIT;
559567
char *buffer;
@@ -637,14 +645,13 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
637645

638646
strbuf_release(&sb);
639647

640-
determine_author_info();
648+
/* This checks and barfs if author is badly specified */
649+
determine_author_info(author_ident);
641650

642651
/* This checks if committer ident is explicitly given */
643-
git_committer_info(0);
652+
strbuf_addstr(&committer_ident, git_committer_info(0));
644653
if (use_editor && include_status) {
645-
char *author_ident;
646-
const char *committer_ident;
647-
654+
char *ai_tmp, *ci_tmp;
648655
if (in_merge)
649656
fprintf(fp,
650657
"#\n"
@@ -672,23 +679,21 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
672679
if (only_include_assumed)
673680
fprintf(fp, "# %s\n", only_include_assumed);
674681

675-
author_ident = xstrdup(fmt_name(author_name, author_email));
676-
committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
677-
getenv("GIT_COMMITTER_EMAIL"));
678-
if (strcmp(author_ident, committer_ident))
682+
ai_tmp = cut_ident_timestamp_part(author_ident->buf);
683+
ci_tmp = cut_ident_timestamp_part(committer_ident.buf);
684+
if (strcmp(author_ident->buf, committer_ident.buf))
679685
fprintf(fp,
680686
"%s"
681687
"# Author: %s\n",
682688
ident_shown++ ? "" : "#\n",
683-
author_ident);
684-
free(author_ident);
689+
author_ident->buf);
685690

686691
if (!user_ident_sufficiently_given())
687692
fprintf(fp,
688693
"%s"
689694
"# Committer: %s\n",
690695
ident_shown++ ? "" : "#\n",
691-
committer_ident);
696+
committer_ident.buf);
692697

693698
if (ident_shown)
694699
fprintf(fp, "#\n");
@@ -697,6 +702,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
697702
s->use_color = 0;
698703
commitable = run_status(fp, index_file, prefix, 1, s);
699704
s->use_color = saved_color_setting;
705+
706+
*ai_tmp = ' ';
707+
*ci_tmp = ' ';
700708
} else {
701709
unsigned char sha1[20];
702710
const char *parent = "HEAD";
@@ -712,6 +720,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
712720
else
713721
commitable = index_differs_from(parent, 0);
714722
}
723+
strbuf_release(&committer_ident);
715724

716725
fclose(fp);
717726

@@ -1246,6 +1255,7 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
12461255
int cmd_commit(int argc, const char **argv, const char *prefix)
12471256
{
12481257
struct strbuf sb = STRBUF_INIT;
1258+
struct strbuf author_ident = STRBUF_INIT;
12491259
const char *index_file, *reflog_msg;
12501260
char *nl, *p;
12511261
unsigned char commit_sha1[20];
@@ -1273,7 +1283,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
12731283

12741284
/* Set up everything for writing the commit object. This includes
12751285
running hooks, writing the trees, and interacting with the user. */
1276-
if (!prepare_to_commit(index_file, prefix, &s)) {
1286+
if (!prepare_to_commit(index_file, prefix, &s, &author_ident)) {
12771287
rollback_index_files();
12781288
return 1;
12791289
}
@@ -1352,11 +1362,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
13521362
}
13531363

13541364
if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
1355-
fmt_ident(author_name, author_email, author_date,
1356-
IDENT_ERROR_ON_NO_NAME))) {
1365+
author_ident.buf)) {
13571366
rollback_index_files();
13581367
die("failed to write commit object");
13591368
}
1369+
strbuf_release(&author_ident);
13601370

13611371
ref_lock = lock_any_ref_for_update("HEAD",
13621372
initial_commit ? NULL : head_sha1,

0 commit comments

Comments
 (0)