rebase: fix --onto A...B parsing and add tests

The previous patch didn't parse "rebase --onto A...B" correctly when A
isn't an empty string. It also tried to be careful to notice a case in
which there are more than one merge bases, but forgot to give --all option
to merge-base, making the test pointless.

Fix these problems and add a test script to verify. Improvements to the
script to parse A...B syntax was taken from review comments by Johannes
Schindelin.

Signed-off-by: しらいし ななこ <nanako3@lavabit.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nanako Shiraishi 2010-01-07 20:05:02 +09:00 committed by Junio C Hamano
parent 61dfa1bb67
commit 9f21e97ddc
2 changed files with 94 additions and 14 deletions

View File

@ -419,22 +419,27 @@ fi
# Make sure the branch to rebase onto is valid. # Make sure the branch to rebase onto is valid.
onto_name=${newbase-"$upstream_name"} onto_name=${newbase-"$upstream_name"}
if left=$(expr "$onto_name" : '\(.*\)\.\.\.') && case "$onto_name" in
right=$(expr "$onto_name" : '\.\.\.\(.*\)$') && *...*)
: ${left:=HEAD} ${right:=HEAD} && if left=${onto_name%...*} right=${onto_name#*...} &&
onto=$(git merge-base "$left" "$right") onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
then then
case "$onto" in case "$onto" in
?*"$LF"?*) ?*"$LF"?*)
die "$onto_name: there are more than one merge bases" die "$onto_name: there are more than one merge bases"
;; ;;
'') '')
die "$onto_name: there is no merge base"
;;
esac
else
die "$onto_name: there is no merge base" die "$onto_name: there is no merge base"
;; fi
esac ;;
else *)
onto=$(git rev-parse --verify "${onto_name}^0") || exit onto=$(git rev-parse --verify "${onto_name}^0") || exit
fi ;;
esac
# If a hook exists, give it a chance to interrupt # If a hook exists, give it a chance to interrupt
run_pre_rebase_hook "$upstream_arg" "$@" run_pre_rebase_hook "$upstream_arg" "$@"

View File

@ -0,0 +1,75 @@
#!/bin/sh
test_description='git rebase --onto A...B'
. ./test-lib.sh
. "$TEST_DIRECTORY/lib-rebase.sh"
# Rebase only the tip commit of "topic" on merge base between "master"
# and "topic". Cannot do this for "side" with "master" because there
# is no single merge base.
#
#
# F---G topic G'
# / /
# A---B---C---D---E master --> A---B---C---D---E
# \ \ /
# \ x
# \ / \
# H---I---J---K side
test_expect_success setup '
test_commit A &&
test_commit B &&
git branch side &&
test_commit C &&
git branch topic &&
git checkout side &&
test_commit H &&
git checkout master &&
test_tick &&
git merge H &&
git tag D &&
test_commit E &&
git checkout topic &&
test_commit F &&
test_commit G &&
git checkout side &&
test_tick &&
git merge C &&
git tag I &&
test_commit J &&
test_commit K
'
test_expect_success 'rebase --onto master...topic' '
git reset --hard &&
git checkout topic &&
git reset --hard G &&
git rebase --onto master...topic F &&
git rev-parse HEAD^1 >actual &&
git rev-parse C^0 >expect &&
test_cmp expect actual
'
test_expect_success 'rebase --onto master...' '
git reset --hard &&
git checkout topic &&
git reset --hard G &&
git rebase --onto master... F &&
git rev-parse HEAD^1 >actual &&
git rev-parse C^0 >expect &&
test_cmp expect actual
'
test_expect_success 'rebase --onto master...side' '
git reset --hard &&
git checkout side &&
git reset --hard K &&
test_must_fail git rebase --onto master...side J
'
test_done