3 test_description
='auto squash'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 TEST_PASSES_SANITIZE_LEAK
=true
11 .
"$TEST_DIRECTORY"/lib-rebase.sh
13 test_expect_success setup
'
17 git commit -m "initial commit" &&
22 git commit -m "first commit" &&
23 git tag first-commit &&
27 git commit -m "second commit" &&
39 git
reset --hard base
&&
43 git commit
-m "fixup! first" &&
47 git rebase
$2 HEAD^^^
&&
48 git log
--oneline >actual
&&
49 if test -n "$no_squash"
51 test_line_count
= 4 actual
53 test_line_count
= 3 actual
&&
54 git
diff --exit-code $1 &&
56 git cat-file blob HEAD^
:file1
>actual
&&
57 test_cmp expect actual
&&
58 git cat-file commit HEAD^
>commit
&&
59 grep first commit
>actual
&&
60 test_line_count
= 1 actual
64 test_expect_success
'auto fixup (option)' '
65 test_auto_fixup fixup-option --autosquash &&
66 test_auto_fixup fixup-option-i "--autosquash -i"
69 test_expect_success
'auto fixup (config true)' '
70 git config rebase.autosquash true &&
71 test_auto_fixup ! fixup-config-true &&
72 test_auto_fixup fixup-config-true-i -i &&
73 test_auto_fixup ! fixup-config-true-no --no-autosquash &&
74 test_auto_fixup ! fixup-config-true-i-no "-i --no-autosquash"
77 test_expect_success
'auto fixup (config false)' '
78 git config rebase.autosquash false &&
79 test_auto_fixup ! fixup-config-false &&
80 test_auto_fixup ! fixup-config-false-i -i &&
81 test_auto_fixup fixup-config-false-yes --autosquash &&
82 test_auto_fixup fixup-config-false-i-yes "-i --autosquash"
93 git
reset --hard base
&&
97 git commit
-m "squash! first" -m "extra para for first" &&
100 git rebase
$2 HEAD^^^
&&
101 git log
--oneline >actual
&&
102 if test -n "$no_squash"
104 test_line_count
= 4 actual
106 test_line_count
= 3 actual
&&
107 git
diff --exit-code $1 &&
109 git cat-file blob HEAD^
:file1
>actual
&&
110 test_cmp expect actual
&&
111 git cat-file commit HEAD^
>commit
&&
112 grep first commit
>actual
&&
113 test_line_count
= 2 actual
117 test_expect_success
'auto squash (option)' '
118 test_auto_squash squash-option --autosquash &&
119 test_auto_squash squash-option-i "--autosquash -i"
122 test_expect_success
'auto squash (config true)' '
123 git config rebase.autosquash true &&
124 test_auto_squash ! squash-config-true &&
125 test_auto_squash squash-config-true-i -i &&
126 test_auto_squash ! squash-config-true-no --no-autosquash &&
127 test_auto_squash ! squash-config-true-i-no "-i --no-autosquash"
130 test_expect_success
'auto squash (config false)' '
131 git config rebase.autosquash false &&
132 test_auto_squash ! squash-config-false &&
133 test_auto_squash ! squash-config-false-i -i &&
134 test_auto_squash squash-config-false-yes --autosquash &&
135 test_auto_squash squash-config-false-i-yes "-i --autosquash"
138 test_expect_success
'misspelled auto squash' '
139 git reset --hard base &&
143 git commit -m "squash! forst" &&
144 git tag final-missquash &&
146 git rebase --autosquash -i HEAD^^^ &&
147 git log --oneline >actual &&
148 test_line_count = 4 actual &&
149 git diff --exit-code final-missquash &&
150 git rev-list final-missquash...HEAD >list &&
151 test_must_be_empty list
154 test_expect_success
'auto squash that matches 2 commits' '
155 git reset --hard base &&
159 git commit -m "first new commit" &&
163 git commit -m "squash! first" -m "extra para for first" &&
164 git tag final-multisquash &&
166 git rebase --autosquash -i HEAD~4 &&
167 git log --oneline >actual &&
168 test_line_count = 4 actual &&
169 git diff --exit-code final-multisquash &&
171 git cat-file blob HEAD^^:file1 >actual &&
172 test_cmp expect actual &&
173 git cat-file commit HEAD^^ >commit &&
174 grep first commit >actual &&
175 test_line_count = 2 actual &&
176 git cat-file commit HEAD >commit &&
177 grep first commit >actual &&
178 test_line_count = 1 actual
181 test_expect_success
'auto squash that matches a commit after the squash' '
182 git reset --hard base &&
186 git commit -m "squash! third" &&
190 git commit -m "third commit" &&
191 git tag final-presquash &&
193 git rebase --autosquash -i HEAD~4 &&
194 git log --oneline >actual &&
195 test_line_count = 5 actual &&
196 git diff --exit-code final-presquash &&
198 git cat-file blob HEAD^^:file1 >actual &&
199 test_cmp expect actual &&
201 git cat-file blob HEAD^:file1 >actual &&
202 test_cmp expect actual &&
203 git cat-file commit HEAD >commit &&
204 grep third commit >actual &&
205 test_line_count = 1 actual &&
206 git cat-file commit HEAD^ >commit &&
207 grep third commit >actual &&
208 test_line_count = 1 actual
210 test_expect_success
'auto squash that matches a sha1' '
211 git reset --hard base &&
215 oid=$(git rev-parse --short HEAD^) &&
216 git commit -m "squash! $oid" -m "extra para" &&
217 git tag final-shasquash &&
219 git rebase --autosquash -i HEAD^^^ &&
220 git log --oneline >actual &&
221 test_line_count = 3 actual &&
222 git diff --exit-code final-shasquash &&
224 git cat-file blob HEAD^:file1 >actual &&
225 test_cmp expect actual &&
226 git cat-file commit HEAD^ >commit &&
227 ! grep "squash" commit &&
228 grep "^extra para" commit >actual &&
229 test_line_count = 1 actual
232 test_expect_success
'auto squash that matches longer sha1' '
233 git reset --hard base &&
237 oid=$(git rev-parse --short=11 HEAD^) &&
238 git commit -m "squash! $oid" -m "extra para" &&
239 git tag final-longshasquash &&
241 git rebase --autosquash -i HEAD^^^ &&
242 git log --oneline >actual &&
243 test_line_count = 3 actual &&
244 git diff --exit-code final-longshasquash &&
246 git cat-file blob HEAD^:file1 >actual &&
247 test_cmp expect actual &&
248 git cat-file commit HEAD^ >commit &&
249 ! grep "squash" commit &&
250 grep "^extra para" commit >actual &&
251 test_line_count = 1 actual
254 test_expect_success
'auto squash of fixup commit that matches branch name which points back to fixup commit' '
255 git reset --hard base &&
256 git commit --allow-empty -m "fixup! self-cycle" &&
257 git branch self-cycle &&
258 GIT_SEQUENCE_EDITOR="cat >tmp" git rebase --autosquash -i HEAD^^ &&
259 sed -ne "/^[^#]/{s/[0-9a-f]\{7,\}/HASH/g;p;}" tmp >actual &&
260 cat <<-EOF >expect &&
261 pick HASH second commit
262 pick HASH fixup! self-cycle # empty
264 test_cmp expect actual
267 test_auto_commit_flags
() {
268 git
reset --hard base
&&
272 git commit
--$1 first-commit
-m "extra para for first" &&
273 git tag final-commit-
$1 &&
275 git rebase
--autosquash -i HEAD^^^
&&
276 git log
--oneline >actual
&&
277 test_line_count
= 3 actual
&&
278 git
diff --exit-code final-commit-
$1 &&
280 git cat-file blob HEAD^
:file1
>actual
&&
281 test_cmp expect actual
&&
282 git cat-file commit HEAD^
>commit
&&
283 grep first commit
>actual
&&
284 test_line_count
= $2 actual
287 test_expect_success
'use commit --fixup' '
288 test_auto_commit_flags fixup 1
291 test_expect_success
'use commit --squash' '
292 test_auto_commit_flags squash 2
295 test_auto_fixup_fixup
() {
296 git
reset --hard base
&&
300 git commit
-m "$1! first" -m "extra para for first" &&
304 git commit
-m "$1! $2! first" -m "second extra para for first" &&
305 git tag
"final-$1-$2" &&
308 set_cat_todo_editor
&&
309 test_must_fail git rebase
--autosquash -i HEAD^^^^
>actual
&&
310 head=$
(git rev-parse
--short HEAD
) &&
311 parent1
=$
(git rev-parse
--short HEAD^
) &&
312 parent2
=$
(git rev-parse
--short HEAD^^
) &&
313 parent3
=$
(git rev-parse
--short HEAD^^^
) &&
314 cat >expected
<<-EOF &&
315 pick $parent3 first commit
316 $1 $parent1 $1! first
317 $1 $head $1! $2! first
318 pick $parent2 second commit
320 test_cmp expected actual
322 git rebase
--autosquash -i HEAD^^^^
&&
323 git log
--oneline >actual
&&
324 test_line_count
= 3 actual
325 git
diff --exit-code "final-$1-$2" &&
327 git cat-file blob HEAD^
:file1
>actual
&&
328 test_cmp expect actual
&&
329 git cat-file commit HEAD^
>commit
&&
330 grep first commit
>actual
&&
331 if test "$1" = "fixup"
333 test_line_count
= 1 actual
334 elif test "$1" = "squash"
336 test_line_count
= 3 actual
342 test_expect_success
'fixup! fixup!' '
343 test_auto_fixup_fixup fixup fixup
346 test_expect_success
'fixup! squash!' '
347 test_auto_fixup_fixup fixup squash
350 test_expect_success
'squash! squash!' '
351 test_auto_fixup_fixup squash squash
354 test_expect_success
'squash! fixup!' '
355 test_auto_fixup_fixup squash fixup
358 test_expect_success
'autosquash with custom inst format' '
359 git reset --hard base &&
360 git config --add rebase.instructionFormat "[%an @ %ar] %s" &&
364 oid=$(git rev-parse --short HEAD^) &&
365 git commit -m "squash! $oid" -m "extra para for first" &&
369 subject=$(git log -n 1 --format=%s HEAD~2) &&
370 git commit -m "squash! $subject" -m "second extra para for first" &&
371 git tag final-squash-instFmt &&
373 git rebase --autosquash -i HEAD~4 &&
374 git log --oneline >actual &&
375 test_line_count = 3 actual &&
376 git diff --exit-code final-squash-instFmt &&
378 git cat-file blob HEAD^:file1 >actual &&
379 test_cmp expect actual &&
380 git cat-file commit HEAD^ >commit &&
381 ! grep "squash" commit &&
382 grep first commit >actual &&
383 test_line_count = 3 actual
386 test_expect_success
'autosquash with empty custom instructionFormat' '
387 git reset --hard base &&
388 test_commit empty-instructionFormat-test &&
390 set_cat_todo_editor &&
391 test_must_fail git -c rebase.instructionFormat= \
392 rebase --autosquash --force-rebase -i HEAD^ >actual &&
393 git log -1 --format="pick %h %s" >expect &&
394 test_cmp expect actual
398 set_backup_editor
() {
399 write_script backup-editor.sh
<<-\EOF
400 cp "$1" .git/backup-"$(basename "$1")"
402 test_set_editor "$PWD/backup-editor.sh"
405 test_expect_success 'autosquash with multiple empty patches' '
407 git commit --allow-empty -m "empty" &&
409 git commit --allow-empty -m "empty2" &&
413 git commit --fixup HEAD^^ &&
416 GIT_USE_REBASE_HELPER=false \
417 git rebase -i --force-rebase --autosquash HEAD~4 &&
418 grep empty2 .git/backup-git-rebase-todo
422 test_expect_success 'extra spaces after fixup!' '
423 base=$(git rev-parse HEAD) &&
424 test_commit to-fixup &&
425 git commit --allow-empty -m "fixup! to-fixup" &&
426 git rebase -i --autosquash --keep-empty HEAD~2 &&
427 parent=$(git rev-parse HEAD^) &&
431 test_expect_success 'wrapped original subject' '
432 if test -d .git/rebase-merge; then git rebase --abort; fi &&
433 base=$(git rev-parse HEAD) &&
434 echo "wrapped subject" >wrapped &&
437 git commit --allow-empty -m "$(printf "To\nfixup")" &&
439 git commit --allow-empty -m "fixup! To fixup" &&
440 git rebase -i --autosquash --keep-empty HEAD~2 &&
441 parent=$(git rev-parse HEAD^) &&
445 test_expect_success 'abort last squash' '
446 test_when_finished "test_might_fail git rebase --abort" &&
447 test_when_finished "git checkout main" &&
449 git checkout -b some-squashes &&
450 git commit --allow-empty -m first &&
451 git commit --allow-empty --squash HEAD &&
452 git commit --allow-empty -m second &&
453 git commit --allow-empty --squash HEAD &&
455 test_must_fail git -c core.editor="grep -q ^pick" \
456 rebase -ki --autosquash HEAD~4 &&
457 : do not finish the squash, but resolve it manually &&
458 git commit --allow-empty --amend -m edited-first &&
464 test_expect_success 'fixup a fixup' '
465 echo 0to-fixup >file0 &&
467 git commit -m "to-fixup" file0 &&
469 git commit --squash HEAD -m X --allow-empty &&
471 git commit --squash HEAD^ -m Y --allow-empty &&
473 git commit -m "squash! $(git rev-parse HEAD^)" -m Z --allow-empty &&
475 git commit -m "squash! $(git rev-parse HEAD^^)" -m W --allow-empty &&
476 git rebase -ki --autosquash HEAD~5 &&
477 test XZWY = $(git show | tr -cd W-Z)
480 test_expect_success 'fixup does not clean up commit message' '
482 git commit --allow-empty -m "$oneline" &&
483 git commit --fixup HEAD --allow-empty &&
484 git -c commit.cleanup=strip rebase -ki --autosquash HEAD~2 &&
485 test "$oneline" = "$(git show -s --format=%s)"