]> git.ipfire.org Git - thirdparty/git.git/blame - t/t3415-rebase-autosquash.sh
The third batch
[thirdparty/git.git] / t / t3415-rebase-autosquash.sh
CommitLineData
f59baa50
NS
1#!/bin/sh
2
3test_description='auto squash'
4
d1c02d93 5GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
6export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
f59baa50
NS
8. ./test-lib.sh
9
22c5b136
AP
10. "$TEST_DIRECTORY"/lib-rebase.sh
11
f59baa50
NS
12test_expect_success setup '
13 echo 0 >file0 &&
14 git add . &&
15 test_tick &&
16 git commit -m "initial commit" &&
17 echo 0 >file1 &&
18 echo 2 >file2 &&
19 git add . &&
20 test_tick &&
21 git commit -m "first commit" &&
b1a6c0a9 22 git tag first-commit &&
f59baa50
NS
23 echo 3 >file3 &&
24 git add . &&
25 test_tick &&
26 git commit -m "second commit" &&
27 git tag base
28'
29
b1a6c0a9 30test_auto_fixup () {
c232ffa8
DL
31 no_squash= &&
32 if test "x$1" = 'x!'
33 then
34 no_squash=true
35 shift
36 fi &&
37
f59baa50
NS
38 git reset --hard base &&
39 echo 1 >file1 &&
40 git add -u &&
41 test_tick &&
7c6eafa3 42 git commit -m "fixup! first" &&
f59baa50 43
dd1e5b31 44 git tag $1 &&
f59baa50 45 test_tick &&
297be594 46 git rebase $2 HEAD^^^ &&
f59baa50 47 git log --oneline >actual &&
c232ffa8
DL
48 if test -n "$no_squash"
49 then
50 test_line_count = 4 actual
51 else
52 test_line_count = 3 actual &&
53 git diff --exit-code $1 &&
54 echo 1 >expect &&
55 git cat-file blob HEAD^:file1 >actual &&
56 test_cmp expect actual &&
57 git cat-file commit HEAD^ >commit &&
58 grep first commit >actual &&
59 test_line_count = 1 actual
60 fi
dd1e5b31
HV
61}
62
63test_expect_success 'auto fixup (option)' '
297be594
AK
64 test_auto_fixup fixup-option --autosquash &&
65 test_auto_fixup fixup-option-i "--autosquash -i"
dd1e5b31
HV
66'
67
297be594 68test_expect_success 'auto fixup (config true)' '
dd1e5b31 69 git config rebase.autosquash true &&
297be594
AK
70 test_auto_fixup ! fixup-config-true &&
71 test_auto_fixup fixup-config-true-i -i &&
c232ffa8 72 test_auto_fixup ! fixup-config-true-no --no-autosquash &&
297be594
AK
73 test_auto_fixup ! fixup-config-true-i-no "-i --no-autosquash"
74'
75
76test_expect_success 'auto fixup (config false)' '
dd1e5b31 77 git config rebase.autosquash false &&
297be594
AK
78 test_auto_fixup ! fixup-config-false &&
79 test_auto_fixup ! fixup-config-false-i -i &&
80 test_auto_fixup fixup-config-false-yes --autosquash &&
81 test_auto_fixup fixup-config-false-i-yes "-i --autosquash"
f59baa50
NS
82'
83
b1a6c0a9 84test_auto_squash () {
c232ffa8
DL
85 no_squash= &&
86 if test "x$1" = 'x!'
87 then
88 no_squash=true
89 shift
90 fi &&
91
f59baa50
NS
92 git reset --hard base &&
93 echo 1 >file1 &&
94 git add -u &&
95 test_tick &&
7cdb9682 96 git commit -m "squash! first" -m "extra para for first" &&
dd1e5b31 97 git tag $1 &&
f59baa50 98 test_tick &&
297be594 99 git rebase $2 HEAD^^^ &&
f59baa50 100 git log --oneline >actual &&
c232ffa8
DL
101 if test -n "$no_squash"
102 then
103 test_line_count = 4 actual
104 else
105 test_line_count = 3 actual &&
106 git diff --exit-code $1 &&
107 echo 1 >expect &&
108 git cat-file blob HEAD^:file1 >actual &&
109 test_cmp expect actual &&
110 git cat-file commit HEAD^ >commit &&
111 grep first commit >actual &&
112 test_line_count = 2 actual
113 fi
dd1e5b31
HV
114}
115
116test_expect_success 'auto squash (option)' '
297be594
AK
117 test_auto_squash squash-option --autosquash &&
118 test_auto_squash squash-option-i "--autosquash -i"
dd1e5b31
HV
119'
120
297be594 121test_expect_success 'auto squash (config true)' '
dd1e5b31 122 git config rebase.autosquash true &&
297be594
AK
123 test_auto_squash ! squash-config-true &&
124 test_auto_squash squash-config-true-i -i &&
c232ffa8 125 test_auto_squash ! squash-config-true-no --no-autosquash &&
297be594
AK
126 test_auto_squash ! squash-config-true-i-no "-i --no-autosquash"
127'
128
129test_expect_success 'auto squash (config false)' '
dd1e5b31 130 git config rebase.autosquash false &&
297be594
AK
131 test_auto_squash ! squash-config-false &&
132 test_auto_squash ! squash-config-false-i -i &&
133 test_auto_squash squash-config-false-yes --autosquash &&
134 test_auto_squash squash-config-false-i-yes "-i --autosquash"
f59baa50
NS
135'
136
137test_expect_success 'misspelled auto squash' '
138 git reset --hard base &&
139 echo 1 >file1 &&
140 git add -u &&
141 test_tick &&
7c6eafa3 142 git commit -m "squash! forst" &&
f59baa50
NS
143 git tag final-missquash &&
144 test_tick &&
145 git rebase --autosquash -i HEAD^^^ &&
146 git log --oneline >actual &&
3fb0459b 147 test_line_count = 4 actual &&
f59baa50 148 git diff --exit-code final-missquash &&
a781cd6f
DL
149 git rev-list final-missquash...HEAD >list &&
150 test_must_be_empty list
f59baa50
NS
151'
152
d3d7a421
KB
153test_expect_success 'auto squash that matches 2 commits' '
154 git reset --hard base &&
155 echo 4 >file4 &&
156 git add file4 &&
157 test_tick &&
158 git commit -m "first new commit" &&
159 echo 1 >file1 &&
160 git add -u &&
161 test_tick &&
7cdb9682 162 git commit -m "squash! first" -m "extra para for first" &&
d3d7a421
KB
163 git tag final-multisquash &&
164 test_tick &&
165 git rebase --autosquash -i HEAD~4 &&
166 git log --oneline >actual &&
3fb0459b 167 test_line_count = 4 actual &&
d3d7a421 168 git diff --exit-code final-multisquash &&
a781cd6f
DL
169 echo 1 >expect &&
170 git cat-file blob HEAD^^:file1 >actual &&
171 test_cmp expect actual &&
172 git cat-file commit HEAD^^ >commit &&
173 grep first commit >actual &&
174 test_line_count = 2 actual &&
175 git cat-file commit HEAD >commit &&
176 grep first commit >actual &&
177 test_line_count = 1 actual
d3d7a421
KB
178'
179
180test_expect_success 'auto squash that matches a commit after the squash' '
181 git reset --hard base &&
182 echo 1 >file1 &&
183 git add -u &&
184 test_tick &&
185 git commit -m "squash! third" &&
186 echo 4 >file4 &&
187 git add file4 &&
188 test_tick &&
189 git commit -m "third commit" &&
190 git tag final-presquash &&
191 test_tick &&
192 git rebase --autosquash -i HEAD~4 &&
193 git log --oneline >actual &&
3fb0459b 194 test_line_count = 5 actual &&
d3d7a421 195 git diff --exit-code final-presquash &&
a781cd6f
DL
196 echo 0 >expect &&
197 git cat-file blob HEAD^^:file1 >actual &&
198 test_cmp expect actual &&
199 echo 1 >expect &&
200 git cat-file blob HEAD^:file1 >actual &&
201 test_cmp expect actual &&
202 git cat-file commit HEAD >commit &&
203 grep third commit >actual &&
204 test_line_count = 1 actual &&
205 git cat-file commit HEAD^ >commit &&
206 grep third commit >actual &&
207 test_line_count = 1 actual
d3d7a421 208'
68d5d03b
KB
209test_expect_success 'auto squash that matches a sha1' '
210 git reset --hard base &&
211 echo 1 >file1 &&
212 git add -u &&
213 test_tick &&
a781cd6f 214 oid=$(git rev-parse --short HEAD^) &&
7cdb9682 215 git commit -m "squash! $oid" -m "extra para" &&
68d5d03b
KB
216 git tag final-shasquash &&
217 test_tick &&
218 git rebase --autosquash -i HEAD^^^ &&
219 git log --oneline >actual &&
3fb0459b 220 test_line_count = 3 actual &&
68d5d03b 221 git diff --exit-code final-shasquash &&
a781cd6f
DL
222 echo 1 >expect &&
223 git cat-file blob HEAD^:file1 >actual &&
224 test_cmp expect actual &&
225 git cat-file commit HEAD^ >commit &&
7cdb9682
PW
226 ! grep "squash" commit &&
227 grep "^extra para" commit >actual &&
a781cd6f 228 test_line_count = 1 actual
68d5d03b
KB
229'
230
231test_expect_success 'auto squash that matches longer sha1' '
232 git reset --hard base &&
233 echo 1 >file1 &&
234 git add -u &&
235 test_tick &&
a781cd6f 236 oid=$(git rev-parse --short=11 HEAD^) &&
7cdb9682 237 git commit -m "squash! $oid" -m "extra para" &&
68d5d03b
KB
238 git tag final-longshasquash &&
239 test_tick &&
240 git rebase --autosquash -i HEAD^^^ &&
241 git log --oneline >actual &&
3fb0459b 242 test_line_count = 3 actual &&
68d5d03b 243 git diff --exit-code final-longshasquash &&
a781cd6f
DL
244 echo 1 >expect &&
245 git cat-file blob HEAD^:file1 >actual &&
246 test_cmp expect actual &&
247 git cat-file commit HEAD^ >commit &&
7cdb9682
PW
248 ! grep "squash" commit &&
249 grep "^extra para" commit >actual &&
a781cd6f 250 test_line_count = 1 actual
68d5d03b 251'
d3d7a421 252
3e367a5f
JA
253test_expect_success 'auto squash of fixup commit that matches branch name which points back to fixup commit' '
254 git reset --hard base &&
255 git commit --allow-empty -m "fixup! self-cycle" &&
256 git branch self-cycle &&
257 GIT_SEQUENCE_EDITOR="cat >tmp" git rebase --autosquash -i HEAD^^ &&
258 sed -ne "/^[^#]/{s/[0-9a-f]\{7,\}/HASH/g;p;}" tmp >actual &&
259 cat <<-EOF >expect &&
260 pick HASH second commit
261 pick HASH fixup! self-cycle # empty
262 EOF
263 test_cmp expect actual
264'
265
b1a6c0a9
PN
266test_auto_commit_flags () {
267 git reset --hard base &&
268 echo 1 >file1 &&
269 git add -u &&
270 test_tick &&
7cdb9682 271 git commit --$1 first-commit -m "extra para for first" &&
b1a6c0a9
PN
272 git tag final-commit-$1 &&
273 test_tick &&
274 git rebase --autosquash -i HEAD^^^ &&
275 git log --oneline >actual &&
3fb0459b 276 test_line_count = 3 actual &&
b1a6c0a9 277 git diff --exit-code final-commit-$1 &&
a781cd6f
DL
278 echo 1 >expect &&
279 git cat-file blob HEAD^:file1 >actual &&
280 test_cmp expect actual &&
281 git cat-file commit HEAD^ >commit &&
282 grep first commit >actual &&
283 test_line_count = $2 actual
b1a6c0a9
PN
284}
285
286test_expect_success 'use commit --fixup' '
287 test_auto_commit_flags fixup 1
288'
289
7951bd30
PN
290test_expect_success 'use commit --squash' '
291 test_auto_commit_flags squash 2
292'
293
22c5b136
AP
294test_auto_fixup_fixup () {
295 git reset --hard base &&
296 echo 1 >file1 &&
297 git add -u &&
298 test_tick &&
7cdb9682 299 git commit -m "$1! first" -m "extra para for first" &&
22c5b136
AP
300 echo 2 >file1 &&
301 git add -u &&
302 test_tick &&
7cdb9682 303 git commit -m "$1! $2! first" -m "second extra para for first" &&
22c5b136
AP
304 git tag "final-$1-$2" &&
305 test_tick &&
306 (
307 set_cat_todo_editor &&
308 test_must_fail git rebase --autosquash -i HEAD^^^^ >actual &&
a781cd6f
DL
309 head=$(git rev-parse --short HEAD) &&
310 parent1=$(git rev-parse --short HEAD^) &&
311 parent2=$(git rev-parse --short HEAD^^) &&
312 parent3=$(git rev-parse --short HEAD^^^) &&
22c5b136 313 cat >expected <<-EOF &&
a781cd6f
DL
314 pick $parent3 first commit
315 $1 $parent1 $1! first
316 $1 $head $1! $2! first
317 pick $parent2 second commit
22c5b136
AP
318 EOF
319 test_cmp expected actual
320 ) &&
321 git rebase --autosquash -i HEAD^^^^ &&
322 git log --oneline >actual &&
323 test_line_count = 3 actual
324 git diff --exit-code "final-$1-$2" &&
a781cd6f
DL
325 echo 2 >expect &&
326 git cat-file blob HEAD^:file1 >actual &&
327 test_cmp expect actual &&
328 git cat-file commit HEAD^ >commit &&
329 grep first commit >actual &&
22c5b136
AP
330 if test "$1" = "fixup"
331 then
a781cd6f 332 test_line_count = 1 actual
22c5b136
AP
333 elif test "$1" = "squash"
334 then
a781cd6f 335 test_line_count = 3 actual
22c5b136
AP
336 else
337 false
338 fi
339}
340
a926c4b9 341test_expect_success 'fixup! fixup!' '
22c5b136
AP
342 test_auto_fixup_fixup fixup fixup
343'
344
a926c4b9 345test_expect_success 'fixup! squash!' '
22c5b136
AP
346 test_auto_fixup_fixup fixup squash
347'
348
a926c4b9 349test_expect_success 'squash! squash!' '
22c5b136
AP
350 test_auto_fixup_fixup squash squash
351'
352
a926c4b9 353test_expect_success 'squash! fixup!' '
22c5b136
AP
354 test_auto_fixup_fixup squash fixup
355'
356
a926c4b9 357test_expect_success 'autosquash with custom inst format' '
16cf51c7
MR
358 git reset --hard base &&
359 git config --add rebase.instructionFormat "[%an @ %ar] %s" &&
360 echo 2 >file1 &&
361 git add -u &&
362 test_tick &&
a781cd6f 363 oid=$(git rev-parse --short HEAD^) &&
7cdb9682 364 git commit -m "squash! $oid" -m "extra para for first" &&
16cf51c7
MR
365 echo 1 >file1 &&
366 git add -u &&
367 test_tick &&
a781cd6f 368 subject=$(git log -n 1 --format=%s HEAD~2) &&
7cdb9682 369 git commit -m "squash! $subject" -m "second extra para for first" &&
16cf51c7
MR
370 git tag final-squash-instFmt &&
371 test_tick &&
372 git rebase --autosquash -i HEAD~4 &&
373 git log --oneline >actual &&
374 test_line_count = 3 actual &&
375 git diff --exit-code final-squash-instFmt &&
a781cd6f
DL
376 echo 1 >expect &&
377 git cat-file blob HEAD^:file1 >actual &&
378 test_cmp expect actual &&
379 git cat-file commit HEAD^ >commit &&
7cdb9682
PW
380 ! grep "squash" commit &&
381 grep first commit >actual &&
382 test_line_count = 3 actual
16cf51c7
MR
383'
384
4e7524e0
JS
385test_expect_success 'autosquash with empty custom instructionFormat' '
386 git reset --hard base &&
387 test_commit empty-instructionFormat-test &&
388 (
389 set_cat_todo_editor &&
390 test_must_fail git -c rebase.instructionFormat= \
f927ae6c 391 rebase --autosquash --force-rebase -i HEAD^ >actual &&
4e7524e0
JS
392 git log -1 --format="pick %h %s" >expect &&
393 test_cmp expect actual
394 )
395'
396
c94e963b
JS
397set_backup_editor () {
398 write_script backup-editor.sh <<-\EOF
399 cp "$1" .git/backup-"$(basename "$1")"
400 EOF
401 test_set_editor "$PWD/backup-editor.sh"
402}
403
c44a4c65 404test_expect_success 'autosquash with multiple empty patches' '
c94e963b
JS
405 test_tick &&
406 git commit --allow-empty -m "empty" &&
407 test_tick &&
408 git commit --allow-empty -m "empty2" &&
409 test_tick &&
410 >fixup &&
411 git add fixup &&
412 git commit --fixup HEAD^^ &&
413 (
414 set_backup_editor &&
415 GIT_USE_REBASE_HELPER=false \
416 git rebase -i --force-rebase --autosquash HEAD~4 &&
417 grep empty2 .git/backup-git-rebase-todo
418 )
419'
420
cbcd2cbd
JS
421test_expect_success 'extra spaces after fixup!' '
422 base=$(git rev-parse HEAD) &&
423 test_commit to-fixup &&
424 git commit --allow-empty -m "fixup! to-fixup" &&
425 git rebase -i --autosquash --keep-empty HEAD~2 &&
426 parent=$(git rev-parse HEAD^) &&
427 test $base = $parent
428'
429
b174ae7d
JS
430test_expect_success 'wrapped original subject' '
431 if test -d .git/rebase-merge; then git rebase --abort; fi &&
432 base=$(git rev-parse HEAD) &&
433 echo "wrapped subject" >wrapped &&
434 git add wrapped &&
435 test_tick &&
436 git commit --allow-empty -m "$(printf "To\nfixup")" &&
437 test_tick &&
438 git commit --allow-empty -m "fixup! To fixup" &&
439 git rebase -i --autosquash --keep-empty HEAD~2 &&
440 parent=$(git rev-parse HEAD^) &&
441 test $base = $parent
442'
443
10d2f354 444test_expect_success 'abort last squash' '
2f3eb68f 445 test_when_finished "test_might_fail git rebase --abort" &&
d1c02d93 446 test_when_finished "git checkout main" &&
2f3eb68f
JS
447
448 git checkout -b some-squashes &&
449 git commit --allow-empty -m first &&
450 git commit --allow-empty --squash HEAD &&
451 git commit --allow-empty -m second &&
452 git commit --allow-empty --squash HEAD &&
453
454 test_must_fail git -c core.editor="grep -q ^pick" \
455 rebase -ki --autosquash HEAD~4 &&
456 : do not finish the squash, but resolve it manually &&
457 git commit --allow-empty --amend -m edited-first &&
458 git rebase --skip &&
459 git show >actual &&
460 ! grep first actual
461'
462
02471e7e
JS
463test_expect_success 'fixup a fixup' '
464 echo 0to-fixup >file0 &&
465 test_tick &&
466 git commit -m "to-fixup" file0 &&
467 test_tick &&
468 git commit --squash HEAD -m X --allow-empty &&
469 test_tick &&
470 git commit --squash HEAD^ -m Y --allow-empty &&
471 test_tick &&
472 git commit -m "squash! $(git rev-parse HEAD^)" -m Z --allow-empty &&
473 test_tick &&
474 git commit -m "squash! $(git rev-parse HEAD^^)" -m W --allow-empty &&
475 git rebase -ki --autosquash HEAD~5 &&
476 test XZWY = $(git show | tr -cd W-Z)
477'
478
f7d42cee
JS
479test_expect_success 'fixup does not clean up commit message' '
480 oneline="#818" &&
481 git commit --allow-empty -m "$oneline" &&
482 git commit --fixup HEAD --allow-empty &&
483 git -c commit.cleanup=strip rebase -ki --autosquash HEAD~2 &&
484 test "$oneline" = "$(git show -s --format=%s)"
485'
486
f59baa50 487test_done