rebase -i: Retain user-edited commit messages after squash/fixup conflicts
When a squash/fixup fails due to a conflict, the user is required to edit the commit message. Previously, if further squash/fixup commands followed the conflicting squash/fixup, this user-edited message was discarded and a new automatically-generated commit message was suggested. Change the handling of conflicts within squash/fixup command series: Whenever the user is required to intervene, consider the resulting commit to be a new basis for the following squash/fixups and use its commit message in later suggested combined commit messages. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
6c4c44c458
commit
6bdcd0d2fc
@ -408,6 +408,21 @@ peek_next_command () {
|
|||||||
sed -n -e "/^#/d" -e "/^$/d" -e "s/ .*//p" -e "q" < "$TODO"
|
sed -n -e "/^#/d" -e "/^$/d" -e "s/ .*//p" -e "q" < "$TODO"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# A squash/fixup has failed. Prepare the long version of the squash
|
||||||
|
# commit message, then die_with_patch. This code path requires the
|
||||||
|
# user to edit the combined commit message for all commits that have
|
||||||
|
# been squashed/fixedup so far. So also erase the old squash
|
||||||
|
# messages, effectively causing the combined commit to be used as the
|
||||||
|
# new basis for any further squash/fixups. Args: sha1 rest
|
||||||
|
die_failed_squash() {
|
||||||
|
mv "$SQUASH_MSG" "$MSG" || exit
|
||||||
|
rm -f "$FIXUP_MSG"
|
||||||
|
cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit
|
||||||
|
warn
|
||||||
|
warn "Could not apply $1... $2"
|
||||||
|
die_with_patch $1 ""
|
||||||
|
}
|
||||||
|
|
||||||
do_next () {
|
do_next () {
|
||||||
rm -f "$MSG" "$AUTHOR_SCRIPT" "$AMEND" || exit
|
rm -f "$MSG" "$AUTHOR_SCRIPT" "$AMEND" || exit
|
||||||
read command sha1 rest < "$TODO"
|
read command sha1 rest < "$TODO"
|
||||||
@ -465,58 +480,31 @@ do_next () {
|
|||||||
|
|
||||||
mark_action_done
|
mark_action_done
|
||||||
update_squash_messages $squash_style $sha1
|
update_squash_messages $squash_style $sha1
|
||||||
failed=f
|
|
||||||
author_script=$(get_author_ident_from_commit HEAD)
|
author_script=$(get_author_ident_from_commit HEAD)
|
||||||
echo "$author_script" > "$AUTHOR_SCRIPT"
|
echo "$author_script" > "$AUTHOR_SCRIPT"
|
||||||
eval "$author_script"
|
eval "$author_script"
|
||||||
output git reset --soft HEAD^
|
output git reset --soft HEAD^
|
||||||
pick_one -n $sha1 || failed=t
|
pick_one -n $sha1 || die_failed_squash $sha1 "$rest"
|
||||||
case "$(peek_next_command)" in
|
case "$(peek_next_command)" in
|
||||||
squash|s|fixup|f)
|
squash|s|fixup|f)
|
||||||
# This is an intermediate commit; its message will only be
|
# This is an intermediate commit; its message will only be
|
||||||
# used in case of trouble. So use the long version:
|
# used in case of trouble. So use the long version:
|
||||||
if test $failed = f
|
|
||||||
then
|
|
||||||
do_with_author output git commit --no-verify -F "$SQUASH_MSG" ||
|
do_with_author output git commit --no-verify -F "$SQUASH_MSG" ||
|
||||||
failed=t
|
die_failed_squash $sha1 "$rest"
|
||||||
fi
|
|
||||||
if test $failed = t
|
|
||||||
then
|
|
||||||
cp "$SQUASH_MSG" "$MSG" || exit
|
|
||||||
# After any kind of hiccup, prevent committing without
|
|
||||||
# opening the commit message editor:
|
|
||||||
rm -f "$FIXUP_MSG"
|
|
||||||
cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit
|
|
||||||
warn
|
|
||||||
warn "Could not apply $sha1... $rest"
|
|
||||||
die_with_patch $sha1 ""
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# This is the final command of this squash/fixup group
|
# This is the final command of this squash/fixup group
|
||||||
if test $failed = f
|
|
||||||
then
|
|
||||||
if test -f "$FIXUP_MSG"
|
if test -f "$FIXUP_MSG"
|
||||||
then
|
then
|
||||||
do_with_author git commit --no-verify -F "$FIXUP_MSG" ||
|
do_with_author git commit --no-verify -F "$FIXUP_MSG" ||
|
||||||
failed=t
|
die_failed_squash $sha1 "$rest"
|
||||||
else
|
else
|
||||||
cp "$SQUASH_MSG" "$GIT_DIR"/SQUASH_MSG || exit
|
cp "$SQUASH_MSG" "$GIT_DIR"/SQUASH_MSG || exit
|
||||||
rm -f "$GIT_DIR"/MERGE_MSG
|
rm -f "$GIT_DIR"/MERGE_MSG
|
||||||
do_with_author git commit --no-verify -e ||
|
do_with_author git commit --no-verify -e ||
|
||||||
failed=t
|
die_failed_squash $sha1 "$rest"
|
||||||
fi
|
fi
|
||||||
fi
|
rm -f "$SQUASH_MSG" "$FIXUP_MSG"
|
||||||
rm -f "$FIXUP_MSG"
|
|
||||||
if test $failed = t
|
|
||||||
then
|
|
||||||
mv "$SQUASH_MSG" "$MSG" || exit
|
|
||||||
cp "$MSG" "$GIT_DIR"/MERGE_MSG || exit
|
|
||||||
warn
|
|
||||||
warn "Could not apply $sha1... $rest"
|
|
||||||
die_with_patch $sha1 ""
|
|
||||||
fi
|
|
||||||
rm -f "$SQUASH_MSG"
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
@ -264,6 +264,42 @@ test_expect_success 'multi-fixup does not fire up editor' '
|
|||||||
git branch -D multi-fixup
|
git branch -D multi-fixup
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'commit message used after conflict' '
|
||||||
|
git checkout -b conflict-fixup conflict-branch &&
|
||||||
|
base=$(git rev-parse HEAD~4) &&
|
||||||
|
(
|
||||||
|
FAKE_LINES="1 fixup 3 fixup 4" &&
|
||||||
|
export FAKE_LINES &&
|
||||||
|
test_must_fail git rebase -i $base
|
||||||
|
) &&
|
||||||
|
echo three > conflict &&
|
||||||
|
git add conflict &&
|
||||||
|
FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \
|
||||||
|
git rebase --continue &&
|
||||||
|
test $base = $(git rev-parse HEAD^) &&
|
||||||
|
test 1 = $(git show | grep ONCE | wc -l) &&
|
||||||
|
git checkout to-be-rebased &&
|
||||||
|
git branch -D conflict-fixup
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'commit message retained after conflict' '
|
||||||
|
git checkout -b conflict-squash conflict-branch &&
|
||||||
|
base=$(git rev-parse HEAD~4) &&
|
||||||
|
(
|
||||||
|
FAKE_LINES="1 fixup 3 squash 4" &&
|
||||||
|
export FAKE_LINES &&
|
||||||
|
test_must_fail git rebase -i $base
|
||||||
|
) &&
|
||||||
|
echo three > conflict &&
|
||||||
|
git add conflict &&
|
||||||
|
FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \
|
||||||
|
git rebase --continue &&
|
||||||
|
test $base = $(git rev-parse HEAD^) &&
|
||||||
|
test 2 = $(git show | grep TWICE | wc -l) &&
|
||||||
|
git checkout to-be-rebased &&
|
||||||
|
git branch -D conflict-squash
|
||||||
|
'
|
||||||
|
|
||||||
cat > expect-squash-fixup << EOF
|
cat > expect-squash-fixup << EOF
|
||||||
B
|
B
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user