Home / Alt manpages / git-am(1)

  • git-am(1)
  • User command
  • linux

Apply emailed Git patches safely with git am

You will apply one or more emailed Git patches to the current branch, check the commits that were created, and recover if one patch does not apply. Allow about ten minutes for a clean mailbox and longer if you need to resolve a conflict. The examples use the installed Git 2.43.0 from the git-man documentation package; newer Git releases can add options, so check your local version before copying a command into a script.

Safety boundary

git am changes the current branch, working tree and index by creating commits. Work on the intended branch, make a clean checkpoint first, and inspect patches from people or systems you trust. No command in this guide needs sudo.

1. Check the repository and mailbox

Start in the repository that should receive the commits. A clean worktree makes it easier to see what the operation changed and gives git am --abort a clear state to restore.

$ git --version
git version 2.43.0
$ git branch --show-current
feature/receiver
$ git status --short

An empty git status --short is the useful checkpoint. If it prints files, either save those changes in a separate commit or stop and decide how they should coexist with the incoming patches. Do not use git reset --hard merely to make this check pass: that can discard work.

A mailbox can be an mbox file, a list of mbox files, or a Maildir directory. The simplest dry inspection is to view the headers and patch text without applying anything:

$ sed -n '1,40p' /path/to/series.mbox

Look for the expected From:, Date: and Subject: headers and a diff. The subject becomes the commit title after common [PATCH ...] prefixes are removed. The author identity and author date come from the message, while the committer is the identity running git am.

2. Apply the mailbox

Give git am the mailbox path. It reads an mbox file directly; if you omit the path, it reads mailbox data from standard input. The command applies the patches in order and normally creates one commit per patch.

$ git am /path/to/series.mbox
Applying: add input validation
Applying: document the error path

The exact titles and progress lines come from your mailbox. Check the new history and worktree immediately:

$ git log --oneline -n 3
8e2e050 document the error path
4d18c2a add input validation
91f2b70 previous commit
$ git status --short

The short status should again be empty if the patches committed all their changes. Verify the resulting diff against the old tip when the change matters:

$ git diff --stat ORIG_HEAD..HEAD
$ git show --stat --oneline HEAD

ORIG_HEAD is set to the branch tip from before the am operation. It is a useful comparison point for a multi-commit mailbox. Keep the original mailbox until you have checked the result.

3. Preserve authorship or add a sign-off deliberately

By default, Git takes the commit author from the message. If your project requires a sign-off from the person applying the patch, use --signoff when you start the operation:

$ git am --signoff /path/to/series.mbox

This adds a Signed-off-by trailer using your committer identity. It is a project policy statement, not a harmless formatting switch, so do not add it unless you are authorised to make that declaration. Hooks named applypatch-msg, pre-applypatch and post-applypatch can run during the operation. The normal path verifies those hooks; --no-verify bypasses the first two apply hooks and should be reserved for a documented, intentional exception.

4. Stop safely when a patch conflicts

Git stops at the first patch that does not apply cleanly. This is a paused am session, not a successful partial import. Inspect the failed patch and the worktree before choosing a recovery path:

$ git am --show-current-patch=diff
$ git status
$ git diff

The command can leave conflict markers or partially applied files. Do not commit them blindly. You have three useful choices.

  1. Resolve and continue. Edit the conflicted files, remove every conflict marker, test the result, then stage exactly the resolved files and continue.
$ git add path/to/resolved-file.c
$ git diff --cached --check
$ git am --continue

git diff --cached --check catches common whitespace errors before the continued commit. Repeat the inspect, resolve and continue cycle if another patch stops.

  1. Skip the current patch. Use this only when you have decided that this patch is unnecessary or superseded. The skipped commit is not created, and Git proceeds with the remaining mailbox.
$ git am --skip
  1. Abort the whole operation. If the mailbox is wrong or you selected the wrong branch, restore the pre-am state with:
$ git am --abort
$ git status --short

After a successful abort, the operation is over and the files involved in it are returned to their pre-am state. If you only want to end the am session while keeping the current HEAD and index untouched, the installed manual also provides git am --quit. That is a specialised choice: inspect the index and working tree yourself before doing anything else.

5. Handle messages without patches

The default for an email that contains no usable patch is stop: Git reports the problem and pauses the am session. You can choose a policy at the start:

$ git am --empty=drop /path/to/series.mbox
$ git am --empty=keep /path/to/series.mbox

drop skips such messages. keep records one as an empty commit using the email content as its log message. Use --empty=stop explicitly when a missing patch should require a human decision. The separate --allow-empty action is for creating an empty commit after Git has stopped on a message lacking a patch.

6. Use three-way fallback only when it is appropriate

A patch normally has to apply cleanly. --3way lets Git fall back to a three-way merge when the patch records the original blob identities and those blobs are available locally:

$ git am --3way /path/to/series.mbox

This can turn a textual mismatch into a normal merge conflict, but it cannot recover missing history or make an unsuitable patch correct. Review any conflict in the same way as above. The local am.threeWay setting defaults to false according to the installed manual; --no-3way overrides a configuration setting when you need strict patch application.

Do not use --3way as a reason to skip review. Test the final tree and inspect the commit diff. If the mailbox came from an untrusted source, remember that the patch text can change files and commit messages, and hooks in the receiving repository can execute.

Done means

  • You confirmed the target branch and started from a known worktree state.
  • The mailbox was applied in order, or every skipped message was an intentional decision.
  • git log, git show and git diff --stat ORIG_HEAD..HEAD match the change you expected.
  • A conflict was either resolved and tested, skipped with a reason, or removed with git am --abort.
  • The final git status --short output is understood, and the original mailbox is still available for recovery.