Mailing-list maintainers
A maintainer saves a contributor's emailed patch series to an mbox, creates a topic branch, and runs git am -3 -s to turn it into signed-off commits that keep the contributor as author.
Git · Command
git am takes patches that arrive as email, in a mailbox file or a Maildir, and turns each one into a commit on the current branch. It keeps the original author, date and message, so it does the reverse of git format-patch.
Last updated
git am splits a mailbox into separate messages. For each message, it pulls the author and date from the headers and uses the Subject line, minus any [PATCH ...] prefix, as the commit title. The body becomes the rest of the commit message, up to the first line that looks like the start of a diff. The diff part is applied with git apply, and the result is committed. If a patch fails, the session stops partway through and saves its state. You then fix the problem and run --continue, or use --skip, --abort, --quit or --retry. Hooks can check each message and the applied tree before the commit is made.
git am [--signoff] [--keep] [--[no-]3way] [--interactive] [--whitespace=<action>] [-p<n>] [--empty=(stop|drop|keep)] [-S[<key-id>]] [--patch-format=<format>] [(<mbox> | <Maildir>)…]
git am (--continue | --skip | --abort | --quit | --retry | --show-current-patch[=(diff|raw)] | --allow-empty)| Name | Type | Description |
|---|---|---|
<mbox> | <Maildir> | path(s) | Mailbox files to read patches from. Directories are treated as Maildirs. If you give none, standard input is used. |
-s, --signoff | flag | Adds a Signed-off-by trailer using your own committer identity. |
-3, --3way / --no-3way | flag | If a patch does not apply cleanly, falls back to a 3-way merge when the needed blobs exist locally. --no-3way overrides the am.threeWay setting. |
-k, --keep | flag | Passes -k to git-mailinfo, which keeps the subject line as it is. |
--empty=(drop|keep|stop) | enum | Decides what happens to a message that has no patch: skip it, record an empty commit, or stop (the default). |
--whitespace=<action>, -p<n>, -C<n>, --directory, --exclude, --include, --reject | options | Passed straight to git apply. Valid --whitespace actions are nowarn, warn, fix, error and error-all. |
--patch-format=<format> | string | Skips automatic format detection. Accepts mbox, mboxrd, stgit, stgit-series or hg. |
--continue / --skip / --abort / --quit / --retry | flag | Controls a session that stopped on a failed patch: commit your manual fix, drop the patch, roll back, leave without resetting, or try the patch again. |
--show-current-patch[=(diff|raw)] | flag | Shows the message the session stopped on, either the whole email (raw, the default) or just the diff. |
One new commit on the current branch for each patch that applies. If a patch fails, the session stops partway and waits for --continue, --skip, --abort, --quit or --retry.
#!/usr/bin/env bash
set -euo pipefail
# Export commits on 'feature' that are not on 'main' as mbox patches
git format-patch main..feature -o /tmp/series
# Apply them on a fresh branch, adding a sign-off and allowing a 3-way fallback
git switch -c integrate main
git am -3 --signoff /tmp/series/*.patch
# If it stops on a conflict:
# git am --show-current-patch=diff # inspect the failing patch
# # ...edit files, then:
# git add -A && git am --continue
# # or give up entirely:
# git am --abort
git log --oneline main..integrateThis exports a branch as email-style patches with format-patch, then replays them onto a new branch with git am, using a 3-way fallback and sign-offs, and shows the commands for handling a conflict.
A maintainer saves a contributor's emailed patch series to an mbox, creates a topic branch, and runs git am -3 -s to turn it into signed-off commits that keep the contributor as author.
Pipe git format-patch --stdout from one repo into git am in another. This carries commits over with their messages and authors, even when the two repos share no history.
Export commits as .patch files, reset the branch, then edit, reorder or delete the files. Running git am *.patch rebuilds the series.
Use the applypatch-msg and pre-applypatch hooks to reject or rewrite messages, or to run checks on the tree, before each emailed patch is committed.
git apply only changes the working tree (and the index, if asked) and never creates a commit. git am reads email messages, takes the author, date, subject and body from each one, applies the diff through git apply, and makes one commit per patch. It also adds a resumable session (--continue/--skip/--abort), hooks and sign-off support.
Follow-up: Which git am options are just passed on to git apply? Options such as --whitespace, -p<n>, -C<n>, --directory, --exclude, --include, --reject and the ignore-whitespace flags are all passed directly to git apply.
You can drop that patch with git am --skip. Or you can fix the files by hand, stage the result with git add, and run git am --continue, which commits using the email's author and message. You can also try git am --retry --3way, or end the session with --abort (restores everything) or --quit (leaves HEAD and the index as they are).
Follow-up: How do you see which patch failed? Run git am --show-current-patch=diff to see only the diff, or use the default raw mode to see the whole email.
When a patch doesn't apply cleanly, --3way falls back to a 3-way merge. It uses the blob IDs recorded in the patch's index lines to rebuild the base version. This only works if those blobs exist in your repository; otherwise it can't help. You can make it the default with am.threeWay=true.
Follow-up: How do you turn off a configured 3-way default for one run? Pass --no-3way, which overrides am.threeWay for that run.
git format-patchgit applygit send-emailgit mailinfogit mailsplitgit rebasegit rereregit interpret-trailers