GIT-AM(1)
๐ธ GIT-AM(1) โ the git am glow-up, bestie edition ๐ธ
okay so. you've wandered into the Git Manual page for git am and honestly? you're about to eat. this one's a whole vibe. ๐
โจ NAME โจ
git-am โ apply a series of patches from a mailbox ๐
๐ฆ SYNOPSIS ๐ฆ
git am [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--[no-]verify]
[--[no-]3way] [--interactive] [--committer-date-is-author-date]
[--ignore-date] [--ignore-space-change | --ignore-whitespace]
[--whitespace=<action>] [-C<n>] [-p<n>] [--directory=<dir>]
[--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
[--[no-]scissors] [-S[<key-id>]] [--patch-format=<format>]
[--quoted-cr=<action>]
[--empty=(stop|drop|keep)]
[(<mbox> | <Maildir>)...]
git am (--continue | --skip | --abort | --quit | --retry | --show-current-patch[=(diff|raw)] | --allow-empty)
๐ DESCRIPTION ๐
so here's the tea: git am splits mail messages in a mailbox into three lil piles โ commit log messages, authorship information, and patches โ and then applies them to the current branch. it's giving โจdispatchโจ. the classic way to think about it is that it's literally a reverse operation of git-format-patch(1) run on a branch with a straight history without merges. iconic behavior tbh. ๐ฅ
๐ OPTIONS ๐
(<mbox>|<Maildir>)...โ the list of mailbox files to read patches from. if you don't supply this argument, the command reads from the standard input ๐ธ. and if you supply directories, they'll be treated as Maildirs, periodt.-s,--signoffโ adds aSigned-off-bytrailer to the commit message (peepgit-interpret-trailers(1)), using the committer identity of yourself ๐. want the full lore? check the signoff option ingit-commit(1).-k,--keepโ passes the-kflag straight togit-mailinfo(1). handoff, slay.--keep-non-patchโ passes the-bflag togit-mailinfo(1). yes bestie, a whole different flag.--keep-cr,--no-keep-crโ with--keep-cr, it callsgit-mailsplit(1)with the same option, so it won't stripCRat the end of lines ๐ซถ. theam.keepcrconfiguration variable can be used to specify the default behaviour, and--no-keep-cris the move when you need to overrideam.keepcr.-c,--scissorsโ removes everything in the body before a scissors line (seegit-mailinfo(1)). can be activated by default using themailinfo.scissorsconfiguration variable. โ๏ธ๐--no-scissorsโ ignores scissors lines (seegit-mailinfo(1)). the scissors stay in the chat, unread.--quoted-cr=<action>โ this flag gets passed down togit-mailinfo(1). that's the whole note, no cap.--empty=(drop|keep|stop)โ how to handle an e-mail message lacking a patch. choose your fighter:dropโ the e-mail message will be skipped. bye girl ๐keepโ an empty commit will be created, with the contents of the e-mail message as its log. main character energy for an empty commit, honestly.stopโ the command will fail, stopping in the middle of the current am session. this is the default behavior. ๐
-m,--message-idโ passes the-mflag togit-mailinfo(1), so that theMessage-IDheader is added to the commit message. theam.messageidconfiguration variable can be used to specify the default behaviour.--no-message-idโ do not add theMessage-IDheader to the commit message.--no-message-idis useful to overrideam.messageid.-q,--quietโ be quiet. only print error messages. ๐คซ lowkey the introvert flag.-u,--utf8โ passes the-uflag togit-mailinfo(1). the proposed commit log message taken from the e-mail is re-coded into UTF-8 encoding (the configuration variablei18n.commitEncodingcan be used to specify the project's preferred encoding if it is not UTF-8). this was optional in prior versions of git, but now it is the default, bestie. you can use--no-utf8to override this.--no-utf8โ passes the-nflag togit-mailinfo(1).-3,--3way,--no-3wayโ when the patch does not apply cleanly, fall back on a 3-way merge if the patch records the identity of blobs it is supposed to apply to and we have those blobs available locally.--no-3waycan be used to override theam.threeWayconfiguration variable. for more info, seeam.threeWayingit-config(1). ๐ง rescue mission mode.--rerere-autoupdate,--no-rerere-autoupdateโ after the rerere mechanism reuses a recorded resolution on the current conflict to update the files in the working tree, this allows it to also update the index with the result of resolution.--no-rerere-autoupdateis a good way to double-check whatgit-rerere(1)did and catch potential mismerges, before committing the result to the index with a separategit-add(1). basically: peek before you commit, queen. ๐--ignore-space-change,--ignore-whitespace,--whitespace=<action>,-C<n>,-p<n>,--directory=<dir>,--exclude=<path>,--include=<path>,--rejectโ these flags are passed to thegit-apply(1)program that applies the patch. valid<action>for the--whitespaceoption are:nowarn,warn,fix,error, anderror-all. โจ that's the whole list, don't @ me.--patch-formatโ by default the command will try to detect the patch format automatically. this option lets the user bypass the automatic detection and specify the patch format that the patch(es) should be interpreted as. valid formats arembox,mboxrd,stgit,stgit-series, andhg. ๐ฆ-i,--interactiveโ run interactively. that's it. that's the bullet. ๐--verify,-n,--no-verifyโ run thepre-applypatchandapplypatch-msghooks. this is the default. skip these hooks with-nor--no-verify. see alsogithooks(5). โ ๏ธ note thatpost-applypatchcannot be skipped. not me warning you twice.--committer-date-is-author-dateโ by default the command records the date from the e-mail message as the commit author date, and uses the time of commit creation as the committer date. this allows the user to lie about the committer date by using the same value as the author date. ๐ญ lying is free, apparently.
Warning โ ๏ธ โ the history walking machinery assumes that commits have non-decreasing commit timestamps. you should consider if you really need to use this option. then you should only use this option to override the committer date when applying commits on top of a base which commit is older (in terms of the commit date) than the oldest patch you are applying. fr fr, be careful.
--ignore-dateโ by default the command records the date from the e-mail message as the commit author date, and uses the time of commit creation as the committer date. this allows the user to lie about the author date by using the same value as the committer date. ๐ two different lies, same energy.--skipโ skip the current patch. this is only meaningful when restarting an aborted patch. ๐-S[<key-id>],--gpg-sign[=<key-id>],--no-gpg-signโ GPG-sign commits. the<key-id>is optional and defaults to the committer identity; if specified, it must be stuck to the option without a space ๐ โ yes, glued, no space, that's the rule.--no-gpg-signis useful to countermand both thecommit.gpgSignconfiguration variable, and earlier--gpg-sign.--continue,-r,--resolvedโ after a patch failure (e.g. attempting to apply a conflicting patch), the user has applied it by hand and the index file stores the result of the application. this makes a commit using the authorship and commit log extracted from the e-mail message and the current index file, and continues. you did the work, now letgittake the credit for typing it out. ๐ซถ--resolvemsg=<msg>โ when a patch failure occurs,<msg>will be printed to the screen before exiting. this overrides the standard message informing you to use--continueor--skipto handle the failure. this is solely for internal use betweengit-rebase(1)andgit-am(1). ๐ง don't touch unless you're on that internal business.--abortโ restore the original branch and abort the patching operation. revert the contents of files involved in the am operation to their pre-am state. โจ undo era โจ--quitโ abort the patching operation but keepHEADand the index untouched. walking away with your hands in your pockets, no cap.--retryโ try to apply the last conflicting patch again. this is generally only useful for passing extra options to the retry attempt (e.g.--3way), since otherwise you'll just see the same failure again. ๐ญ the definition of insanity, but make it git.--show-current-patch[=(diff|raw)]โ show the message at whichgit-am(1)has stopped due to conflicts. ifrawis specified, show the raw contents of the e-mail message; ifdiff, show the diff portion only. defaults toraw. ๐ต๏ธโ๏ธ receipts time.--allow-emptyโ after a patch failure on an input e-mail message lacking a patch, create an empty commit with the contents of the e-mail message as its log message. โจ the empty commit gets to be the main character โจ
๐ DISCUSSION ๐
okay so the commit author name is taken from the "From: " line of the message, and the commit author date is taken from the "Date: " line of the message. the "Subject: " line is used as the title of the commit, after stripping the common prefix "[PATCH <anything>]". and the "Subject: " line is supposed to concisely describe what the commit is about in one line of text. keep it snappy, bestie. ๐
"From: ", "Date: ", and "Subject: " lines starting the body override the respective commit author name and title values taken from the headers. the body said "actually, no", and the body wins. ๐ธ
the commit message is formed by the title taken from the "Subject: ", a blank line, and the body of the message up to where the patch begins. excess whitespace at the end of each line is automatically stripped. ๐ง auto-clean, love that for us.
the patch is expected to be inline, directly following the message. any line that is of the form:
- three-dashes and end-of-line, or
- a line that begins with
diff -, or - a line that begins with
Index:
is taken as the beginning of a patch, and the commit log message is terminated before the first occurrence of such a line. ๐
this means that the contents of the commit message can inadvertently interrupt the processing (see the CAVEATS section below). ๐ awkward, but we move.
when initially invoking git-am(1), you give it the names of the mailboxes to process. upon seeing the first patch that does not apply, it aborts in the middle. you can recover from this in one of two ways:
- skip the current patch by re-running the command with the
--skipoption. โ๏ธ - hand resolve the conflict in the working directory, and update the index file to bring it into a state that the patch should have produced. then run the command with the
--continueoption. ๐ซถ
the command refuses to process new mailboxes until the current operation is finished, so if you decide to start over from scratch, run git am --abort before running the command with mailbox names. no skipping ahead, babe. ๐
before any patches are applied, ORIG_HEAD is set to the tip of the current branch. this is useful if you have problems with multiple commits, like running git-am(1) on the wrong branch or an error in the commits that is more easily fixed by changing the mailbox (e.g. errors in the From: lines). โจ your little safety net โจ
๐ CAVEATS ๐
Okay bestie, this is the part where we get real. The tea is: the output from git-format-patch(1) can end up giving you a totally different commit message when you apply it with git-am(1). Not a vibe. And the patch that actually gets applied might be different from the one that got generated, or โ worst case โ patch application just fails outright. Yikes. The syntactic rules live up in the DISCUSSION section, so go peek there.
Heads up, this is especially messy for unindented diffs that show up inside the commit message. Like, the diff in the commit message might get applied along with the patch section, or the patch machinery might trip up because the patch target doesn't apply. A classic way this happens? A diff inside a Markdown code block. ๐ญ
The fix for all of this: indent the diff (or any other text that could cause problems). That's it. That's the whole hack. โจ
This loss of fidelity might be easy to notice if you're applying patches directly from a mailbox. But when changes originating from Git get applied in bulk, it's way harder to catch. Think, like, a Linux distribution that uses patch files to apply changes on top of commits from the upstream repositories. So yeah โ this behaviour doesn't only impact email workflows, fr fr. ๐ซถ
And given these limitations, you might be tempted to reach for a general-purpose utility like patch(1) instead. But plot twist: patch(1) will not only look for unindented diffs (like git-am(1) does) โ it'll try to apply indented diffs as well. ๐ So it's not the clean escape you think it is.
๐ช HOOKS ๐ช
This command can run applypatch-msg, pre-applypatch, and post-applypatch hooks. See githooks(5) for the full lore.
Also see the --verify / -n / --no-verify options. ๐
โ๏ธ CONFIGURATION โ๏ธ
Everything below this line in this section is selectively included from the git-config(1) documentation. The content is the same as what's found there: (just keeping it faithful, bestie ๐
)
am.keepcrโ If true,git-am(1)will callgit-mailsplit(1)for patches in mbox format with the parameter--keep-cr. In that case,git-mailsplit(1)will not remove\rfrom lines ending with\r\n. You can override this by giving--no-keep-crfrom the command line. โจam.threeWayโ By default,git-am(1)will fail if the patch does not apply cleanly. But when this is set to true, it tellsgit-am(1)to fall back on a 3-way merge if the patch records the identity of blobs it's supposed to apply to and we have those blobs available locally (equivalent to giving the--3wayoption from the command line). Defaults tofalse. ๐ธam.messageIdโ Adds aMessage-IDtrailer based on the email header to the commit when usinggit-am(1)(seegit-interpret-trailers(1)). Also peep the--message-idand--no-message-idoptions. ๐
๐ SEE ALSO ๐
๐ง GIT ๐ง
Part of the git(1) suite. Obviously. ๐
And that's the whole page, bestie โ you ate that. ๐ This lil masterpiece is from Git 2.56.0, dated 2026-09-27, and it's serving GIT-AM(1) realness. Go forth and git am responsibly, mwah ๐
๐ฆ where this page comes from
- arch rolling: git 2.56.0-1 ยท GPL-2.0-only
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms