merge: save merge state earlier

If the `git merge` process is killed while waiting for the editor to finish, the merge state is lost but the prepared merge msg and tree is kept. So, a subsequent `git commit` creates a squashed merge even when the user asked for proper merge commit originally. Demonstrate the problem with a test crafted after the in t7502. The test requires EXECKEEPSPID (thus does not run under MINGW). Save the merge state earlier (in the non-squash case) so that it does not get lost. This makes the test pass. Reported-by: hIpPy <hippy2981@gmail.com> Signed-off-by: Michael J Gruber <git@grubix.eu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael J Gruber committed Aug 23, 2017 at 14:10 UTC 9d89b35526b54c3ba33371b184a1ba6e30f8f46f
2 files changed +17
builtin/merge.c
+2
@@ -756,6 +756,7 @@ N_("Please enter a commit message to explain why this merge is necessary,\n"
756 "Lines starting with '%c' will be ignored, and an empty message aborts\n"
757 "the commit.\n");
758
759 +static void write_merge_heads(struct commit_list *);
760 static void prepare_to_commit(struct commit_list *remoteheads)
761 {
762 struct strbuf msg = STRBUF_INIT;
@@ -765,6 +766,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)
766 BUG("the control must not reach here under --squash");
767 if (0 < option_edit)
768 strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
769 + write_merge_heads(remoteheads);
770 write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
771 if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
772 git_path_merge_msg(), "merge", NULL))
t/t7600-merge.sh
+15
@@ -774,4 +774,19 @@ test_expect_success 'merge can be completed with --continue' '
774 verify_parents $c0 $c1
775 '
776
777 +write_script .git/FAKE_EDITOR <<EOF
778 +# kill -TERM command added below.
779 +EOF
780 +
781 +test_expect_success EXECKEEPSPID 'killed merge can be completed with --continue' '
782 + git reset --hard c0 &&
783 + ! "$SHELL_PATH" -c '\''
784 + echo kill -TERM $$ >> .git/FAKE_EDITOR
785 + GIT_EDITOR=.git/FAKE_EDITOR
786 + export GIT_EDITOR
787 + exec git merge --no-ff --edit c1'\'' &&
788 + git merge --continue &&
789 + verify_parents $c0 $c1
790 +'
791 +
792 test_done