Skip to content

mailsplit Git Command Guide

The git mailsplit command is a simple UNIX mbox splitter program that splits mbox files or Maildir directories into individual email message files for further processing. It creates sequentially numbered files (0001, 0002, etc.) in a specified output directory.

Terminal window
git mailsplit [-b] [-f<nn>] [-d<prec>] [--keep-cr] [--mboxrd]
-o<directory> [--] [(<mbox>|<Maildir>)...]
OptionDescription
-bStop processing at first blank line
-f<nn>Start numbering from nn instead of 1
-d<prec>Set precision of generated numbers
--keep-crKeep CR characters in output
--mboxrdUse mboxrd rather than mboxo format
-o<directory>Output directory for split files (required)
ParameterDescription
<mbox>Mbox file to split (stdin if omitted)
<Maildir>Maildir directory to process
Terminal window
# Split mbox file into individual email files
git mailsplit -o emails/ patches.mbox
# Start numbering from 1000
git mailsplit -f1000 -o emails/ patches.mbox
# Split with 4-digit precision
git mailsplit -d4 -o emails/ patches.mbox
Terminal window
# Process Maildir into numbered email files
git mailsplit -o output/ ~/Maildir/
# Combine multiple Maildir
git mailsplit -o emails/ ~/Maildir ~/another-maildir/
Terminal window
# Read from stdin, split into directory
cat big-mbox.eml | git mailsplit -o split-emails/
# Process email from pipe
wget -qO- https://example.com/mail.mbox | git mailsplit -o downloads/
Terminal window
# Handle large patch series
git mailsplit -b -o patches/ large-patches.mbox
# Preserve original formatting
git mailsplit --keep-cr -o formatted/ special-encoding.mbox
# Use mboxrd format
git mailsplit --mboxrd -o mboxrd/ legacy-mail.mbox
Terminal window
# Process multiple mbox files
for mbox in *.mbox; do
base=$(basename "$mbox" .mbox)
git mailsplit -f1 -d3 -o "patches/$base/" "$mbox"
done
# Process with date-based naming
timestamp=$(date +%Y%m%d_%H%M%S)
git mailsplit -o "mail_$timestamp/" inbox.mbox
Terminal window
# Process specific email range
git mailsplit -f100 -o emails/ large-mailbox.mbox | head -20
# Split by subject pattern
grep -l "PATCH" *.mbox | while read mbox; do
git mailsplit -o "patches/$(basename "$mbox" .mbox)/" "$mbox"
done
#!/bin/bash
# Complete patch processing workflow
# Step 1: Split mbox into individual emails
git mailsplit -o temp-patches/ patch-series.mbox
# Step 2: Process each patch
for patch in temp-patches/*; do
echo "Processing $patch"
# Extract commit message and patch
git mailinfo msg.txt patch.txt < "$patch"
# Apply the patch
git am patch.txt
# Clean up
rm msg.txt patch.txt
done
# Clean up temporary directory
rm -rf temp-patches
# Process multiple patch series in parallel
#!/bin/bash
process_patch_series() {
local mbox_file="$1"
local output_dir="$2"
# Create output directory
mkdir -p "$output_dir"
# Split the mbox
git mailsplit -o "$output_dir/" "$mbox_file"
echo "Split $(ls "$output_dir" | wc -l) emails from $mbox_file"
}
# Process multiple series concurrently
process_patch_series "series1.mbox" "out1" &
process_patch_series "series2.mbox" "out2" &
process_patch_series "series3.mbox" "out3" &
wait
echo "All patch series processed"
Terminal window
# Validate patch formatting before processing
validate_mbox() {
local mbox_file="$1"
# Check if valid mbox format
if grep -q '^From .*@' "$mbox_file"; then
echo "Valid mbox format detected"
# Count emails
count=$(grep '^From .*@' "$mbox_file" | wc -l)
echo "Found $count emails"
return 0
else
echo "Invalid mbox format"
return 1
fi
}
# Process only valid mbox files
for mbox in *.mbox; do
if validate_mbox "$mbox"; then
git mailsplit -o "validated/$(basename "$mbox" .mbox)/" "$mbox"
fi
done
Terminal window
# Create organized directory structure
output_base="processed-patches"
timestamp=$(date +%Y%m%d_%H%M%S)
output_dir="$output_base/$timestamp"
mkdir -p "$output_dir"
# Process with organized output
for series in *-patches.mbox; do
series_name=$(basename "$series" -patches.mbox)
series_dir="$output_dir/$series_name"
git mailsplit -o "$series_dir/" "$series"
echo "Processed $series_name: $(ls "$series_dir" | wc -l) patches"
done
Terminal window
# Handle very large mbox files
big_mbox="large-archive.mbox"
total_emails=$(grep -c '^From ' "$big_mbox")
# Split in batches
batch_size=1000
for ((start=1; start<=$total_emails; start+=batch_size)); do
end=$((start + batch_size - 1))
if [ $end -gt $total_emails ]; then end=$total_emails; fi
echo "Processing emails $start to $end"
# Extract batch to temporary file
awk "/^From .*@$start/,/^From .*@$end/" "$big_mbox" > "batch_$start.mbox"
# Process batch
git mailsplit -f$start -o "batches/batch_$start/" "batch_$start.mbox"
# Clean up
rm "batch_$start.mbox"
done
Terminal window
# Check mbox format validity
grep -n "^From " mailbox.mbox | head -5
# Fix mbox format issues
# Add missing "From " lines
# Ensure proper line endings
dos2unix mailbox.mbox || unix2dos mailbox.mbox
# Convert to standard mbox format
formail -ds < mailbox.mbox | git mailsplit -o fixed/
Terminal window
# Verify patch content
ls -la output-dir/
cat output-dir/0001 | head -10
# Check for zero-byte files
find output-dir/ -size 0 -delete
echo "Removed $(find output-dir/ -size 0 -print | wc -l) empty files"
# Validate patch format
find output-dir/ -name "*" -exec git mailinfo /dev/null /dev/null < {} \; -print | grep -v "Author:"
Terminal window
# Check Maildir structure
ls -la ~/Maildir/cur/ ~/Maildir/new/
# Sort filenames for correct order
ls ~/Maildir/cur/ ~/Maildir/new/ | sort > maildir-files.txt
# Process sorted Maildir
cat maildir-files.txt | xargs -I {} git mailsplit -o processed/ ~/Maildir/{}
Terminal window
# Handle different encodings
git mailsplit --mboxrd -o processed/ international-mails.mbox
# Convert encoding before processing
iconv -f iso-8859-1 -t utf-8 foreign-mails.mbox | git mailsplit -o converted/
# Preserve special characters
git mailsplit --keep-cr -o preserved/ special-chars.mbox
# Process patch submissions from mailing list
#!/bin/bash
# Download latest patches from list
wget -q https://lists.kernel.org/archive/patches.mbox
# Split into individual patches
git mailsplit -o kernel-patches/ patches.mbox
# Validate each patch
for patch in kernel-patches/*; do
if git mailinfo /dev/null /dev/null < "$patch" > /dev/null 2>&1; then
echo "✓ Valid patch: $patch"
else
echo "✗ Invalid patch: $patch"
fi
done
# Apply valid patches
for patch in kernel-patches/*; do
git mailinfo commit-msg.txt patch-file.txt < "$patch"
git am patch-file.txt
done
# Clean up
rm -rf kernel-patches/ commit-msg.txt patch-file.txt patches.mbox
Terminal window
# Automated patch processing for review
patch_dir="review-patches"
processed_dir="processed"
# Create directories
mkdir -p "$patch_dir" "$processed_dir"
# Receive and split patches
# (Assuming patches.mbox is received via email)
git mailsplit -o "$patch_dir/" patches.mbox
# Process each patch for review
for patch_file in "$patch_dir"/*; do
patch_num=$(basename "$patch_file")
# Extract patch information
git mailinfo "$processed_dir/${patch_num}-msg.txt" \
"$processed_dir/${patch_num}-patch.txt" \
< "$patch_file"
# Create review directory
review_base="$processed_dir/review-$patch_num"
mkdir -p "$review_base"
# Generate review information
echo "Original email: $patch_file" > "$review_base/review-info.txt"
echo "Commit message:" >> "$review_base/review-info.txt"
cat "$processed_dir/${patch_num}-msg.txt" >> "$review_base/review-info.txt"
# Check patch applicability
if git apply --check "$processed_dir/${patch_num}-patch.txt" 2>/dev/null; then
echo "Status: Can apply cleanly" >> "$review_base/review-info.txt"
else
echo "Status: Conflicts detected" >> "$review_base/review-info.txt"
fi
# Assign reviewer based on file changes
if grep -q "src/security/" "$processed_dir/${patch_num}-patch.txt"; then
echo "Assigned Reviewer: security-team" >> "$review_base/review-info.txt"
fi
echo "Prepared review for patch $patch_num"
done
# Notify review team
echo "Prepared $(ls "$patch_dir” | wc -l) patches for review in $processed_dir"
# CI pipeline for patch validation
#!/bin/bash
# Split incoming patches
patches_received="incoming-patches.mbox"
temp_dir=$(mktemp -d "/tmp/patch-validation-XXXXXX")
git mailsplit -o "$temp_dir/" "$patches_received"
failed_patches=0
successful_patches=0
# Validate each patch
for patch_file in "$temp_dir"/*; do
echo "Validating patch: $(basename "$patch_file")"
# Test patch application
if git mailinfo "/dev/null" "$temp_dir/test.patch" < "$patch_file" > /dev/null 2>&1; then
# Apply to test branch
if git apply --check "$temp_dir/test.patch" > /dev/null 2>&1; then
echo "✓ Patch applies cleanly"
successful_patches=$((successful_patches + 1))
else
echo "✗ Patch has conflicts"
failed_patches=$((failed_patches + 1))
fi
else
echo "✗ Invalid patch format"
failed_patches=$((failed_patches + 1))
fi
# Clean up test patch
rm -f "$temp_dir/test.patch"
done
# Summary report
total_patches=$((successful_patches + failed_patches))
echo "Patch validation complete:"
echo "Total patches: $total_patches"
echo "Successful: $successful_patches"
echo "Failed: $failed_patches"
# Exit with appropriate code
if [ "$failed_patches" -gt 0 ]; then
echo "Some patches failed validation"
exit 1
else
echo "All patches passed validation"
exit 0
fi
# Clean up
rm -rf "$temp_dir"

How does mailsplit handle different mbox formats?

Section titled “How does mailsplit handle different mbox formats?”

Recognizes mboxo (traditional) and mboxrd (with >From escaping) formats. —mboxrd option forces mboxrd interpretation for maildir-style quoting.

What’s the difference between mbox and Maildir processing?

Section titled “What’s the difference between mbox and Maildir processing?”

Mbox files contain all emails concatenated; Maildir stores each email as separate file. mailsplit creates consistent numbered output from both.

How do I handle mal-ordered Maildir files?

Section titled “How do I handle mal-ordered Maildir files?”

Maildir filenames should be sorted for correct patch order. Use ls -t for time-ordering if alphabetical order doesn’t match chronological order.

Can mailsplit process compressed mbox files?

Section titled “Can mailsplit process compressed mbox files?”

No, decompress first: gunzip archive.mbox.gz | git mailsplit -o output/ or zcat archive.mbox.gz | git mailsplit -o output/

What’s the impact of -b option on patch processing?

Section titled “What’s the impact of -b option on patch processing?”

Stops at first blank line, useful for processing only email headers when you don’t need full patch content for initial processing.

mailsplit extracts all content. Use email processing tools like munpack first if you need to separate attachments before Git processing.

What’s the performance overhead for large mbox files?

Section titled “What’s the performance overhead for large mbox files?”

Minimal memory usage, processes emails sequentially. Time depends on mbox size and number of emails, typically fast for reasonable sizes.

Can mailsplit work with multipart messages?

Section titled “Can mailsplit work with multipart messages?”

Processes raw mbox content, doesn’t decode MIME multipart. Use email parsing tools if you need to handle multipart before mailsplit.

How do I reconstruct original mbox from split files?

Section titled “How do I reconstruct original mbox from split files?”

cat output-dir/* > reconstructed.mbox rebuilds mbox, but loses original formatting. Not recommended for archival purposes.

What’s the relationship between mailsplit and git am?

Section titled “What’s the relationship between mailsplit and git am?”

mailsplit splits archives into individual emails; git am processes individual emails. mailsplit is preprocessing for git am workflows.

Can mailsplit handle international email encodings?

Section titled “Can mailsplit handle international email encodings?”

Use —keep-cr to preserve original line endings. Convert encoding with iconv before or after mailsplit processing.

How do I handle emails with multiple patches?

Section titled “How do I handle emails with multiple patches?”

Each patch should be separate email. If multiple patches in one email, manual splitting required before mailsplit.

What’s the output format naming convention?

Section titled “What’s the output format naming convention?”

Creates sequentially numbered files: 0001, 0002, etc. Use -f option to change starting number, -d for digit precision control.

Treats each email individually. Thread context is lost unless processed through email client or tools that understand threading.

Usually indicates mbox format issues. Check “From ” line format, ensure emails are properly separated in the mbox file.

What’s the relationship between mailsplit and git-mailinfo?

Section titled “What’s the relationship between mailsplit and git-mailinfo?”

mailsplit splits mbox into individual emails; mailinfo extracts commit message and patches from individual email. Used together in patch workflows.

  1. Patch Series Processing: Split mbox archives into individual patches for git-am application
  2. Email Archive Management: Organize large email archives into manageable individual files
  3. Automated Patch Management: Process incoming patch emails in CI/CD pipelines
  4. Mailing List Integration: Handle patch submissions from development mailing lists
  5. Code Review Workflows: Prepare email-based patch reviews for individual assessment
  6. Backup and Recovery: Extract individual emails from corrupted mail archives