Merge branch 'tb/commit-graph-no-check-oids'
[git/raj.git] / t / t3415-rebase-autosquash.sh
blob7bab6000dc73fc1639e2f215b2632ed3c97c9f99
1 #!/bin/sh
3 test_description='auto squash'
5 . ./test-lib.sh
7 . "$TEST_DIRECTORY"/lib-rebase.sh
9 test_expect_success setup '
10 echo 0 >file0 &&
11 git add . &&
12 test_tick &&
13 git commit -m "initial commit" &&
14 echo 0 >file1 &&
15 echo 2 >file2 &&
16 git add . &&
17 test_tick &&
18 git commit -m "first commit" &&
19 git tag first-commit &&
20 echo 3 >file3 &&
21 git add . &&
22 test_tick &&
23 git commit -m "second commit" &&
24 git tag base
27 test_auto_fixup () {
28 no_squash= &&
29 if test "x$1" = 'x!'
30 then
31 no_squash=true
32 shift
33 fi &&
35 git reset --hard base &&
36 echo 1 >file1 &&
37 git add -u &&
38 test_tick &&
39 git commit -m "fixup! first" &&
41 git tag $1 &&
42 test_tick &&
43 git rebase $2 -i HEAD^^^ &&
44 git log --oneline >actual &&
45 if test -n "$no_squash"
46 then
47 test_line_count = 4 actual
48 else
49 test_line_count = 3 actual &&
50 git diff --exit-code $1 &&
51 echo 1 >expect &&
52 git cat-file blob HEAD^:file1 >actual &&
53 test_cmp expect actual &&
54 git cat-file commit HEAD^ >commit &&
55 grep first commit >actual &&
56 test_line_count = 1 actual
60 test_expect_success 'auto fixup (option)' '
61 test_auto_fixup final-fixup-option --autosquash
64 test_expect_success 'auto fixup (config)' '
65 git config rebase.autosquash true &&
66 test_auto_fixup final-fixup-config-true &&
67 test_auto_fixup ! fixup-config-true-no --no-autosquash &&
68 git config rebase.autosquash false &&
69 test_auto_fixup ! final-fixup-config-false
72 test_auto_squash () {
73 no_squash= &&
74 if test "x$1" = 'x!'
75 then
76 no_squash=true
77 shift
78 fi &&
80 git reset --hard base &&
81 echo 1 >file1 &&
82 git add -u &&
83 test_tick &&
84 git commit -m "squash! first" &&
86 git tag $1 &&
87 test_tick &&
88 git rebase $2 -i HEAD^^^ &&
89 git log --oneline >actual &&
90 if test -n "$no_squash"
91 then
92 test_line_count = 4 actual
93 else
94 test_line_count = 3 actual &&
95 git diff --exit-code $1 &&
96 echo 1 >expect &&
97 git cat-file blob HEAD^:file1 >actual &&
98 test_cmp expect actual &&
99 git cat-file commit HEAD^ >commit &&
100 grep first commit >actual &&
101 test_line_count = 2 actual
105 test_expect_success 'auto squash (option)' '
106 test_auto_squash final-squash --autosquash
109 test_expect_success 'auto squash (config)' '
110 git config rebase.autosquash true &&
111 test_auto_squash final-squash-config-true &&
112 test_auto_squash ! squash-config-true-no --no-autosquash &&
113 git config rebase.autosquash false &&
114 test_auto_squash ! final-squash-config-false
117 test_expect_success 'misspelled auto squash' '
118 git reset --hard base &&
119 echo 1 >file1 &&
120 git add -u &&
121 test_tick &&
122 git commit -m "squash! forst" &&
123 git tag final-missquash &&
124 test_tick &&
125 git rebase --autosquash -i HEAD^^^ &&
126 git log --oneline >actual &&
127 test_line_count = 4 actual &&
128 git diff --exit-code final-missquash &&
129 git rev-list final-missquash...HEAD >list &&
130 test_must_be_empty list
133 test_expect_success 'auto squash that matches 2 commits' '
134 git reset --hard base &&
135 echo 4 >file4 &&
136 git add file4 &&
137 test_tick &&
138 git commit -m "first new commit" &&
139 echo 1 >file1 &&
140 git add -u &&
141 test_tick &&
142 git commit -m "squash! first" &&
143 git tag final-multisquash &&
144 test_tick &&
145 git rebase --autosquash -i HEAD~4 &&
146 git log --oneline >actual &&
147 test_line_count = 4 actual &&
148 git diff --exit-code final-multisquash &&
149 echo 1 >expect &&
150 git cat-file blob HEAD^^:file1 >actual &&
151 test_cmp expect actual &&
152 git cat-file commit HEAD^^ >commit &&
153 grep first commit >actual &&
154 test_line_count = 2 actual &&
155 git cat-file commit HEAD >commit &&
156 grep first commit >actual &&
157 test_line_count = 1 actual
160 test_expect_success 'auto squash that matches a commit after the squash' '
161 git reset --hard base &&
162 echo 1 >file1 &&
163 git add -u &&
164 test_tick &&
165 git commit -m "squash! third" &&
166 echo 4 >file4 &&
167 git add file4 &&
168 test_tick &&
169 git commit -m "third commit" &&
170 git tag final-presquash &&
171 test_tick &&
172 git rebase --autosquash -i HEAD~4 &&
173 git log --oneline >actual &&
174 test_line_count = 5 actual &&
175 git diff --exit-code final-presquash &&
176 echo 0 >expect &&
177 git cat-file blob HEAD^^:file1 >actual &&
178 test_cmp expect actual &&
179 echo 1 >expect &&
180 git cat-file blob HEAD^:file1 >actual &&
181 test_cmp expect actual &&
182 git cat-file commit HEAD >commit &&
183 grep third commit >actual &&
184 test_line_count = 1 actual &&
185 git cat-file commit HEAD^ >commit &&
186 grep third commit >actual &&
187 test_line_count = 1 actual
189 test_expect_success 'auto squash that matches a sha1' '
190 git reset --hard base &&
191 echo 1 >file1 &&
192 git add -u &&
193 test_tick &&
194 oid=$(git rev-parse --short HEAD^) &&
195 git commit -m "squash! $oid" &&
196 git tag final-shasquash &&
197 test_tick &&
198 git rebase --autosquash -i HEAD^^^ &&
199 git log --oneline >actual &&
200 test_line_count = 3 actual &&
201 git diff --exit-code final-shasquash &&
202 echo 1 >expect &&
203 git cat-file blob HEAD^:file1 >actual &&
204 test_cmp expect actual &&
205 git cat-file commit HEAD^ >commit &&
206 grep squash commit >actual &&
207 test_line_count = 1 actual
210 test_expect_success 'auto squash that matches longer sha1' '
211 git reset --hard base &&
212 echo 1 >file1 &&
213 git add -u &&
214 test_tick &&
215 oid=$(git rev-parse --short=11 HEAD^) &&
216 git commit -m "squash! $oid" &&
217 git tag final-longshasquash &&
218 test_tick &&
219 git rebase --autosquash -i HEAD^^^ &&
220 git log --oneline >actual &&
221 test_line_count = 3 actual &&
222 git diff --exit-code final-longshasquash &&
223 echo 1 >expect &&
224 git cat-file blob HEAD^:file1 >actual &&
225 test_cmp expect actual &&
226 git cat-file commit HEAD^ >commit &&
227 grep squash commit >actual &&
228 test_line_count = 1 actual
231 test_auto_commit_flags () {
232 git reset --hard base &&
233 echo 1 >file1 &&
234 git add -u &&
235 test_tick &&
236 git commit --$1 first-commit &&
237 git tag final-commit-$1 &&
238 test_tick &&
239 git rebase --autosquash -i HEAD^^^ &&
240 git log --oneline >actual &&
241 test_line_count = 3 actual &&
242 git diff --exit-code final-commit-$1 &&
243 echo 1 >expect &&
244 git cat-file blob HEAD^:file1 >actual &&
245 test_cmp expect actual &&
246 git cat-file commit HEAD^ >commit &&
247 grep first commit >actual &&
248 test_line_count = $2 actual
251 test_expect_success 'use commit --fixup' '
252 test_auto_commit_flags fixup 1
255 test_expect_success 'use commit --squash' '
256 test_auto_commit_flags squash 2
259 test_auto_fixup_fixup () {
260 git reset --hard base &&
261 echo 1 >file1 &&
262 git add -u &&
263 test_tick &&
264 git commit -m "$1! first" &&
265 echo 2 >file1 &&
266 git add -u &&
267 test_tick &&
268 git commit -m "$1! $2! first" &&
269 git tag "final-$1-$2" &&
270 test_tick &&
272 set_cat_todo_editor &&
273 test_must_fail git rebase --autosquash -i HEAD^^^^ >actual &&
274 head=$(git rev-parse --short HEAD) &&
275 parent1=$(git rev-parse --short HEAD^) &&
276 parent2=$(git rev-parse --short HEAD^^) &&
277 parent3=$(git rev-parse --short HEAD^^^) &&
278 cat >expected <<-EOF &&
279 pick $parent3 first commit
280 $1 $parent1 $1! first
281 $1 $head $1! $2! first
282 pick $parent2 second commit
284 test_cmp expected actual
285 ) &&
286 git rebase --autosquash -i HEAD^^^^ &&
287 git log --oneline >actual &&
288 test_line_count = 3 actual
289 git diff --exit-code "final-$1-$2" &&
290 echo 2 >expect &&
291 git cat-file blob HEAD^:file1 >actual &&
292 test_cmp expect actual &&
293 git cat-file commit HEAD^ >commit &&
294 grep first commit >actual &&
295 if test "$1" = "fixup"
296 then
297 test_line_count = 1 actual
298 elif test "$1" = "squash"
299 then
300 test_line_count = 3 actual
301 else
302 false
306 test_expect_success C_LOCALE_OUTPUT 'fixup! fixup!' '
307 test_auto_fixup_fixup fixup fixup
310 test_expect_success C_LOCALE_OUTPUT 'fixup! squash!' '
311 test_auto_fixup_fixup fixup squash
314 test_expect_success C_LOCALE_OUTPUT 'squash! squash!' '
315 test_auto_fixup_fixup squash squash
318 test_expect_success C_LOCALE_OUTPUT 'squash! fixup!' '
319 test_auto_fixup_fixup squash fixup
322 test_expect_success C_LOCALE_OUTPUT 'autosquash with custom inst format' '
323 git reset --hard base &&
324 git config --add rebase.instructionFormat "[%an @ %ar] %s" &&
325 echo 2 >file1 &&
326 git add -u &&
327 test_tick &&
328 oid=$(git rev-parse --short HEAD^) &&
329 git commit -m "squash! $oid" &&
330 echo 1 >file1 &&
331 git add -u &&
332 test_tick &&
333 subject=$(git log -n 1 --format=%s HEAD~2) &&
334 git commit -m "squash! $subject" &&
335 git tag final-squash-instFmt &&
336 test_tick &&
337 git rebase --autosquash -i HEAD~4 &&
338 git log --oneline >actual &&
339 test_line_count = 3 actual &&
340 git diff --exit-code final-squash-instFmt &&
341 echo 1 >expect &&
342 git cat-file blob HEAD^:file1 >actual &&
343 test_cmp expect actual &&
344 git cat-file commit HEAD^ >commit &&
345 grep squash commit >actual &&
346 test_line_count = 2 actual
349 test_expect_success 'autosquash with empty custom instructionFormat' '
350 git reset --hard base &&
351 test_commit empty-instructionFormat-test &&
353 set_cat_todo_editor &&
354 test_must_fail git -c rebase.instructionFormat= \
355 rebase --autosquash --force-rebase -i HEAD^ >actual &&
356 git log -1 --format="pick %h %s" >expect &&
357 test_cmp expect actual
361 set_backup_editor () {
362 write_script backup-editor.sh <<-\EOF
363 cp "$1" .git/backup-"$(basename "$1")"
365 test_set_editor "$PWD/backup-editor.sh"
368 test_expect_success 'autosquash with multiple empty patches' '
369 test_tick &&
370 git commit --allow-empty -m "empty" &&
371 test_tick &&
372 git commit --allow-empty -m "empty2" &&
373 test_tick &&
374 >fixup &&
375 git add fixup &&
376 git commit --fixup HEAD^^ &&
378 set_backup_editor &&
379 GIT_USE_REBASE_HELPER=false \
380 git rebase -i --force-rebase --autosquash HEAD~4 &&
381 grep empty2 .git/backup-git-rebase-todo
385 test_expect_success 'extra spaces after fixup!' '
386 base=$(git rev-parse HEAD) &&
387 test_commit to-fixup &&
388 git commit --allow-empty -m "fixup! to-fixup" &&
389 git rebase -i --autosquash --keep-empty HEAD~2 &&
390 parent=$(git rev-parse HEAD^) &&
391 test $base = $parent
394 test_expect_success 'wrapped original subject' '
395 if test -d .git/rebase-merge; then git rebase --abort; fi &&
396 base=$(git rev-parse HEAD) &&
397 echo "wrapped subject" >wrapped &&
398 git add wrapped &&
399 test_tick &&
400 git commit --allow-empty -m "$(printf "To\nfixup")" &&
401 test_tick &&
402 git commit --allow-empty -m "fixup! To fixup" &&
403 git rebase -i --autosquash --keep-empty HEAD~2 &&
404 parent=$(git rev-parse HEAD^) &&
405 test $base = $parent
408 test_expect_success 'abort last squash' '
409 test_when_finished "test_might_fail git rebase --abort" &&
410 test_when_finished "git checkout master" &&
412 git checkout -b some-squashes &&
413 git commit --allow-empty -m first &&
414 git commit --allow-empty --squash HEAD &&
415 git commit --allow-empty -m second &&
416 git commit --allow-empty --squash HEAD &&
418 test_must_fail git -c core.editor="grep -q ^pick" \
419 rebase -ki --autosquash HEAD~4 &&
420 : do not finish the squash, but resolve it manually &&
421 git commit --allow-empty --amend -m edited-first &&
422 git rebase --skip &&
423 git show >actual &&
424 ! grep first actual
427 test_expect_success 'fixup a fixup' '
428 echo 0to-fixup >file0 &&
429 test_tick &&
430 git commit -m "to-fixup" file0 &&
431 test_tick &&
432 git commit --squash HEAD -m X --allow-empty &&
433 test_tick &&
434 git commit --squash HEAD^ -m Y --allow-empty &&
435 test_tick &&
436 git commit -m "squash! $(git rev-parse HEAD^)" -m Z --allow-empty &&
437 test_tick &&
438 git commit -m "squash! $(git rev-parse HEAD^^)" -m W --allow-empty &&
439 git rebase -ki --autosquash HEAD~5 &&
440 test XZWY = $(git show | tr -cd W-Z)
443 test_done