From 69cdff28e0ff91e2a340ecb300145462182eab9b Mon Sep 17 00:00:00 2001 From: L4XB Date: Fri, 23 Oct 2026 04:13:06 +0200 Subject: [PATCH] fix(hooks): treat only backslash-LF as a line continuation in a commit message Bash removes a backslash before a newline, but not one before a carriage return. Removing backslash-CRLF joined two lines of the message, and their text was then read as the subject. --- scripts/hooks/pre-bash-commit-quality.js | 2 +- tests/hooks/pre-bash-commit-quality.test.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/hooks/pre-bash-commit-quality.js b/scripts/hooks/pre-bash-commit-quality.js index ac06203d1..7869a6993 100644 --- a/scripts/hooks/pre-bash-commit-quality.js +++ b/scripts/hooks/pre-bash-commit-quality.js @@ -206,7 +206,7 @@ function validateCommitMessage(command) { : null; // In double quotes, Bash drops the backslash before $ ` " \ and drops a backslash-newline, // a line continuation, altogether. Before any other character the backslash stays. - const doubleQuoted = messageMatch[1]?.replace(/\\(\r?\n|[$`"\\])/g, (escape, next) => (next.endsWith('\n') ? '' : next)); + const doubleQuoted = messageMatch[1]?.replace(/\\([\n$`"\\])/g, (escape, next) => (next === '\n' ? '' : next)); const message = heredoc ?? doubleQuoted ?? messageMatch[2] ?? messageMatch[3]; // The format rules apply to the subject: git drops leading blank lines and trailing // whitespace, and the first line left is the subject. diff --git a/tests/hooks/pre-bash-commit-quality.test.js b/tests/hooks/pre-bash-commit-quality.test.js index c5653e57d..faa14c932 100644 --- a/tests/hooks/pre-bash-commit-quality.test.js +++ b/tests/hooks/pre-bash-commit-quality.test.js @@ -531,7 +531,9 @@ if (test('drops a line continuation from a double-quoted message, as Bash does', assert.deepStrictEqual(res.issues, []); // An escaped backslash before a newline is one backslash, and the newline stays assert.strictEqual(hook.validateCommitMessage('git commit -m "fix: path C:\\\\\nbody"').message, 'fix: path C:\\\nbody'); - // Bash removes the backslash only before $ ` " \ and a newline + // Bash removes the backslash only before $ ` " \ and a newline; before a CR it stays + assert.strictEqual(hook.validateCommitMessage('git commit -m "fix: keep path\\\r\nbody."').message, 'fix: keep path\\\r\nbody.'); + assert.deepStrictEqual(hook.validateCommitMessage('git commit -m "fix: keep path\\\r\nbody."').issues, []); assert.strictEqual(hook.validateCommitMessage('git commit -m "fix: cost \\$5 in \\d+ steps"').message, 'fix: cost $5 in \\d+ steps'); })) passed++; else failed++;