git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 2/2] templates: detect commit messages containing diffs

From
Junio C Hamano <gitster@pobox.com>
Date
Feb 13, 2026, 17:59 UTC
Message-ID
<xmqqfr74msm9.fsf@gitster.g>
In-Reply-To
<494f4df6865f81eba42584ead81327c9a305d0d4.1770993281.git.phillip.wood@dunelm.org.uk>
Phillip Wood <phillip.wood123@gmail.com> writes:
Show 21 quoted lines
> From: Phillip Wood <phillip.wood@dunelm.org.uk>
>
> 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". 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.
"git format match" -> "git format-patch".
> 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.

Sorry, but I do not quite understand the logic here. In e-mailed messages, the way the scissors line is most commonly used is to have something like this.

	Hi, I read your problem report, and I think what is going on
	is ... (lengthy discussion here).
	Can you try this patch?
	--- >8 ---
	Subject: frotz: try working around nitfol
	As we cannot easily tell if the gostak will distim these
	patciular doshes, let's be careful to see ...
	diff - will be used to confuse the mailinfo
	Signed-off-by: a.u.thour
	---
	(diffstat here)
	(patch here)

and "diff - will be used to confuse" is something we would want to notice. But I am not sure if the use case of committing a scissors line. You help those who write a three-dash line and materials meant to be kept outside of the final commit at the end, so if is this an attempt to help those who write a scissors line and materials meant to be kept outside of the final commit at the beginning, I can understand, but then don't you want to notice "diff -" that appears after the scissors line? I do not offhand remember what happens to a "diff -" that appears before the scissors (i.e., if you write "diff -" before "Can you try this patch?"), but I wouldn't be surprised if mailinfo stopped there long before it sees the scissors.

> There are also two possible
> config keys to check to find the comment character at the start of
> the scissors line.
Also I do not think scissors requires to be a comment.
So, I am a bit confused.
> The first paragraph of the commit message becomes
> the email subject header which beings "Subject: " and so does not
> need to be checked.
Great.
> The trailing ".*" when matching commented lines
> ensures that if the comment string ends with a "$" it is not treated
> as an anchor.
I am not sure what this means.  Wouldn't these three
	sed -e '/^#/d'
	sed -e '/^#.*/d'
	sed -e '/^#.*$/d'
