Code

rebase -i: add exec command to launch a shell command
[git.git] / t / t3404-rebase-interactive.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Johannes E. Schindelin
4 #
6 test_description='git rebase interactive
8 This test runs git rebase "interactively", by faking an edit, and verifies
9 that the result still makes sense.
10 '
11 . ./test-lib.sh
13 . "$TEST_DIRECTORY"/lib-rebase.sh
15 set_fake_editor
17 # Set up the repository like this:
18 #
19 #     one - two - three - four (conflict-branch)
20 #   /
21 # A - B - C - D - E            (master)
22 # | \
23 # |   F - G - H                (branch1)
24 # |     \
25 # |\      I                    (branch2)
26 # | \
27 # |   J - K - L - M            (no-conflict-branch)
28 #  \
29 #    N - O - P                 (no-ff-branch)
30 #
31 # where A, B, D and G all touch file1, and one, two, three, four all
32 # touch file "conflict".
33 #
34 # WARNING: Modifications to the initial repository can change the SHA ID used
35 # in the expect2 file for the 'stop on conflicting pick' test.
38 test_expect_success 'setup' '
39         test_commit A file1 &&
40         test_commit B file1 &&
41         test_commit C file2 &&
42         test_commit D file1 &&
43         test_commit E file3 &&
44         git checkout -b branch1 A &&
45         test_commit F file4 &&
46         test_commit G file1 &&
47         test_commit H file5 &&
48         git checkout -b branch2 F &&
49         test_commit I file6
50         git checkout -b conflict-branch A &&
51         for n in one two three four
52         do
53                 test_commit $n conflict
54         done &&
55         git checkout -b no-conflict-branch A &&
56         for n in J K L M
57         do
58                 test_commit $n file$n
59         done &&
60         git checkout -b no-ff-branch A &&
61         for n in N O P
62         do
63                 test_commit $n file$n
64         done
65 '
67 # "exec" commands are ran with the user shell by default, but this may
68 # be non-POSIX. For example, if SHELL=zsh then ">file" doesn't work
69 # to create a file. Unseting SHELL avoids such non-portable behavior
70 # in tests.
71 SHELL=
73 test_expect_success 'rebase -i with the exec command' '
74         git checkout master &&
75         (
76         FAKE_LINES="1 exec_>touch-one
77                 2 exec_>touch-two exec_false exec_>touch-three
78                 3 4 exec_>\"touch-file__name_with_spaces\";_>touch-after-semicolon 5" &&
79         export FAKE_LINES &&
80         test_must_fail git rebase -i A
81         ) &&
82         test -f touch-one &&
83         test -f touch-two &&
84         ! test -f touch-three &&
85         test $(git rev-parse C) = $(git rev-parse HEAD) || {
86                 echo "Stopped at wrong revision:"
87                 echo "($(git describe --tags HEAD) instead of C)"
88                 false
89         } &&
90         git rebase --continue &&
91         test -f touch-three &&
92         test -f "touch-file  name with spaces" &&
93         test -f touch-after-semicolon &&
94         test $(git rev-parse master) = $(git rev-parse HEAD) || {
95                 echo "Stopped at wrong revision:"
96                 echo "($(git describe --tags HEAD) instead of master)"
97                 false
98         } &&
99         rm -f touch-*
102 test_expect_success 'rebase -i with the exec command runs from tree root' '
103         git checkout master &&
104         mkdir subdir && cd subdir &&
105         FAKE_LINES="1 exec_>touch-subdir" \
106                 git rebase -i HEAD^ &&
107         cd .. &&
108         test -f touch-subdir &&
109         rm -fr subdir
112 test_expect_success 'rebase -i with the exec command checks tree cleanness' '
113         git checkout master &&
114         (
115         FAKE_LINES="exec_echo_foo_>file1 1" &&
116         export FAKE_LINES &&
117         test_must_fail git rebase -i HEAD^
118         ) &&
119         test $(git rev-parse master^) = $(git rev-parse HEAD) || {
120                 echo "Stopped at wrong revision:"
121                 echo "($(git describe --tags HEAD) instead of master^)"
122                 false
123         } &&
124         git reset --hard &&
125         git rebase --continue
128 test_expect_success 'no changes are a nop' '
129         git checkout branch2 &&
130         git rebase -i F &&
131         test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&
132         test $(git rev-parse I) = $(git rev-parse HEAD)
135 test_expect_success 'test the [branch] option' '
136         git checkout -b dead-end &&
137         git rm file6 &&
138         git commit -m "stop here" &&
139         git rebase -i F branch2 &&
140         test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&
141         test $(git rev-parse I) = $(git rev-parse branch2) &&
142         test $(git rev-parse I) = $(git rev-parse HEAD)
145 test_expect_success 'test --onto <branch>' '
146         git checkout -b test-onto branch2 &&
147         git rebase -i --onto branch1 F &&
148         test "$(git symbolic-ref -q HEAD)" = "refs/heads/test-onto" &&
149         test $(git rev-parse HEAD^) = $(git rev-parse branch1) &&
150         test $(git rev-parse I) = $(git rev-parse branch2)
153 test_expect_success 'rebase on top of a non-conflicting commit' '
154         git checkout branch1 &&
155         git tag original-branch1 &&
156         git rebase -i branch2 &&
157         test file6 = $(git diff --name-only original-branch1) &&
158         test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" &&
159         test $(git rev-parse I) = $(git rev-parse branch2) &&
160         test $(git rev-parse I) = $(git rev-parse HEAD~2)
163 test_expect_success 'reflog for the branch shows state before rebase' '
164         test $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1)
167 test_expect_success 'exchange two commits' '
168         FAKE_LINES="2 1" git rebase -i HEAD~2 &&
169         test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
170         test G = $(git cat-file commit HEAD | sed -ne \$p)
173 cat > expect << EOF
174 diff --git a/file1 b/file1
175 index f70f10e..fd79235 100644
176 --- a/file1
177 +++ b/file1
178 @@ -1 +1 @@
179 -A
180 +G
181 EOF
183 cat > expect2 << EOF
184 <<<<<<< HEAD
186 =======
188 >>>>>>> 5d18e54... G
189 EOF
191 test_expect_success 'stop on conflicting pick' '
192         git tag new-branch1 &&
193         test_must_fail git rebase -i master &&
194         test "$(git rev-parse HEAD~3)" = "$(git rev-parse master)" &&
195         test_cmp expect .git/rebase-merge/patch &&
196         test_cmp expect2 file1 &&
197         test "$(git diff --name-status |
198                 sed -n -e "/^U/s/^U[^a-z]*//p")" = file1 &&
199         test 4 = $(grep -v "^#" < .git/rebase-merge/done | wc -l) &&
200         test 0 = $(grep -c "^[^#]" < .git/rebase-merge/git-rebase-todo)
203 test_expect_success 'abort' '
204         git rebase --abort &&
205         test $(git rev-parse new-branch1) = $(git rev-parse HEAD) &&
206         test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" &&
207         ! test -d .git/rebase-merge
210 test_expect_success 'abort with error when new base cannot be checked out' '
211         git rm --cached file1 &&
212         git commit -m "remove file in base" &&
213         test_must_fail git rebase -i master > output 2>&1 &&
214         grep "Untracked working tree file .file1. would be overwritten" \
215                 output &&
216         ! test -d .git/rebase-merge &&
217         git reset --hard HEAD^
220 test_expect_success 'retain authorship' '
221         echo A > file7 &&
222         git add file7 &&
223         test_tick &&
224         GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
225         git tag twerp &&
226         git rebase -i --onto master HEAD^ &&
227         git show HEAD | grep "^Author: Twerp Snog"
230 test_expect_success 'squash' '
231         git reset --hard twerp &&
232         echo B > file7 &&
233         test_tick &&
234         GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 &&
235         echo "******************************" &&
236         FAKE_LINES="1 squash 2" EXPECT_HEADER_COUNT=2 \
237                 git rebase -i --onto master HEAD~2 &&
238         test B = $(cat file7) &&
239         test $(git rev-parse HEAD^) = $(git rev-parse master)
242 test_expect_success 'retain authorship when squashing' '
243         git show HEAD | grep "^Author: Twerp Snog"
246 test_expect_success '-p handles "no changes" gracefully' '
247         HEAD=$(git rev-parse HEAD) &&
248         git rebase -i -p HEAD^ &&
249         git update-index --refresh &&
250         git diff-files --quiet &&
251         git diff-index --quiet --cached HEAD -- &&
252         test $HEAD = $(git rev-parse HEAD)
255 test_expect_failure 'exchange two commits with -p' '
256         FAKE_LINES="2 1" git rebase -i -p HEAD~2 &&
257         test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
258         test G = $(git cat-file commit HEAD | sed -ne \$p)
261 test_expect_success 'preserve merges with -p' '
262         git checkout -b to-be-preserved master^ &&
263         : > unrelated-file &&
264         git add unrelated-file &&
265         test_tick &&
266         git commit -m "unrelated" &&
267         git checkout -b another-branch master &&
268         echo B > file1 &&
269         test_tick &&
270         git commit -m J file1 &&
271         test_tick &&
272         git merge to-be-preserved &&
273         echo C > file1 &&
274         test_tick &&
275         git commit -m K file1 &&
276         echo D > file1 &&
277         test_tick &&
278         git commit -m L1 file1 &&
279         git checkout HEAD^ &&
280         echo 1 > unrelated-file &&
281         test_tick &&
282         git commit -m L2 unrelated-file &&
283         test_tick &&
284         git merge another-branch &&
285         echo E > file1 &&
286         test_tick &&
287         git commit -m M file1 &&
288         git checkout -b to-be-rebased &&
289         test_tick &&
290         git rebase -i -p --onto branch1 master &&
291         git update-index --refresh &&
292         git diff-files --quiet &&
293         git diff-index --quiet --cached HEAD -- &&
294         test $(git rev-parse HEAD~6) = $(git rev-parse branch1) &&
295         test $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) &&
296         test $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) &&
297         test $(git show HEAD~5:file1) = B &&
298         test $(git show HEAD~3:file1) = C &&
299         test $(git show HEAD:file1) = E &&
300         test $(git show HEAD:unrelated-file) = 1
303 test_expect_success 'edit ancestor with -p' '
304         FAKE_LINES="1 edit 2 3 4" git rebase -i -p HEAD~3 &&
305         echo 2 > unrelated-file &&
306         test_tick &&
307         git commit -m L2-modified --amend unrelated-file &&
308         git rebase --continue &&
309         git update-index --refresh &&
310         git diff-files --quiet &&
311         git diff-index --quiet --cached HEAD -- &&
312         test $(git show HEAD:unrelated-file) = 2
315 test_expect_success '--continue tries to commit' '
316         test_tick &&
317         test_must_fail git rebase -i --onto new-branch1 HEAD^ &&
318         echo resolved > file1 &&
319         git add file1 &&
320         FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
321         test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&
322         git show HEAD | grep chouette
325 test_expect_success 'verbose flag is heeded, even after --continue' '
326         git reset --hard HEAD@{1} &&
327         test_tick &&
328         test_must_fail git rebase -v -i --onto new-branch1 HEAD^ &&
329         echo resolved > file1 &&
330         git add file1 &&
331         git rebase --continue > output &&
332         grep "^ file1 |    2 +-$" output
335 test_expect_success 'multi-squash only fires up editor once' '
336         base=$(git rev-parse HEAD~4) &&
337         FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 squash 2 squash 3 squash 4" \
338                 EXPECT_HEADER_COUNT=4 \
339                 git rebase -i $base &&
340         test $base = $(git rev-parse HEAD^) &&
341         test 1 = $(git show | grep ONCE | wc -l)
344 test_expect_success 'multi-fixup does not fire up editor' '
345         git checkout -b multi-fixup E &&
346         base=$(git rev-parse HEAD~4) &&
347         FAKE_COMMIT_AMEND="NEVER" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \
348                 git rebase -i $base &&
349         test $base = $(git rev-parse HEAD^) &&
350         test 0 = $(git show | grep NEVER | wc -l) &&
351         git checkout to-be-rebased &&
352         git branch -D multi-fixup
355 test_expect_success 'commit message used after conflict' '
356         git checkout -b conflict-fixup conflict-branch &&
357         base=$(git rev-parse HEAD~4) &&
358         (
359                 FAKE_LINES="1 fixup 3 fixup 4" &&
360                 export FAKE_LINES &&
361                 test_must_fail git rebase -i $base
362         ) &&
363         echo three > conflict &&
364         git add conflict &&
365         FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \
366                 git rebase --continue &&
367         test $base = $(git rev-parse HEAD^) &&
368         test 1 = $(git show | grep ONCE | wc -l) &&
369         git checkout to-be-rebased &&
370         git branch -D conflict-fixup
373 test_expect_success 'commit message retained after conflict' '
374         git checkout -b conflict-squash conflict-branch &&
375         base=$(git rev-parse HEAD~4) &&
376         (
377                 FAKE_LINES="1 fixup 3 squash 4" &&
378                 export FAKE_LINES &&
379                 test_must_fail git rebase -i $base
380         ) &&
381         echo three > conflict &&
382         git add conflict &&
383         FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \
384                 git rebase --continue &&
385         test $base = $(git rev-parse HEAD^) &&
386         test 2 = $(git show | grep TWICE | wc -l) &&
387         git checkout to-be-rebased &&
388         git branch -D conflict-squash
391 cat > expect-squash-fixup << EOF
396 ONCE
397 EOF
399 test_expect_success 'squash and fixup generate correct log messages' '
400         git checkout -b squash-fixup E &&
401         base=$(git rev-parse HEAD~4) &&
402         FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 squash 3 fixup 4" \
403                 EXPECT_HEADER_COUNT=4 \
404                 git rebase -i $base &&
405         git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup &&
406         test_cmp expect-squash-fixup actual-squash-fixup &&
407         git checkout to-be-rebased &&
408         git branch -D squash-fixup
411 test_expect_success 'squash ignores comments' '
412         git checkout -b skip-comments E &&
413         base=$(git rev-parse HEAD~4) &&
414         FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \
415                 EXPECT_HEADER_COUNT=4 \
416                 git rebase -i $base &&
417         test $base = $(git rev-parse HEAD^) &&
418         test 1 = $(git show | grep ONCE | wc -l) &&
419         git checkout to-be-rebased &&
420         git branch -D skip-comments
423 test_expect_success 'squash ignores blank lines' '
424         git checkout -b skip-blank-lines E &&
425         base=$(git rev-parse HEAD~4) &&
426         FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \
427                 EXPECT_HEADER_COUNT=4 \
428                 git rebase -i $base &&
429         test $base = $(git rev-parse HEAD^) &&
430         test 1 = $(git show | grep ONCE | wc -l) &&
431         git checkout to-be-rebased &&
432         git branch -D skip-blank-lines
435 test_expect_success 'squash works as expected' '
436         git checkout -b squash-works no-conflict-branch &&
437         one=$(git rev-parse HEAD~3) &&
438         FAKE_LINES="1 squash 3 2" EXPECT_HEADER_COUNT=2 \
439                 git rebase -i HEAD~3 &&
440         test $one = $(git rev-parse HEAD~2)
443 test_expect_success 'interrupted squash works as expected' '
444         git checkout -b interrupted-squash conflict-branch &&
445         one=$(git rev-parse HEAD~3) &&
446         (
447                 FAKE_LINES="1 squash 3 2" &&
448                 export FAKE_LINES &&
449                 test_must_fail git rebase -i HEAD~3
450         ) &&
451         (echo one; echo two; echo four) > conflict &&
452         git add conflict &&
453         test_must_fail git rebase --continue &&
454         echo resolved > conflict &&
455         git add conflict &&
456         git rebase --continue &&
457         test $one = $(git rev-parse HEAD~2)
460 test_expect_success 'interrupted squash works as expected (case 2)' '
461         git checkout -b interrupted-squash2 conflict-branch &&
462         one=$(git rev-parse HEAD~3) &&
463         (
464                 FAKE_LINES="3 squash 1 2" &&
465                 export FAKE_LINES &&
466                 test_must_fail git rebase -i HEAD~3
467         ) &&
468         (echo one; echo four) > conflict &&
469         git add conflict &&
470         test_must_fail git rebase --continue &&
471         (echo one; echo two; echo four) > conflict &&
472         git add conflict &&
473         test_must_fail git rebase --continue &&
474         echo resolved > conflict &&
475         git add conflict &&
476         git rebase --continue &&
477         test $one = $(git rev-parse HEAD~2)
480 test_expect_success 'ignore patch if in upstream' '
481         HEAD=$(git rev-parse HEAD) &&
482         git checkout -b has-cherry-picked HEAD^ &&
483         echo unrelated > file7 &&
484         git add file7 &&
485         test_tick &&
486         git commit -m "unrelated change" &&
487         git cherry-pick $HEAD &&
488         EXPECT_COUNT=1 git rebase -i $HEAD &&
489         test $HEAD = $(git rev-parse HEAD^)
492 test_expect_success '--continue tries to commit, even for "edit"' '
493         parent=$(git rev-parse HEAD^) &&
494         test_tick &&
495         FAKE_LINES="edit 1" git rebase -i HEAD^ &&
496         echo edited > file7 &&
497         git add file7 &&
498         FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
499         test edited = $(git show HEAD:file7) &&
500         git show HEAD | grep chouette &&
501         test $parent = $(git rev-parse HEAD^)
504 test_expect_success 'aborted --continue does not squash commits after "edit"' '
505         old=$(git rev-parse HEAD) &&
506         test_tick &&
507         FAKE_LINES="edit 1" git rebase -i HEAD^ &&
508         echo "edited again" > file7 &&
509         git add file7 &&
510         (
511                 FAKE_COMMIT_MESSAGE=" " &&
512                 export FAKE_COMMIT_MESSAGE &&
513                 test_must_fail git rebase --continue
514         ) &&
515         test $old = $(git rev-parse HEAD) &&
516         git rebase --abort
519 test_expect_success 'auto-amend only edited commits after "edit"' '
520         test_tick &&
521         FAKE_LINES="edit 1" git rebase -i HEAD^ &&
522         echo "edited again" > file7 &&
523         git add file7 &&
524         FAKE_COMMIT_MESSAGE="edited file7 again" git commit &&
525         echo "and again" > file7 &&
526         git add file7 &&
527         test_tick &&
528         (
529                 FAKE_COMMIT_MESSAGE="and again" &&
530                 export FAKE_COMMIT_MESSAGE &&
531                 test_must_fail git rebase --continue
532         ) &&
533         git rebase --abort
536 test_expect_success 'rebase a detached HEAD' '
537         grandparent=$(git rev-parse HEAD~2) &&
538         git checkout $(git rev-parse HEAD) &&
539         test_tick &&
540         FAKE_LINES="2 1" git rebase -i HEAD~2 &&
541         test $grandparent = $(git rev-parse HEAD~2)
544 test_expect_success 'rebase a commit violating pre-commit' '
546         mkdir -p .git/hooks &&
547         PRE_COMMIT=.git/hooks/pre-commit &&
548         echo "#!/bin/sh" > $PRE_COMMIT &&
549         echo "test -z \"\$(git diff --cached --check)\"" >> $PRE_COMMIT &&
550         chmod a+x $PRE_COMMIT &&
551         echo "monde! " >> file1 &&
552         test_tick &&
553         test_must_fail git commit -m doesnt-verify file1 &&
554         git commit -m doesnt-verify --no-verify file1 &&
555         test_tick &&
556         FAKE_LINES=2 git rebase -i HEAD~2
560 test_expect_success 'rebase with a file named HEAD in worktree' '
562         rm -fr .git/hooks &&
563         git reset --hard &&
564         git checkout -b branch3 A &&
566         (
567                 GIT_AUTHOR_NAME="Squashed Away" &&
568                 export GIT_AUTHOR_NAME &&
569                 >HEAD &&
570                 git add HEAD &&
571                 git commit -m "Add head" &&
572                 >BODY &&
573                 git add BODY &&
574                 git commit -m "Add body"
575         ) &&
577         FAKE_LINES="1 squash 2" git rebase -i to-be-rebased &&
578         test "$(git show -s --pretty=format:%an)" = "Squashed Away"
582 test_expect_success 'do "noop" when there is nothing to cherry-pick' '
584         git checkout -b branch4 HEAD &&
585         GIT_EDITOR=: git commit --amend \
586                 --author="Somebody else <somebody@else.com>" 
587         test $(git rev-parse branch3) != $(git rev-parse branch4) &&
588         git rebase -i branch3 &&
589         test $(git rev-parse branch3) = $(git rev-parse branch4)
593 test_expect_success 'submodule rebase setup' '
594         git checkout A &&
595         mkdir sub &&
596         (
597                 cd sub && git init && >elif &&
598                 git add elif && git commit -m "submodule initial"
599         ) &&
600         echo 1 >file1 &&
601         git add file1 sub
602         test_tick &&
603         git commit -m "One" &&
604         echo 2 >file1 &&
605         test_tick &&
606         git commit -a -m "Two" &&
607         (
608                 cd sub && echo 3 >elif &&
609                 git commit -a -m "submodule second"
610         ) &&
611         test_tick &&
612         git commit -a -m "Three changes submodule"
615 test_expect_success 'submodule rebase -i' '
616         FAKE_LINES="1 squash 2 3" git rebase -i A
619 test_expect_success 'avoid unnecessary reset' '
620         git checkout master &&
621         test-chmtime =123456789 file3 &&
622         git update-index --refresh &&
623         HEAD=$(git rev-parse HEAD) &&
624         git rebase -i HEAD~4 &&
625         test $HEAD = $(git rev-parse HEAD) &&
626         MTIME=$(test-chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&
627         test 123456789 = $MTIME
630 test_expect_success 'reword' '
631         git checkout -b reword-branch master &&
632         FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" git rebase -i A &&
633         git show HEAD | grep "E changed" &&
634         test $(git rev-parse master) != $(git rev-parse HEAD) &&
635         test $(git rev-parse master^) = $(git rev-parse HEAD^) &&
636         FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" git rebase -i A &&
637         git show HEAD^ | grep "D changed" &&
638         FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" git rebase -i A &&
639         git show HEAD~3 | grep "B changed" &&
640         FAKE_LINES="1 reword 2 3 4" FAKE_COMMIT_MESSAGE="C changed" git rebase -i A &&
641         git show HEAD~2 | grep "C changed"
644 test_expect_success 'rebase -i can copy notes' '
645         git config notes.rewrite.rebase true &&
646         git config notes.rewriteRef "refs/notes/*" &&
647         test_commit n1 &&
648         test_commit n2 &&
649         test_commit n3 &&
650         git notes add -m"a note" n3 &&
651         git rebase --onto n1 n2 &&
652         test "a note" = "$(git notes show HEAD)"
655 cat >expect <<EOF
656 an earlier note
657 a note
658 EOF
660 test_expect_success 'rebase -i can copy notes over a fixup' '
661         git reset --hard n3 &&
662         git notes add -m"an earlier note" n2 &&
663         GIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES="1 fixup 2" git rebase -i n1 &&
664         git notes show > output &&
665         test_cmp expect output
668 test_expect_success 'rebase while detaching HEAD' '
669         git symbolic-ref HEAD &&
670         grandparent=$(git rev-parse HEAD~2) &&
671         test_tick &&
672         FAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0 &&
673         test $grandparent = $(git rev-parse HEAD~2) &&
674         test_must_fail git symbolic-ref HEAD
677 test_tick # Ensure that the rebased commits get a different timestamp.
678 test_expect_success 'always cherry-pick with --no-ff' '
679         git checkout no-ff-branch &&
680         git tag original-no-ff-branch &&
681         git rebase -i --no-ff A &&
682         touch empty &&
683         for p in 0 1 2
684         do
685                 test ! $(git rev-parse HEAD~$p) = $(git rev-parse original-no-ff-branch~$p) &&
686                 git diff HEAD~$p original-no-ff-branch~$p > out &&
687                 test_cmp empty out
688         done &&
689         test $(git rev-parse HEAD~3) = $(git rev-parse original-no-ff-branch~3) &&
690         git diff HEAD~3 original-no-ff-branch~3 > out &&
691         test_cmp empty out
694 test_expect_success 'set up commits with funny messages' '
695         git checkout -b funny A &&
696         echo >>file1 &&
697         test_tick &&
698         git commit -a -m "end with slash\\" &&
699         echo >>file1 &&
700         test_tick &&
701         git commit -a -m "another commit"
704 test_expect_success 'rebase-i history with funny messages' '
705         git rev-list A..funny >expect &&
706         test_tick &&
707         FAKE_LINES="1 2" git rebase -i A &&
708         git rev-list A.. >actual &&
709         test_cmp expect actual
712 test_done