Merge branch 'pw/rebase-skip-commit-message-fix' into next
"git rebase -i" with a series of squash/fixup, when one of the steps stopped in conflicts and ended up getting skipped, did not handle the accumulated commit log messages, which has been corrected. * pw/rebase-skip-commit-message-fix: rebase --skip: fix commit message clean up when skipping squash
This commit is contained in:
28
sequencer.c
28
sequencer.c
@ -5048,19 +5048,31 @@ static int commit_staged_changes(struct repository *r,
|
|||||||
* We need to update the squash message to skip
|
* We need to update the squash message to skip
|
||||||
* the latest commit message.
|
* the latest commit message.
|
||||||
*/
|
*/
|
||||||
|
int res = 0;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
|
const char *msg;
|
||||||
const char *path = rebase_path_squash_msg();
|
const char *path = rebase_path_squash_msg();
|
||||||
const char *encoding = get_commit_output_encoding();
|
const char *encoding = get_commit_output_encoding();
|
||||||
|
|
||||||
if (parse_head(r, &commit) ||
|
if (parse_head(r, &commit))
|
||||||
!(p = repo_logmsg_reencode(r, commit, NULL, encoding)) ||
|
return error(_("could not parse HEAD"));
|
||||||
write_message(p, strlen(p), path, 0)) {
|
|
||||||
repo_unuse_commit_buffer(r, commit, p);
|
p = repo_logmsg_reencode(r, commit, NULL, encoding);
|
||||||
return error(_("could not write file: "
|
if (!p) {
|
||||||
"'%s'"), path);
|
res = error(_("could not parse commit %s"),
|
||||||
|
oid_to_hex(&commit->object.oid));
|
||||||
|
goto unuse_commit_buffer;
|
||||||
}
|
}
|
||||||
repo_unuse_commit_buffer(r,
|
find_commit_subject(p, &msg);
|
||||||
commit, p);
|
if (write_message(msg, strlen(msg), path, 0)) {
|
||||||
|
res = error(_("could not write file: "
|
||||||
|
"'%s'"), path);
|
||||||
|
goto unuse_commit_buffer;
|
||||||
|
}
|
||||||
|
unuse_commit_buffer:
|
||||||
|
repo_unuse_commit_buffer(r, commit, p);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,15 +115,23 @@ test_expect_success '--skip after failed fixup cleans commit message' '
|
|||||||
test_when_finished "test_might_fail git rebase --abort" &&
|
test_when_finished "test_might_fail git rebase --abort" &&
|
||||||
git checkout -b with-conflicting-fixup &&
|
git checkout -b with-conflicting-fixup &&
|
||||||
test_commit wants-fixup &&
|
test_commit wants-fixup &&
|
||||||
test_commit "fixup! wants-fixup" wants-fixup.t 1 wants-fixup-1 &&
|
test_commit "fixup 1" wants-fixup.t 1 wants-fixup-1 &&
|
||||||
test_commit "fixup! wants-fixup" wants-fixup.t 2 wants-fixup-2 &&
|
test_commit "fixup 2" wants-fixup.t 2 wants-fixup-2 &&
|
||||||
test_commit "fixup! wants-fixup" wants-fixup.t 3 wants-fixup-3 &&
|
test_commit "fixup 3" wants-fixup.t 3 wants-fixup-3 &&
|
||||||
test_must_fail env FAKE_LINES="1 fixup 2 squash 4" \
|
test_must_fail env FAKE_LINES="1 fixup 2 squash 4" \
|
||||||
git rebase -i HEAD~4 &&
|
git rebase -i HEAD~4 &&
|
||||||
|
|
||||||
: now there is a conflict, and comments in the commit message &&
|
: now there is a conflict, and comments in the commit message &&
|
||||||
git show HEAD >out &&
|
test_commit_message HEAD <<-\EOF &&
|
||||||
grep "fixup! wants-fixup" out &&
|
# This is a combination of 2 commits.
|
||||||
|
# This is the 1st commit message:
|
||||||
|
|
||||||
|
wants-fixup
|
||||||
|
|
||||||
|
# The commit message #2 will be skipped:
|
||||||
|
|
||||||
|
# fixup 1
|
||||||
|
EOF
|
||||||
|
|
||||||
: skip and continue &&
|
: skip and continue &&
|
||||||
echo "cp \"\$1\" .git/copy.txt" | write_script copy-editor.sh &&
|
echo "cp \"\$1\" .git/copy.txt" | write_script copy-editor.sh &&
|
||||||
@ -133,33 +141,49 @@ test_expect_success '--skip after failed fixup cleans commit message' '
|
|||||||
test_path_is_missing .git/copy.txt &&
|
test_path_is_missing .git/copy.txt &&
|
||||||
|
|
||||||
: now the comments in the commit message should have been cleaned up &&
|
: now the comments in the commit message should have been cleaned up &&
|
||||||
git show HEAD >out &&
|
test_commit_message HEAD -m wants-fixup &&
|
||||||
! grep "fixup! wants-fixup" out &&
|
|
||||||
|
|
||||||
: now, let us ensure that "squash" is handled correctly &&
|
: now, let us ensure that "squash" is handled correctly &&
|
||||||
git reset --hard wants-fixup-3 &&
|
git reset --hard wants-fixup-3 &&
|
||||||
test_must_fail env FAKE_LINES="1 squash 4 squash 2 squash 4" \
|
test_must_fail env FAKE_LINES="1 squash 2 squash 1 squash 3 squash 1" \
|
||||||
git rebase -i HEAD~4 &&
|
git rebase -i HEAD~4 &&
|
||||||
|
|
||||||
: the first squash failed, but there are two more in the chain &&
|
: the second squash failed, but there are two more in the chain &&
|
||||||
(test_set_editor "$PWD/copy-editor.sh" &&
|
(test_set_editor "$PWD/copy-editor.sh" &&
|
||||||
test_must_fail git rebase --skip) &&
|
test_must_fail git rebase --skip) &&
|
||||||
|
|
||||||
: not the final squash, no need to edit the commit message &&
|
: not the final squash, no need to edit the commit message &&
|
||||||
test_path_is_missing .git/copy.txt &&
|
test_path_is_missing .git/copy.txt &&
|
||||||
|
|
||||||
: The first squash was skipped, therefore: &&
|
: The first and third squashes succeeded, therefore: &&
|
||||||
git show HEAD >out &&
|
test_commit_message HEAD <<-\EOF &&
|
||||||
test_i18ngrep "# This is a combination of 2 commits" out &&
|
# This is a combination of 3 commits.
|
||||||
test_i18ngrep "# This is the commit message #2:" out &&
|
# This is the 1st commit message:
|
||||||
|
|
||||||
|
wants-fixup
|
||||||
|
|
||||||
|
# This is the commit message #2:
|
||||||
|
|
||||||
|
fixup 1
|
||||||
|
|
||||||
|
# This is the commit message #3:
|
||||||
|
|
||||||
|
fixup 2
|
||||||
|
EOF
|
||||||
|
|
||||||
(test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
|
(test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
|
||||||
git show HEAD >out &&
|
test_commit_message HEAD <<-\EOF &&
|
||||||
test_i18ngrep ! "# This is a combination" out &&
|
wants-fixup
|
||||||
|
|
||||||
|
fixup 1
|
||||||
|
|
||||||
|
fixup 2
|
||||||
|
EOF
|
||||||
|
|
||||||
: Final squash failed, but there was still a squash &&
|
: Final squash failed, but there was still a squash &&
|
||||||
test_i18ngrep "# This is a combination of 2 commits" .git/copy.txt &&
|
head -n1 .git/copy.txt >first-line &&
|
||||||
test_i18ngrep "# This is the commit message #2:" .git/copy.txt
|
test_i18ngrep "# This is a combination of 3 commits" first-line &&
|
||||||
|
test_i18ngrep "# This is the commit message #3:" .git/copy.txt
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'setup rerere database' '
|
test_expect_success 'setup rerere database' '
|
||||||
|
@ -21,21 +21,6 @@ TEST_PASSES_SANITIZE_LEAK=true
|
|||||||
|
|
||||||
EMPTY=""
|
EMPTY=""
|
||||||
|
|
||||||
# test_commit_message <rev> -m <msg>
|
|
||||||
# test_commit_message <rev> <path>
|
|
||||||
# Verify that the commit message of <rev> matches
|
|
||||||
# <msg> or the content of <path>.
|
|
||||||
test_commit_message () {
|
|
||||||
git show --no-patch --pretty=format:%B "$1" >actual &&
|
|
||||||
case "$2" in
|
|
||||||
-m)
|
|
||||||
echo "$3" >expect &&
|
|
||||||
test_cmp expect actual ;;
|
|
||||||
*)
|
|
||||||
test_cmp "$2" actual ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
get_author () {
|
get_author () {
|
||||||
rev="$1" &&
|
rev="$1" &&
|
||||||
git log -1 --pretty=format:"%an %ae %at" "$rev"
|
git log -1 --pretty=format:"%an %ae %at" "$rev"
|
||||||
|
@ -1291,6 +1291,39 @@ test_cmp_rev () {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Tests that a commit message matches the expected text
|
||||||
|
#
|
||||||
|
# Usage: test_commit_message <rev> [-m <msg> | <file>]
|
||||||
|
#
|
||||||
|
# When using "-m" <msg> will have a line feed appended. If the second
|
||||||
|
# argument is omitted then the expected message is read from stdin.
|
||||||
|
|
||||||
|
test_commit_message () {
|
||||||
|
local msg_file=expect.msg
|
||||||
|
|
||||||
|
case $# in
|
||||||
|
3)
|
||||||
|
if test "$2" = "-m"
|
||||||
|
then
|
||||||
|
printf "%s\n" "$3" >"$msg_file"
|
||||||
|
else
|
||||||
|
BUG "Usage: test_commit_message <rev> [-m <message> | <file>]"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
msg_file="$2"
|
||||||
|
;;
|
||||||
|
1)
|
||||||
|
cat >"$msg_file"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
BUG "Usage: test_commit_message <rev> [-m <message> | <file>]"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
git show --no-patch --pretty=format:%B "$1" -- >actual.msg &&
|
||||||
|
test_cmp "$msg_file" actual.msg
|
||||||
|
}
|
||||||
|
|
||||||
# Compare paths respecting core.ignoreCase
|
# Compare paths respecting core.ignoreCase
|
||||||
test_cmp_fspath () {
|
test_cmp_fspath () {
|
||||||
if test "x$1" = "x$2"
|
if test "x$1" = "x$2"
|
||||||
|
Reference in New Issue
Block a user