1#!/bin/sh
2
3test_description='basic rebase topology tests'
4. ./test-lib.sh
5. "$TEST_DIRECTORY"/lib-rebase.sh
6
7# a---b---c
8# \
9# d---e
10test_expect_success 'setup' '
11 test_commit a &&
12 test_commit b &&
13 test_commit c &&
14 git checkout b &&
15 test_commit d &&
16 test_commit e
17'
18
19test_run_rebase () {
20 result=$1
21 shift
22 test_expect_$result "simple rebase $*" "
23 reset_rebase &&
24 git rebase $* c e &&
25 test_cmp_rev c HEAD~2 &&
26 test_linear_range 'd e' c..
27 "
28}
29test_run_rebase success ''
30test_run_rebase success -m
31test_run_rebase success -i
32test_have_prereq !REBASE_P || test_run_rebase success -p
33
34test_expect_success 'setup branches and remote tracking' '
35 git tag -l >tags &&
36 for tag in $(cat tags)
37 do
38 git branch branch-$tag $tag || return 1
39 done &&
40 git remote add origin "file://$PWD" &&
41 git fetch origin
42'
43
44test_run_rebase () {
45 result=$1
46 shift
47 test_expect_$result "rebase $* is no-op if upstream is an ancestor" "
48 reset_rebase &&
49 git rebase $* b e &&
50 test_cmp_rev e HEAD
51 "
52}
53test_run_rebase success ''
54test_run_rebase success -m
55test_run_rebase success -i
56test_have_prereq !REBASE_P || test_run_rebase success -p
57
58test_run_rebase () {
59 result=$1
60 shift
61 test_expect_$result "rebase $* -f rewrites even if upstream is an ancestor" "
62 reset_rebase &&
63 git rebase $* -f b e &&
64 ! test_cmp_rev e HEAD &&
65 test_cmp_rev b HEAD~2 &&
66 test_linear_range 'd e' b..
67 "
68}
69test_run_rebase success ''
70test_run_rebase success --fork-point
71test_run_rebase success -m
72test_run_rebase success -i
73test_have_prereq !REBASE_P || test_run_rebase failure -p
74
75test_run_rebase () {
76 result=$1
77 shift
78 test_expect_$result "rebase $* -f rewrites even if remote upstream is an ancestor" "
79 reset_rebase &&
80 git rebase $* -f branch-b branch-e &&
81 ! test_cmp_rev branch-e origin/branch-e &&
82 test_cmp_rev branch-b HEAD~2 &&
83 test_linear_range 'd e' branch-b..
84 "
85}
86test_run_rebase success ''
87test_run_rebase success --fork-point
88test_run_rebase success -m
89test_run_rebase success -i
90test_have_prereq !REBASE_P || test_run_rebase success -p
91
92test_run_rebase () {
93 result=$1
94 shift
95 test_expect_$result "rebase $* fast-forwards from ancestor of upstream" "
96 reset_rebase &&
97 git rebase $* e b &&
98 test_cmp_rev e HEAD
99 "
100}
101test_run_rebase success ''
102test_run_rebase success --fork-point
103test_run_rebase success -m
104test_run_rebase success -i
105test_have_prereq !REBASE_P || test_run_rebase success -p
106
107# f
108# /
109# a---b---c---g---h
110# \
111# d---gp--i
112#
113# gp = cherry-picked g
114# h = reverted g
115#
116# Reverted patches are there for tests to be able to check if a commit
117# that introduced the same change as another commit is
118# dropped. Without reverted commits, we could get false positives
119# because applying the patch succeeds, but simply results in no
120# changes.
121test_expect_success 'setup of linear history for range selection tests' '
122 git checkout c &&
123 test_commit g &&
124 revert h g &&
125 git checkout d &&
126 cherry_pick gp g &&
127 test_commit i &&
128 git checkout b &&
129 test_commit f
130'
131
132test_run_rebase () {
133 result=$1
134 shift
135 test_expect_$result "rebase $* drops patches in upstream" "
136 reset_rebase &&
137 git rebase $* h i &&
138 test_cmp_rev h HEAD~2 &&
139 test_linear_range 'd i' h..
140 "
141}
142test_run_rebase success ''
143test_run_rebase success -m
144test_run_rebase success -i
145test_have_prereq !REBASE_P || test_run_rebase success -p
146
147test_run_rebase () {
148 result=$1
149 shift
150 test_expect_$result "rebase $* can drop last patch if in upstream" "
151 reset_rebase &&
152 git rebase $* h gp &&
153 test_cmp_rev h HEAD^ &&
154 test_linear_range 'd' h..
155 "
156}
157test_run_rebase success ''
158test_run_rebase success -m
159test_run_rebase success -i
160test_have_prereq !REBASE_P || test_run_rebase success -p
161
162test_run_rebase () {
163 result=$1
164 shift
165 test_expect_$result "rebase $* --onto drops patches in upstream" "
166 reset_rebase &&
167 git rebase $* --onto f h i &&
168 test_cmp_rev f HEAD~2 &&
169 test_linear_range 'd i' f..
170 "
171}
172test_run_rebase success ''
173test_run_rebase success -m
174test_run_rebase success -i
175test_have_prereq !REBASE_P || test_run_rebase success -p
176
177test_run_rebase () {
178 result=$1
179 shift
180 test_expect_$result "rebase $* --onto does not drop patches in onto" "
181 reset_rebase &&
182 git rebase $* --onto h f i &&
183 test_cmp_rev h HEAD~3 &&
184 test_linear_range 'd gp i' h..
185 "
186}
187test_run_rebase success ''
188test_run_rebase success -m
189test_run_rebase success -i
190test_have_prereq !REBASE_P || test_run_rebase success -p
191
192# a---b---c---j!
193# \
194# d---k!--l
195#
196# ! = empty
197test_expect_success 'setup of linear history for empty commit tests' '
198 git checkout c &&
199 make_empty j &&
200 git checkout d &&
201 make_empty k &&
202 test_commit l
203'
204
205test_run_rebase () {
206 result=$1
207 shift
208 test_expect_$result "rebase $* drops empty commit" "
209 reset_rebase &&
210 git rebase $* c l &&
211 test_cmp_rev c HEAD~2 &&
212 test_linear_range 'd l' c..
213 "
214}
215test_run_rebase success ''
216test_run_rebase success -m
217test_run_rebase success -i
218test_have_prereq !REBASE_P || test_run_rebase success -p
219
220test_run_rebase () {
221 result=$1
222 shift
223 test_expect_$result "rebase $* --keep-empty" "
224 reset_rebase &&
225 git rebase $* --keep-empty c l &&
226 test_cmp_rev c HEAD~3 &&
227 test_linear_range 'd k l' c..
228 "
229}
230test_run_rebase success ''
231test_run_rebase success -m
232test_run_rebase success -i
233test_have_prereq !REBASE_P || test_run_rebase failure -p
234
235test_run_rebase () {
236 result=$1
237 shift
238 test_expect_$result "rebase $* --keep-empty keeps empty even if already in upstream" "
239 reset_rebase &&
240 git rebase $* --keep-empty j l &&
241 test_cmp_rev j HEAD~3 &&
242 test_linear_range 'd k l' j..
243 "
244}
245test_run_rebase success ''
246test_run_rebase success -m
247test_run_rebase success -i
248test_have_prereq !REBASE_P || test_run_rebase failure -p
249test_run_rebase success --rebase-merges
250
251# m
252# /
253# a---b---c---g
254#
255# x---y---bp
256#
257# bp = cherry-picked b
258# m = reverted b
259#
260# Reverted patches are there for tests to be able to check if a commit
261# that introduced the same change as another commit is
262# dropped. Without reverted commits, we could get false positives
263# because applying the patch succeeds, but simply results in no
264# changes.
265test_expect_success 'setup of linear history for test involving root' '
266 git checkout b &&
267 revert m b &&
268 git checkout --orphan disjoint &&
269 git rm -rf . &&
270 test_commit x &&
271 test_commit y &&
272 cherry_pick bp b
273'
274
275test_run_rebase () {
276 result=$1
277 shift
278 test_expect_$result "rebase $* --onto --root" "
279 reset_rebase &&
280 git rebase $* --onto c --root y &&
281 test_cmp_rev c HEAD~2 &&
282 test_linear_range 'x y' c..
283 "
284}
285test_run_rebase success ''
286test_run_rebase success -m
287test_run_rebase success -i
288test_have_prereq !REBASE_P || test_run_rebase success -p
289
290test_run_rebase () {
291 result=$1
292 shift
293 test_expect_$result "rebase $* without --onto --root with disjoint history" "
294 reset_rebase &&
295 git rebase $* c y &&
296 test_cmp_rev c HEAD~2 &&
297 test_linear_range 'x y' c..
298 "
299}
300test_run_rebase success ''
301test_run_rebase success -m
302test_run_rebase success -i
303test_have_prereq !REBASE_P || test_run_rebase failure -p
304
305test_run_rebase () {
306 result=$1
307 shift
308 test_expect_$result "rebase $* --onto --root drops patch in onto" "
309 reset_rebase &&
310 git rebase $* --onto m --root bp &&
311 test_cmp_rev m HEAD~2 &&
312 test_linear_range 'x y' m..
313 "
314}
315test_run_rebase success ''
316test_run_rebase success -m
317test_run_rebase success -i
318test_have_prereq !REBASE_P || test_run_rebase success -p
319
320test_run_rebase () {
321 result=$1
322 shift
323 test_expect_$result "rebase $* --onto --root with merge-base does not go to root" "
324 reset_rebase &&
325 git rebase $* --onto m --root g &&
326 test_cmp_rev m HEAD~2 &&
327 test_linear_range 'c g' m..
328 "
329}
330
331test_run_rebase success ''
332test_run_rebase success -m
333test_run_rebase success -i
334test_have_prereq !REBASE_P || test_run_rebase failure -p
335
336test_run_rebase () {
337 result=$1
338 shift
339 test_expect_$result "rebase $* without --onto --root with disjoint history drops patch in onto" "
340 reset_rebase &&
341 git rebase $* m bp &&
342 test_cmp_rev m HEAD~2 &&
343 test_linear_range 'x y' m..
344 "
345}
346test_run_rebase success ''
347test_run_rebase success -m
348test_run_rebase success -i
349test_have_prereq !REBASE_P || test_run_rebase failure -p
350
351test_run_rebase () {
352 result=$1
353 shift
354 test_expect_$result "rebase $* --root on linear history is a no-op" "
355 reset_rebase &&
356 git rebase $* --root c &&
357 test_cmp_rev c HEAD
358 "
359}
360test_run_rebase success ''
361test_run_rebase success -m
362test_run_rebase success -i
363test_have_prereq !REBASE_P || test_run_rebase failure -p
364
365test_run_rebase () {
366 result=$1
367 shift
368 test_expect_$result "rebase $* -f --root on linear history causes re-write" "
369 reset_rebase &&
370 git rebase $* -f --root c &&
371 ! test_cmp_rev a HEAD~2 &&
372 test_linear_range 'a b c' HEAD
373 "
374}
375test_run_rebase success ''
376test_run_rebase success -m
377test_run_rebase success -i
378test_have_prereq !REBASE_P || test_run_rebase success -p
379
380test_done