]> git.ipfire.org Git - thirdparty/git.git/blame - t/t3400-rebase.sh
Merge branch 'js/ci-use-macos-13'
[thirdparty/git.git] / t / t3400-rebase.sh
CommitLineData
294c695d
AW
1#!/bin/sh
2#
3# Copyright (c) 2005 Amos Waterland
4#
5
c2ca1d79 6test_description='git rebase assorted tests
294c695d 7
c2ca1d79
JH
8This test runs git rebase and checks that the author information is not lost
9among other things.
294c695d 10'
d1c02d93 11GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
12export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
13
294c695d
AW
14. ./test-lib.sh
15
43c23251
JS
16GIT_AUTHOR_NAME=author@name
17GIT_AUTHOR_EMAIL=bogus@email@address
18export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
294c695d 19
e877a4c1 20test_expect_success 'prepare repository with topic branches' '
77ab58c0 21 test_commit "Add A." A First First &&
840b3ca7
JH
22 git checkout -b force-3way &&
23 echo Dummy >Y &&
24 git update-index --add Y &&
25 git commit -m "Add Y." &&
26 git checkout -b filemove &&
d1c02d93 27 git reset --soft main &&
840b3ca7
JH
28 mkdir D &&
29 git mv A D/A &&
30 git commit -m "Move A." &&
d1c02d93 31 git checkout -b my-topic-branch main &&
77ab58c0 32 test_commit "Add B." B Second Second &&
d1c02d93 33 git checkout -f main &&
e877a4c1
JN
34 echo Third >>A &&
35 git update-index A &&
36 git commit -m "Modify A." &&
37 git checkout -b side my-topic-branch &&
38 echo Side >>C &&
39 git add C &&
40 git commit -m "Add C" &&
e877a4c1
JN
41 git checkout -f my-topic-branch &&
42 git tag topic
1308c17b
JS
43'
44
7a7eb517 45test_expect_success 'rebase on dirty worktree' '
e877a4c1 46 echo dirty >>A &&
d1c02d93 47 test_must_fail git rebase main
e877a4c1 48'
7a7eb517
NTND
49
50test_expect_success 'rebase on dirty cache' '
e877a4c1 51 git add A &&
d1c02d93 52 test_must_fail git rebase main
e877a4c1 53'
7a7eb517 54
d1c02d93 55test_expect_success 'rebase against main' '
e877a4c1 56 git reset --hard HEAD &&
d1c02d93 57 git rebase main
e877a4c1 58'
294c695d 59
cbd29ead 60test_expect_success 'rebase sets ORIG_HEAD to pre-rebase state' '
c2d96293
JS
61 git checkout -b orig-head topic &&
62 pre="$(git rev-parse --verify HEAD)" &&
d1c02d93 63 git rebase main &&
c2d96293 64 test_cmp_rev "$pre" ORIG_HEAD &&
2c9e125b 65 test_cmp_rev ! "$pre" HEAD
c2d96293
JS
66'
67
2e6e276d 68test_expect_success 'rebase, with <onto> and <upstream> specified as :/quuxery' '
6567dc05
RR
69 test_when_finished "git branch -D torebase" &&
70 git checkout -b torebase my-topic-branch^ &&
71 upstream=$(git rev-parse ":/Add B") &&
72 onto=$(git rev-parse ":/Add A") &&
73 git rebase --onto $onto $upstream &&
74 git reset --hard my-topic-branch^ &&
75 git rebase --onto ":/Add A" ":/Add B" &&
76 git checkout my-topic-branch
77'
78
e877a4c1
JN
79test_expect_success 'the rebase operation should not have destroyed author information' '
80 ! (git log | grep "Author:" | grep "<>")
81'
294c695d 82
e877a4c1
JN
83test_expect_success 'the rebase operation should not have destroyed author information (2)' "
84 git log -1 |
85 grep 'Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>'
86"
43c23251 87
2559bff3 88test_expect_success 'HEAD was detached during rebase' '
e877a4c1 89 test $(git rev-parse HEAD@{1}) != $(git rev-parse my-topic-branch@{1})
2559bff3
JS
90'
91
ea709800
PH
92test_expect_success 'rebase from ambiguous branch name' '
93 git checkout -b topic side &&
d1c02d93 94 git rebase main
ea709800
PH
95'
96
4f407407 97test_expect_success 'rebase off of the previous branch using "-"' '
d1c02d93 98 git checkout main &&
4f407407
BG
99 git checkout HEAD^ &&
100 git rebase @{-1} >expect.messages &&
d1c02d93 101 git merge-base main HEAD >expect.forkpoint &&
4f407407 102
d1c02d93 103 git checkout main &&
4f407407
BG
104 git checkout HEAD^ &&
105 git rebase - >actual.messages &&
d1c02d93 106 git merge-base main HEAD >actual.forkpoint &&
4f407407
BG
107
108 test_cmp expect.forkpoint actual.forkpoint &&
109 # the next one is dubious---we may want to say "-",
110 # instead of @{-1}, in the message
1108cea7 111 test_cmp expect.messages actual.messages
4f407407
BG
112'
113
ece7b749 114test_expect_success 'rebase a single mode change' '
d1c02d93 115 git checkout main &&
3f213981 116 git branch -D topic &&
e877a4c1
JN
117 echo 1 >X &&
118 git add X &&
119 test_tick &&
120 git commit -m prepare &&
121 git checkout -b modechange HEAD^ &&
122 echo 1 >X &&
123 git add X &&
124 test_chmod +x A &&
125 test_tick &&
126 git commit -m modechange &&
d1c02d93 127 GIT_TRACE=1 git rebase main
ece7b749
JS
128'
129
840b3ca7 130test_expect_success 'rebase is not broken by diff.renames' '
55adef06 131 test_config diff.renames copies &&
840b3ca7
JH
132 git checkout filemove &&
133 GIT_TRACE=1 git rebase force-3way
134'
135
136test_expect_success 'setup: recover' '
137 test_might_fail git rebase --abort &&
138 git reset --hard &&
139 git checkout modechange
140'
141
3ec7371f 142test_expect_success 'Show verbose error when HEAD could not be detached' '
e877a4c1 143 >B &&
df126ca1 144 test_when_finished "rm -f B" &&
e877a4c1 145 test_must_fail git rebase topic 2>output.err >output.out &&
e5c1272c
VA
146 test_i18ngrep "The following untracked working tree files would be overwritten by checkout:" output.err &&
147 test_i18ngrep B output.err
3ec7371f 148'
bffd750a 149
15a147e6
MZ
150test_expect_success 'fail when upstream arg is missing and not on branch' '
151 git checkout topic &&
3c02396a 152 test_must_fail git rebase
15a147e6
MZ
153'
154
155test_expect_success 'fail when upstream arg is missing and not configured' '
156 git checkout -b no-config topic &&
3c02396a 157 test_must_fail git rebase
15a147e6
MZ
158'
159
cae0bc09 160test_expect_success 'rebase works with format.useAutoBase' '
0c47e061
DL
161 test_config format.useAutoBase true &&
162 git checkout topic &&
d1c02d93 163 git rebase main
0c47e061
DL
164'
165
93122c98 166test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg (--merge)' '
d1c02d93 167 git checkout -b default-base main &&
15a147e6 168 git checkout -b default topic &&
02380389 169 git config branch.default.remote . &&
bb3f4583 170 git config branch.default.merge refs/heads/default-base &&
93122c98
EN
171 git rebase --merge &&
172 git rev-parse --verify default-base >expect &&
173 git rev-parse default~1 >actual &&
174 test_cmp expect actual &&
175 git checkout default-base &&
176 git reset --hard HEAD^ &&
177 git checkout default &&
178 git rebase --merge &&
179 git rev-parse --verify default-base >expect &&
180 git rev-parse default~1 >actual &&
181 test_cmp expect actual
182'
183
10cdb9f3 184test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg (--apply)' '
d1c02d93 185 git checkout -B default-base main &&
93122c98
EN
186 git checkout -B default topic &&
187 git config branch.default.remote . &&
188 git config branch.default.merge refs/heads/default-base &&
10cdb9f3 189 git rebase --apply &&
bb3f4583
JK
190 git rev-parse --verify default-base >expect &&
191 git rev-parse default~1 >actual &&
192 test_cmp expect actual &&
193 git checkout default-base &&
194 git reset --hard HEAD^ &&
195 git checkout default &&
10cdb9f3 196 git rebase --apply &&
bb3f4583 197 git rev-parse --verify default-base >expect &&
ad8261d2
JK
198 git rev-parse default~1 >actual &&
199 test_cmp expect actual
bffd750a 200'
3ec7371f 201
1e0dacdb
JK
202test_expect_success 'cherry-picked commits and fork-point work together' '
203 git checkout default-base &&
204 echo Amended >A &&
205 git commit -a --no-edit --amend &&
206 test_commit B B &&
207 test_commit new_B B "New B" &&
208 test_commit C C &&
209 git checkout default &&
210 git reset --hard default-base@{4} &&
211 test_commit D D &&
212 git cherry-pick -2 default-base^ &&
213 test_commit final_B B "Final B" &&
214 git rebase &&
215 echo Amended >expect &&
dcbaa0b3 216 test_cmp expect A &&
1e0dacdb 217 echo "Final B" >expect &&
dcbaa0b3 218 test_cmp expect B &&
1e0dacdb 219 echo C >expect &&
dcbaa0b3 220 test_cmp expect C &&
1e0dacdb 221 echo D >expect &&
dcbaa0b3 222 test_cmp expect D
1e0dacdb
JK
223'
224
10cdb9f3 225test_expect_success 'rebase --apply -q is quiet' '
e877a4c1 226 git checkout -b quiet topic &&
d1c02d93 227 git rebase --apply -q main >output.out 2>&1 &&
ca8d148d 228 test_must_be_empty output.out
0e987a12
SB
229'
230
55d2b6d7
EN
231test_expect_success 'rebase --merge -q is quiet' '
232 git checkout -B quiet topic &&
d1c02d93 233 git rebase --merge -q main >output.out 2>&1 &&
55d2b6d7
EN
234 test_must_be_empty output.out
235'
236
c2ca1d79
JH
237test_expect_success 'Rebase a commit that sprinkles CRs in' '
238 (
3ea67379
ES
239 echo "One" &&
240 echo "TwoQ" &&
241 echo "Three" &&
242 echo "FQur" &&
c2ca1d79
JH
243 echo "Five"
244 ) | q_to_cr >CR &&
245 git add CR &&
246 test_tick &&
247 git commit -a -m "A file with a line with CR" &&
248 git tag file-with-cr &&
249 git checkout HEAD^0 &&
250 git rebase --onto HEAD^^ HEAD^ &&
251 git diff --exit-code file-with-cr:CR HEAD:CR
252'
253
eb2151bb
TR
254test_expect_success 'rebase can copy notes' '
255 git config notes.rewrite.rebase true &&
256 git config notes.rewriteRef "refs/notes/*" &&
257 test_commit n1 &&
258 test_commit n2 &&
259 test_commit n3 &&
260 git notes add -m"a note" n3 &&
261 git rebase --onto n1 n2 &&
262 test "a note" = "$(git notes show HEAD)"
263'
264
265test_expect_success 'rebase -m can copy notes' '
266 git reset --hard n3 &&
267 git rebase -m --onto n1 n2 &&
268 test "a note" = "$(git notes show HEAD)"
269'
270
2c733fb2
JH
271test_expect_success 'rebase commit with an ancient timestamp' '
272 git reset --hard &&
273
274 >old.one && git add old.one && test_tick &&
275 git commit --date="@12345 +0400" -m "Old one" &&
276 >old.two && git add old.two && test_tick &&
277 git commit --date="@23456 +0500" -m "Old two" &&
278 >old.three && git add old.three && test_tick &&
279 git commit --date="@34567 +0600" -m "Old three" &&
280
281 git cat-file commit HEAD^^ >actual &&
282 grep "author .* 12345 +0400$" actual &&
283 git cat-file commit HEAD^ >actual &&
284 grep "author .* 23456 +0500$" actual &&
285 git cat-file commit HEAD >actual &&
286 grep "author .* 34567 +0600$" actual &&
287
288 git rebase --onto HEAD^^ HEAD^ &&
289
290 git cat-file commit HEAD >actual &&
291 grep "author .* 34567 +0600$" actual
292'
293
ae3b2b04 294test_expect_success 'rebase with "From " line in commit message' '
d1c02d93 295 git checkout -b preserve-from main~1 &&
ae3b2b04
EW
296 cat >From_.msg <<EOF &&
297Somebody embedded an mbox in a commit message
298
299This is from so-and-so:
300
301From a@b Mon Sep 17 00:00:00 2001
302From: John Doe <nobody@example.com>
303Date: Sat, 11 Nov 2017 00:00:00 +0000
304Subject: not this message
305
306something
307EOF
308 >From_ &&
309 git add From_ &&
310 git commit -F From_.msg &&
d1c02d93 311 git rebase main &&
ae3b2b04
EW
312 git log -1 --pretty=format:%B >out &&
313 test_cmp From_.msg out
314'
315
10cdb9f3 316test_expect_success 'rebase --apply and --show-current-patch' '
66335298
NTND
317 test_create_repo conflict-apply &&
318 (
319 cd conflict-apply &&
320 test_commit init &&
321 echo one >>init.t &&
322 git commit -a -m one &&
323 echo two >>init.t &&
324 git commit -a -m two &&
325 git tag two &&
10cdb9f3 326 test_must_fail git rebase --apply -f --onto init HEAD^ &&
66335298
NTND
327 GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&
328 grep "show.*$(git rev-parse two)" stderr
329 )
330'
331
10cdb9f3 332test_expect_success 'rebase --apply and .gitattributes' '
2c65d90f 333 test_create_repo attributes &&
334 (
335 cd attributes &&
336 test_commit init &&
337 git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
338 git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
339
340 test_commit second &&
341 git checkout -b test HEAD^ &&
342
343 echo "*.txt filter=test" >.gitattributes &&
344 git add .gitattributes &&
345 test_commit third &&
346
347 echo "This text is smudged." >a.txt &&
348 git add a.txt &&
349 test_commit fourth &&
350
351 git checkout -b removal HEAD^ &&
352 git rm .gitattributes &&
353 git add -u &&
354 test_commit fifth &&
355 git cherry-pick test &&
356
357 git checkout test &&
d1c02d93 358 git rebase main &&
2c65d90f 359 grep "smudged" a.txt &&
360
361 git checkout removal &&
362 git reset --hard &&
d1c02d93 363 git rebase main &&
2c65d90f 364 grep "clean" a.txt
365 )
366'
367
66335298
NTND
368test_expect_success 'rebase--merge.sh and --show-current-patch' '
369 test_create_repo conflict-merge &&
370 (
371 cd conflict-merge &&
372 test_commit init &&
373 echo one >>init.t &&
374 git commit -a -m one &&
375 echo two >>init.t &&
376 git commit -a -m two &&
377 git tag two &&
378 test_must_fail git rebase --merge --onto init HEAD^ &&
379 git rebase --show-current-patch >actual.patch &&
380 GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&
fbd7a232
NTND
381 grep "show.*REBASE_HEAD" stderr &&
382 test "$(git rev-parse REBASE_HEAD)" = "$(git rev-parse two)"
66335298
NTND
383 )
384'
385
b5cabb4a 386test_expect_success 'switch to branch checked out here' '
d1c02d93
JS
387 git checkout main &&
388 git rebase main main
b5cabb4a
ES
389'
390
279f42fa
RJ
391test_expect_success 'switch to branch checked out elsewhere fails' '
392 test_when_finished "
393 git worktree remove wt1 &&
394 git worktree remove wt2 &&
395 git branch -d shared
396 " &&
397 git worktree add wt1 -b shared &&
398 git worktree add wt2 -f shared &&
399 # we test in both worktrees to ensure that works
400 # as expected with "first" and "next" worktrees
401 test_must_fail git -C wt1 rebase shared shared &&
402 test_must_fail git -C wt2 rebase shared shared
403'
404
b5cabb4a 405test_expect_success 'switch to branch not checked out' '
d1c02d93 406 git checkout main &&
b5cabb4a 407 git branch other &&
d1c02d93 408 git rebase main other
b5cabb4a
ES
409'
410
bdff97a3
JC
411test_expect_success 'switch to non-branch detaches HEAD' '
412 git checkout main &&
413 old_main=$(git rev-parse HEAD) &&
414 git rebase First Second^0 &&
415 test_cmp_rev HEAD Second &&
416 test_cmp_rev main $old_main &&
417 test_must_fail git symbolic-ref HEAD
418'
419
b5cabb4a 420test_expect_success 'refuse to switch to branch checked out elsewhere' '
d1c02d93 421 git checkout main &&
b5cabb4a 422 git worktree add wt &&
d1c02d93 423 test_must_fail git -C wt rebase main main 2>err &&
2a499264 424 test_i18ngrep "already used by worktree at" err
b5cabb4a
ES
425'
426
3e7d4888
TB
427test_expect_success MINGW,SYMLINKS_WINDOWS 'rebase when .git/logs is a symlink' '
428 git checkout main &&
429 mv .git/logs actual_logs &&
430 cmd //c "mklink /D .git\logs ..\actual_logs" &&
431 git rebase -f HEAD^ &&
432 test -L .git/logs &&
433 rm .git/logs &&
434 mv actual_logs .git/logs
435'
436
ff5b7913
EN
437test_expect_success 'rebase when inside worktree subdirectory' '
438 git init main-wt &&
439 (
440 cd main-wt &&
441 git commit --allow-empty -m "initial" &&
442 mkdir -p foo/bar &&
443 test_commit foo/bar/baz &&
444 mkdir -p a/b &&
445 test_commit a/b/c &&
446 # create another branch for our other worktree
447 git branch other &&
448 git worktree add ../other-wt other &&
449 cd ../other-wt &&
450 # create and cd into a subdirectory
451 mkdir -p random/dir &&
452 cd random/dir &&
453 # now do the rebase
454 git rebase --onto HEAD^^ HEAD^ # drops the HEAD^ commit
455 )
456'
457
294c695d 458test_done