Skip to content
Git Basics: Transfer a Commit as a Mailbox Patch

Git Basics: Transfer a Commit as a Mailbox Patch

October 28, 2026

A mailbox patch carries a commit message and author information as well as its file changes. This differs from a raw working-tree diff applied without creating a commit.

Prepare a scratch directory

Tested on Linux with Git 2.52.0 and GNU Bash 5.2.37. You need Bash, a text editor, the named runtime, and standard mktemp, rm, and rmdir utilities. The examples use only controlled local data; generated fixture directories are cleaned automatically.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as demonstrate-format-patch-am.sh:

#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_AUTHOR_NAME='Example Author'
export GIT_AUTHOR_EMAIL='author@example.invalid'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
export GIT_AUTHOR_DATE='2026-10-28T00:00:00+00:00'
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git init -q -b main "$fixture_dir/repo"
cd -- "$fixture_dir/repo"
git config commit.gpgsign false
git config core.hooksPath /dev/null
printf 'base\n' > report.txt
git add report.txt
git commit -qm 'Base report'
git branch receiver
printf 'base\nreviewed\n' > report.txt
git commit -qam 'Add reviewed row'
git format-patch -1 --stdout > "$fixture_dir/change.patch"
git switch -q receiver
git am --quiet "$fixture_dir/change.patch"
printf 'Imported subject:\n'
git log -1 --format=%s
printf 'Imported author:\n'
git log -1 --format='%an <%ae>'
printf 'Imported content:\n'
cat report.txt
git diff --exit-code main receiver
printf 'Source and receiver trees: identical\n'

Run it:

bash demonstrate-format-patch-am.sh

Observed output:

Imported subject:
Add reviewed row
Imported author:
Example Author <author@example.invalid>
Imported content:
base
reviewed
Source and receiver trees: identical

Read the result

format-patch serializes the latest commit into mailbox form. The receiver starts from its parent, and am applies the patch as a commit. The final diff checks tree equality; a normal transfer need not preserve the source commit ID because committer metadata can differ.

Apply it carefully

Inspect patches before importing them. If am stops with a conflict in a real repository, resolve and stage the change before am --continue, or use am --abort to abandon the session. This fixture disables hooks and does not send email or contact a remote. Run this script from an ordinary shell with no repository-selection variables such as GIT_DIR or GIT_WORK_TREE set. All commits and cleanup stay inside the newly created temporary fixture.

The official reference describes the behavior and options. These checks cover the fixture above rather than every input or platform.

Clean up

Remove the saved source, return to the starting directory, then remove the empty practice directory:

rm -- demonstrate-format-patch-am.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect its remaining contents rather than deleting unknown files.

Acknowledgements

This post was created with assistance from AI.

Last updated on