Files
git/t/t3451-history-reword.sh
Patrick Steinhardt 060e602dcb builtin/history: rename "--ref-action=" to "--update-refs="
With the preceding commit we have changed "--ref-action=" to only
control which refs are supposed to be updated, not what happens with
them. As a consequence, the option is now somewhat misnamed, as we don't
control the action itself anymore.

Rename it to "--update-refs=" to better align it with its new use.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-17 08:37:51 -08:00

400 lines
7.9 KiB
Bash
Executable File

#!/bin/sh
test_description='tests for git-history reword subcommand'
. ./test-lib.sh
. "$TEST_DIRECTORY/lib-log-graph.sh"
reword_with_message () {
cat >message &&
write_script fake-editor.sh <<-\EOF &&
cp message "$1"
EOF
test_set_editor "$(pwd)"/fake-editor.sh &&
git history reword "$@" &&
rm fake-editor.sh message
}
expect_graph () {
cat >expect &&
lib_test_cmp_graph --graph --format=%s "$@"
}
expect_log () {
git log --format="%s" "$@" >actual &&
cat >expect &&
test_cmp expect actual
}
test_expect_success 'can reword tip of a branch' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
test_commit second &&
test_commit third &&
git symbolic-ref HEAD >expect &&
reword_with_message HEAD <<-EOF &&
third reworded
EOF
git symbolic-ref HEAD >actual &&
test_cmp expect actual &&
expect_log <<-\EOF &&
third reworded
second
first
EOF
git reflog >reflog &&
test_grep "reword: updating HEAD" reflog
)
'
test_expect_success 'can reword commit in the middle' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
test_commit second &&
test_commit third &&
git symbolic-ref HEAD >expect &&
reword_with_message HEAD~ <<-EOF &&
second reworded
EOF
git symbolic-ref HEAD >actual &&
test_cmp expect actual &&
expect_log <<-\EOF
third
second reworded
first
EOF
)
'
test_expect_success 'can reword commit in the middle even on detached head' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
test_commit second &&
test_commit third_on_main &&
git checkout --detach HEAD^ &&
test_commit third_on_head &&
reword_with_message HEAD~ <<-EOF &&
second reworded
EOF
expect_graph HEAD --branches <<-\EOF
* third_on_head
| * third_on_main
|/
* second reworded
* first
EOF
)
'
test_expect_success 'can reword the detached head' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
test_commit second &&
git checkout --detach HEAD &&
test_commit third &&
reword_with_message HEAD <<-EOF &&
third reworded
EOF
expect_log <<-\EOF
third reworded
second
first
EOF
)
'
test_expect_success 'can reword root commit' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
test_commit second &&
test_commit third &&
reword_with_message HEAD~2 <<-EOF &&
first reworded
EOF
expect_log <<-\EOF
third
second
first reworded
EOF
)
'
test_expect_success 'can reword in a bare repo' '
test_when_finished "rm -rf repo repo.git" &&
git init repo &&
test_commit -C repo first &&
git clone --bare repo repo.git &&
(
cd repo.git &&
reword_with_message HEAD <<-EOF &&
reworded
EOF
expect_log <<-\EOF
reworded
EOF
)
'
test_expect_success 'can reword a commit on a different branch' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit base &&
git branch theirs &&
test_commit ours &&
git switch theirs &&
test_commit theirs &&
git rev-parse ours >ours-before &&
reword_with_message theirs <<-EOF &&
Reworded theirs
EOF
git rev-parse ours >ours-after &&
test_cmp ours-before ours-after &&
expect_graph --branches <<-\EOF
* Reworded theirs
| * ours
|/
* base
EOF
)
'
test_expect_success 'can reword a merge commit' '
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 &&
# It is not possible to replay merge commits embedded in the
# history (yet).
test_must_fail git -c core.editor=false history reword HEAD~ 2>err &&
test_grep "replaying merge commits is not supported yet" err &&
# But it is possible to reword a merge commit directly.
reword_with_message HEAD <<-EOF &&
Reworded merge commit
EOF
expect_graph <<-\EOF
* Reworded merge commit
|\
| * theirs
* | ours
|/
* base
EOF
)
'
test_expect_success '--dry-run prints ref updates without modifying repo' '
test_when_finished "rm -rf repo" &&
git init repo --initial-branch=main &&
(
cd repo &&
test_commit base &&
git branch branch &&
test_commit ours &&
git switch branch &&
test_commit theirs &&
git refs list >refs-expect &&
reword_with_message --dry-run --update-refs=head base >updates <<-\EOF &&
reworded commit
EOF
git refs list >refs-actual &&
test_cmp refs-expect refs-actual &&
test_grep "update refs/heads/branch" updates &&
test_grep ! "update refs/heads/main" updates &&
reword_with_message --dry-run base >updates <<-\EOF &&
reworded commit
EOF
git refs list >refs-actual &&
test_cmp refs-expect refs-actual &&
test_grep "update refs/heads/branch" updates &&
test_grep "update refs/heads/main" updates &&
git update-ref --stdin <updates &&
expect_log --branches <<-\EOF
theirs
ours
reworded commit
EOF
)
'
test_expect_success '--update-refs=head updates only HEAD' '
test_when_finished "rm -rf repo" &&
git init repo --initial-branch=main &&
(
cd repo &&
test_commit base &&
git branch branch &&
test_commit theirs &&
git switch branch &&
test_commit ours &&
# When told to update HEAD, only, the command will refuse to
# rewrite commits that are not an ancestor of HEAD.
test_must_fail git -c core.editor=false history reword --update-refs=head theirs 2>err &&
test_grep "rewritten commit must be an ancestor of HEAD" err &&
reword_with_message --update-refs=head base >updates <<-\EOF &&
reworded base
EOF
expect_log HEAD <<-\EOF &&
ours
reworded base
EOF
expect_log main <<-\EOF
theirs
base
EOF
)
'
test_expect_success 'editor shows proper status' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
write_script fake-editor.sh <<-\EOF &&
cp "$1" . &&
printf "\namend a comment\n" >>"$1"
EOF
test_set_editor "$(pwd)"/fake-editor.sh &&
git history reword HEAD &&
cat >expect <<-EOF &&
first
# Please enter the commit message for the reworded changes. Lines starting
# with ${SQ}#${SQ} will be ignored, and an empty message aborts the commit.
# Changes to be committed:
# new file: first.t
#
EOF
test_cmp expect COMMIT_EDITMSG &&
test_commit_message HEAD <<-\EOF
first
amend a comment
EOF
)
'
# For now, git-history(1) does not yet execute any hooks. This is subject to
# change in the future, and if it does this test here is expected to start
# failing. In other words, this test is not an endorsement of the current
# status quo.
test_expect_success 'hooks are not executed for rewritten commits' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
test_commit second &&
test_commit third &&
ORIG_PATH="$(pwd)" &&
export ORIG_PATH &&
for hook in prepare-commit-msg pre-commit post-commit post-rewrite commit-msg
do
write_script .git/hooks/$hook <<-\EOF || exit 1
touch "$ORIG_PATH/hooks.log
EOF
done &&
reword_with_message HEAD~ <<-EOF &&
second reworded
EOF
cat >expect <<-EOF &&
third
second reworded
first
EOF
git log --format=%s >actual &&
test_cmp expect actual &&
test_path_is_missing hooks.log
)
'
test_expect_success 'aborts with empty commit message' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit first &&
! reword_with_message HEAD 2>err </dev/null &&
test_grep "Aborting commit due to empty commit message." err
)
'
test_expect_success 'retains changes in the worktree and index' '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
touch a b &&
git add . &&
git commit -m "initial commit" &&
echo foo >a &&
echo bar >b &&
git add b &&
reword_with_message HEAD <<-EOF &&
message
EOF
cat >expect <<-\EOF &&
M a
M b
?? actual
?? expect
EOF
git status --porcelain >actual &&
test_cmp expect actual
)
'
test_done