Skip to content

Commit 9f21e97

Browse files
Nanako Shiraishigitster
authored andcommitted
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: しらいし ななこ <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 61dfa1b commit 9f21e97

File tree

2 files changed

+94
-14
lines changed

2 files changed

+94
-14
lines changed

git-rebase.sh

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -419,22 +419,27 @@ fi
419419

420420
# Make sure the branch to rebase onto is valid.
421421
onto_name=${newbase-"$upstream_name"}
422-
if left=$(expr "$onto_name" : '\(.*\)\.\.\.') &&
423-
right=$(expr "$onto_name" : '\.\.\.\(.*\)$') &&
424-
: ${left:=HEAD} ${right:=HEAD} &&
425-
onto=$(git merge-base "$left" "$right")
426-
then
427-
case "$onto" in
428-
?*"$LF"?*)
429-
die "$onto_name: there are more than one merge bases"
430-
;;
431-
'')
422+
case "$onto_name" in
423+
*...*)
424+
if left=${onto_name%...*} right=${onto_name#*...} &&
425+
onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
426+
then
427+
case "$onto" in
428+
?*"$LF"?*)
429+
die "$onto_name: there are more than one merge bases"
430+
;;
431+
'')
432+
die "$onto_name: there is no merge base"
433+
;;
434+
esac
435+
else
432436
die "$onto_name: there is no merge base"
433-
;;
434-
esac
435-
else
437+
fi
438+
;;
439+
*)
436440
onto=$(git rev-parse --verify "${onto_name}^0") || exit
437-
fi
441+
;;
442+
esac
438443

439444
# If a hook exists, give it a chance to interrupt
440445
run_pre_rebase_hook "$upstream_arg" "$@"

t/t3415-rebase-onto-threedots.sh

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/sh
2+
3+
test_description='git rebase --onto A...B'
4+
5+
. ./test-lib.sh
6+
. "$TEST_DIRECTORY/lib-rebase.sh"
7+
8+
# Rebase only the tip commit of "topic" on merge base between "master"
9+
# and "topic". Cannot do this for "side" with "master" because there
10+
# is no single merge base.
11+
#
12+
#
13+
# F---G topic G'
14+
# / /
15+
# A---B---C---D---E master --> A---B---C---D---E
16+
# \ \ /
17+
# \ x
18+
# \ / \
19+
# H---I---J---K side
20+
21+
test_expect_success setup '
22+
test_commit A &&
23+
test_commit B &&
24+
git branch side &&
25+
test_commit C &&
26+
git branch topic &&
27+
git checkout side &&
28+
test_commit H &&
29+
git checkout master &&
30+
test_tick &&
31+
git merge H &&
32+
git tag D &&
33+
test_commit E &&
34+
git checkout topic &&
35+
test_commit F &&
36+
test_commit G &&
37+
git checkout side &&
38+
test_tick &&
39+
git merge C &&
40+
git tag I &&
41+
test_commit J &&
42+
test_commit K
43+
'
44+
45+
test_expect_success 'rebase --onto master...topic' '
46+
git reset --hard &&
47+
git checkout topic &&
48+
git reset --hard G &&
49+
50+
git rebase --onto master...topic F &&
51+
git rev-parse HEAD^1 >actual &&
52+
git rev-parse C^0 >expect &&
53+
test_cmp expect actual
54+
'
55+
56+
test_expect_success 'rebase --onto master...' '
57+
git reset --hard &&
58+
git checkout topic &&
59+
git reset --hard G &&
60+
61+
git rebase --onto master... F &&
62+
git rev-parse HEAD^1 >actual &&
63+
git rev-parse C^0 >expect &&
64+
test_cmp expect actual
65+
'
66+
67+
test_expect_success 'rebase --onto master...side' '
68+
git reset --hard &&
69+
git checkout side &&
70+
git reset --hard K &&
71+
72+
test_must_fail git rebase --onto master...side J
73+
'
74+
75+
test_done

0 commit comments

Comments
 (0)