Home / Alt manpages / git-am(1)

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

Apply Emailed Git Patches Safely with git am

Someone sent you a patch series by email, and you need it on your branch as proper commits with the right authors. This guide takes about ten minutes for a clean mailbox and longer if a conflict turns up. You will apply the patches with git am, check the commits it created, and recover if one patch does not apply. 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. It also 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

Checkpoint

An empty git status --short is what you want. 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
  • Headers. Look for the expected From:, Date: and Subject: lines, plus a diff.
  • Commit title. The subject becomes the title once common [PATCH ...] prefixes are removed.
  • Author and committer. The author identity and author date come from the message. The committer is whoever runs 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

Tip

ORIG_HEAD is set to the branch tip from before the am operation, which makes it a handy comparison point for a multi-commit mailbox. Keep the original mailbox until you have checked the result.

3. Keep authorship or add a sign-off

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.

Warning

A sign-off is a project policy statement, not a harmless formatting switch. 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

Warning

The command can leave conflict markers or partially applied files. Do not commit them blindly.

You have three useful choices.

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.

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

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

Recovery

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 are ignored.
  • keep records. The message becomes an empty commit, using the email content as its log message.
  • stop asks a human. Use --empty=stop explicitly when a missing patch should require a 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 with care

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.

Warning

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

  • Branch confirmed. You checked the target branch and started from a known worktree state.
  • Mailbox applied. Patches went in order, or every skipped message was an intentional decision.
  • History matches. git log, git show and git diff --stat ORIG_HEAD..HEAD show the change you expected.
  • Conflicts settled. Each one was resolved and tested, skipped with a reason, or removed with git am --abort.
  • Status understood. The final git status --short output makes sense, and the original mailbox is still available for recovery.