From: Phillip Wood Date: Fri, 13 Feb 2026 14:34:47 GMT Subject: [PATCH v2 0/2] commit-msg.sample: reject messages that would confuse "git am" Message-ID: In-Reply-To: <20260206090358.GA2761602@coredump.intra.peff.net> From: Phillip Wood This series adds a check to the sample commit-msg hook to reject commit messages where the body of the message contains lines starting with "diff -" and "Index: ". Such lines confuse "git am". Changes since V1: - Allow subjects to start with "diff -" as they end up in an email header and so do not confuse "git am" - Allow "---" lines as they are useful when preparing patches. Base-Commit: b2826b52eb7caff9f4ed6e85ec45e338bf02ad09 Published-As: https://github.com/phillipwood/git/releases/tag/pw%2Fsample-commit-msg-reject-diff%2Fv2 View-Changes-At: https://github.com/phillipwood/git/compare/b2826b52e...494f4df68 Fetch-It-Via: git fetch https://github.com/phillipwood/git pw/sample-commit-msg-reject-diff/v2 Phillip Wood (2): templates: add .gitattributes entry for sample hooks templates: detect commit messages containing diffs .editorconfig | 2 +- .gitattributes | 1 + templates/hooks/commit-msg.sample | 54 +++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 3 deletions(-) Range-diff against v1: 1: 5f5e3091435 = 1: 5f5e3091435 templates: add .gitattributes entry for sample hooks 2: e75978b9591 ! 2: 494f4df6865 templates: detect commit messages containing diffs @@ Metadata ## Commit message ## templates: detect commit messages containing diffs - If a commit message contains a diff that is not indented then "git - am" will treat that diff as part of the patch rather than as part - of the commit message. This allows it to apply email messages that - were created by adding a commit message in front of a regular diff + If the body of a commit message contains a diff that is not indented + then "git am" will treat that diff as part of the patch rather than + as part of the commit message. This allows it to apply email messages + that were created by adding a commit message in front of a regular diff without adding the "---" separator used by "git format-patch". This often surprises users [1-4] so add a check to the sample "commit-msg" - hook to reject messages that would confuse "git am". - - Detecting if the message contains a diff is complicated by the hook - being passed the message before it is cleaned up so we need to ignore - any diffs below the scissors line. There are also two possible - config keys to check to find the comment character at the start - of the scissors line. + hook to reject messages that would confuse "git am". Even if a project + does not use an email based workflow it is not uncommon for people + to generate patches from it and apply them with "git am". Therefore + it is still worth discouraging the creation of commit messages that + would not be applied correctly. + + A further source of confusion when applying patches with "git am" is + the "---" separator that is added by "git format patch". If a commit + message body contains that line then it will be truncated by "git am". + As this is often used by patch authors to add some commentary that + they do not want to end up in the commit message when the patch is + applied, the hook does not complain about the presence of "---" lines + in the message. + + Detecting if the message contains a diff is complicated by the + hook being passed the message before it is cleaned up so we need to + ignore any diffs below the scissors line. There are also two possible + config keys to check to find the comment character at the start of + the scissors line. The first paragraph of the commit message becomes + the email subject header which beings "Subject: " and so does not + need to be checked. The trailing ".*" when matching commented lines + ensures that if the comment string ends with a "$" it is not treated + as an anchor. [1] https://lore.kernel.org/git/bcqvh7ahjjgzpgxwnr4kh3hfkksfruf54refyry3ha7qk7dldf@fij5calmscvm [2] https://lore.kernel.org/git/ca13705ae4817ffba16f97530637411b59c9eb19.camel@scientia.org/ @@ templates/hooks/commit-msg.sample + p + }' +)" -+line="$(sed -n -e "/^${comment_re} -\{8,\} >8 -\{8,\}\$/q -+ /^diff -/{p;q;} -+ /^Index: /{p;q;}" "$1")" ++scissors_line="^${comment_re} -\{8,\} >8 -\{8,\}\$" ++comment_line="^${comment_re}.*" ++blank_line='^[ ]*$' ++# Disallow lines starting with "diff -" or "Index: " in the body of the ++# message. Stop looking if we see a scissors line. ++line="$(sed -n -e " ++ # Skip comments and blank lines at the start of the file. ++ /${scissors_line}/q ++ /${comment_line}/d ++ /${blank_line}/d ++ # The first paragraph will become the subject header so ++ # does not need to be checked. ++ : subject ++ n ++ /${scissors_line}/q ++ /${blank_line}/!b subject ++ # Check the body of the message for problematic ++ # prefixes. ++ : body ++ n ++ /${scissors_line}/q ++ /${comment_line}/b body ++ /^diff -/{p;q;} ++ /^Index: /{p;q;} ++ b body ++ " "$1")" +if test -n "$line" +then + echo >&2 "Message contains a diff that will confuse 'git am'." 3: 83c100a73ec < -: ----------- templates: detect messages that contain a separator line -- 2.52.0.362.g884e03848a9