rebase -i: add exec command to launch a shell command
[gitweb.git] / t / t3404-rebase-interactive.sh
index f20ea38411d0ca67709dbde0bfd1108e28c0dd71..67fe76173827fed4e165f52c6a3184162b825f56 100755 (executable)
@@ -64,6 +64,67 @@ test_expect_success 'setup' '
        done
 '
 
+# "exec" commands are ran with the user shell by default, but this may
+# be non-POSIX. For example, if SHELL=zsh then ">file" doesn't work
+# to create a file. Unseting SHELL avoids such non-portable behavior
+# in tests.
+SHELL=
+
+test_expect_success 'rebase -i with the exec command' '
+       git checkout master &&
+       (
+       FAKE_LINES="1 exec_>touch-one
+               2 exec_>touch-two exec_false exec_>touch-three
+               3 4 exec_>\"touch-file__name_with_spaces\";_>touch-after-semicolon 5" &&
+       export FAKE_LINES &&
+       test_must_fail git rebase -i A
+       ) &&
+       test -f touch-one &&
+       test -f touch-two &&
+       ! test -f touch-three &&
+       test $(git rev-parse C) = $(git rev-parse HEAD) || {
+               echo "Stopped at wrong revision:"
+               echo "($(git describe --tags HEAD) instead of C)"
+               false
+       } &&
+       git rebase --continue &&
+       test -f touch-three &&
+       test -f "touch-file  name with spaces" &&
+       test -f touch-after-semicolon &&
+       test $(git rev-parse master) = $(git rev-parse HEAD) || {
+               echo "Stopped at wrong revision:"
+               echo "($(git describe --tags HEAD) instead of master)"
+               false
+       } &&
+       rm -f touch-*
+'
+
+test_expect_success 'rebase -i with the exec command runs from tree root' '
+       git checkout master &&
+       mkdir subdir && cd subdir &&
+       FAKE_LINES="1 exec_>touch-subdir" \
+               git rebase -i HEAD^ &&
+       cd .. &&
+       test -f touch-subdir &&
+       rm -fr subdir
+'
+
+test_expect_success 'rebase -i with the exec command checks tree cleanness' '
+       git checkout master &&
+       (
+       FAKE_LINES="exec_echo_foo_>file1 1" &&
+       export FAKE_LINES &&
+       test_must_fail git rebase -i HEAD^
+       ) &&
+       test $(git rev-parse master^) = $(git rev-parse HEAD) || {
+               echo "Stopped at wrong revision:"
+               echo "($(git describe --tags HEAD) instead of master^)"
+               false
+       } &&
+       git reset --hard &&
+       git rebase --continue
+'
+
 test_expect_success 'no changes are a nop' '
        git checkout branch2 &&
        git rebase -i F &&
@@ -146,6 +207,16 @@ test_expect_success 'abort' '
        ! test -d .git/rebase-merge
 '
 
+test_expect_success 'abort with error when new base cannot be checked out' '
+       git rm --cached file1 &&
+       git commit -m "remove file in base" &&
+       test_must_fail git rebase -i master > output 2>&1 &&
+       grep "Untracked working tree file .file1. would be overwritten" \
+               output &&
+       ! test -d .git/rebase-merge &&
+       git reset --hard HEAD^
+'
+
 test_expect_success 'retain authorship' '
        echo A > file7 &&
        git add file7 &&
@@ -181,6 +252,12 @@ test_expect_success '-p handles "no changes" gracefully' '
        test $HEAD = $(git rev-parse HEAD)
 '
 
+test_expect_failure 'exchange two commits with -p' '
+       FAKE_LINES="2 1" git rebase -i -p HEAD~2 &&
+       test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
+       test G = $(git cat-file commit HEAD | sed -ne \$p)
+'
+
 test_expect_success 'preserve merges with -p' '
        git checkout -b to-be-preserved master^ &&
        : > unrelated-file &&
@@ -614,4 +691,22 @@ test_expect_success 'always cherry-pick with --no-ff' '
        test_cmp empty out
 '
 
+test_expect_success 'set up commits with funny messages' '
+       git checkout -b funny A &&
+       echo >>file1 &&
+       test_tick &&
+       git commit -a -m "end with slash\\" &&
+       echo >>file1 &&
+       test_tick &&
+       git commit -a -m "another commit"
+'
+
+test_expect_success 'rebase-i history with funny messages' '
+       git rev-list A..funny >expect &&
+       test_tick &&
+       FAKE_LINES="1 2" git rebase -i A &&
+       git rev-list A.. >actual &&
+       test_cmp expect actual
+'
+
 test_done