commit: avoid scanning trailing comments when 'core.commentChar' is "auto"
When core.commentChar is set to "auto", Git selects a comment character by scanning the commit message contents and avoiding any character already present in the message. If the message still contains old conflict comments (starting with a comment character), Git assumes that character is in use and chooses a different one. As a result, those existing comment lines are no longer recognized as comments and end up being included in the final commit message. To avoid this, skip scanning the trailing comment block when selecting the comment character. This allows Git to safely reuse the original character when appropriate, keeping the commit message clean and free of leftover conflict information. Background: The "auto" value for core.commentchar was introduced in the commit84c9dc2c5a(commit: allow core.commentChar=auto for character auto selection, 2014-05-17) but did not exhibit this issue at that time. The bug was introduced in commita6c2654f83(rebase -m: fix --signoff with conflicts, 2024-04-18) where Git started writing conflict comments to the file at 'rebase_path_message()'. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Ghanshyam Thakkar <shyamthakkar001@gmail.com> Signed-off-by: Ayush Chandekar <ayu.chandekar@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
16bd9f20a4
commit
e69bbfa294
@@ -688,6 +688,10 @@ static void adjust_comment_line_char(const struct strbuf *sb)
|
||||
char candidates[] = "#;@!$%^&|:";
|
||||
char *candidate;
|
||||
const char *p;
|
||||
size_t cutoff;
|
||||
|
||||
/* Ignore comment chars in trailing comments (e.g., Conflicts:) */
|
||||
cutoff = sb->len - ignored_log_message_bytes(sb->buf, sb->len);
|
||||
|
||||
if (!memchr(sb->buf, candidates[0], sb->len)) {
|
||||
free(comment_line_str_to_free);
|
||||
@@ -700,7 +704,7 @@ static void adjust_comment_line_char(const struct strbuf *sb)
|
||||
candidate = strchr(candidates, *p);
|
||||
if (candidate)
|
||||
*candidate = ' ';
|
||||
for (p = sb->buf; *p; p++) {
|
||||
for (p = sb->buf; p + 1 < sb->buf + cutoff; p++) {
|
||||
if ((p[0] == '\n' || p[0] == '\r') && p[1]) {
|
||||
candidate = strchr(candidates, p[1]);
|
||||
if (candidate)
|
||||
|
||||
@@ -328,6 +328,19 @@ test_expect_success 'there is no --no-reschedule-failed-exec in an ongoing rebas
|
||||
test_expect_code 129 git rebase --edit-todo --no-reschedule-failed-exec
|
||||
'
|
||||
|
||||
test_expect_success 'no change in comment character due to conflicts markers with core.commentChar=auto' '
|
||||
git checkout -b branch-a &&
|
||||
test_commit A F1 &&
|
||||
git checkout -b branch-b HEAD^ &&
|
||||
test_commit B F1 &&
|
||||
test_must_fail git rebase branch-a &&
|
||||
printf "B\nA\n" >F1 &&
|
||||
git add F1 &&
|
||||
GIT_EDITOR="cat >actual" git -c core.commentChar=auto rebase --continue &&
|
||||
# Check that "#" is still the comment character.
|
||||
test_grep "^# Changes to be committed" actual
|
||||
'
|
||||
|
||||
test_orig_head_helper () {
|
||||
test_when_finished 'git rebase --abort &&
|
||||
git checkout topic &&
|
||||
|
||||
Reference in New Issue
Block a user