Merge branch 'ag/rebase-avoid-unneeded-checkout'
[git] / t / t3421-rebase-topology-linear.sh
1 #!/bin/sh
2
3 test_description='basic rebase topology tests'
4 . ./test-lib.sh
5 . "$TEST_DIRECTORY"/lib-rebase.sh
6
7 # a---b---c
8 #      \
9 #       d---e
10 test_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
19 test_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 }
29 test_run_rebase success ''
30 test_run_rebase success -m
31 test_run_rebase success -i
32 test_have_prereq !REBASE_P || test_run_rebase success -p
33
34 test_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
44 test_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 }
53 test_run_rebase success ''
54 test_run_rebase success -m
55 test_run_rebase success -i
56 test_have_prereq !REBASE_P || test_run_rebase success -p
57
58 test_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 }
69 test_run_rebase success ''
70 test_run_rebase success --fork-point
71 test_run_rebase success -m
72 test_run_rebase success -i
73 test_have_prereq !REBASE_P || test_run_rebase failure -p
74
75 test_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 }
86 test_run_rebase success ''
87 test_run_rebase success --fork-point
88 test_run_rebase success -m
89 test_run_rebase success -i
90 test_have_prereq !REBASE_P || test_run_rebase success -p
91
92 test_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 }
101 test_run_rebase success ''
102 test_run_rebase success --fork-point
103 test_run_rebase success -m
104 test_run_rebase success -i
105 test_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.
121 test_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
132 test_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 }
142 test_run_rebase success ''
143 test_run_rebase success -m
144 test_run_rebase success -i
145 test_have_prereq !REBASE_P || test_run_rebase success -p
146
147 test_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 }
157 test_run_rebase success ''
158 test_run_rebase success -m
159 test_run_rebase success -i
160 test_have_prereq !REBASE_P || test_run_rebase success -p
161
162 test_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 }
172 test_run_rebase success ''
173 test_run_rebase success -m
174 test_run_rebase success -i
175 test_have_prereq !REBASE_P || test_run_rebase success -p
176
177 test_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 }
187 test_run_rebase success ''
188 test_run_rebase success -m
189 test_run_rebase success -i
190 test_have_prereq !REBASE_P || test_run_rebase success -p
191
192 # a---b---c---j!
193 #      \
194 #       d---k!--l
195 #
196 # ! = empty
197 test_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
205 test_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 }
215 test_run_rebase success ''
216 test_run_rebase success -m
217 test_run_rebase success -i
218 test_have_prereq !REBASE_P || test_run_rebase success -p
219
220 test_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 }
230 test_run_rebase success ''
231 test_run_rebase success -m
232 test_run_rebase success -i
233 test_have_prereq !REBASE_P || test_run_rebase failure -p
234
235 test_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 }
245 test_run_rebase success ''
246 test_run_rebase success -m
247 test_run_rebase success -i
248 test_have_prereq !REBASE_P || test_run_rebase failure -p
249 test_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.
265 test_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
275 test_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 }
285 test_run_rebase success ''
286 test_run_rebase success -m
287 test_run_rebase success -i
288 test_have_prereq !REBASE_P || test_run_rebase success -p
289
290 test_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 }
300 test_run_rebase success ''
301 test_run_rebase success -m
302 test_run_rebase success -i
303 test_have_prereq !REBASE_P || test_run_rebase failure -p
304
305 test_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 }
315 test_run_rebase success ''
316 test_run_rebase success -m
317 test_run_rebase success -i
318 test_have_prereq !REBASE_P || test_run_rebase success -p
319
320 test_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
331 test_run_rebase success ''
332 test_run_rebase success -m
333 test_run_rebase success -i
334 test_have_prereq !REBASE_P || test_run_rebase failure -p
335
336 test_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 }
346 test_run_rebase success ''
347 test_run_rebase success -m
348 test_run_rebase success -i
349 test_have_prereq !REBASE_P || test_run_rebase failure -p
350
351 test_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 }
360 test_run_rebase success ''
361 test_run_rebase success -m
362 test_run_rebase success -i
363 test_have_prereq !REBASE_P || test_run_rebase failure -p
364
365 test_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 }
375 test_run_rebase success ''
376 test_run_rebase success -m
377 test_run_rebase success -i
378 test_have_prereq !REBASE_P || test_run_rebase success -p
379
380 test_done