Skip to content
masterclass Buddy

Git · Command

git am

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

How it works

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.

Syntax

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)

Parameters

NameTypeDescription
<mbox> | <Maildir>path(s)Mailbox files to read patches from. Directories are treated as Maildirs. If you give none, standard input is used.
-s, --signoffflagAdds a Signed-off-by trailer using your own committer identity.
-3, --3way / --no-3wayflagIf 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, --keepflagPasses -k to git-mailinfo, which keeps the subject line as it is.
--empty=(drop|keep|stop)enumDecides 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, --rejectoptionsPassed straight to git apply. Valid --whitespace actions are nowarn, warn, fix, error and error-all.
--patch-format=<format>stringSkips automatic format detection. Accepts mbox, mboxrd, stgit, stgit-series or hg.
--continue / --skip / --abort / --quit / --retryflagControls 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)]flagShows the message the session stopped on, either the whole email (raw, the default) or just the diff.

Returns

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.

Key points

  • Authorship is preserved: the email's From: header becomes the commit author and its Date: header becomes the author date. You can override these with matching lines at the very start of the body.
  • The Subject: line becomes the commit title, with a leading [PATCH ...] tag removed first. This way, series numbering from format-patch does not end up in the history.
  • If you give no mailbox arguments, git am reads from stdin. This lets you pipe output straight in, for example git format-patch --stdout A..B | git am.
  • The commit message ends at the first line that is exactly '---', starts with 'diff -', or starts with 'Index: '. Everything after that point is treated as the patch.
  • Before applying anything, git am saves the current branch tip as ORIG_HEAD. If you applied a series to the wrong branch, you can reset back to that point.
  • A message with no diff, such as a cover letter, stops the session by default. Use --empty=drop to skip such messages or --empty=keep to record them as empty commits.
  • --abort and --quit both end the session but leave the repo differently. --abort puts the branch and files back as they were before git am started, while --quit leaves HEAD and the index exactly as they are.

Common mistakes

  • --committer-date-is-author-date can make committer dates go backwards in history, which can confuse tools that walk history. Only use it when the base commit is older than every patch you are applying.
  • A diff that is not indented inside a commit message (for example, in a Markdown code block) can be taken for the real patch. It may then be applied wrongly or cause the patch to fail. Indent such text to avoid this.
  • You can't start a new mailbox while an earlier session is still stopped. Finish it, or run git am --abort first.
  • Running --retry with the same options just fails the same way again. It only helps if you add something new, such as --3way.

Example: Round-trip a branch through format-patch and am

#!/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..integrate

This 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.

When to use it

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.

Moving commits between unrelated repositories

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.

Editing a patch series by hand

Export commits as .patch files, reset the branch, then edit, reorder or delete the files. Running git am *.patch rebuilds the series.

Enforcing message rules on incoming patches

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.

Interview questions

QHow is git am different from git apply?

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.

Qgit am stops partway through a series because a patch doesn't apply. What can you do?

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.

QWhat does --3way do, and when does it fail to help?

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-patch
  • git apply
  • git send-email
  • git mailinfo
  • git mailsplit
  • git rebase
  • git rerere
  • git interpret-trailers

Source: Git - git-am Documentation. Checked 2026-11-02.