rebase -i: handle fixup of root commit correctly
There is a bug with git rebase -i --root when a fixup or squash line is applied to the new root. We attempt to amend the commit onto which they apply with git reset --soft HEAD^ followed by a normal commit. Unlike a real commit --amend, this sequence will fail against a root commit as it has no parent. Fix rebase -i to use commit --amend for fixup and squash instead, and add a test for the case of a fixup of the root commit. Signed-off-by: Chris Webb <chris@arachsys.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
994fd91d1f
commit
2147f844ed
@ -495,25 +495,28 @@ do_next () {
|
|||||||
author_script_content=$(get_author_ident_from_commit HEAD)
|
author_script_content=$(get_author_ident_from_commit HEAD)
|
||||||
echo "$author_script_content" > "$author_script"
|
echo "$author_script_content" > "$author_script"
|
||||||
eval "$author_script_content"
|
eval "$author_script_content"
|
||||||
output git reset --soft HEAD^
|
if ! pick_one -n $sha1
|
||||||
pick_one -n $sha1 || die_failed_squash $sha1 "$rest"
|
then
|
||||||
|
git rev-parse --verify HEAD >"$amend"
|
||||||
|
die_failed_squash $sha1 "$rest"
|
||||||
|
fi
|
||||||
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:
|
||||||
do_with_author output git commit --no-verify -F "$squash_msg" ||
|
do_with_author output git commit --amend --no-verify -F "$squash_msg" ||
|
||||||
die_failed_squash $sha1 "$rest"
|
die_failed_squash $sha1 "$rest"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# This is the final command of this squash/fixup group
|
# This is the final command of this squash/fixup group
|
||||||
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 --amend --no-verify -F "$fixup_msg" ||
|
||||||
die_failed_squash $sha1 "$rest"
|
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 --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e ||
|
||||||
die_failed_squash $sha1 "$rest"
|
die_failed_squash $sha1 "$rest"
|
||||||
fi
|
fi
|
||||||
rm -f "$squash_msg" "$fixup_msg"
|
rm -f "$squash_msg" "$fixup_msg"
|
||||||
@ -729,7 +732,6 @@ In both case, once you're done, continue with:
|
|||||||
fi
|
fi
|
||||||
. "$author_script" ||
|
. "$author_script" ||
|
||||||
die "Error trying to find the author identity to amend commit"
|
die "Error trying to find the author identity to amend commit"
|
||||||
current_head=
|
|
||||||
if test -f "$amend"
|
if test -f "$amend"
|
||||||
then
|
then
|
||||||
current_head=$(git rev-parse --verify HEAD)
|
current_head=$(git rev-parse --verify HEAD)
|
||||||
@ -737,13 +739,12 @@ In both case, once you're done, continue with:
|
|||||||
die "\
|
die "\
|
||||||
You have uncommitted changes in your working tree. Please, commit them
|
You have uncommitted changes in your working tree. Please, commit them
|
||||||
first and then run 'git rebase --continue' again."
|
first and then run 'git rebase --continue' again."
|
||||||
git reset --soft HEAD^ ||
|
do_with_author git commit --amend --no-verify -F "$msg" -e ||
|
||||||
die "Cannot rewind the HEAD"
|
die "Could not commit staged changes."
|
||||||
|
else
|
||||||
|
do_with_author git commit --no-verify -F "$msg" -e ||
|
||||||
|
die "Could not commit staged changes."
|
||||||
fi
|
fi
|
||||||
do_with_author git commit --no-verify -F "$msg" -e || {
|
|
||||||
test -n "$current_head" && git reset --soft $current_head
|
|
||||||
die "Could not commit staged changes."
|
|
||||||
}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
|
record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
|
||||||
|
@ -786,4 +786,12 @@ test_expect_success 'rebase -i --root temporary sentinel commit' '
|
|||||||
git rebase --abort
|
git rebase --abort
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rebase -i --root fixup root commit' '
|
||||||
|
git checkout B &&
|
||||||
|
FAKE_LINES="1 fixup 2" git rebase -i --root &&
|
||||||
|
test A = $(git cat-file commit HEAD | sed -ne \$p) &&
|
||||||
|
test B = $(git show HEAD:file1) &&
|
||||||
|
test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user