Skip to content

Commit e8c53ff

Browse files
committed
Merge branch 'pw/rebase-skip-commit-message-fix'
"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
2 parents 8cdd5e7 + 6ce7afe commit e8c53ff

File tree

4 files changed

+93
-39
lines changed

4 files changed

+93
-39
lines changed

sequencer.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5048,19 +5048,31 @@ static int commit_staged_changes(struct repository *r,
50485048
* We need to update the squash message to skip
50495049
* the latest commit message.
50505050
*/
5051+
int res = 0;
50515052
struct commit *commit;
5053+
const char *msg;
50525054
const char *path = rebase_path_squash_msg();
50535055
const char *encoding = get_commit_output_encoding();
50545056

5055-
if (parse_head(r, &commit) ||
5056-
!(p = repo_logmsg_reencode(r, commit, NULL, encoding)) ||
5057-
write_message(p, strlen(p), path, 0)) {
5058-
repo_unuse_commit_buffer(r, commit, p);
5059-
return error(_("could not write file: "
5057+
if (parse_head(r, &commit))
5058+
return error(_("could not parse HEAD"));
5059+
5060+
p = repo_logmsg_reencode(r, commit, NULL, encoding);
5061+
if (!p) {
5062+
res = error(_("could not parse commit %s"),
5063+
oid_to_hex(&commit->object.oid));
5064+
goto unuse_commit_buffer;
5065+
}
5066+
find_commit_subject(p, &msg);
5067+
if (write_message(msg, strlen(msg), path, 0)) {
5068+
res = error(_("could not write file: "
50605069
"'%s'"), path);
5070+
goto unuse_commit_buffer;
50615071
}
5062-
repo_unuse_commit_buffer(r,
5063-
commit, p);
5072+
unuse_commit_buffer:
5073+
repo_unuse_commit_buffer(r, commit, p);
5074+
if (res)
5075+
return res;
50645076
}
50655077
}
50665078

t/t3418-rebase-continue.sh

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,23 @@ test_expect_success '--skip after failed fixup cleans commit message' '
115115
test_when_finished "test_might_fail git rebase --abort" &&
116116
git checkout -b with-conflicting-fixup &&
117117
test_commit wants-fixup &&
118-
test_commit "fixup! wants-fixup" wants-fixup.t 1 wants-fixup-1 &&
119-
test_commit "fixup! wants-fixup" wants-fixup.t 2 wants-fixup-2 &&
120-
test_commit "fixup! wants-fixup" wants-fixup.t 3 wants-fixup-3 &&
118+
test_commit "fixup 1" wants-fixup.t 1 wants-fixup-1 &&
119+
test_commit "fixup 2" wants-fixup.t 2 wants-fixup-2 &&
120+
test_commit "fixup 3" wants-fixup.t 3 wants-fixup-3 &&
121121
test_must_fail env FAKE_LINES="1 fixup 2 squash 4" \
122122
git rebase -i HEAD~4 &&
123123
124124
: now there is a conflict, and comments in the commit message &&
125-
git show HEAD >out &&
126-
grep "fixup! wants-fixup" out &&
125+
test_commit_message HEAD <<-\EOF &&
126+
# This is a combination of 2 commits.
127+
# This is the 1st commit message:
128+
129+
wants-fixup
130+
131+
# The commit message #2 will be skipped:
132+
133+
# fixup 1
134+
EOF
127135
128136
: skip and continue &&
129137
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' '
133141
test_path_is_missing .git/copy.txt &&
134142
135143
: now the comments in the commit message should have been cleaned up &&
136-
git show HEAD >out &&
137-
! grep "fixup! wants-fixup" out &&
144+
test_commit_message HEAD -m wants-fixup &&
138145
139146
: now, let us ensure that "squash" is handled correctly &&
140147
git reset --hard wants-fixup-3 &&
141-
test_must_fail env FAKE_LINES="1 squash 4 squash 2 squash 4" \
148+
test_must_fail env FAKE_LINES="1 squash 2 squash 1 squash 3 squash 1" \
142149
git rebase -i HEAD~4 &&
143150
144-
: the first squash failed, but there are two more in the chain &&
151+
: the second squash failed, but there are two more in the chain &&
145152
(test_set_editor "$PWD/copy-editor.sh" &&
146153
test_must_fail git rebase --skip) &&
147154
148155
: not the final squash, no need to edit the commit message &&
149156
test_path_is_missing .git/copy.txt &&
150157
151-
: The first squash was skipped, therefore: &&
152-
git show HEAD >out &&
153-
test_i18ngrep "# This is a combination of 2 commits" out &&
154-
test_i18ngrep "# This is the commit message #2:" out &&
158+
: The first and third squashes succeeded, therefore: &&
159+
test_commit_message HEAD <<-\EOF &&
160+
# This is a combination of 3 commits.
161+
# This is the 1st commit message:
162+
163+
wants-fixup
164+
165+
# This is the commit message #2:
166+
167+
fixup 1
168+
169+
# This is the commit message #3:
170+
171+
fixup 2
172+
EOF
155173
156174
(test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
157-
git show HEAD >out &&
158-
test_i18ngrep ! "# This is a combination" out &&
175+
test_commit_message HEAD <<-\EOF &&
176+
wants-fixup
177+
178+
fixup 1
179+
180+
fixup 2
181+
EOF
159182
160183
: Final squash failed, but there was still a squash &&
161-
test_i18ngrep "# This is a combination of 2 commits" .git/copy.txt &&
162-
test_i18ngrep "# This is the commit message #2:" .git/copy.txt
184+
head -n1 .git/copy.txt >first-line &&
185+
test_i18ngrep "# This is a combination of 3 commits" first-line &&
186+
test_i18ngrep "# This is the commit message #3:" .git/copy.txt
163187
'
164188

165189
test_expect_success 'setup rerere database' '

t/t3437-rebase-fixup-options.sh

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,6 @@ TEST_PASSES_SANITIZE_LEAK=true
2121

2222
EMPTY=""
2323

24-
# test_commit_message <rev> -m <msg>
25-
# test_commit_message <rev> <path>
26-
# Verify that the commit message of <rev> matches
27-
# <msg> or the content of <path>.
28-
test_commit_message () {
29-
git show --no-patch --pretty=format:%B "$1" >actual &&
30-
case "$2" in
31-
-m)
32-
echo "$3" >expect &&
33-
test_cmp expect actual ;;
34-
*)
35-
test_cmp "$2" actual ;;
36-
esac
37-
}
38-
3924
get_author () {
4025
rev="$1" &&
4126
git log -1 --pretty=format:"%an %ae %at" "$rev"

t/test-lib-functions.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,39 @@ test_cmp_rev () {
12911291
fi
12921292
}
12931293

1294+
# Tests that a commit message matches the expected text
1295+
#
1296+
# Usage: test_commit_message <rev> [-m <msg> | <file>]
1297+
#
1298+
# When using "-m" <msg> will have a line feed appended. If the second
1299+
# argument is omitted then the expected message is read from stdin.
1300+
1301+
test_commit_message () {
1302+
local msg_file=expect.msg
1303+
1304+
case $# in
1305+
3)
1306+
if test "$2" = "-m"
1307+
then
1308+
printf "%s\n" "$3" >"$msg_file"
1309+
else
1310+
BUG "Usage: test_commit_message <rev> [-m <message> | <file>]"
1311+
fi
1312+
;;
1313+
2)
1314+
msg_file="$2"
1315+
;;
1316+
1)
1317+
cat >"$msg_file"
1318+
;;
1319+
*)
1320+
BUG "Usage: test_commit_message <rev> [-m <message> | <file>]"
1321+
;;
1322+
esac
1323+
git show --no-patch --pretty=format:%B "$1" -- >actual.msg &&
1324+
test_cmp "$msg_file" actual.msg
1325+
}
1326+
12941327
# Compare paths respecting core.ignoreCase
12951328
test_cmp_fspath () {
12961329
if test "x$1" = "x$2"

0 commit comments

Comments
 (0)