(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: { (SQ <'git rebase interactive\n'> <'\n'> <'This test runs git rebase "interactively", by faking an edit, and verifies\n'> <'that the result still makes sense.\n'> <'\n'> <'Initial setup:\n'> <'\n'> <' one - two - three - four (conflict-branch)\n'> <' /\n'> <' A - B - C - D - E (master)\n'> <' | \\\n'> <' | F - G - H (branch1)\n'> <' | \\\n'> <' |\\ I (branch2)\n'> <' | \\\n'> <' | J - K - L - M (no-conflict-branch)\n'> <' \\\n'> <' N - O - P (no-ff-branch)\n'> <'\n'> <' where A, B, D and G all touch file1, and one, two, three, four all\n'> <' touch file "conflict".\n'> ) } spids: [13] ) ] spids: [13] ) (C {(.)} {(./test-lib.sh)}) (C {(.)} {(DQ ($ VSub_Name '$TEST_DIRECTORY')) (/lib-rebase.sh)}) (C {(test_expect_success)} {(SQ <setup>)} { (SQ <'\n'> <'\ttest_commit A file1 &&\n'> <'\ttest_commit B file1 &&\n'> <'\ttest_commit C file2 &&\n'> <'\ttest_commit D file1 &&\n'> <'\ttest_commit E file3 &&\n'> <'\tgit checkout -b branch1 A &&\n'> <'\ttest_commit F file4 &&\n'> <'\ttest_commit G file1 &&\n'> <'\ttest_commit H file5 &&\n'> <'\tgit checkout -b branch2 F &&\n'> <'\ttest_commit I file6 &&\n'> <'\tgit checkout -b conflict-branch A &&\n'> <'\ttest_commit one conflict &&\n'> <'\ttest_commit two conflict &&\n'> <'\ttest_commit three conflict &&\n'> <'\ttest_commit four conflict &&\n'> <'\tgit checkout -b no-conflict-branch A &&\n'> <'\ttest_commit J fileJ &&\n'> <'\ttest_commit K fileK &&\n'> <'\ttest_commit L fileL &&\n'> <'\ttest_commit M fileM &&\n'> <'\tgit checkout -b no-ff-branch A &&\n'> <'\ttest_commit N fileN &&\n'> <'\ttest_commit O fileO &&\n'> <'\ttest_commit P fileP\n'> ) } ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:SHELL) op:Equal rhs:{(SQ )} spids:[106])] spids: [106] ) (C {(export)} {(SHELL)}) (C {(test_expect_success)} {(SQ <'rebase --keep-empty'>)} { (SQ <'\n'> <'\tgit checkout -b emptybranch master &&\n'> <'\tgit commit --allow-empty -m "empty" &&\n'> <'\tgit rebase --keep-empty -i HEAD~2 &&\n'> <'\tgit log --oneline >actual &&\n'> <'\ttest_line_count = 6 actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i with the exec command'>)} { (SQ <'\n'> <'\tgit checkout master &&\n'> <'\t(\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 exec_>touch-one\n'> <'\t\t2 exec_>touch-two exec_false exec_>touch-three\n'> <'\t\t3 4 exec_>\\"touch-file__name_with_spaces\\";_>touch-after-semicolon 5" &&\n'> <'\texport FAKE_LINES &&\n'> <'\ttest_must_fail git rebase -i A\n'> <'\t) &&\n'> <'\ttest_path_is_file touch-one &&\n'> <'\ttest_path_is_file touch-two &&\n'> <'\ttest_path_is_missing touch-three " (should have stopped before)" &&\n'> <'\ttest_cmp_rev C HEAD &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest_path_is_file touch-three &&\n'> <'\ttest_path_is_file "touch-file name with spaces" &&\n'> <'\ttest_path_is_file touch-after-semicolon &&\n'> <'\ttest_cmp_rev master HEAD &&\n'> <'\trm -f touch-*\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i with the exec command runs from tree root'>)} { (SQ <'\n'> <'\tgit checkout master &&\n'> <'\tmkdir subdir && (cd subdir &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 exec_>touch-subdir" \\\n'> <'\t\tgit rebase -i HEAD^\n'> <'\t) &&\n'> <'\ttest_path_is_file touch-subdir &&\n'> <'\trm -fr subdir\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i with the exec command checks tree cleanness'>)} { (SQ <'\n'> <'\tgit checkout master &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="exec_echo_foo_>file1 1" git rebase -i HEAD^ &&\n'> <'\ttest_cmp_rev master^ HEAD &&\n'> <'\tgit reset --hard &&\n'> <'\tgit rebase --continue\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i with exec of inexistent command'>)} { (SQ <'\n'> <'\tgit checkout master &&\n'> <'\ttest_when_finished "git rebase --abort" &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="exec_this-command-does-not-exist 1" \\\n'> <'\tgit rebase -i HEAD^ >actual 2>&1 &&\n'> <'\t! grep "Maybe git-rebase is broken" actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'no changes are a nop'>)} { (SQ <'\n'> <'\tgit checkout branch2 &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i F &&\n'> <'\ttest "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&\n'> <'\ttest $(git rev-parse I) = $(git rev-parse HEAD)\n'> ) } ) (C {(test_expect_success)} {(SQ <'test the [branch] option'>)} { (SQ <'\n'> <'\tgit checkout -b dead-end &&\n'> <'\tgit rm file6 &&\n'> <'\tgit commit -m "stop here" &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i F branch2 &&\n'> <'\ttest "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" &&\n'> <'\ttest $(git rev-parse I) = $(git rev-parse branch2) &&\n'> <'\ttest $(git rev-parse I) = $(git rev-parse HEAD)\n'> ) } ) (C {(test_expect_success)} {(SQ <'test --onto <branch>'>)} { (SQ <'\n'> <'\tgit checkout -b test-onto branch2 &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i --onto branch1 F &&\n'> <'\ttest "$(git symbolic-ref -q HEAD)" = "refs/heads/test-onto" &&\n'> <'\ttest $(git rev-parse HEAD^) = $(git rev-parse branch1) &&\n'> <'\ttest $(git rev-parse I) = $(git rev-parse branch2)\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase on top of a non-conflicting commit'>)} { (SQ <'\n'> <'\tgit checkout branch1 &&\n'> <'\tgit tag original-branch1 &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i branch2 &&\n'> <'\ttest file6 = $(git diff --name-only original-branch1) &&\n'> <'\ttest "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" &&\n'> <'\ttest $(git rev-parse I) = $(git rev-parse branch2) &&\n'> <'\ttest $(git rev-parse I) = $(git rev-parse HEAD~2)\n'> ) } ) (C {(test_expect_success)} {(SQ <'reflog for the branch shows state before rebase'>)} {(SQ <'\n'> <'\ttest $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1)\n'>)} ) (C {(test_expect_success)} {(SQ <'exchange two commits'>)} { (SQ <'\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="2 1" git rebase -i HEAD~2 &&\n'> <'\ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n'> <'\ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect)} spids:[312]) (HereDoc op_id: Redir_DLess fd: 16777215 body: { (DQ ('diff --git a/file1 b/file1\n') ('index f70f10e..fd79235 100644\n') ('--- a/file1\n') ('+++ b/file1\n') ('@@ -1 +1 @@\n') ('-A\n') ('+G\n') ) } do_expansion: True here_end: EOF was_filled: True spids: [316] ) ] ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect2)} spids:[331]) (HereDoc op_id: Redir_DLess fd: 16777215 body: {(DQ ('<<<<<<< HEAD\n') ('D\n') ('=======\n') ('G\n') ('>>>>>>> 5d18e54... G\n'))} do_expansion: True here_end: EOF was_filled: True spids: [335] ) ] ) (C {(test_expect_success)} {(SQ <'stop on conflicting pick'>)} { (SQ <'\n'> <'\tgit tag new-branch1 &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase -i master &&\n'> <'\ttest "$(git rev-parse HEAD~3)" = "$(git rev-parse master)" &&\n'> <'\ttest_cmp expect .git/rebase-merge/patch &&\n'> <'\ttest_cmp expect2 file1 &&\n'> <'\ttest "$(git diff --name-status |\n'> <'\t\tsed -n -e "/^U/s/^U[^a-z]*//p")" = file1 &&\n'> <'\ttest 4 = $(grep -v "^#" < .git/rebase-merge/done | wc -l) &&\n'> <'\ttest 0 = $(grep -c "^[^#]" < .git/rebase-merge/git-rebase-todo)\n'> ) } ) (C {(test_expect_success)} {(SQ <abort>)} { (SQ <'\n'> <'\tgit rebase --abort &&\n'> <'\ttest $(git rev-parse new-branch1) = $(git rev-parse HEAD) &&\n'> <'\ttest "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" &&\n'> <'\ttest_path_is_missing .git/rebase-merge\n'> ) } ) (C {(test_expect_success)} {(SQ <'abort with error when new base cannot be checked out'>)} { (SQ <'\n'> <'\tgit rm --cached file1 &&\n'> <'\tgit commit -m "remove file in base" &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase -i master > output 2>&1 &&\n'> < '\ttest_i18ngrep "The following untracked working tree files would be overwritten by checkout:" \\\n' > <'\t\toutput &&\n'> <'\ttest_i18ngrep "file1" output &&\n'> <'\ttest_path_is_missing .git/rebase-merge &&\n'> <'\tgit reset --hard HEAD^\n'> ) } ) (C {(test_expect_success)} {(SQ <'retain authorship'>)} { (SQ <'\n'> <'\techo A > file7 &&\n'> <'\tgit add file7 &&\n'> <'\ttest_tick &&\n'> <'\tGIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&\n'> <'\tgit tag twerp &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i --onto master HEAD^ &&\n'> <'\tgit show HEAD | grep "^Author: Twerp Snog"\n'> ) } ) (C {(test_expect_success)} {(SQ <squash>)} { (SQ <'\n'> <'\tgit reset --hard twerp &&\n'> <'\techo B > file7 &&\n'> <'\ttest_tick &&\n'> <'\tGIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 &&\n'> <'\techo "******************************" &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 squash 2" EXPECT_HEADER_COUNT=2 \\\n'> <'\t\tgit rebase -i --onto master HEAD~2 &&\n'> <'\ttest B = $(cat file7) &&\n'> <'\ttest $(git rev-parse HEAD^) = $(git rev-parse master)\n'> ) } ) (C {(test_expect_success)} {(SQ <'retain authorship when squashing'>)} {(SQ <'\n'> <'\tgit show HEAD | grep "^Author: Twerp Snog"\n'>)} ) (C {(test_expect_success)} {(SQ <'-p handles "no changes" gracefully'>)} { (SQ <'\n'> <'\tHEAD=$(git rev-parse HEAD) &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i -p HEAD^ &&\n'> <'\tgit update-index --refresh &&\n'> <'\tgit diff-files --quiet &&\n'> <'\tgit diff-index --quiet --cached HEAD -- &&\n'> <'\ttest $HEAD = $(git rev-parse HEAD)\n'> ) } ) (C {(test_expect_failure)} {(SQ <'exchange two commits with -p'>)} { (SQ <'\n'> <'\tgit checkout H &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="2 1" git rebase -i -p HEAD~2 &&\n'> <'\ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n'> <'\ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n'> ) } ) (C {(test_expect_success)} {(SQ <'preserve merges with -p'>)} { (SQ <'\n'> <'\tgit checkout -b to-be-preserved master^ &&\n'> <'\t: > unrelated-file &&\n'> <'\tgit add unrelated-file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "unrelated" &&\n'> <'\tgit checkout -b another-branch master &&\n'> <'\techo B > file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m J file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit merge to-be-preserved &&\n'> <'\techo C > file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m K file1 &&\n'> <'\techo D > file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m L1 file1 &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\techo 1 > unrelated-file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m L2 unrelated-file &&\n'> <'\ttest_tick &&\n'> <'\tgit merge another-branch &&\n'> <'\techo E > file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m M file1 &&\n'> <'\tgit checkout -b to-be-rebased &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i -p --onto branch1 master &&\n'> <'\tgit update-index --refresh &&\n'> <'\tgit diff-files --quiet &&\n'> <'\tgit diff-index --quiet --cached HEAD -- &&\n'> <'\ttest $(git rev-parse HEAD~6) = $(git rev-parse branch1) &&\n'> <'\ttest $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) &&\n'> <'\ttest $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) &&\n'> <'\ttest $(git show HEAD~5:file1) = B &&\n'> <'\ttest $(git show HEAD~3:file1) = C &&\n'> <'\ttest $(git show HEAD:file1) = E &&\n'> <'\ttest $(git show HEAD:unrelated-file) = 1\n'> ) } ) (C {(test_expect_success)} {(SQ <'edit ancestor with -p'>)} { (SQ <'\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3 &&\n'> <'\techo 2 > unrelated-file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m L2-modified --amend unrelated-file &&\n'> <'\tgit rebase --continue &&\n'> <'\tgit update-index --refresh &&\n'> <'\tgit diff-files --quiet &&\n'> <'\tgit diff-index --quiet --cached HEAD -- &&\n'> <'\ttest $(git show HEAD:unrelated-file) = 2\n'> ) } ) (C {(test_expect_success)} {(SQ <'--continue tries to commit'>)} { (SQ <'\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase -i --onto new-branch1 HEAD^ &&\n'> <'\techo resolved > file1 &&\n'> <'\tgit add file1 &&\n'> <'\tFAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&\n'> <'\ttest $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&\n'> <'\tgit show HEAD | grep chouette\n'> ) } ) (C {(test_expect_success)} {(SQ <'verbose flag is heeded, even after --continue'>)} { (SQ <'\n'> <'\tgit reset --hard master@{1} &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase -v -i --onto new-branch1 HEAD^ &&\n'> <'\techo resolved > file1 &&\n'> <'\tgit add file1 &&\n'> <'\tgit rebase --continue > output &&\n'> <'\tgrep "^ file1 | 2 +-$" output\n'> ) } ) (C {(test_expect_success)} {(SQ <'multi-squash only fires up editor once'>)} { (SQ <'\n'> <'\tbase=$(git rev-parse HEAD~4) &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 squash 2 squash 3 squash 4" \\\n'> <'\t\tEXPECT_HEADER_COUNT=4 \\\n'> <'\t\tgit rebase -i $base &&\n'> <'\ttest $base = $(git rev-parse HEAD^) &&\n'> <'\ttest 1 = $(git show | grep ONCE | wc -l)\n'> ) } ) (C {(test_expect_success)} {(SQ <'multi-fixup does not fire up editor'>)} { (SQ <'\n'> <'\tgit checkout -b multi-fixup E &&\n'> <'\tbase=$(git rev-parse HEAD~4) &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_COMMIT_AMEND="NEVER" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \\\n'> <'\t\tgit rebase -i $base &&\n'> <'\ttest $base = $(git rev-parse HEAD^) &&\n'> <'\ttest 0 = $(git show | grep NEVER | wc -l) &&\n'> <'\tgit checkout to-be-rebased &&\n'> <'\tgit branch -D multi-fixup\n'> ) } ) (C {(test_expect_success)} {(SQ <'commit message used after conflict'>)} { (SQ <'\n'> <'\tgit checkout -b conflict-fixup conflict-branch &&\n'> <'\tbase=$(git rev-parse HEAD~4) &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="1 fixup 3 fixup 4" git rebase -i $base &&\n'> <'\techo three > conflict &&\n'> <'\tgit add conflict &&\n'> <'\tFAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \\\n'> <'\t\tgit rebase --continue &&\n'> <'\ttest $base = $(git rev-parse HEAD^) &&\n'> <'\ttest 1 = $(git show | grep ONCE | wc -l) &&\n'> <'\tgit checkout to-be-rebased &&\n'> <'\tgit branch -D conflict-fixup\n'> ) } ) (C {(test_expect_success)} {(SQ <'commit message retained after conflict'>)} { (SQ <'\n'> <'\tgit checkout -b conflict-squash conflict-branch &&\n'> <'\tbase=$(git rev-parse HEAD~4) &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="1 fixup 3 squash 4" git rebase -i $base &&\n'> <'\techo three > conflict &&\n'> <'\tgit add conflict &&\n'> <'\tFAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \\\n'> <'\t\tgit rebase --continue &&\n'> <'\ttest $base = $(git rev-parse HEAD^) &&\n'> <'\ttest 2 = $(git show | grep TWICE | wc -l) &&\n'> <'\tgit checkout to-be-rebased &&\n'> <'\tgit branch -D conflict-squash\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect-squash-fixup)} spids:[684]) (HereDoc op_id: Redir_DLess fd: 16777215 body: {(DQ ('B\n') ('\n') ('D\n') ('\n') ('ONCE\n'))} do_expansion: True here_end: EOF was_filled: True spids: [688] ) ] ) (C {(test_expect_success)} {(SQ <'squash and fixup generate correct log messages'>)} { (SQ <'\n'> <'\tgit checkout -b squash-fixup E &&\n'> <'\tbase=$(git rev-parse HEAD~4) &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 squash 3 fixup 4" \\\n'> <'\t\tEXPECT_HEADER_COUNT=4 \\\n'> <'\t\tgit rebase -i $base &&\n'> <'\tgit cat-file commit HEAD | sed -e 1,/^\\$/d > actual-squash-fixup &&\n'> <'\ttest_cmp expect-squash-fixup actual-squash-fixup &&\n'> <'\tgit checkout to-be-rebased &&\n'> <'\tgit branch -D squash-fixup\n'> ) } ) (C {(test_expect_success)} {(SQ <'squash ignores comments'>)} { (SQ <'\n'> <'\tgit checkout -b skip-comments E &&\n'> <'\tbase=$(git rev-parse HEAD~4) &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_COMMIT_AMEND="ONCE" FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \\\n'> <'\t\tEXPECT_HEADER_COUNT=4 \\\n'> <'\t\tgit rebase -i $base &&\n'> <'\ttest $base = $(git rev-parse HEAD^) &&\n'> <'\ttest 1 = $(git show | grep ONCE | wc -l) &&\n'> <'\tgit checkout to-be-rebased &&\n'> <'\tgit branch -D skip-comments\n'> ) } ) (C {(test_expect_success)} {(SQ <'squash ignores blank lines'>)} { (SQ <'\n'> <'\tgit checkout -b skip-blank-lines E &&\n'> <'\tbase=$(git rev-parse HEAD~4) &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_COMMIT_AMEND="ONCE" FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \\\n'> <'\t\tEXPECT_HEADER_COUNT=4 \\\n'> <'\t\tgit rebase -i $base &&\n'> <'\ttest $base = $(git rev-parse HEAD^) &&\n'> <'\ttest 1 = $(git show | grep ONCE | wc -l) &&\n'> <'\tgit checkout to-be-rebased &&\n'> <'\tgit branch -D skip-blank-lines\n'> ) } ) (C {(test_expect_success)} {(SQ <'squash works as expected'>)} { (SQ <'\n'> <'\tgit checkout -b squash-works no-conflict-branch &&\n'> <'\tone=$(git rev-parse HEAD~3) &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 squash 3 2" EXPECT_HEADER_COUNT=2 \\\n'> <'\t\tgit rebase -i HEAD~3 &&\n'> <'\ttest $one = $(git rev-parse HEAD~2)\n'> ) } ) (C {(test_expect_success)} {(SQ <'interrupted squash works as expected'>)} { (SQ <'\n'> <'\tgit checkout -b interrupted-squash conflict-branch &&\n'> <'\tone=$(git rev-parse HEAD~3) &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="1 squash 3 2" git rebase -i HEAD~3 &&\n'> <'\t(echo one; echo two; echo four) > conflict &&\n'> <'\tgit add conflict &&\n'> <'\ttest_must_fail git rebase --continue &&\n'> <'\techo resolved > conflict &&\n'> <'\tgit add conflict &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest $one = $(git rev-parse HEAD~2)\n'> ) } ) (C {(test_expect_success)} {(SQ <'interrupted squash works as expected (case 2)'>)} { (SQ <'\n'> <'\tgit checkout -b interrupted-squash2 conflict-branch &&\n'> <'\tone=$(git rev-parse HEAD~3) &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="3 squash 1 2" git rebase -i HEAD~3 &&\n'> <'\t(echo one; echo four) > conflict &&\n'> <'\tgit add conflict &&\n'> <'\ttest_must_fail git rebase --continue &&\n'> <'\t(echo one; echo two; echo four) > conflict &&\n'> <'\tgit add conflict &&\n'> <'\ttest_must_fail git rebase --continue &&\n'> <'\techo resolved > conflict &&\n'> <'\tgit add conflict &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest $one = $(git rev-parse HEAD~2)\n'> ) } ) (C {(test_expect_success)} {(SQ <'--continue tries to commit, even for "edit"'>)} { (SQ <'\n'> <'\techo unrelated > file7 &&\n'> <'\tgit add file7 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "unrelated change" &&\n'> <'\tparent=$(git rev-parse HEAD^) &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1" git rebase -i HEAD^ &&\n'> <'\techo edited > file7 &&\n'> <'\tgit add file7 &&\n'> <'\tFAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&\n'> <'\ttest edited = $(git show HEAD:file7) &&\n'> <'\tgit show HEAD | grep chouette &&\n'> <'\ttest $parent = $(git rev-parse HEAD^)\n'> ) } ) (C {(test_expect_success)} {(SQ <'aborted --continue does not squash commits after "edit"'>)} { (SQ <'\n'> <'\told=$(git rev-parse HEAD) &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1" git rebase -i HEAD^ &&\n'> <'\techo "edited again" > file7 &&\n'> <'\tgit add file7 &&\n'> <'\ttest_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue &&\n'> <'\ttest $old = $(git rev-parse HEAD) &&\n'> <'\tgit rebase --abort\n'> ) } ) (C {(test_expect_success)} {(SQ <'auto-amend only edited commits after "edit"'>)} { (SQ <'\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1" git rebase -i HEAD^ &&\n'> <'\techo "edited again" > file7 &&\n'> <'\tgit add file7 &&\n'> <'\tFAKE_COMMIT_MESSAGE="edited file7 again" git commit &&\n'> <'\techo "and again" > file7 &&\n'> <'\tgit add file7 &&\n'> <'\ttest_tick &&\n'> <'\ttest_must_fail env FAKE_COMMIT_MESSAGE="and again" git rebase --continue &&\n'> <'\tgit rebase --abort\n'> ) } ) (C {(test_expect_success)} {(SQ <'clean error after failed "exec"'>)} { (SQ <'\n'> <'\ttest_tick &&\n'> <'\ttest_when_finished "git rebase --abort || :" &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="1 exec_false" git rebase -i HEAD^ &&\n'> <'\techo "edited again" > file7 &&\n'> <'\tgit add file7 &&\n'> <'\ttest_must_fail git rebase --continue 2>error &&\n'> <'\ttest_i18ngrep "You have staged changes in your working tree." error\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase a detached HEAD'>)} { (SQ <'\n'> <'\tgrandparent=$(git rev-parse HEAD~2) &&\n'> <'\tgit checkout $(git rev-parse HEAD) &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="2 1" git rebase -i HEAD~2 &&\n'> <'\ttest $grandparent = $(git rev-parse HEAD~2)\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase a commit violating pre-commit'>)} { (SQ <'\n'> <'\n'> <'\tmkdir -p .git/hooks &&\n'> <'\twrite_script .git/hooks/pre-commit <<-\\EOF &&\n'> <'\ttest -z "$(git diff --cached --check)"\n'> <'\tEOF\n'> <'\techo "monde! " >> file1 &&\n'> <'\ttest_tick &&\n'> <'\ttest_must_fail git commit -m doesnt-verify file1 &&\n'> <'\tgit commit -m doesnt-verify --no-verify file1 &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES=2 git rebase -i HEAD~2\n'> <'\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase with a file named HEAD in worktree'>)} { (SQ <'\n'> <'\n'> <'\trm -fr .git/hooks &&\n'> <'\tgit reset --hard &&\n'> <'\tgit checkout -b branch3 A &&\n'> <'\n'> <'\t(\n'> <'\t\tGIT_AUTHOR_NAME="Squashed Away" &&\n'> <'\t\texport GIT_AUTHOR_NAME &&\n'> <'\t\t>HEAD &&\n'> <'\t\tgit add HEAD &&\n'> <'\t\tgit commit -m "Add head" &&\n'> <'\t\t>BODY &&\n'> <'\t\tgit add BODY &&\n'> <'\t\tgit commit -m "Add body"\n'> <'\t) &&\n'> <'\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 squash 2" git rebase -i to-be-rebased &&\n'> <'\ttest "$(git show -s --pretty=format:%an)" = "Squashed Away"\n'> <'\n'> ) } ) (C {(test_expect_success)} {(SQ <'do "noop" when there is nothing to cherry-pick'>)} { (SQ <'\n'> <'\n'> <'\tgit checkout -b branch4 HEAD &&\n'> <'\tGIT_EDITOR=: git commit --amend \\\n'> <'\t\t--author="Somebody else <somebody@else.com>" &&\n'> <'\ttest $(git rev-parse branch3) != $(git rev-parse branch4) &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i branch3 &&\n'> <'\ttest $(git rev-parse branch3) = $(git rev-parse branch4)\n'> <'\n'> ) } ) (C {(test_expect_success)} {(SQ <'submodule rebase setup'>)} { (SQ <'\n'> <'\tgit checkout A &&\n'> <'\tmkdir sub &&\n'> <'\t(\n'> <'\t\tcd sub && git init && >elif &&\n'> <'\t\tgit add elif && git commit -m "submodule initial"\n'> <'\t) &&\n'> <'\techo 1 >file1 &&\n'> <'\tgit add file1 sub &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "One" &&\n'> <'\techo 2 >file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -a -m "Two" &&\n'> <'\t(\n'> <'\t\tcd sub && echo 3 >elif &&\n'> <'\t\tgit commit -a -m "submodule second"\n'> <'\t) &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tgit commit -a -m "Three changes submodule"\n'> ) } ) (C {(test_expect_success)} {(SQ <'submodule rebase -i'>)} {(SQ <'\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 squash 2 3" git rebase -i A\n'>)} ) (C {(test_expect_success)} {(SQ <'submodule conflict setup'>)} { (SQ <'\n'> <'\tgit tag submodule-base &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\t(\n'> <'\t\tcd sub && git checkout HEAD^ && echo 4 >elif &&\n'> <'\t\tgit add elif && git commit -m "submodule conflict"\n'> <'\t) &&\n'> <'\tgit add sub &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "Conflict in submodule" &&\n'> <'\tgit tag submodule-topic\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i continue with only submodule staged'>)} { (SQ <'\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase -i submodule-base &&\n'> <'\tgit add sub &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest $(git rev-parse submodule-base) != $(git rev-parse HEAD)\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i continue with unstaged submodule'>)} { (SQ <'\n'> <'\tgit checkout submodule-topic &&\n'> <'\tgit reset --hard &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase -i submodule-base &&\n'> <'\tgit reset &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest $(git rev-parse submodule-base) = $(git rev-parse HEAD)\n'> ) } ) (C {(test_expect_success)} {(SQ <'avoid unnecessary reset'>)} { (SQ <'\n'> <'\tgit checkout master &&\n'> <'\tgit reset --hard &&\n'> <'\ttest-chmtime =123456789 file3 &&\n'> <'\tgit update-index --refresh &&\n'> <'\tHEAD=$(git rev-parse HEAD) &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i HEAD~4 &&\n'> <'\ttest $HEAD = $(git rev-parse HEAD) &&\n'> <'\tMTIME=$(test-chmtime -v +0 file3 | sed '> ) (s/) (Lit_Other '[') (Lit_Other '^') (0-9) (Lit_Other ']') (.) (Lit_Other '*') (Lit_Other '$') (//) (SQ <') &&\n'> <'\ttest 123456789 = $MTIME\n'>) } ) (C {(test_expect_success)} {(SQ <reword>)} { (SQ <'\n'> <'\tgit checkout -b reword-branch master &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" git rebase -i A &&\n'> <'\tgit show HEAD | grep "E changed" &&\n'> <'\ttest $(git rev-parse master) != $(git rev-parse HEAD) &&\n'> <'\ttest $(git rev-parse master^) = $(git rev-parse HEAD^) &&\n'> <'\tFAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" git rebase -i A &&\n'> <'\tgit show HEAD^ | grep "D changed" &&\n'> <'\tFAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" git rebase -i A &&\n'> <'\tgit show HEAD~3 | grep "B changed" &&\n'> <'\tFAKE_LINES="1 reword 2 3 4" FAKE_COMMIT_MESSAGE="C changed" git rebase -i A &&\n'> <'\tgit show HEAD~2 | grep "C changed"\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i can copy notes'>)} { (SQ <'\n'> <'\tgit config notes.rewrite.rebase true &&\n'> <'\tgit config notes.rewriteRef "refs/notes/*" &&\n'> <'\ttest_commit n1 &&\n'> <'\ttest_commit n2 &&\n'> <'\ttest_commit n3 &&\n'> <'\tgit notes add -m"a note" n3 &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i --onto n1 n2 &&\n'> <'\ttest "a note" = "$(git notes show HEAD)"\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect)} spids:[1181]) (HereDoc op_id: Redir_DLess fd: 16777215 body: {(DQ ('an earlier note\n') ('\n') ('a note\n'))} do_expansion: True here_end: EOF was_filled: True spids: [1184] ) ] ) (C {(test_expect_success)} {(SQ <'rebase -i can copy notes over a fixup'>)} { (SQ <'\n'> <'\tgit reset --hard n3 &&\n'> <'\tgit notes add -m"an earlier note" n2 &&\n'> <'\tset_fake_editor &&\n'> <'\tGIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES="1 fixup 2" git rebase -i n1 &&\n'> <'\tgit notes show > output &&\n'> <'\ttest_cmp expect output\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase while detaching HEAD'>)} { (SQ <'\n'> <'\tgit symbolic-ref HEAD &&\n'> <'\tgrandparent=$(git rev-parse HEAD~2) &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="2 1" git rebase -i HEAD~2 HEAD^0 &&\n'> <'\ttest $grandparent = $(git rev-parse HEAD~2) &&\n'> <'\ttest_must_fail git symbolic-ref HEAD\n'> ) } ) (C {(test_tick)}) (C {(test_expect_success)} {(SQ <'always cherry-pick with --no-ff'>)} { (SQ <'\n'> <'\tgit checkout no-ff-branch &&\n'> <'\tgit tag original-no-ff-branch &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i --no-ff A &&\n'> <'\ttouch empty &&\n'> <'\tfor p in 0 1 2\n'> <'\tdo\n'> <'\t\ttest ! $(git rev-parse HEAD~$p) = $(git rev-parse original-no-ff-branch~$p) &&\n'> <'\t\tgit diff HEAD~$p original-no-ff-branch~$p > out &&\n'> <'\t\ttest_cmp empty out\n'> <'\tdone &&\n'> <'\ttest $(git rev-parse HEAD~3) = $(git rev-parse original-no-ff-branch~3) &&\n'> <'\tgit diff HEAD~3 original-no-ff-branch~3 > out &&\n'> <'\ttest_cmp empty out\n'> ) } ) (C {(test_expect_success)} {(SQ <'set up commits with funny messages'>)} { (SQ <'\n'> <'\tgit checkout -b funny A &&\n'> <'\techo >>file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -a -m "end with slash\\\\" &&\n'> <'\techo >>file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -a -m "something (\\000) that looks like octal" &&\n'> <'\techo >>file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -a -m "something (\\n) that looks like a newline" &&\n'> <'\techo >>file1 &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -a -m "another commit"\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase-i history with funny messages'>)} { (SQ <'\n'> <'\tgit rev-list A..funny >expect &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 2 3 4" git rebase -i A &&\n'> <'\tgit rev-list A.. >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'prepare for rebase -i --exec'>)} { (SQ <'\n'> <'\tgit checkout master &&\n'> <'\tgit checkout -b execute &&\n'> <'\ttest_commit one_exec main.txt one_exec &&\n'> <'\ttest_commit two_exec main.txt two_exec &&\n'> <'\ttest_commit three_exec main.txt three_exec\n'> ) } ) (C {(test_expect_success)} {(SQ <'running "git rebase -i --exec git show HEAD"'>)} { (SQ <'\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i --exec "git show HEAD" HEAD~2 >actual &&\n'> <'\t(\n'> <'\t\tFAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&\n'> <'\t\texport FAKE_LINES &&\n'> <'\t\tgit rebase -i HEAD~2 >expect\n'> <'\t) &&\n'> <'\tsed -e "1,9d" expect >expected &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'running "git rebase --exec git show HEAD -i"'>)} { (SQ <'\n'> <'\tgit reset --hard execute &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase --exec "git show HEAD" -i HEAD~2 >actual &&\n'> <'\t(\n'> <'\t\tFAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&\n'> <'\t\texport FAKE_LINES &&\n'> <'\t\tgit rebase -i HEAD~2 >expect\n'> <'\t) &&\n'> <'\tsed -e "1,9d" expect >expected &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'running "git rebase -ix git show HEAD"'>)} { (SQ <'\n'> <'\tgit reset --hard execute &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -ix "git show HEAD" HEAD~2 >actual &&\n'> <'\t(\n'> <'\t\tFAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&\n'> <'\t\texport FAKE_LINES &&\n'> <'\t\tgit rebase -i HEAD~2 >expect\n'> <'\t) &&\n'> <'\tsed -e "1,9d" expect >expected &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -ix with several <CMD>'>)} { (SQ <'\n'> <'\tgit reset --hard execute &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&\n'> <'\t(\n'> <'\t\tFAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&\n'> <'\t\texport FAKE_LINES &&\n'> <'\t\tgit rebase -i HEAD~2 >expect\n'> <'\t) &&\n'> <'\tsed -e "1,9d" expect >expected &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -ix with several instances of --exec'>)} { (SQ <'\n'> <'\tgit reset --hard execute &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&\n'> <'\t(\n'> <'\t\tFAKE_LINES="1 exec_git_show_HEAD exec_pwd 2\n'> <'\t\t\t\texec_git_show_HEAD exec_pwd" &&\n'> <'\t\texport FAKE_LINES &&\n'> <'\t\tgit rebase -i HEAD~2 >expect\n'> <'\t) &&\n'> <'\tsed -e "1,11d" expect >expected &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -ix with --autosquash'>)} { (SQ <'\n'> <'\tgit reset --hard execute &&\n'> <'\tgit checkout -b autosquash &&\n'> <'\techo second >second.txt &&\n'> <'\tgit add second.txt &&\n'> <'\tgit commit -m "fixup! two_exec" &&\n'> <'\techo bis >bis.txt &&\n'> <'\tgit add bis.txt &&\n'> <'\tgit commit -m "fixup! two_exec" &&\n'> <'\tset_fake_editor &&\n'> <'\t(\n'> <'\t\tgit checkout -b autosquash_actual &&\n'> <'\t\tgit rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual\n'> <'\t) &&\n'> <'\tgit checkout autosquash &&\n'> <'\t(\n'> <'\t\tgit checkout -b autosquash_expected &&\n'> <'\t\tFAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&\n'> <'\t\texport FAKE_LINES &&\n'> <'\t\tgit rebase -i HEAD~4 >expect\n'> <'\t) &&\n'> <'\tsed -e "1,13d" expect >expected &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase --exec works without -i '>)} { (SQ <'\n'> <'\tgit reset --hard execute &&\n'> <'\trm -rf exec_output &&\n'> < '\tEDITOR="echo >invoked_editor" git rebase --exec "echo a line >>exec_output" HEAD~2 2>actual &&\n' > <'\ttest_i18ngrep "Successfully rebased and updated" actual &&\n'> <'\ttest_line_count = 2 exec_output &&\n'> <'\ttest_path_is_missing invoked_editor\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i --exec without <CMD>'>)} { (SQ <'\n'> <'\tgit reset --hard execute &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase -i --exec 2>tmp &&\n'> <'\tsed -e "1d" tmp >actual &&\n'> <'\ttest_must_fail git rebase -h >expected &&\n'> <'\ttest_cmp expected actual &&\n'> <'\tgit checkout master\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i --root re-order and drop commits'>)} { (SQ <'\n'> <'\tgit checkout E &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="3 1 2 5" git rebase -i --root &&\n'> <'\ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n'> <'\ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n'> <'\ttest A = $(git cat-file commit HEAD^^ | sed -ne \\$p) &&\n'> <'\ttest C = $(git cat-file commit HEAD^^^ | sed -ne \\$p) &&\n'> <'\ttest 0 = $(git cat-file commit HEAD^^^ | grep -c ^parent\\ )\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i --root retain root commit author and message'>)} { (SQ <'\n'> <'\tgit checkout A &&\n'> <'\techo B >file7 &&\n'> <'\tgit add file7 &&\n'> <'\tGIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="2" git rebase -i --root &&\n'> <'\tgit cat-file commit HEAD | grep -q "^author Twerp Snog" &&\n'> <'\tgit cat-file commit HEAD | grep -q "^different author$"\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i --root temporary sentinel commit'>)} { (SQ <'\n'> <'\tgit checkout B &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="2" git rebase -i --root &&\n'> <'\tgit cat-file commit HEAD | grep "^tree 4b825dc642cb" &&\n'> <'\tgit rebase --abort\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i --root fixup root commit'>)} { (SQ <'\n'> <'\tgit checkout B &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 fixup 2" git rebase -i --root &&\n'> <'\ttest A = $(git cat-file commit HEAD | sed -ne \\$p) &&\n'> <'\ttest B = $(git show HEAD:file1) &&\n'> <'\ttest 0 = $(git cat-file commit HEAD | grep -c ^parent\\ )\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase --edit-todo does not works on non-interactive rebase'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit checkout conflict-branch &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail git rebase --onto HEAD~2 HEAD~ &&\n'> <'\ttest_must_fail git rebase --edit-todo &&\n'> <'\tgit rebase --abort\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase --edit-todo can be used to modify todo'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit checkout no-conflict-branch^0 &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1 2 3" git rebase -i HEAD~3 &&\n'> <'\tFAKE_LINES="2 1" git rebase --edit-todo &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest M = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n'> <'\ttest L = $(git cat-file commit HEAD | sed -ne \\$p)\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i produces readable reflog'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit branch -f branch-reflog-test H &&\n'> <'\tset_fake_editor &&\n'> <'\tgit rebase -i --onto I F branch-reflog-test &&\n'> <'\tcat >expect <<-\\EOF &&\n'> <'\trebase -i (finish): returning to refs/heads/branch-reflog-test\n'> <'\trebase -i (pick): H\n'> <'\trebase -i (pick): G\n'> <'\trebase -i (start): checkout I\n'> <'\tEOF\n'> <'\tgit reflog -n4 HEAD |\n'> <'\tsed "s/[^:]*: //" >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i respects core.commentchar'>)} { (SQ <'\n'> <'\tgit reset --hard &&\n'> <'\tgit checkout E^0 &&\n'> <'\ttest_config core.commentchar "\\\\" &&\n'> <'\twrite_script remove-all-but-first.sh <<-\\EOF &&\n'> <'\tsed -e "2,\\$s/^/\\\\\\\\/" "$1" >"$1.tmp" &&\n'> <'\tmv "$1.tmp" "$1"\n'> <'\tEOF\n'> <'\ttest_set_editor "$(pwd)/remove-all-but-first.sh" &&\n'> <'\tgit rebase -i B &&\n'> <'\ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p)\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i, with <onto> and <upstream> specified as :/quuxery'>)} { (SQ <'\n'> <'\ttest_when_finished "git branch -D torebase" &&\n'> <'\tgit checkout -b torebase branch1 &&\n'> <'\tupstream=$(git rev-parse ":/J") &&\n'> <'\tonto=$(git rev-parse ":/A") &&\n'> <'\tgit rebase --onto $onto $upstream &&\n'> <'\tgit reset --hard branch1 &&\n'> <'\tgit rebase --onto ":/A" ":/J" &&\n'> <'\tgit checkout branch1\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i with --strategy and -X'>)} { (SQ <'\n'> <'\tgit checkout -b conflict-merge-use-theirs conflict-branch &&\n'> <'\tgit reset --hard HEAD^ &&\n'> <'\techo five >conflict &&\n'> <'\techo Z >file1 &&\n'> <'\tgit commit -a -m "one file conflict" &&\n'> <'\tEDITOR=true git rebase -i --strategy=recursive -Xours conflict-branch &&\n'> <'\ttest $(git show conflict-branch:conflict) = $(cat conflict) &&\n'> <'\ttest $(cat file1) = Z\n'> ) } ) (C {(test_expect_success)} {(SQ <'interrupted rebase -i with --strategy and -X'>)} { (SQ <'\n'> <'\tgit checkout -b conflict-merge-use-theirs-interrupted conflict-branch &&\n'> <'\tgit reset --hard HEAD^ &&\n'> <'\t>breakpoint &&\n'> <'\tgit add breakpoint &&\n'> <'\tgit commit -m "breakpoint for interactive mode" &&\n'> <'\techo five >conflict &&\n'> <'\techo Z >file1 &&\n'> <'\tgit commit -a -m "one file conflict" &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1 2" git rebase -i --strategy=recursive -Xours conflict-branch &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest $(git show conflict-branch:conflict) = $(cat conflict) &&\n'> <'\ttest $(cat file1) = Z\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i error on commits with \\ in message'>)} { (SQ <'\n'> <'\tcurrent_head=$(git rev-parse HEAD) &&\n'> < '\ttest_when_finished "git rebase --abort; git reset --hard $current_head; rm -f error" &&\n' > <'\ttest_commit TO-REMOVE will-conflict old-content &&\n'> <'\ttest_commit "\\temp" will-conflict new-content dummy &&\n'> <'\ttest_must_fail env EDITOR=true git rebase -i HEAD^ --onto HEAD^^ 2>error &&\n'> <'\ttest_expect_code 1 grep "\temp" error\n'> ) } ) (C {(test_expect_success)} {(SQ <'short SHA-1 setup'>)} { (SQ <'\n'> <'\ttest_when_finished "git checkout master" &&\n'> <'\tgit checkout --orphan collide &&\n'> <'\tgit rm -rf . &&\n'> <'\t(\n'> <'\tunset test_tick &&\n'> <'\ttest_commit collide1 collide &&\n'> <'\ttest_commit --notick collide2 collide &&\n'> <'\ttest_commit --notick collide3 collide\n'> <'\t)\n'> ) } ) (C {(test_expect_success)} {(SQ <'short SHA-1 collide'>)} { (SQ <'\n'> <'\ttest_when_finished "reset_rebase && git checkout master" &&\n'> <'\tgit checkout collide &&\n'> <'\t(\n'> <'\tunset test_tick &&\n'> <'\ttest_tick &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \\\n'> <'\tFAKE_LINES="reword 1 2" git rebase -i HEAD~2\n'> <'\t)\n'> ) } ) (C {(test_expect_success)} {(SQ <'respect core.abbrev'>)} { (SQ <'\n'> <'\tgit config core.abbrev 12 &&\n'> <'\tset_cat_todo_editor &&\n'> <'\ttest_must_fail git rebase -i HEAD~4 >todo-list &&\n'> <'\ttest 4 = $(grep -c "pick [0-9a-f]\\{12,\\}" todo-list)\n'> ) } ) (C {(test_expect_success)} {(SQ <'todo count'>)} { (SQ <'\n'> <'\twrite_script dump-raw.sh <<-\\EOF &&\n'> <'\t\tcat "$1"\n'> <'\tEOF\n'> <'\ttest_set_editor "$(pwd)/dump-raw.sh" &&\n'> <'\tgit rebase -i HEAD~4 >actual &&\n'> <'\ttest_i18ngrep "^# Rebase ..* onto ..* ([0-9]" actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i commits that overwrite untracked files (pick)'>)} { (SQ <'\n'> <'\tgit checkout --force branch2 &&\n'> <'\tgit clean -f &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1 2" git rebase -i A &&\n'> <'\ttest_cmp_rev HEAD F &&\n'> <'\ttest_path_is_missing file6 &&\n'> <'\t>file6 &&\n'> <'\ttest_must_fail git rebase --continue &&\n'> <'\ttest_cmp_rev HEAD F &&\n'> <'\trm file6 &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest_cmp_rev HEAD I\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i commits that overwrite untracked files (squash)'>)} { (SQ <'\n'> <'\tgit checkout --force branch2 &&\n'> <'\tgit clean -f &&\n'> <'\tgit tag original-branch2 &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1 squash 2" git rebase -i A &&\n'> <'\ttest_cmp_rev HEAD F &&\n'> <'\ttest_path_is_missing file6 &&\n'> <'\t>file6 &&\n'> <'\ttest_must_fail git rebase --continue &&\n'> <'\ttest_cmp_rev HEAD F &&\n'> <'\trm file6 &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest $(git cat-file commit HEAD | sed -ne \\$p) = I &&\n'> <'\tgit reset --hard original-branch2\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase -i commits that overwrite untracked files (no ff)'>)} { (SQ <'\n'> <'\tgit checkout --force branch2 &&\n'> <'\tgit clean -f &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1 2" git rebase -i --no-ff A &&\n'> <'\ttest $(git cat-file commit HEAD | sed -ne \\$p) = F &&\n'> <'\ttest_path_is_missing file6 &&\n'> <'\t>file6 &&\n'> <'\ttest_must_fail git rebase --continue &&\n'> <'\ttest $(git cat-file commit HEAD | sed -ne \\$p) = F &&\n'> <'\trm file6 &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest $(git cat-file commit HEAD | sed -ne \\$p) = I\n'> ) } ) (C {(test_expect_success)} {(SQ <'rebase --continue removes CHERRY_PICK_HEAD'>)} { (SQ <'\n'> <'\tgit checkout -b commit-to-skip &&\n'> <'\tfor double in X 3 1\n'> <'\tdo\n'> <'\t\ttest_seq 5 | sed "s/$double/&&/" >seq &&\n'> <'\t\tgit add seq &&\n'> <'\t\ttest_tick &&\n'> <'\t\tgit commit -m seq-$double\n'> <'\tdone &&\n'> <'\tgit tag seq-onto &&\n'> <'\tgit reset --hard HEAD~2 &&\n'> <'\tgit cherry-pick seq-onto &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES= git rebase -i seq-onto &&\n'> <'\ttest -d .git/rebase-merge &&\n'> <'\tgit rebase --continue &&\n'> <'\tgit diff --exit-code seq-onto &&\n'> <'\ttest ! -d .git/rebase-merge &&\n'> <'\ttest ! -f .git/CHERRY_PICK_HEAD\n'> ) } ) (FuncDef name: rebase_setup_and_clean body: (BraceGroup children: [ (AndOr children: [ (C {(test_when_finished)} { (DQ ('\n') ('\t\tgit checkout master &&\n') ('\t\ttest_might_fail git branch -D ') ($ VSub_Number '$1') (' &&\n') ('\t\ttest_might_fail git rebase --abort\n') ('\t') ) } ) (C {(git)} {(checkout)} {(-b)} {($ VSub_Number '$1')} {(master)}) ] op_id: Op_DAmp ) ] spids: [1896] ) spids: [1891 1895] ) (C {(test_expect_success)} {(SQ <drop>)} { (SQ <'\n'> <'\trebase_setup_and_clean drop-test &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 drop 2 3 drop 4 5" git rebase -i --root &&\n'> <'\ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n'> <'\ttest C = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n'> <'\ttest A = $(git cat-file commit HEAD^^ | sed -ne \\$p)\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect)} spids:[1946]) (HereDoc op_id: Redir_DLess fd: 16777215 body: {(DQ ('Successfully rebased and updated refs/heads/missing-commit.\n'))} do_expansion: True here_end: EOF was_filled: True spids: [1949] ) ] ) (C {(test_expect_success)} {(SQ <'rebase -i respects rebase.missingCommitsCheck = ignore'>)} { (SQ <'\n'> <'\ttest_config rebase.missingCommitsCheck ignore &&\n'> <'\trebase_setup_and_clean missing-commit &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 2 3 4" \\\n'> <'\t\tgit rebase -i --root 2>actual &&\n'> <'\ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n'> <'\ttest_i18ncmp expect actual\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect)} spids:[1975]) (HereDoc op_id: Redir_DLess fd: 16777215 body: { (DQ ('Warning: some commits may have been dropped accidentally.\n') ('Dropped commits (newer to older):\n') (' - ') (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(rev-list)} {(--pretty) (Lit_Other '=') (oneline)} {(--abbrev-commit)} {(-1)} {(master)} ) ] ) left_token: <Left_CommandSub '$('> spids: [1984 1998] ) ('\n') ('To avoid this message, use ') (Right_DoubleQuote '"') (drop) (Right_DoubleQuote '"') (' to explicitly remove a commit.\n') ('\n') ("Use 'git config rebase.missingCommitsCheck' to change the level of warnings.\n") ('The possible behaviours are: ignore, warn, error.\n') ('\n') ('Successfully rebased and updated refs/heads/missing-commit.\n') ) } do_expansion: True here_end: EOF was_filled: True spids: [1978] ) ] ) (C {(test_expect_success)} {(SQ <'rebase -i respects rebase.missingCommitsCheck = warn'>)} { (SQ <'\n'> <'\ttest_config rebase.missingCommitsCheck warn &&\n'> <'\trebase_setup_and_clean missing-commit &&\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="1 2 3 4" \\\n'> <'\t\tgit rebase -i --root 2>actual &&\n'> <'\ttest_i18ncmp expect actual &&\n'> <'\ttest D = $(git cat-file commit HEAD | sed -ne \\$p)\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect)} spids:[2032]) (HereDoc op_id: Redir_DLess fd: 16777215 body: { (DQ ('Warning: some commits may have been dropped accidentally.\n') ('Dropped commits (newer to older):\n') (' - ') (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(rev-list)} {(--pretty) (Lit_Other '=') (oneline)} {(--abbrev-commit)} {(-1)} {(master)} ) ] ) left_token: <Left_CommandSub '$('> spids: [2041 2055] ) ('\n') (' - ') (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(rev-list)} {(--pretty) (Lit_Other '=') (oneline)} {(--abbrev-commit)} {(-1)} {(master) (Lit_Tilde '~') (2)} ) ] ) left_token: <Left_CommandSub '$('> spids: [2058 2074] ) ('\n') ('To avoid this message, use ') (Right_DoubleQuote '"') (drop) (Right_DoubleQuote '"') (' to explicitly remove a commit.\n') ('\n') ("Use 'git config rebase.missingCommitsCheck' to change the level of warnings.\n") ('The possible behaviours are: ignore, warn, error.\n') ('\n') ("You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.\n") ("Or you can abort the rebase with 'git rebase --abort'.\n") ) } do_expansion: True here_end: EOF was_filled: True spids: [2035] ) ] ) (C {(test_expect_success)} {(SQ <'rebase -i respects rebase.missingCommitsCheck = error'>)} { (SQ <'\n'> <'\ttest_config rebase.missingCommitsCheck error &&\n'> <'\trebase_setup_and_clean missing-commit &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="1 2 4" \\\n'> <'\t\tgit rebase -i --root 2>actual &&\n'> <'\ttest_i18ncmp expect actual &&\n'> <'\tcp .git/rebase-merge/git-rebase-todo.backup \\\n'> <'\t\t.git/rebase-merge/git-rebase-todo &&\n'> <'\tFAKE_LINES="1 2 drop 3 4 drop 5" \\\n'> <'\t\tgit rebase --edit-todo &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n'> <'\ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p)\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect)} spids:[2115]) (HereDoc op_id: Redir_DLess fd: 16777215 body: { (DQ ("Warning: the command isn't recognized in the following line:\n") (' - badcmd ') (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(rev-list)} {(--oneline)} {(-1)} {(master) (Lit_Tilde '~') (1)}) ] ) left_token: <Left_CommandSub '$('> spids: [2123 2135] ) ('\n') ('\n') ( "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.\n" ) ("Or you can abort the rebase with 'git rebase --abort'.\n") ) } do_expansion: True here_end: EOF was_filled: True spids: [2118] ) ] ) (C {(test_expect_success)} {(SQ <'static check of bad command'>)} { (SQ <'\n'> <'\trebase_setup_and_clean bad-cmd &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="1 2 3 bad 4 5" \\\n'> <'\t\tgit rebase -i --root 2>actual &&\n'> <'\ttest_i18ncmp expect actual &&\n'> <'\tFAKE_LINES="1 2 3 drop 4 5" git rebase --edit-todo &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n'> <'\ttest C = $(git cat-file commit HEAD^ | sed -ne \\$p)\n'> ) } ) (C {(test_expect_success)} {(SQ <'tabs and spaces are accepted in the todolist'>)} { (SQ <'\n'> <'\trebase_setup_and_clean indented-comment &&\n'> <'\twrite_script add-indent.sh <<-\\EOF &&\n'> <'\t(\n'> <'\t\t# Turn single spaces into space/tab mix\n'> <'\t\tsed "1s/ /\t/g; 2s/ / /g; 3s/ / \t/g" "$1"\n'> <'\t\tprintf "\\n\\t# comment\\n #more\\n\\t # comment\\n"\n'> <'\t) >"$1.new"\n'> <'\tmv "$1.new" "$1"\n'> <'\tEOF\n'> <'\ttest_set_editor "$(pwd)/add-indent.sh" &&\n'> <'\tgit rebase -i HEAD^^^ &&\n'> <'\ttest E = $(git cat-file commit HEAD | sed -ne \\$p)\n'> ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect)} spids:[2187]) (HereDoc op_id: Redir_DLess fd: 16777215 body: { (DQ ("Warning: the SHA-1 is missing or isn't a commit in the following line:\n") (' - edit XXXXXXX False commit\n') ('\n') ("You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.\n") ("Or you can abort the rebase with 'git rebase --abort'.\n") ) } do_expansion: True here_end: EOF was_filled: True spids: [2190] ) ] ) (C {(test_expect_success)} {(SQ <'static check of bad SHA-1'>)} { (SQ <'\n'> <'\trebase_setup_and_clean bad-sha &&\n'> <'\tset_fake_editor &&\n'> <'\ttest_must_fail env FAKE_LINES="1 2 edit fakesha 3 4 5 #" \\\n'> <'\t\tgit rebase -i --root 2>actual &&\n'> <'\ttest_i18ncmp expect actual &&\n'> <'\tFAKE_LINES="1 2 4 5 6" git rebase --edit-todo &&\n'> <'\tgit rebase --continue &&\n'> <'\ttest E = $(git cat-file commit HEAD | sed -ne \\$p)\n'> ) } ) (C {(test_expect_success)} {(SQ <'editor saves as CR/LF'>)} { (SQ <'\n'> <'\tgit checkout -b with-crlf &&\n'> <'\twrite_script add-crs.sh <<-\\EOF &&\n'> <'\tsed -e "s/\\$/Q/" <"$1" | tr Q "\\\\015" >"$1".new &&\n'> <'\tmv -f "$1".new "$1"\n'> <'\tEOF\n'> <'\t(\n'> <'\t\ttest_set_editor "$(pwd)/add-crs.sh" &&\n'> <'\t\tgit rebase -i HEAD^\n'> <'\t)\n'> ) } ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:SQ) op:Equal rhs:{(DQ ("'"))} spids:[2239])] spids: [2239] ) (C {(test_expect_success)} {(SQ <'rebase -i --gpg-sign=<key-id>'>)} { (SQ <'\n'> <'\tset_fake_editor &&\n'> <'\tFAKE_LINES="edit 1" git rebase -i --gpg-sign="\\"S I Gner\\"" HEAD^ \\\n'> <'\t\t>out 2>err &&\n'> <'\ttest_i18ngrep "$SQ-S\\"S I Gner\\"$SQ" err\n'> ) } ) (C {(test_done)}) ] )