Files
git/Documentation/format-patch-caveats.adoc
Kristoffer Haugsbakk a454cdca42 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>
2026-02-12 14:37:56 -08:00

34 lines
1.5 KiB
Plaintext

The output from linkgit:git-format-patch[1] can lead to a different
commit message when applied with linkgit:git-am[1]. The patch that is
applied may also be different from the one that was generated, or patch
application may fail outright.
ifdef::git-am[]
See the <<discussion,DISCUSSION>> section above for the syntactic rules.
endif::git-am[]
ifndef::git-am[]
include::format-patch-end-of-commit-message.adoc[]
endif::git-am[]
Note that this is especially problematic for unindented diffs that occur
in the commit message; the diff in the commit message might get applied
along with the patch section, or the patch application machinery might
trip up because the patch target doesn't apply. This could for example
be caused by a diff in a Markdown code block.
The solution for this is to indent the diff or other text that could
cause problems.
This loss of fidelity might be simple to notice if you are applying
patches directly from a mailbox. However, changes originating from Git
could be applied in bulk, in which case this would be much harder to
notice. This could for example be a Linux distribution which uses patch
files to apply changes on top of the commits from the upstream
repositories. This goes to show that this behavior does not only impact
email workflows.
Given these limitations, one might be tempted to use a general-purpose
utility like patch(1) instead. However, patch(1) will not only look for
unindented diffs (like linkgit:git-am[1]) but will try to apply indented
diffs as well.