doc: add caveat about round-tripping format-patch

git-format-patch(1) and git-am(1) deal with formatting commits as patches and applying them, respectively. Naturally they use a few delimiters to mark where the commit message ends. This can lead to surprising behavior when these delimiters are used in the commit message itself. git-format-patch(1) will accept any commit message and not warn or error about these delimiters being used.[1] Especially problematic is the presence of unindented diffs in the commit message; the patch machinery will naturally (since the commit message has ended) try to apply that diff and everything after it.[2] It is unclear whether any commands in this chain will learn to warn about this. One concern could be that users have learned to rely on the three-dash line rule to conveniently add extra-commit message information in the commit message, knowing that git-am(1) will ignore it.[4] All of this is covered already, technically. However, we should spell out the implications. † 1: There is also git-commit(1) to consider. However, making that command warn or error out over such delimiters would be disruptive to all Git users who never use email in their workflow. † 2: Recently patch(1) caused this issue for a project, but it was noted that git-am(1) has the same behavior[3] † 3: https://github.com/i3/i3/pull/6564#issuecomment-3858381425 † 4: https://lore.kernel.org/git/xmqqldh4b5y2.fsf@gitster.g/ https://lore.kernel.org/git/V3_format-patch_caveats.354@msgid.xyz/ Reported-by: Matthias Beyer <mail@beyermatthias.de> Reported-by: Christoph Anton Mitterer <calestyo@scientia.org> Reported-by: Matheus Tavares <matheus.tavb@gmail.com> Reported-by: Chris Packham <judge.packham@gmail.com> Helped-by: Jakob Haufe <sur5r@sur5r.net> Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kristoffer Haugsbakk committed Feb 12, 2026 at 23:28 UTC a454cdca42fda0afaade73d7e90010289d1e7ba8
5 files changed +62 -7
Documentation/format-patch-caveats.adoc new
+33
@@ -0,0 +1,33 @@
1 +The output from linkgit:git-format-patch[1] can lead to a different
2 +commit message when applied with linkgit:git-am[1]. The patch that is
3 +applied may also be different from the one that was generated, or patch
4 +application may fail outright.
5 +ifdef::git-am[]
6 +See the <<discussion,DISCUSSION>> section above for the syntactic rules.
7 +endif::git-am[]
8 +
9 +ifndef::git-am[]
10 +include::format-patch-end-of-commit-message.adoc[]
11 +endif::git-am[]
12 +
13 +Note that this is especially problematic for unindented diffs that occur
14 +in the commit message; the diff in the commit message might get applied
15 +along with the patch section, or the patch application machinery might
16 +trip up because the patch target doesn't apply. This could for example
17 +be caused by a diff in a Markdown code block.
18 +
19 +The solution for this is to indent the diff or other text that could
20 +cause problems.
21 +
22 +This loss of fidelity might be simple to notice if you are applying
23 +patches directly from a mailbox. However, changes originating from Git
24 +could be applied in bulk, in which case this would be much harder to
25 +notice. This could for example be a Linux distribution which uses patch
26 +files to apply changes on top of the commits from the upstream
27 +repositories. This goes to show that this behavior does not only impact
28 +email workflows.
29 +
30 +Given these limitations, one might be tempted to use a general-purpose
31 +utility like patch(1) instead. However, patch(1) will not only look for
32 +unindented diffs (like linkgit:git-am[1]) but will try to apply indented
33 +diffs as well.
Documentation/format-patch-end-of-commit-message.adoc new
+8
@@ -0,0 +1,8 @@
1 +Any line that is of the form:
2 +
3 +* three-dashes and end-of-line, or
4 +* a line that begins with "diff -", or
5 +* a line that begins with "Index: "
6 +
7 +is taken as the beginning of a patch, and the commit log message
8 +is terminated before the first occurrence of such a line.
Documentation/git-am.adoc
+12 -7
@@ -233,6 +233,7 @@ applying.
233 create an empty commit with the contents of the e-mail message
234 as its log message.
235
236 +[[discussion]]
237 DISCUSSION
238 ----------
239
@@ -252,14 +253,11 @@ where the patch begins. Excess whitespace at the end of each
253 line is automatically stripped.
254
255 The patch is expected to be inline, directly following the
255 -message. Any line that is of the form:
256 +message.
257 +include::format-patch-end-of-commit-message.adoc[]
258
257 -* three-dashes and end-of-line, or
258 -* a line that begins with "diff -", or
259 -* a line that begins with "Index: "
260 -
261 -is taken as the beginning of a patch, and the commit log message
262 -is terminated before the first occurrence of such a line.
259 +This means that the contents of the commit message can inadvertently
260 +interrupt the processing (see the <<caveats,CAVEATS>> section below).
261
262 When initially invoking `git am`, you give it the names of the mailboxes
263 to process. Upon seeing the first patch that does not apply, it
@@ -283,6 +281,13 @@ commits, like running 'git am' on the wrong branch or an error in the
281 commits that is more easily fixed by changing the mailbox (e.g.
282 errors in the "From:" lines).
283
284 +[[caveats]]
285 +CAVEATS
286 +-------
287 +
288 +:git-am: 1
289 +include::format-patch-caveats.adoc[]
290 +
291 HOOKS
292 -----
293 This command can run `applypatch-msg`, `pre-applypatch`,
Documentation/git-format-patch.adoc
+4
@@ -798,6 +798,10 @@ if they are part of the requested range. A simple "patch" does not
798 include enough information for the receiving end to reproduce the same
799 merge commit.
800
801 +=== PATCH APPLICATION
802 +
803 +include::format-patch-caveats.adoc[]
804 +
805 SEE ALSO
806 --------
807 linkgit:git-am[1], linkgit:git-send-email[1]
Documentation/git-send-email.adoc
+5
@@ -692,6 +692,11 @@ Links of a few such community maintained helpers are:
692 - https://github.com/AdityaGarg8/git-credential-email[git-msgraph]
693 (cross platform client that can send emails using the Microsoft Graph API)
694
695 +CAVEATS
696 +-------
697 +
698 +include::format-patch-caveats.adoc[]
699 +
700 SEE ALSO
701 --------
702 linkgit:git-format-patch[1], linkgit:git-imap-send[1], mbox(5)