# 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 `.bundle` file 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)

```bash
# 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)

```bash
# 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)

```bash
# 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)

```bash
# 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). |

