Skip to content

Commit 556b3d8

Browse files
LemmingAvalanchegitster
authored andcommitted
doc: add caveat about roundtripping format-patch
git-format-patch(1), git-send-email(1), and git-am(1) deal with formatting commits as patches, sending them (perhaps directly), 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) and git-send-email(1) will accept any commit message and not warn or error about these delimiters being used.[1] Moreover, the presence of unindented diffs in the commit message will cause git-am(1) to apply both the diffs from the commit message as well as the patch section.[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]: i3/i3#6564 (comment) [4]: https://lore.kernel.org/git/xmqqldh4b5y2.fsf@gitster.g/ 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> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 67ad421 commit 556b3d8

4 files changed

Lines changed: 57 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Patches produced by linkgit:git-format-patch[1] or
2+
linkgit:git-send-email[1] are inline. This means that the output of
3+
these two commands can lead to a different commit message when applied
4+
with linkgit:git-am[1]. It can also mean that the patch is not applied
5+
correctly.
6+
7+
The commit message might contain a three-dash line (`---`) which was
8+
perhaps meant to be a thematic break. That means that the commit message
9+
will be cut short. The presence of a line starting with "Index: " can
10+
cause the patch not to be found, giving an error about an empty patch.
11+
12+
Furthermore, the presence of an unindented diff in the commit message
13+
will not only cut the message short but cause that very diff to be
14+
applied, along with the patch in the patch section. The commit message
15+
might for example have a diff in a GitHub MarkDown code fence:
16+
17+
----
18+
```
19+
diff ...
20+
```
21+
----
22+
23+
The solution for this is to indent the diff instead:
24+
25+
----
26+
diff ...
27+
----
28+
29+
This loss of fidelity might be simple to notice if you are applying
30+
patches directly from a mailbox. However, a commit authored long ago
31+
might be applied in a different context, perhaps because many changes
32+
are being integrated via patch files and the
33+
linkgit:git-format-patch[1] format is trusted to import changes of a
34+
Git origin.
35+
36+
One might want to use a general-purpose utility like patch(1) instead,
37+
given these limitations. However, patch(1) will not only look for
38+
unindented diffs (like linkgit:git-am[1]) but will try to apply indented
39+
diffs as well.

Documentation/git-am.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ message. Any line that is of the form:
261261
is taken as the beginning of a patch, and the commit log message
262262
is terminated before the first occurrence of such a line.
263263

264+
This means that the content of the commit message can inadverently
265+
interrupt the processing (see the <<caveats,CAVEATS>> section below).
266+
264267
When initially invoking `git am`, you give it the names of the mailboxes
265268
to process. Upon seeing the first patch that does not apply, it
266269
aborts in the middle. You can recover from this in one of two ways:
@@ -283,6 +286,12 @@ commits, like running 'git am' on the wrong branch or an error in the
283286
commits that is more easily fixed by changing the mailbox (e.g.
284287
errors in the "From:" lines).
285288

289+
[[caveats]]
290+
CAVEATS
291+
-------
292+
293+
include::format-patch-caveats.adoc[]
294+
286295
HOOKS
287296
-----
288297
This command can run `applypatch-msg`, `pre-applypatch`,

Documentation/git-format-patch.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,10 @@ if they are part of the requested range. A simple "patch" does not
798798
include enough information for the receiving end to reproduce the same
799799
merge commit.
800800
801+
'''
802+
803+
include::format-patch-caveats.adoc[]
804+
801805
SEE ALSO
802806
--------
803807
linkgit:git-am[1], linkgit:git-send-email[1]

Documentation/git-send-email.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,11 @@ Links of a few such community maintained helpers are:
692692
- https://github.com/AdityaGarg8/git-credential-email[git-msgraph]
693693
(cross platform client that can send emails using the Microsoft Graph API)
694694

695+
CAVEATS
696+
-------
697+
698+
include::format-patch-caveats.adoc[]
699+
695700
SEE ALSO
696701
--------
697702
linkgit:git-format-patch[1], linkgit:git-imap-send[1], mbox(5)

0 commit comments

Comments
 (0)