work exactly the same way?
Thanks.
Show 77 quoted lines
> [1] https://lore.kernel.org/git/bcqvh7ahjjgzpgxwnr4kh3hfkksfruf54refyry3ha7qk7dldf@fij5calmscvm
> [2] https://lore.kernel.org/git/ca13705ae4817ffba16f97530637411b59c9eb19.camel@scientia.org/
> [3] https://lore.kernel.org/git/d0b577825124ac684ab304d3a1395f3d2d0708e8.1662333027.git.matheus.bernardino@usp.br/
> [4] https://lore.kernel.org/git/CAFOYHZC6Qd9wkoWPcTJDxAs9u=FGpHQTkjE-guhwkya0DRVA6g@mail.gmail.com/
>
> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
> ---
>  templates/hooks/commit-msg.sample | 54 +++++++++++++++++++++++++++++--
>  1 file changed, 52 insertions(+), 2 deletions(-)
>
> diff --git a/templates/hooks/commit-msg.sample b/templates/hooks/commit-msg.sample
> index b58d1184a9d..f7458efe62f 100755
> --- a/templates/hooks/commit-msg.sample
> +++ b/templates/hooks/commit-msg.sample
> @@ -15,10 +15,60 @@
>  # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
>  # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
>  
> -# This example catches duplicate Signed-off-by lines.
> +# This example catches duplicate Signed-off-by lines and messages that
> +# would confuse 'git am'.
> +
> +ret=0
>  
>  test "" = "$(grep '^Signed-off-by: ' "$1" |
>  	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
>  	echo >&2 Duplicate Signed-off-by lines.
> -	exit 1
> +	ret=1
>  }
> +
> +comment_re="$(
> +	{
> +		git config --get-regexp "^core\.comment(char|string)\$" ||
> +			echo '#'
> +	} | sed -n -e '
> +		${
> +			s/^[^ ]* //
> +			s|[][*./\]|\\&|g
> +			s/^auto$/[#;@!$%^&|:]/
> +			p
> +		}'
> +)"
> +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'."
> +	echo >&2 "To fix this indent the diff."
> +	ret=1
> +fi
> +
> +exit $ret
Previous: Phillip WoodNext: Phillip Wood
Message 35 of 65 in “git-am applies commit message diffs”
  1. Matthias BeyerFeb 6, 2026
  2. Jacob KellerFeb 6, 2026
  3. Matthias BeyerFeb 6, 2026
  4. Jeff KingFeb 6, 2026
  5. 0/3 commit-msg.sample: reject messages that would confuse "git am"Phillip Wood, Feb 7, 2026
  6. 1/3 templates: add .gitattributes entry for sample hooksPhillip Wood, Feb 7, 2026
  7. 2/3 templates: detect commit messages containing diffsPhillip Wood, Feb 7, 2026
  8. 3/3 templates: detect messages that contain a separator linePhillip Wood, Feb 7, 2026
  9. Junio C HamanoFeb 7, 2026
  10. Kristoffer HaugsbakkFeb 7, 2026
  11. Junio C HamanoFeb 9, 2026
  12. Jeff KingFeb 9, 2026
  13. Phillip WoodFeb 9, 2026
  14. Jeff KingFeb 10, 2026
  15. Jeff KingFeb 9, 2026
  16. Phillip WoodFeb 9, 2026
  17. Matthias BeyerFeb 9, 2026
  18. Jeff KingFeb 10, 2026
  19. Patrick SteinhardtFeb 9, 2026
  20. Jacob KellerFeb 10, 2026
  21. Patrick SteinhardtFeb 10, 2026
  22. Junio C HamanoFeb 10, 2026
  23. Jacob KellerFeb 11, 2026
  24. Jacob KellerFeb 11, 2026
  25. Jeff KingFeb 11, 2026
  26. Kristoffer HaugsbakkFeb 11, 2026
  27. Junio C HamanoFeb 11, 2026
  28. Jeff KingFeb 10, 2026
  29. 0/2 commit-msg.sample: reject messages that would confuse "git am"Phillip Wood, Feb 13, 2026
  30. 1/2 templates: add .gitattributes entry for sample hooksPhillip Wood, Feb 13, 2026
  31. 2/2 templates: detect commit messages containing diffsPhillip Wood, Feb 13, 2026
  32. Kristoffer HaugsbakkFeb 13, 2026
  33. Junio C HamanoFeb 13, 2026
  34. Phillip WoodFeb 14, 2026
  35. Junio C HamanoFeb 13, 2026
  36. Phillip WoodFeb 14, 2026
  37. Junio C HamanoFeb 14, 2026
  38. Junio C HamanoFeb 13, 2026
  39. Florian WeimerFeb 6, 2026
  40. Jeff KingFeb 6, 2026
  41. Florian WeimerFeb 6, 2026
  42. Jeff KingFeb 6, 2026
  43. Kristoffer HaugsbakkFeb 6, 2026
  44. Jakob HaufeFeb 6, 2026
  45. Kristoffer HaugsbakkFeb 7, 2026
  46. Kristoffer HaugsbakkFeb 7, 2026
  47. doc: add caveat about roundtripping format-patchkristofferhaugsbakk@fastmail.com, Feb 8, 2026
  48. Junio C HamanoFeb 8, 2026
  49. Kristoffer HaugsbakkFeb 8, 2026
  50. Phillip WoodFeb 9, 2026
  51. Kristoffer HaugsbakkFeb 9, 2026
  52. Phillip WoodFeb 10, 2026
  53. Kristoffer HaugsbakkFeb 10, 2026
  54. doc: add caveat about roundtripping format-patchkristofferhaugsbakk@fastmail.com, Feb 9, 2026
  55. Junio C HamanoFeb 9, 2026
  56. Kristoffer HaugsbakkFeb 9, 2026
  57. Phillip WoodFeb 10, 2026
  58. Kristoffer HaugsbakkFeb 10, 2026
  59. doc: add caveat about round-tripping format-patchkristofferhaugsbakk@fastmail.com, Feb 12, 2026
  60. Junio C HamanoFeb 12, 2026
  61. Phillip WoodFeb 13, 2026
  62. Kristoffer HaugsbakkFeb 13, 2026
  63. Junio C HamanoFeb 13, 2026
  64. Christoph Anton MittererFeb 10, 2026
  65. Kristoffer HaugsbakkFeb 10, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.