Offline Git Collaboration: Bundles vs. Patches
When working with Git, we typically rely on a central server like GitHub or GitLab. However, in scenarios like air-gapped networks, unstable internet, or transferring data via USB, a direct connection is impossible. In these cases, Git provides two powerful offline solutions: Git Bundle and Git Patch.
1. Git Bundle (git bundle)
A Git bundle is a single binary file that acts exactly like a remote repository. It packs objects, references, and history into one file.
How it works: You treat the
.bundlefile exactly like a remote server (origin). You can clone, fetch, and pull from it.Key Advantage: It preserves the full Git graph (DAG). This allows Git to perform smart merges, detect renames, and resolve conflicts using history.
Best Use Case: Syncing branches, transferring large history, or backing up repositories.
On the Source Computer (Sender)
# Syntax: git bundle create <filename> <branch_name_or_range>
# 1. Full Backup: Bundle the 'master' branch (and full history)
git bundle create repo.bundle master
# 2. Bundle all branches and tags
git bundle create all-changes.bundle --all
# 3. PRO TIP: Incremental Bundle (Save space)
# Only bundle commits added since the last time you synced (e.g., since 'v1.0')
# Note: The receiver MUST have the 'v1.0' commit for this to work.
git bundle create update.bundle v1.0..master
On the Target Computer (Receiver)
# 1. Verify the file is valid and you have the prerequisite commits
git bundle verify repo.bundle
# 2. See what branches are inside
git bundle list-heads repo.bundle
# 3. Safer Method: Fetch into a temporary branch first
# This lets you inspect changes before merging
git fetch repo.bundle master:temp-branch
# 4. Integrate changes (Standard Git workflow)
git checkout master
git rebase temp-branch
# or
git merge temp-branch
2. Git Patch (git format-patch)
A Git patch is a text-based file containing the differences (diffs) and metadata (author, date, message) for specific commits.
How it works: It generates email-friendly text files. The recipient uses
git am(Apply Mailbox) to reconstruct the commits.Limitation: Patches are "brittle." They rely on context (line numbers and surrounding text). If the file structure on the target differs (e.g., renamed files), the patch often fails.
Binary Files: While modern patches can include binary data, it is inefficient and bloats the text file. Bundles are preferred for binaries.
Best Use Case: Sending single bug fixes, code reviews via email, or applying a commit to a disconnected codebase.
On the Source Computer (Sender)
# 1. Create a patch for the very last commit
git format-patch -1 HEAD
# 2. Create patches for all commits not on origin/master
git format-patch origin/master
# 3. Create a patch for a specific commit hash
git format-patch -1 <commit-hash>
# (Output: 0001-fix-login-bug.patch)
On the Target Computer (Receiver)
# 1. Dry Run: Check statistics without applying
git apply --stat 0001-fix-login-bug.patch
# 2. Check for errors/conflicts
git apply --check 0001-fix-login-bug.patch
# 3. APPLY: The Correct Way (Preserves Author/Date)
git am 0001-fix-login-bug.patch
# 4. Troubleshooting: If conflict occurs
git am --abort
CRITICAL WARNING:
Do not use git apply to merge the code unless you want to lose the commit history.
git apply: Changes the files in your working directory (Author = You, Date = Now).
git am: Reconstructs the actual commit (Author = Original Sender, Date = Original Date).
3. Summary: Which one should you choose?
| Feature | Git Bundle | Git Patch |
| Data Type | Binary (Packfile + Refs) | Text (Diffs + Metadata) |
| Context Awareness | High (Uses history graph) | Low (Uses line numbers/text) |
| Renamed Files | Handles automatically | Usually fails |
| Prerequisites | Strict (Receiver needs basis commit if incremental) | Loose (Receiver just needs matching file content) |
| Commit History | 100% Preserved (GPG sigs, etc.) | Preserved only if using git am |
| Recommended For | Syncing branches or large updates. | Communication (Email reviews, single fixes). |