diff options
-rwxr-xr-x | git-rebase--interactive.sh | 18 | ||||
-rwxr-xr-x | t/t3409-rebase-preserve-merges.sh | 56 |
2 files changed, 58 insertions, 16 deletions
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 1172e4757..c8b0861c0 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -115,9 +115,18 @@ mark_action_done () { } make_patch () { - parent_sha1=$(git rev-parse --verify "$1"^) || - die "Cannot get patch for $1^" - git diff-tree -p "$parent_sha1".."$1" > "$DOTEST"/patch + sha1_and_parents="$(git rev-list --parents -1 "$1")" + case "$sha1_and_parents" in + ?*' '?*' '?*) + git diff --cc $sha1_and_parents + ;; + ?*' '?*) + git diff-tree -p "$1^!" + ;; + *) + echo "Root commit" + ;; + esac > "$DOTEST"/patch test -f "$DOTEST"/message || git cat-file commit "$1" | sed "1,/^$/d" > "$DOTEST"/message test -f "$DOTEST"/author-script || @@ -256,9 +265,8 @@ pick_one_preserving_merges () { output git merge $STRATEGY -m "$msg" \ $new_parents then - git rerere printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG - die Error redoing merge $sha1 + die_with_patch $sha1 "Error redoing merge $sha1" fi ;; *) diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh index 8cde40f8e..e6c832780 100755 --- a/t/t3409-rebase-preserve-merges.sh +++ b/t/t3409-rebase-preserve-merges.sh @@ -11,15 +11,23 @@ Run "git rebase -p" and check that merges are properly carried along GIT_AUTHOR_EMAIL=bogus_email_address export GIT_AUTHOR_EMAIL -#echo 'Setting up: +# Clone 1 (trivial merge): # -#A1--A2 <-- origin/master -# \ \ -# B1--M <-- topic -# \ -# B2 <-- origin/topic +# A1--A2 <-- origin/master +# \ \ +# B1--M <-- topic +# \ +# B2 <-- origin/topic # -#' +# Clone 2 (conflicting merge): +# +# A1--A2--B3 <-- origin/master +# \ \ +# B1------M <-- topic +# \ +# B2 <-- origin/topic +# +# In both cases, 'topic' is rebased onto 'origin/topic'. test_expect_success 'setup for merge-preserving rebase' \ 'echo First > A && @@ -37,12 +45,19 @@ test_expect_success 'setup for merge-preserving rebase' \ cd clone1 && git checkout -b topic origin/topic && git merge origin/master && - cd .. + cd .. && + + echo Fifth > B && + git add B && + git commit -m "Add different B" && - git clone ./. clone2 + git clone ./. clone2 && cd clone2 && git checkout -b topic origin/topic && - git merge origin/master && + test_must_fail git merge origin/master && + echo Resolved > B && + git add B && + git commit -m "Merge origin/master into topic" && cd .. && git checkout topic && @@ -51,11 +66,30 @@ test_expect_success 'setup for merge-preserving rebase' \ ' test_expect_success 'rebase -p fakes interactive rebase' ' - cd clone2 && + ( + cd clone1 && git fetch && git rebase -p origin/topic && test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && test 1 = $(git rev-list --all --pretty=oneline | grep "Merge commit" | wc -l) + ) +' + +test_expect_success '--continue works after a conflict' ' + ( + cd clone2 && + git fetch && + test_must_fail git rebase -p origin/topic && + test 2 = $(git ls-files B | wc -l) && + echo Resolved again > B && + test_must_fail git rebase --continue && + grep "^@@@ " .git/rebase-merge/patch && + git add B && + git rebase --continue && + test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && + test 1 = $(git rev-list --all --pretty=oneline | grep "Add different" | wc -l) && + test 1 = $(git rev-list --all --pretty=oneline | grep "Merge origin" | wc -l) + ) ' test_done |