thunderbird-patch-review
Easy-to-use patch review interface for Thunderbird
Contribute: ~marcc/thunderbird-review-plugin@lists.sr.ht
git clone git://mccd.space/thunderbird-patch-review
| Log | Files | Refs | README | LICENSE |
commit b8ab32ae75bafc8224bcd1317f468a16d1103467 parent ac9de41f8a07dfe3a659abfc604305ba4c9f3281 Author: Pi Agent <agent@pi.local> Date: Sat, 18 Jul 2026 13:06:49 +0200 diff-parse: strip git format-patch mbox header block from commit message git format-patch prepends an mbox-style header to the body (the 'From <sha> Mon Sep 17 00:00:00 2001' From_ line followed by From:, Date:, Subject:, then a blank). The review UI now renders author and subject in its own header, so keeping that block in the parsed commitMessage duplicated the From:/Subject: lines above the real message text. Detect the mbox From_ line by its fixed 'Mon Sep 17 00:00:00 2001' timestamp and drop the header block up to the first blank line, leaving only the real commit message. formatReview does not use commitMessage, so stripping is safe. Diffstat:
| M | extension/modules/diff-parse.js | | | 13 | ++++++++++++- |
| M | tests/run.mjs | | | 31 | +++++++++++++++++++++++++++++++ |
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/extension/modules/diff-parse.js b/extension/modules/diff-parse.js
@@ -45,7 +45,18 @@ export function parsePatchEmail(text) {
}
}
const messageEnd = scissors === -1 ? firstDiff : scissors;
- result.commitMessage = bodyLines.slice(0, messageEnd).join("\n").trim();
+ // git format-patch prepends an mbox-style header block to the body
+ // ("From <sha> Mon Sep 17 ...", From:, Date:, Subject:, then a blank
+ // line). The UI shows author and subject separately, so drop that
+ // block to keep only the real commit message text. reply-format does
+ // not use commitMessage, so stripping is safe.
+ let messageStart = 0;
+ if (messageEnd > 0 && /^From .*Mon Sep 17 00:00:00 2001$/.test(bodyLines[0])) {
+ let blank = 1;
+ while (blank < messageEnd && bodyLines[blank] !== "") blank++;
+ messageStart = Math.min(blank + 1, messageEnd);
+ }
+ result.commitMessage = bodyLines.slice(messageStart, messageEnd).join("\n").trim();
if (scissors !== -1) {
result.diffstat = bodyLines.slice(scissors + 1, firstDiff).join("\n").trim();
}
diff --git a/tests/run.mjs b/tests/run.mjs
@@ -142,6 +142,37 @@ function check(name, cond, extra = "") {
check("parse: scissors-first diffstat", p.diffstat.includes("1 file changed"));
}
+{
+ // git format-patch prepends an mbox-style header block to the body; the
+ // UI renders author/subject separately, so the parser must drop that
+ // block and keep only the real commit message.
+ const body = [
+ "From 0123456789abcdef0123456789abcdef01234567 Mon Sep 17 00:00:00 2001",
+ "From: Author Name <author@example.com>",
+ "Date: Thu, 1 Jan 2026 00:00:00 +0000",
+ "Subject: [PATCH] fix a bug",
+ "",
+ "This is the actual commit message.",
+ "",
+ "---",
+ " file.txt | 1 +",
+ " 1 file changed, 1 insertion(+)",
+ "",
+ "diff --git a/file.txt b/file.txt",
+ "index e69de29..8baef1b 100644",
+ "--- a/file.txt",
+ "+++ b/file.txt",
+ "@@ -0,0 +1 @@",
+ "+hello",
+ "-- ",
+ "2.45.0",
+ "",
+ ].join("\n");
+ const p = parsePatchEmail(body);
+ check("parse: format-patch header stripped", p.commitMessage === "This is the actual commit message.", JSON.stringify(p.commitMessage));
+ check("parse: format-patch diff still parsed", p.files.length === 1);
+}
+
// --- sourcehut detection ----------------------------------------------------
{