(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:-1 arg_word:{(expect)} spids:[312]) (HereDoc op_id: Redir_DLess fd: -1 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:-1 arg_word:{(expect2)} spids:[330]) (HereDoc op_id: Redir_DLess fd: -1 body: {(DQ ("<<<<<<< HEAD\n") ("D\n") ("=======\n") ("G\n") (">>>>>>> 5d18e54... G\n"))} do_expansion: True here_end: EOF was_filled: True spids: [334] ) ] ) (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:-1 arg_word:{(expect-squash-fixup)} spids:[682]) (HereDoc op_id: Redir_DLess fd: -1 body: {(DQ ("B\n") ("\n") ("D\n") ("\n") ("ONCE\n"))} do_expansion: True here_end: EOF was_filled: True spids: [686] ) ] ) (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:-1 arg_word:{(expect)} spids:[1178]) (HereDoc op_id: Redir_DLess fd: -1 body: {(DQ ("an earlier note\n") ("\n") ("a note\n"))} do_expansion: True here_end: EOF was_filled: True spids: [1181] ) ] ) (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: [1892] ) spids: [1887 1891] ) (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:-1 arg_word:{(expect)} spids:[1942]) (HereDoc op_id: Redir_DLess fd: -1 body: {(DQ ("Successfully rebased and updated refs/heads/missing-commit.\n"))} do_expansion: True here_end: EOF was_filled: True spids: [1945] ) ] ) (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:-1 arg_word:{(expect)} spids:[1970]) (HereDoc op_id: Redir_DLess fd: -1 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: [1979 1993] ) ("\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: [1973] ) ] ) (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:-1 arg_word:{(expect)} spids:[2026]) (HereDoc op_id: Redir_DLess fd: -1 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: [2035 2049] ) ("\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: [2052 2068] ) ("\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: [2029] ) ] ) (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:-1 arg_word:{(expect)} spids:[2108]) (HereDoc op_id: Redir_DLess fd: -1 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: [2116 2128] ) ("\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: [2111] ) ] ) (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:-1 arg_word:{(expect)} spids:[2179]) (HereDoc op_id: Redir_DLess fd: -1 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: [2182] ) ] ) (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:[2230])] spids: [2230] ) (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)}) ] )