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>
Nanako Shiraishi committed
Jan 7, 2010 at 20:05 UTC
9f21e97ddccf114a6919cf4b8cf57c2838328f36
2 files changed
+94
-14
git-rebase.sh
+19
-14
@@ -419,22 +419,27 @@ fi
419
420
# Make sure the branch to rebase onto is valid.
421
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
436
die "$onto_name: there is no merge base"
433
- ;;
434
- esac
435
-else
437
+ fi
438
+ ;;
439
+*)
440
onto=$(git rev-parse --verify "${onto_name}^0") || exit
437
-fi
441
+ ;;
442
+esac
443
444
# If a hook exists, give it a chance to interrupt
445
run_pre_rebase_hook "$upstream_arg" "$@"
t/t3415-rebase-onto-threedots.sh
new
+75
@@ -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