How to Format Git Patch Series as an MBOX File in Python
Generate a patch-series mbox file from commit metadata with numbered [PATCH nnn/nnn] subjects and a Git-style footer.
Python code
53 linesimport re
from pathlib import Path
def format_patch_series_mbox(commits, output_path="series.mbox"):
entries = []
for idx, commit in enumerate(commits, start=1):
subject = commit["subject"]
author = commit["author"]
email = commit["email"]
date = commit["date"]
body = commit["body"]
entry = (
f"From {email} {date}\n"
f"From: {author} <{email}>\n"
f"Date: {date}\n"
f"Subject: [PATCH {idx:03d}/{len(commits):03d}] {subject}\n"
f"\n"
f"{body}\n"
f"-- \n"
f"---\n"
f"---\n"
)
entries.append(entry)
mbox_content = "\n".join(entries)
Path(output_path).write_text(mbox_content, encoding="utf-8")
return mbox_content
if __name__ == "__main__":
commits = [
{
"subject": "Add user authentication",
"author": "Alice Developer",
"email": "alice@example.com",
"date": "Mon, 03 Jun 2024 10:00:00 +0000",
"body": "Implement login and session management.",
},
{
"subject": "Fix password reset flow",
"author": "Bob Maintainer",
"email": "bob@example.com",
"date": "Tue, 04 Jun 2024 14:30:00 +0000",
"body": "Resolve redirect loop and add email validation.",
},
]
result = format_patch_series_mbox(commits)
clean_subjects = re.findall(r"Subject:.*", result)
for line in clean_subjects:
print(line)
Output
Subject: [PATCH 001/002] Add user authentication
Subject: [PATCH 002/002] Fix password reset flow
How it works
The function iterates over commit dictionaries and builds each mbox entry with a From_ escape line, headers (From, Date, Subject), body, and a -- separator. The [PATCH {idx:03d}/{len(commits):03d}] format pads indices to three digits, matching how git format-patch numbers series. The full mbox content is written to disk with Path.write_text using UTF-8 encoding, and also returned so callers can inspect or pipe it. Using f-strings keeps the template readable, and \n joins entries to mimic the blank line between mbox messages.
Common mistakes
- Forgetting the blank line between the header block and the body — mbox parsers rely on it.
- Using a literal `\n` inside the f-string instead of an actual newline escape.
- Not padding patch numbers with `:03d` — git-style series expect zero-padded indices.
- Missing the `From ` escape line, which some mail tools require as the first line of each entry.
Variations
- Use `mailbox.mbox` from the stdlib to write entries into a real mbox container instead of raw text.
- Read commits directly from `git log --format=...` output with subprocess instead of hand-built dicts.
Real-world use cases
- Automating export of a feature branch as a patch series for email-based code review or mailing-list submission.
- Feeding formatted commits into a CI pipeline that archives patch series for release notes or changelog generation.
- Generating mbox files for local patch backups or for tools like git-send-email that consume mbox-style input.
Sponsored
More from Git + Python
- Amend Last Commit Message in Python easy
- Bisect Good Bad Automation Script in Python easy
- Build a Simple Log Graph in Python easy
- Bump Semantic Version Git Tag in Python easy
- Count Unique Contributors from Git Shortlog in Python easy
- Create a Mock GitHub Release API in Python for Testing gh CLI easy
Keep learning
Related tutorials and quizzes for this topic.