git/t/t3452-history-split.sh

433 lines
7.0 KiB
Bash
Executable File

#!/bin/sh
test_description='tests for git-history split subcommand'
. ./test-lib.sh
set_fake_editor () {
write_script fake-editor.sh <<-\EOF &&
echo "split-out commit" >"$1"
EOF
test_set_editor "$(pwd)"/fake-editor.sh
}
expect_log () {
git log --format="%s" >actual &&
cat >expect &&
test_cmp expect actual
}
expect_tree_entries () {
git ls-tree --name-only "$1" >actual &&
cat >expect &&
test_cmp expect actual
}
test_expect_success 'refuses to work with merge commits' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit base &&
git branch branch &&
test_commit ours &&
git switch branch &&
test_commit theirs &&
git switch - &&
git merge theirs &&
test_must_fail git history split HEAD 2>err &&
test_grep "commit to be split must not be a merge commit" err &&
test_must_fail git history split HEAD~ 2>err &&
test_grep "cannot rearrange commit history with merges" err
)
'
test_expect_success 'can split up tip commit' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit initial &&
touch bar foo &&
git add . &&
git commit -m split-me &&
git symbolic-ref HEAD >expect &&
set_fake_editor &&
git history split HEAD <<-EOF &&
y
n
EOF
git symbolic-ref HEAD >actual &&
test_cmp expect actual &&
expect_log <<-EOF &&
split-me
split-out commit
initial
EOF
expect_tree_entries HEAD~ <<-EOF &&
bar
initial.t
EOF
expect_tree_entries HEAD <<-EOF
bar
foo
initial.t
EOF
)
'
test_expect_success 'can split up root commit' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m root &&
test_commit tip &&
set_fake_editor &&
git history split HEAD~ <<-EOF &&
y
n
EOF
expect_log <<-EOF &&
tip
root
split-out commit
EOF
expect_tree_entries HEAD~2 <<-EOF &&
bar
EOF
expect_tree_entries HEAD~ <<-EOF &&
bar
foo
EOF
expect_tree_entries HEAD <<-EOF
bar
foo
tip.t
EOF
)
'
test_expect_success 'can split up in-between commit' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit initial &&
touch bar foo &&
git add . &&
git commit -m split-me &&
test_commit tip &&
set_fake_editor &&
git history split HEAD~ <<-EOF &&
y
n
EOF
expect_log <<-EOF &&
tip
split-me
split-out commit
initial
EOF
expect_tree_entries HEAD~2 <<-EOF &&
bar
initial.t
EOF
expect_tree_entries HEAD~ <<-EOF &&
bar
foo
initial.t
EOF
expect_tree_entries HEAD <<-EOF
bar
foo
initial.t
tip.t
EOF
)
'
test_expect_success 'can pick multiple hunks' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar baz foo qux &&
git add . &&
git commit -m split-me &&
git history split HEAD -m "split-out commit" <<-EOF &&
y
n
y
n
EOF
expect_tree_entries HEAD~ <<-EOF &&
bar
foo
EOF
expect_tree_entries HEAD <<-EOF
bar
baz
foo
qux
EOF
)
'
test_expect_success 'can use only last hunk' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m split-me &&
git history split HEAD -m "split-out commit" <<-EOF &&
n
y
EOF
expect_log <<-EOF &&
split-me
split-out commit
EOF
expect_tree_entries HEAD~ <<-EOF &&
foo
EOF
expect_tree_entries HEAD <<-EOF
bar
foo
EOF
)
'
test_expect_success 'aborts with empty commit message' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m split-me &&
test_must_fail git history split HEAD -m "" <<-EOF 2>err &&
y
n
EOF
test_grep "Aborting commit due to empty commit message." err
)
'
test_expect_success 'can specify message via option' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m split-me &&
git history split HEAD -m "message option" <<-EOF &&
y
n
EOF
expect_log <<-EOF
split-me
message option
EOF
)
'
test_expect_success 'commit message editor sees split-out changes' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m split-me &&
write_script fake-editor.sh <<-\EOF &&
cp "$1" . &&
echo "some commit message" >>"$1"
EOF
test_set_editor "$(pwd)"/fake-editor.sh &&
git history split HEAD <<-EOF &&
y
n
EOF
cat >expect <<-EOF &&
# Please enter the commit message for the split-out changes. Lines starting
# with ${SQ}#${SQ} will be kept; you may remove them yourself if you want to.
# Changes to be committed:
# new file: bar
#
EOF
test_cmp expect COMMIT_EDITMSG &&
expect_log <<-EOF
split-me
some commit message
EOF
)
'
test_expect_success 'can use pathspec to limit what gets split' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m split-me &&
git history split HEAD -m "message option" -- foo <<-EOF &&
y
EOF
expect_tree_entries HEAD~ <<-EOF &&
foo
EOF
expect_tree_entries HEAD <<-EOF
bar
foo
EOF
)
'
test_expect_success 'refuses to create empty split-out commit' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit base &&
touch bar foo &&
git add . &&
git commit -m split-me &&
test_must_fail git history split HEAD 2>err <<-EOF &&
n
n
EOF
test_grep "split commit is empty" err
)
'
test_expect_success 'hooks are executed for rewritten commits' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m split-me &&
old_head=$(git rev-parse HEAD) &&
write_script .git/hooks/prepare-commit-msg <<-EOF &&
touch "$(pwd)/hooks.log"
EOF
write_script .git/hooks/post-commit <<-EOF &&
touch "$(pwd)/hooks.log"
EOF
write_script .git/hooks/post-rewrite <<-EOF &&
touch "$(pwd)/hooks.log"
EOF
set_fake_editor &&
git history split HEAD <<-EOF &&
y
n
EOF
expect_log <<-EOF &&
split-me
split-out commit
EOF
test_path_is_missing hooks.log
)
'
test_expect_success 'refuses to create empty original commit' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch bar foo &&
git add . &&
git commit -m split-me &&
test_must_fail git history split HEAD 2>err <<-EOF &&
y
y
EOF
test_grep "split commit tree matches original commit" err
)
'
test_expect_success 'retains changes in the worktree and index' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
echo a >a &&
echo b >b &&
git add . &&
git commit -m "initial commit" &&
echo a-modified >a &&
echo b-modified >b &&
git add b &&
git history split HEAD -m a-only <<-EOF &&
y
n
EOF
expect_tree_entries HEAD~ <<-EOF &&
a
EOF
expect_tree_entries HEAD <<-EOF &&
a
b
EOF
cat >expect <<-\EOF &&
M a
M b
?? actual
?? expect
EOF
git status --porcelain >actual &&
test_cmp expect actual
)
'
test_done