merge: add scissors line on merge conflict
This fixes a bug where the scissors line is placed after the Conflicts: section, in the case where a merge conflict occurs and commit.cleanup = scissors. Next, if commit.cleanup = scissors is specified, don't produce a scissors line in commit if one already exists in the MERGE_MSG file. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Denton Liu committed
Apr 17, 2019 at 11:23 UTC
1055997e2fc707a15baf232df2ac481055c14321
4 files changed
+82
-7
Documentation/merge-options.txt
+5
-2
@@ -33,8 +33,11 @@ updated behaviour, the environment variable `GIT_MERGE_AUTOEDIT` can be
33
set to `no` at the beginning of them.
34
35
--cleanup=<mode>::
36
- This option determines how the merge message will be cleaned up
37
- before commiting. See linkgit:git-commit[1] for more details.
36
+ This option determines how the merge message will be cleaned up before
37
+ commiting. See linkgit:git-commit[1] for more details. In addition, if
38
+ the '<mode>' is given a value of `scissors`, scissors will be appended
39
+ to `MERGE_MSG` before being passed on to the commit machinery in the
40
+ case of a merge conflict.
41
42
--ff::
43
When the merge resolves as a fast-forward, only update the branch
builtin/commit.c
+17
-5
@@ -668,6 +668,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
668
const char *hook_arg2 = NULL;
669
int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE);
670
int old_display_comment_prefix;
671
+ int merge_contains_scissors = 0;
672
673
/* This checks and barfs if author is badly specified */
674
determine_author_info(author_ident);
@@ -728,6 +729,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
729
strbuf_addbuf(&sb, &message);
730
hook_arg1 = "message";
731
} else if (!stat(git_path_merge_msg(the_repository), &statbuf)) {
732
+ size_t merge_msg_start;
733
+
734
/*
735
* prepend SQUASH_MSG here if it exists and a
736
* "merge --squash" was originally performed
@@ -738,8 +741,16 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
741
hook_arg1 = "squash";
742
} else
743
hook_arg1 = "merge";
744
+
745
+ merge_msg_start = sb.len;
746
if (strbuf_read_file(&sb, git_path_merge_msg(the_repository), 0) < 0)
747
die_errno(_("could not read MERGE_MSG"));
748
+
749
+ if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
750
+ wt_status_locate_end(sb.buf + merge_msg_start,
751
+ sb.len - merge_msg_start) <
752
+ sb.len - merge_msg_start)
753
+ merge_contains_scissors = 1;
754
} else if (!stat(git_path_squash_msg(the_repository), &statbuf)) {
755
if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0)
756
die_errno(_("could not read SQUASH_MSG"));
@@ -807,7 +818,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
818
struct ident_split ci, ai;
819
820
if (whence != FROM_COMMIT) {
810
- if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
821
+ if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
822
+ !merge_contains_scissors)
823
wt_status_add_cut_line(s->fp);
824
status_printf_ln(s, GIT_COLOR_NORMAL,
825
whence == FROM_MERGE
@@ -832,10 +844,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
844
_("Please enter the commit message for your changes."
845
" Lines starting\nwith '%c' will be ignored, and an empty"
846
" message aborts the commit.\n"), comment_line_char);
835
- else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
836
- whence == FROM_COMMIT)
837
- wt_status_add_cut_line(s->fp);
838
- else /* COMMIT_MSG_CLEANUP_SPACE, that is. */
847
+ else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {
848
+ if (whence == FROM_COMMIT && !merge_contains_scissors)
849
+ wt_status_add_cut_line(s->fp);
850
+ } else /* COMMIT_MSG_CLEANUP_SPACE, that is. */
851
status_printf(s, GIT_COLOR_NORMAL,
852
_("Please enter the commit message for your changes."
853
" Lines starting\n"
builtin/merge.c
+14
@@ -920,6 +920,20 @@ static int suggest_conflicts(void)
920
filename = git_path_merge_msg(the_repository);
921
fp = xfopen(filename, "a");
922
923
+ /*
924
+ * We can't use cleanup_mode because if we're not using the editor,
925
+ * get_cleanup_mode will return COMMIT_MSG_CLEANUP_SPACE instead, even
926
+ * though the message is meant to be processed later by git-commit.
927
+ * Thus, we will get the cleanup mode which is returned when we _are_
928
+ * using an editor.
929
+ */
930
+ if (get_cleanup_mode(cleanup_arg, 1) == COMMIT_MSG_CLEANUP_SCISSORS) {
931
+ fputc('\n', fp);
932
+ wt_status_add_cut_line(fp);
933
+ /* comments out the newline from append_conflicts_hint */
934
+ fputc(comment_line_char, fp);
935
+ }
936
+
937
append_conflicts_hint(&the_index, &msgbuf);
938
fputs(msgbuf.buf, fp);
939
strbuf_release(&msgbuf);
t/t7600-merge.sh
+46
@@ -246,6 +246,52 @@ test_expect_success 'merge --squash c3 with c7' '
246
test_cmp expect actual
247
'
248
249
+test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '
250
+ git config commit.cleanup scissors &&
251
+ git reset --hard c3 &&
252
+ test_must_fail git merge c7 &&
253
+ cat result.9z >file &&
254
+ git commit --no-edit -a &&
255
+
256
+ cat >expect <<-\EOF &&
257
+ Merge tag '"'"'c7'"'"'
258
+
259
+ # ------------------------ >8 ------------------------
260
+ # Do not modify or remove the line above.
261
+ # Everything below it will be ignored.
262
+ #
263
+ # Conflicts:
264
+ # file
265
+ EOF
266
+ git cat-file commit HEAD >raw &&
267
+ sed -e '1,/^$/d' raw >actual &&
268
+ test_i18ncmp expect actual
269
+'
270
+
271
+test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' '
272
+ git config commit.cleanup scissors &&
273
+ git reset --hard c3 &&
274
+ test_must_fail git merge --squash c7 &&
275
+ cat result.9z >file &&
276
+ git commit --no-edit -a &&
277
+
278
+ cat >expect <<-EOF &&
279
+ Squashed commit of the following:
280
+
281
+ $(git show -s c7)
282
+
283
+ # ------------------------ >8 ------------------------
284
+ # Do not modify or remove the line above.
285
+ # Everything below it will be ignored.
286
+ #
287
+ # Conflicts:
288
+ # file
289
+ EOF
290
+ git cat-file commit HEAD >raw &&
291
+ sed -e '1,/^$/d' raw >actual &&
292
+ test_i18ncmp expect actual
293
+'
294
+
295
test_debug 'git log --graph --decorate --oneline --all'
296
297
test_expect_success 'merge c1 with c2 and c3' '