Skip to content

Commit 1055997

Browse files
Denton-Lgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Denton Liu <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d540b70 commit 1055997

File tree

4 files changed

+82
-7
lines changed

4 files changed

+82
-7
lines changed

Documentation/merge-options.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ updated behaviour, the environment variable `GIT_MERGE_AUTOEDIT` can be
3333
set to `no` at the beginning of them.
3434

3535
--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.
3841

3942
--ff::
4043
When the merge resolves as a fast-forward, only update the branch

builtin/commit.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
668668
const char *hook_arg2 = NULL;
669669
int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE);
670670
int old_display_comment_prefix;
671+
int merge_contains_scissors = 0;
671672

672673
/* This checks and barfs if author is badly specified */
673674
determine_author_info(author_ident);
@@ -728,6 +729,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
728729
strbuf_addbuf(&sb, &message);
729730
hook_arg1 = "message";
730731
} else if (!stat(git_path_merge_msg(the_repository), &statbuf)) {
732+
size_t merge_msg_start;
733+
731734
/*
732735
* prepend SQUASH_MSG here if it exists and a
733736
* "merge --squash" was originally performed
@@ -738,8 +741,16 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
738741
hook_arg1 = "squash";
739742
} else
740743
hook_arg1 = "merge";
744+
745+
merge_msg_start = sb.len;
741746
if (strbuf_read_file(&sb, git_path_merge_msg(the_repository), 0) < 0)
742747
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;
743754
} else if (!stat(git_path_squash_msg(the_repository), &statbuf)) {
744755
if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0)
745756
die_errno(_("could not read SQUASH_MSG"));
@@ -807,7 +818,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
807818
struct ident_split ci, ai;
808819

809820
if (whence != FROM_COMMIT) {
810-
if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
821+
if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
822+
!merge_contains_scissors)
811823
wt_status_add_cut_line(s->fp);
812824
status_printf_ln(s, GIT_COLOR_NORMAL,
813825
whence == FROM_MERGE
@@ -832,10 +844,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
832844
_("Please enter the commit message for your changes."
833845
" Lines starting\nwith '%c' will be ignored, and an empty"
834846
" 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. */
839851
status_printf(s, GIT_COLOR_NORMAL,
840852
_("Please enter the commit message for your changes."
841853
" Lines starting\n"

builtin/merge.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,20 @@ static int suggest_conflicts(void)
920920
filename = git_path_merge_msg(the_repository);
921921
fp = xfopen(filename, "a");
922922

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+
923937
append_conflicts_hint(&the_index, &msgbuf);
924938
fputs(msgbuf.buf, fp);
925939
strbuf_release(&msgbuf);

t/t7600-merge.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,52 @@ test_expect_success 'merge --squash c3 with c7' '
246246
test_cmp expect actual
247247
'
248248

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+
249295
test_debug 'git log --graph --decorate --oneline --all'
250296

251297
test_expect_success 'merge c1 with c2 and c3' '

0 commit comments

Comments
 (0)