summaryrefslogtreecommitdiff
path: root/sequencer.c
diff options
context:
space:
mode:
authorPhillip Wood <phillip.wood@dunelm.org.uk>2018-08-15 09:39:35 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-08-16 15:54:50 (GMT)
commitbc9238bb0910f6d21e021e5c3061bf2124c3a176 (patch)
tree2dbaa5e5e6e7a0e5e3e4be774d210df7713b6358 /sequencer.c
parentd54e18986291474f077283c9d4cb5e970e1373a4 (diff)
downloadgit-bc9238bb0910f6d21e021e5c3061bf2124c3a176.zip
git-bc9238bb0910f6d21e021e5c3061bf2124c3a176.tar.gz
git-bc9238bb0910f6d21e021e5c3061bf2124c3a176.tar.bz2
rebase -i: fix SIGSEGV when 'merge <branch>' fails
If a merge command in the todo list specifies just a branch to merge with no -C/-c argument then item->commit is NULL. This means that if there are merge conflicts error_with_patch() is passed a NULL commit which causes a segmentation fault when make_patch() tries to look it up. This commit implements a minimal fix which fixes the crash and allows the user to successfully commit a conflict resolution with 'git rebase --continue'. It does not write .git/rebase-merge/patch, .git/rebase-merge/stopped-sha or update REBASE_HEAD. To sensibly get the hashes of the merge parents would require refactoring do_merge() to extract the code that parses the merge parents into a separate function which error_with_patch() could then use to write the parents into the stopped-sha file. To create meaningful output make_patch() and 'git rebase --show-current-patch' would also need to be modified to diff the merge parent and merge base in this case. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'sequencer.c')
-rw-r--r--sequencer.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/sequencer.c b/sequencer.c
index 4034c04..df49199 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2590,8 +2590,12 @@ static int error_with_patch(struct commit *commit,
const char *subject, int subject_len,
struct replay_opts *opts, int exit_code, int to_amend)
{
- if (make_patch(commit, opts))
- return -1;
+ if (commit) {
+ if (make_patch(commit, opts))
+ return -1;
+ } else if (copy_file(rebase_path_message(), git_path_merge_msg(), 0666))
+ return error(_("unable to copy '%s' to '%s'"),
+ git_path_merge_msg(), rebase_path_message());
if (to_amend) {
if (intend_to_amend())
@@ -2604,9 +2608,19 @@ static int error_with_patch(struct commit *commit,
"Once you are satisfied with your changes, run\n"
"\n"
" git rebase --continue\n", gpg_sign_opt_quoted(opts));
- } else if (exit_code)
- fprintf(stderr, "Could not apply %s... %.*s\n",
- short_commit_name(commit), subject_len, subject);
+ } else if (exit_code) {
+ if (commit)
+ fprintf(stderr, "Could not apply %s... %.*s\n",
+ short_commit_name(commit),
+ subject_len, subject);
+ else
+ /*
+ * We don't have the hash of the parent so
+ * just print the line from the todo file.
+ */
+ fprintf(stderr, "Could not merge %.*s\n",
+ subject_len, subject);
+ }
return exit_code;
}