rebase -r: make 'merge -c' behave like reword

If the user runs git log while rewording a commit it is confusing if
sometimes we're amending the commit that's being reworded and at other
times we're creating a new commit depending on whether we could
fast-forward or not[1]. For this reason the reword command ensures
that there are no uncommitted changes when rewording. The reword
command also allows the user to edit the todo list while the rebase is
paused. As 'merge -c' also rewords commits make it behave like reword
and add a test.

[1] https://lore.kernel.org/git/xmqqlfvu4be3.fsf@gitster-ct.c.googlers.com/T/#m133009cb91cf0917bcf667300f061178be56680a

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Phillip Wood
2021-08-20 15:40:35 +00:00
committed by Junio C Hamano
parent 5d213e46bb
commit 2be6b6f411
3 changed files with 75 additions and 19 deletions

View File

@@ -151,3 +151,53 @@ test_editor_unchanged () {
EOF
test_cmp expect actual
}
# Set up an editor for testing reword commands
# Checks that there are no uncommitted changes when rewording and that the
# todo-list is reread after each
set_reword_editor () {
>reword-actual &&
>reword-oid &&
# Check rewording keeps the original authorship
GIT_AUTHOR_NAME="Reword Author"
GIT_AUTHOR_EMAIL="reword.author@example.com"
GIT_AUTHOR_DATE=@123456
write_script reword-sequence-editor.sh <<-\EOF &&
todo="$(cat "$1")" &&
echo "exec git log -1 --pretty=format:'%an <%ae> %at%n%B%n' \
>>reword-actual" >"$1" &&
printf "%s\n" "$todo" >>"$1"
EOF
write_script reword-editor.sh <<-EOF &&
# Save the oid of the first reworded commit so we can check rebase
# fast-forwards to it
if ! test -s reword-oid
then
git rev-parse HEAD >reword-oid
fi &&
# There should be no uncommited changes
git diff --exit-code HEAD &&
# The todo-list should be re-read after a reword
GIT_SEQUENCE_EDITOR="\"$PWD/reword-sequence-editor.sh\"" \
git rebase --edit-todo &&
echo edited >>"\$1"
EOF
test_set_editor "$PWD/reword-editor.sh"
}
# Check the results of a rebase after calling set_reword_editor
# Pass the commits that were reworded in the order that they were picked
# Expects the first pick to be a fast-forward
check_reworded_commits () {
test_cmp_rev "$(cat reword-oid)" "$1^{commit}" &&
git log --format="%an <%ae> %at%n%B%nedited%n" --no-walk=unsorted "$@" \
>reword-expected &&
test_cmp reword-expected reword-actual &&
git log --format="%an <%ae> %at%n%B" -n $# --first-parent --reverse \
>reword-log &&
test_cmp reword-expected reword-log
}