Skip to content

Commit aeb53c0

Browse files
fix(git-extension): trim trailing whitespace before stripping commit-message quotes
The auto-commit bash and Python twins strip a leading/trailing quote from the configured `message:` value with an end-of-string-anchored quote strip. When the YAML value has trailing whitespace after the closing quote (`message: "Done" `), the close-quote strip is anchored to end-of-string, so it never matches the quote (spaces follow it). The commit message then keeps a dangling quote and trailing spaces (`Done" `). The PowerShell twin already .Trim()s before stripping, so it produced the clean `Done`. This left the three script variants out of parity. Trim the value before stripping quotes in the bash and Python twins so all three agree. Verified at the exact-code level: the old bash sed pipeline yields `spec done" ` and the new one `spec done`; the Python _strip_quotes matches. Add a parity regression test with trailing whitespace after the closing quote (runs under CI where Git bash is resolvable).
1 parent d7699c3 commit aeb53c0

3 files changed

Lines changed: 41 additions & 2 deletions

File tree

extensions/git/scripts/bash/auto-commit.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@ if [ -f "$_config_file" ]; then
9494
[ "$_val" = "false" ] && _enabled=false
9595
fi
9696
if echo "$_line" | grep -Eq '[[:space:]]+message:'; then
97-
_commit_msg=$(echo "$_line" | sed 's/^[^:]*:[[:space:]]*//' | sed 's/^["'\'']//' | sed 's/["'\'']*$//')
97+
# Trim trailing whitespace before stripping the closing quote:
98+
# a value like `message: "Done" ` (trailing spaces after the
99+
# quote) would otherwise leave the quote dangling (`Done" `),
100+
# since the closing-quote strip is anchored to end-of-string.
101+
# The PowerShell twin .Trim()s first; match it for parity.
102+
_commit_msg=$(echo "$_line" | sed 's/^[^:]*:[[:space:]]*//' | sed 's/[[:space:]]*$//' | sed 's/^["'\'']//' | sed 's/["'\'']*$//')
98103
fi
99104
fi
100105
fi

extensions/git/scripts/python/auto_commit.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@ def _value_after_colon(line: str) -> str:
3333

3434

3535
def _strip_quotes(value: str) -> str:
36-
"""Strip one leading quote and all trailing quotes, mirroring the bash sed."""
36+
"""Strip surrounding whitespace, then one leading quote and all trailing quotes.
37+
38+
Trimming first matters when the YAML value has trailing whitespace after a
39+
closing quote (``message: "Done" ``): stripping quotes anchored to the end
40+
of string would leave the closing quote dangling (``Done" ``) because the
41+
quote is no longer at the end. The PowerShell twin ``.Trim()``s before
42+
stripping, so trim here too to keep all three script variants in parity.
43+
"""
44+
value = value.strip()
3745
value = re.sub(r"^[\"']", "", value)
3846
return re.sub(r"[\"']*$", "", value)
3947

tests/extensions/git/test_git_extension_python_parity.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,32 @@ def test_enabled_per_command_with_custom_message(self, tmp_path: Path):
515515
assert p.stderr.strip() == b.stderr.strip()
516516
assert self._last_message(bash_proj) == self._last_message(py_proj) == "spec done"
517517

518+
def test_custom_message_with_trailing_whitespace_after_quote(self, tmp_path: Path):
519+
"""Trailing whitespace after a closing quote must not leave the quote
520+
dangling in the commit message. A raw close-quote strip anchored to
521+
end-of-string skips the quote when spaces follow it (``spec done" ``);
522+
trimming first (matching the PowerShell twin) yields a clean message and
523+
keeps bash/python in parity."""
524+
bash_proj, py_proj = _twin_projects(tmp_path)
525+
config = (
526+
"auto_commit:\n"
527+
" default: false\n"
528+
" after_specify:\n"
529+
" enabled: true\n"
530+
' message: "spec done" \n' # trailing spaces after the closing quote
531+
)
532+
for proj in (bash_proj, py_proj):
533+
_write_config(proj, config)
534+
self._dirty(proj)
535+
b = _run_bash("auto-commit.sh", bash_proj, "after_specify")
536+
p = _run_py("auto-commit", py_proj, "after_specify")
537+
_assert_parity(b, p)
538+
assert (
539+
self._last_message(bash_proj)
540+
== self._last_message(py_proj)
541+
== "spec done"
542+
)
543+
518544
def test_default_true_applies_to_unlisted_event(self, tmp_path: Path):
519545
bash_proj, py_proj = _twin_projects(tmp_path)
520546
for proj in (bash_proj, py_proj):

0 commit comments

Comments
 (0)