git-commit: Refactor creation of log message.
This patch moves the code of run_commit, up to writing the trees, editing the message and running the commit-msg hook to prepare_log_message. It also renames the latter to prepare_to_commit. This simplifies a little the code for the next patch. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Paolo Bonzini committed
Feb 5, 2008 at 11:01 UTC
ec84bd000a89e657b36136ec927144cd13f26079
2 files changed
+117
-83
builtin-commit.c
+88
-83
@@ -377,9 +377,17 @@ static int run_hook(const char *index_file, const char *name, ...)
377
return run_command(&hook);
378
}
379
380
+static int is_a_merge(const unsigned char *sha1)
381
+{
382
+ struct commit *commit = lookup_commit(sha1);
383
+ if (!commit || parse_commit(commit))
384
+ die("could not parse HEAD commit");
385
+ return !!(commit->parents && commit->parents->next);
386
+}
387
+
388
static const char sign_off_header[] = "Signed-off-by: ";
389
382
-static int prepare_log_message(const char *index_file, const char *prefix)
390
+static int prepare_to_commit(const char *index_file, const char *prefix)
391
{
392
struct stat statbuf;
393
int commitable, saved_color_setting;
@@ -387,6 +395,9 @@ static int prepare_log_message(const char *index_file, const char *prefix)
395
char *buffer;
396
FILE *fp;
397
398
+ if (!no_verify && run_hook(index_file, "pre-commit", NULL))
399
+ return 0;
400
+
401
strbuf_init(&sb, 0);
402
if (message.len) {
403
strbuf_addbuf(&sb, &message);
@@ -447,13 +458,38 @@ static int prepare_log_message(const char *index_file, const char *prefix)
458
459
strbuf_release(&sb);
460
450
- if (!use_editor) {
461
+ if (use_editor) {
462
+ if (in_merge)
463
+ fprintf(fp,
464
+ "#\n"
465
+ "# It looks like you may be committing a MERGE.\n"
466
+ "# If this is not correct, please remove the file\n"
467
+ "# %s\n"
468
+ "# and try again.\n"
469
+ "#\n",
470
+ git_path("MERGE_HEAD"));
471
+
472
+ fprintf(fp,
473
+ "\n"
474
+ "# Please enter the commit message for your changes.\n"
475
+ "# (Comment lines starting with '#' will ");
476
+ if (cleanup_mode == CLEANUP_ALL)
477
+ fprintf(fp, "not be included)\n");
478
+ else /* CLEANUP_SPACE, that is. */
479
+ fprintf(fp, "be kept.\n"
480
+ "# You can remove them yourself if you want to)\n");
481
+ if (only_include_assumed)
482
+ fprintf(fp, "# %s\n", only_include_assumed);
483
+
484
+ saved_color_setting = wt_status_use_color;
485
+ wt_status_use_color = 0;
486
+ commitable = run_status(fp, index_file, prefix, 1);
487
+ wt_status_use_color = saved_color_setting;
488
+ } else {
489
struct rev_info rev;
490
unsigned char sha1[20];
491
const char *parent = "HEAD";
492
455
- fclose(fp);
456
-
493
if (!active_nr && read_cache() < 0)
494
die("Cannot read index");
495
@@ -461,48 +497,56 @@ static int prepare_log_message(const char *index_file, const char *prefix)
497
parent = "HEAD^1";
498
499
if (get_sha1(parent, sha1))
464
- return !!active_nr;
500
+ commitable = !!active_nr;
501
+ else {
502
+ init_revisions(&rev, "");
503
+ rev.abbrev = 0;
504
+ setup_revisions(0, NULL, &rev, parent);
505
+ DIFF_OPT_SET(&rev.diffopt, QUIET);
506
+ DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);
507
+ run_diff_index(&rev, 1 /* cached */);
508
+
509
+ commitable = !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES);
510
+ }
511
+ }
512
466
- init_revisions(&rev, "");
467
- rev.abbrev = 0;
468
- setup_revisions(0, NULL, &rev, parent);
469
- DIFF_OPT_SET(&rev.diffopt, QUIET);
470
- DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);
471
- run_diff_index(&rev, 1 /* cached */);
513
+ fclose(fp);
514
+
515
+ if (!commitable && !in_merge && !allow_empty &&
516
+ !(amend && is_a_merge(head_sha1))) {
517
+ run_status(stdout, index_file, prefix, 0);
518
+ unlink(commit_editmsg);
519
+ return 0;
520
+ }
521
473
- return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES);
522
+ /*
523
+ * Re-read the index as pre-commit hook could have updated it,
524
+ * and write it out as a tree. We must do this before we invoke
525
+ * the editor and after we invoke run_status above.
526
+ */
527
+ discard_cache();
528
+ read_cache_from(index_file);
529
+ if (!active_cache_tree)
530
+ active_cache_tree = cache_tree();
531
+ if (cache_tree_update(active_cache_tree,
532
+ active_cache, active_nr, 0, 0) < 0) {
533
+ error("Error building trees");
534
+ return 0;
535
}
536
476
- if (in_merge)
477
- fprintf(fp,
478
- "#\n"
479
- "# It looks like you may be committing a MERGE.\n"
480
- "# If this is not correct, please remove the file\n"
481
- "# %s\n"
482
- "# and try again.\n"
483
- "#\n",
484
- git_path("MERGE_HEAD"));
485
-
486
- fprintf(fp,
487
- "\n"
488
- "# Please enter the commit message for your changes.\n"
489
- "# (Comment lines starting with '#' will ");
490
- if (cleanup_mode == CLEANUP_ALL)
491
- fprintf(fp, "not be included)\n");
492
- else /* CLEANUP_SPACE, that is. */
493
- fprintf(fp, "be kept.\n"
494
- "# You can remove them yourself if you want to)\n");
495
- if (only_include_assumed)
496
- fprintf(fp, "# %s\n", only_include_assumed);
497
-
498
- saved_color_setting = wt_status_use_color;
499
- wt_status_use_color = 0;
500
- commitable = run_status(fp, index_file, prefix, 1);
501
- wt_status_use_color = saved_color_setting;
537
+ if (use_editor) {
538
+ char index[PATH_MAX];
539
+ const char *env[2] = { index, NULL };
540
+ snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
541
+ launch_editor(git_path(commit_editmsg), NULL, env);
542
+ }
543
503
- fclose(fp);
544
+ if (!no_verify &&
545
+ run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
546
+ return 0;
547
+ }
548
505
- return commitable;
549
+ return 1;
550
}
551
552
/*
@@ -761,14 +805,6 @@ int git_commit_config(const char *k, const char *v)
805
return git_status_config(k, v);
806
}
807
764
-static int is_a_merge(const unsigned char *sha1)
765
-{
766
- struct commit *commit = lookup_commit(sha1);
767
- if (!commit || parse_commit(commit))
768
- die("could not parse HEAD commit");
769
- return !!(commit->parents && commit->parents->next);
770
-}
771
-
808
static const char commit_utf8_warn[] =
809
"Warning: commit message does not conform to UTF-8.\n"
810
"You may want to amend it after fixing the message, or set the config\n"
@@ -800,33 +836,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
836
837
index_file = prepare_index(argc, argv, prefix);
838
803
- if (!no_verify && run_hook(index_file, "pre-commit", NULL)) {
804
- rollback_index_files();
805
- return 1;
806
- }
807
-
808
- if (!prepare_log_message(index_file, prefix) && !in_merge &&
809
- !allow_empty && !(amend && is_a_merge(head_sha1))) {
810
- run_status(stdout, index_file, prefix, 0);
839
+ /* Set up everything for writing the commit object. This includes
840
+ running hooks, writing the trees, and interacting with the user. */
841
+ if (!prepare_to_commit(index_file, prefix)) {
842
rollback_index_files();
812
- unlink(commit_editmsg);
843
return 1;
844
}
845
816
- /*
817
- * Re-read the index as pre-commit hook could have updated it,
818
- * and write it out as a tree.
819
- */
820
- discard_cache();
821
- read_cache_from(index_file);
822
- if (!active_cache_tree)
823
- active_cache_tree = cache_tree();
824
- if (cache_tree_update(active_cache_tree,
825
- active_cache, active_nr, 0, 0) < 0) {
826
- rollback_index_files();
827
- die("Error building trees");
828
- }
829
-
846
/*
847
* The commit object
848
*/
@@ -878,19 +894,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
894
strbuf_addf(&sb, "encoding %s\n", git_commit_encoding);
895
strbuf_addch(&sb, '\n');
896
881
- /* Get the commit message and validate it */
897
+ /* Finally, get the commit message */
898
header_len = sb.len;
883
- if (use_editor) {
884
- char index[PATH_MAX];
885
- const char *env[2] = { index, NULL };
886
- snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
887
- launch_editor(git_path(commit_editmsg), NULL, env);
888
- }
889
- if (!no_verify &&
890
- run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
891
- rollback_index_files();
892
- exit(1);
893
- }
899
if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
900
rollback_index_files();
901
die("could not read commit message");
t/t7502-commit.sh
+29
@@ -154,4 +154,33 @@ test_expect_success 'cleanup commit messages (strip,-F,-e)' '
154
155
'
156
157
+pwd=`pwd`
158
+cat >> .git/FAKE_EDITOR << EOF
159
+#! /bin/sh
160
+echo editor started > "$pwd/.git/result"
161
+exit 0
162
+EOF
163
+chmod +x .git/FAKE_EDITOR
164
+
165
+test_expect_success 'do not fire editor in the presence of conflicts' '
166
+
167
+ git clean
168
+ echo f>g
169
+ git add g
170
+ git commit -myes
171
+ git branch second
172
+ echo master>g
173
+ echo g>h
174
+ git add g h
175
+ git commit -mmaster
176
+ git checkout second
177
+ echo second>g
178
+ git add g
179
+ git commit -msecond
180
+ git cherry-pick -n master
181
+ echo "editor not started" > .git/result
182
+ GIT_EDITOR=`pwd`/.git/FAKE_EDITOR git commit && exit 1 # should fail
183
+ test "`cat .git/result`" = "editor not started"
184
+'
185
+
186
test_done