diff options
Diffstat (limited to 't/t3404-rebase-interactive.sh')
-rwxr-xr-x | t/t3404-rebase-interactive.sh | 221 |
1 files changed, 191 insertions, 30 deletions
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index ae6e55ce79..4a7d21f898 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -72,15 +72,16 @@ test_expect_success 'rebase --keep-empty' ' test_line_count = 6 actual ' -test_expect_success 'rebase -i with empty HEAD' ' +test_expect_success 'rebase -i with empty todo list' ' cat >expect <<-\EOF && error: nothing to do EOF ( set_fake_editor && - test_must_fail env FAKE_LINES="1 exec_true" \ - git rebase -i HEAD^ >actual 2>&1 + test_must_fail env FAKE_LINES="#" \ + git rebase -i HEAD^ >output 2>&1 ) && + tail -n 1 output >actual && # Ignore output about changing todo list test_i18ncmp expect actual ' @@ -186,7 +187,7 @@ test_expect_success 'no changes are a nop' ' git checkout branch2 && git rebase -i F && test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" && - test $(git rev-parse I) = $(git rev-parse HEAD) + test_cmp_rev I HEAD ' test_expect_success 'test the [branch] option' ' @@ -195,16 +196,16 @@ test_expect_success 'test the [branch] option' ' git commit -m "stop here" && git rebase -i F branch2 && test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" && - test $(git rev-parse I) = $(git rev-parse branch2) && - test $(git rev-parse I) = $(git rev-parse HEAD) + test_cmp_rev I branch2 && + test_cmp_rev I HEAD ' test_expect_success 'test --onto <branch>' ' git checkout -b test-onto branch2 && git rebase -i --onto branch1 F && test "$(git symbolic-ref -q HEAD)" = "refs/heads/test-onto" && - test $(git rev-parse HEAD^) = $(git rev-parse branch1) && - test $(git rev-parse I) = $(git rev-parse branch2) + test_cmp_rev HEAD^ branch1 && + test_cmp_rev I branch2 ' test_expect_success 'rebase on top of a non-conflicting commit' ' @@ -213,16 +214,16 @@ test_expect_success 'rebase on top of a non-conflicting commit' ' git rebase -i branch2 && test file6 = $(git diff --name-only original-branch1) && test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" && - test $(git rev-parse I) = $(git rev-parse branch2) && - test $(git rev-parse I) = $(git rev-parse HEAD~2) + test_cmp_rev I branch2 && + test_cmp_rev I HEAD~2 ' test_expect_success 'reflog for the branch shows state before rebase' ' - test $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1) + test_cmp_rev branch1@{1} original-branch1 ' test_expect_success 'reflog for the branch shows correct finish message' ' - printf "rebase -i (finish): refs/heads/branch1 onto %s\n" \ + printf "rebase (finish): refs/heads/branch1 onto %s\n" \ "$(git rev-parse branch2)" >expected && git log -g --pretty=%gs -1 refs/heads/branch1 >actual && test_cmp expected actual @@ -278,7 +279,7 @@ test_expect_success 'show conflicted patch' ' test_expect_success 'abort' ' git rebase --abort && - test $(git rev-parse new-branch1) = $(git rev-parse HEAD) && + test_cmp_rev new-branch1 HEAD && test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch1" && test_path_is_missing .git/rebase-merge ' @@ -321,7 +322,7 @@ test_expect_success 'retain authorship w/ conflicts' ' echo resolved >conflict && git add conflict && git rebase --continue && - test $(git rev-parse conflict-a^0) = $(git rev-parse HEAD^) && + test_cmp_rev conflict-a^0 HEAD^ && git show >out && grep AttributeMe out ' @@ -338,7 +339,7 @@ test_expect_success 'squash' ' git rebase -i --onto master HEAD~2 ) && test B = $(cat file7) && - test $(git rev-parse HEAD^) = $(git rev-parse master) + test_cmp_rev HEAD^ master ' test_expect_success 'retain authorship when squashing' ' @@ -397,9 +398,9 @@ test_expect_success REBASE_P 'preserve merges with -p' ' git update-index --refresh && git diff-files --quiet && git diff-index --quiet --cached HEAD -- && - test $(git rev-parse HEAD~6) = $(git rev-parse branch1) && - test $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) && - test $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) && + test_cmp_rev HEAD~6 branch1 && + test_cmp_rev HEAD~4^2 to-be-preserved && + test_cmp_rev HEAD^^2^ HEAD^^^ && test $(git show HEAD~5:file1) = B && test $(git show HEAD~3:file1) = C && test $(git show HEAD:file1) = E && @@ -431,7 +432,7 @@ test_expect_success '--continue tries to commit' ' git add file1 && FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue ) && - test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) && + test_cmp_rev HEAD^ new-branch1 && git show HEAD | grep chouette ' @@ -738,7 +739,7 @@ test_expect_success 'do "noop" when there is nothing to cherry-pick' ' --author="Somebody else <somebody@else.com>" && test $(git rev-parse branch3) != $(git rev-parse branch4) && git rebase -i branch3 && - test $(git rev-parse branch3) = $(git rev-parse branch4) + test_cmp_rev branch3 branch4 ' @@ -797,7 +798,7 @@ test_expect_success 'rebase -i continue with unstaged submodule' ' test_must_fail git rebase -i submodule-base && git reset && git rebase --continue && - test $(git rev-parse submodule-base) = $(git rev-parse HEAD) + test_cmp_rev submodule-base HEAD ' test_expect_success 'avoid unnecessary reset' ' @@ -820,7 +821,7 @@ test_expect_success 'reword' ' git rebase -i A && git show HEAD | grep "E changed" && test $(git rev-parse master) != $(git rev-parse HEAD) && - test $(git rev-parse master^) = $(git rev-parse HEAD^) && + test_cmp_rev master^ HEAD^ && FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" \ git rebase -i A && git show HEAD^ | grep "D changed" && @@ -884,7 +885,7 @@ test_expect_success 'always cherry-pick with --no-ff' ' git diff HEAD~$p original-no-ff-branch~$p > out && test_must_be_empty out done && - test $(git rev-parse HEAD~3) = $(git rev-parse original-no-ff-branch~3) && + test_cmp_rev HEAD~3 original-no-ff-branch~3 && git diff HEAD~3 original-no-ff-branch~3 > out && test_must_be_empty out ' @@ -1137,7 +1138,7 @@ test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-int git checkout conflict-branch && ( set_fake_editor && - test_must_fail git rebase -f --onto HEAD~2 HEAD~ && + test_must_fail git rebase -f --apply --onto HEAD~2 HEAD~ && test_must_fail git rebase --edit-todo ) && git rebase --abort @@ -1161,10 +1162,10 @@ test_expect_success 'rebase -i produces readable reflog' ' git branch -f branch-reflog-test H && git rebase -i --onto I F branch-reflog-test && cat >expect <<-\EOF && - rebase -i (finish): returning to refs/heads/branch-reflog-test - rebase -i (pick): H - rebase -i (pick): G - rebase -i (start): checkout I + rebase (finish): returning to refs/heads/branch-reflog-test + rebase (pick): H + rebase (pick): G + rebase (start): checkout I EOF git reflog -n4 HEAD | sed "s/[^:]*: //" >actual && @@ -1264,13 +1265,26 @@ test_expect_success SHA1 'short SHA-1 setup' ' test_expect_success SHA1 'short SHA-1 collide' ' test_when_finished "reset_rebase && git checkout master" && git checkout collide && + colliding_sha1=6bcda37 && + test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && ( unset test_tick && test_tick && set_fake_editor && FAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \ - FAKE_LINES="reword 1 2" git rebase -i HEAD~2 - ) + FAKE_LINES="reword 1 break 2" git rebase -i HEAD~2 && + test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && + grep "^pick $colliding_sha1 " \ + .git/rebase-merge/git-rebase-todo.tmp && + grep "^pick [0-9a-f]\{40\}" \ + .git/rebase-merge/git-rebase-todo && + grep "^pick [0-9a-f]\{40\}" \ + .git/rebase-merge/git-rebase-todo.backup && + git rebase --continue + ) && + collide2="$(git rev-parse HEAD~1 | cut -c 1-4)" && + collide3="$(git rev-parse collide3 | cut -c 1-4)" && + test "$collide2" = "$collide3" ' test_expect_success 'respect core.abbrev' ' @@ -1450,6 +1464,127 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' ' test B = $(git cat-file commit HEAD^ | sed -ne \$p) ' +test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = ignore' ' + test_config rebase.missingCommitsCheck ignore && + rebase_setup_and_clean missing-commit && + ( + set_fake_editor && + FAKE_LINES="break 1 2 3 4 5" git rebase -i --root && + FAKE_LINES="1 2 3 4" git rebase --edit-todo && + git rebase --continue 2>actual + ) && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test_i18ngrep \ + "Successfully rebased and updated refs/heads/missing-commit" \ + actual +' + +test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = warn' ' + cat >expect <<-EOF && + error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + Warning: some commits may have been dropped accidentally. + Dropped commits (newer to older): + - $(git rev-list --pretty=oneline --abbrev-commit -1 master) + - $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + To avoid this message, use "drop" to explicitly remove a commit. + EOF + head -n4 expect >expect.2 && + tail -n1 expect >>expect.2 && + tail -n4 expect.2 >expect.3 && + test_config rebase.missingCommitsCheck warn && + rebase_setup_and_clean missing-commit && + ( + set_fake_editor && + test_must_fail env FAKE_LINES="bad 1 2 3 4 5" \ + git rebase -i --root && + cp .git/rebase-merge/git-rebase-todo.backup orig && + FAKE_LINES="2 3 4" git rebase --edit-todo 2>actual.2 && + head -n6 actual.2 >actual && + test_i18ncmp expect actual && + cp orig .git/rebase-merge/git-rebase-todo && + FAKE_LINES="1 2 3 4" git rebase --edit-todo 2>actual.2 && + head -n4 actual.2 >actual && + test_i18ncmp expect.3 actual && + git rebase --continue 2>actual + ) && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test_i18ngrep \ + "Successfully rebased and updated refs/heads/missing-commit" \ + actual +' + +test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = error' ' + cat >expect <<-EOF && + error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + Warning: some commits may have been dropped accidentally. + Dropped commits (newer to older): + - $(git rev-list --pretty=oneline --abbrev-commit -1 master) + - $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + To avoid this message, use "drop" to explicitly remove a commit. + + Use '\''git config rebase.missingCommitsCheck'\'' to change the level of warnings. + The possible behaviours are: ignore, warn, error. + + You can fix this with '\''git rebase --edit-todo'\'' and then run '\''git rebase --continue'\''. + Or you can abort the rebase with '\''git rebase --abort'\''. + EOF + tail -n11 expect >expect.2 && + head -n3 expect.2 >expect.3 && + tail -n7 expect.2 >>expect.3 && + test_config rebase.missingCommitsCheck error && + rebase_setup_and_clean missing-commit && + ( + set_fake_editor && + test_must_fail env FAKE_LINES="bad 1 2 3 4 5" \ + git rebase -i --root && + cp .git/rebase-merge/git-rebase-todo.backup orig && + test_must_fail env FAKE_LINES="2 3 4" \ + git rebase --edit-todo 2>actual && + test_i18ncmp expect actual && + test_must_fail git rebase --continue 2>actual && + test_i18ncmp expect.2 actual && + test_must_fail git rebase --edit-todo && + cp orig .git/rebase-merge/git-rebase-todo && + test_must_fail env FAKE_LINES="1 2 3 4" \ + git rebase --edit-todo 2>actual && + test_i18ncmp expect.3 actual && + test_must_fail git rebase --continue 2>actual && + test_i18ncmp expect.3 actual && + cp orig .git/rebase-merge/git-rebase-todo && + FAKE_LINES="1 2 3 4 drop 5" git rebase --edit-todo && + git rebase --continue 2>actual + ) && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test_i18ngrep \ + "Successfully rebased and updated refs/heads/missing-commit" \ + actual +' + +test_expect_success 'rebase.missingCommitsCheck = error after resolving conflicts' ' + test_config rebase.missingCommitsCheck error && + ( + set_fake_editor && + FAKE_LINES="drop 1 break 2 3 4" git rebase -i A E + ) && + git rebase --edit-todo && + test_must_fail git rebase --continue && + echo x >file1 && + git add file1 && + git rebase --continue +' + +test_expect_success 'rebase.missingCommitsCheck = error when editing for a second time' ' + test_config rebase.missingCommitsCheck error && + ( + set_fake_editor && + FAKE_LINES="1 break 2 3" git rebase -i A D && + cp .git/rebase-merge/git-rebase-todo todo && + test_must_fail env FAKE_LINES=2 git rebase --edit-todo && + GIT_SEQUENCE_EDITOR="cp todo" git rebase --edit-todo && + git rebase --continue + ) +' + test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and exec' ' rebase_setup_and_clean abbrevcmd && test_commit "first" file1.txt "first line" first && @@ -1599,6 +1734,32 @@ test_expect_success 'post-commit hook is called' ' test_cmp expect actual ' +test_expect_success 'correct error message for partial commit after empty pick' ' + test_when_finished "git rebase --abort" && + ( + set_fake_editor && + FAKE_LINES="2 1 1" && + export FAKE_LINES && + test_must_fail git rebase -i A D + ) && + echo x >file1 && + test_must_fail git commit file1 2>err && + test_i18ngrep "cannot do a partial commit during a rebase." err +' + +test_expect_success 'correct error message for commit --amend after empty pick' ' + test_when_finished "git rebase --abort" && + ( + set_fake_editor && + FAKE_LINES="1 1" && + export FAKE_LINES && + test_must_fail git rebase -i A D + ) && + echo x>file1 && + test_must_fail git commit -a --amend 2>err && + test_i18ngrep "middle of a rebase -- cannot amend." err +' + # This must be the last test in this file test_expect_success '$EDITOR and friends are unchanged' ' test_editor_unchanged |