Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Git Bundle: Move Git History Offline

Create, inspect, verify, and consume Git bundle files for offline transfer, full backups, and incremental history exchange.

Levels: Advanced ~50 min read

Advanced

What a bundle is

A Git bundle is a file that packages Git objects together with the refs that the bundle offers. It is designed for offline transfer when there is no active Git server connection between the two repositories. A self-contained bundle can bootstrap a repository; a prerequisite-based bundle can carry only later history while requiring the recipient to already have an earlier point in history.

bash
git bundle create backup.bundle --all
git bundle verify backup.bundle
git bundle list-heads backup.bundle

Quick check

What is the main purpose of a Git bundle?

Create a disposable repository with one commit.git bundle create backup.bundle --all

Create a self-contained bundle

Pass a ref such as `main` to `git bundle create` to include the objects reachable from that ref. Use `--all` when the intent is to include all refs that are reachable in the repository. A bundle made from a positive revision without prerequisites is self-contained, so it can be cloned from or unbundled into a repository without the source repository's history already being present.

bash
git bundle create main.bundle main
git bundle create backup.bundle --all
git bundle create --version=2 backup-v2.bundle main

`--version=2` was verified locally in a SHA-1 repository. The current official documentation describes version 2 as the older format and version 3 as the newer format with capability support; the default format is selected from the hash algorithm and supported format rules. Treat explicit version selection as an interoperability decision rather than something to add casually.

Quick check

Which command creates a self-contained bundle containing the history reachable from `main`?

Create a disposable repository with a `main` branch.git bundle create main.bundle main

Incremental bundles and prerequisites

A bundle can be made smaller by excluding history the recipient is expected to already possess. The official documentation expresses this with a revision range such as `old..new`. The important rule is that the right-hand side must resolve to a ref. In a disposable test, a tag named `cutoff` and the `main` branch were used so the range could be verified locally.

bash
git tag cutoff <commit-the-recipient-already-has>
git bundle create update.bundle cutoff..main
git bundle verify update.bundle

An incremental bundle records the excluded history as prerequisites. The bundle is therefore not independently extractable into an unrelated empty repository. `git bundle verify` is the safety check: it validates the bundle and checks that the current repository contains the required prerequisite commits and their linked history.

Quick check

Why can an incremental bundle fail verification in an unrelated empty repository?

Create an incremental bundle from a later branch tip with an excluded earlier ref.git bundle verify update.bundle

Inspect the refs advertised by a bundle

`git bundle list-heads` lists the refs defined in the bundle. You can optionally supply ref names to restrict which advertised refs are printed. This is about the bundle's ref advertisement, not about changing refs in the receiving repository.

bash
git bundle list-heads backup.bundle
git bundle list-heads backup.bundle refs/heads/main
git ls-remote backup.bundle

The last command uses the bundle as a read-only Git source through the normal remote-reading interface. Bundles have read/fetch support, but there is no corresponding `git push` operation that writes into a bundle file.

Verify before consuming an incremental bundle

Run `git bundle verify` from the intended receiving repository before relying on an incremental bundle. A successful verification proves the bundle format is valid and the prerequisite commits are present and fully linked. A failed verification identifies missing prerequisites rather than silently inventing the missing history.

bash
git -C recipient bundle verify update.bundle
# A failed verification is expected if recipient lacks the prerequisite.
# Do not unbundle an incremental bundle into an unrelated repository.

Unbundle objects into a repository

`git bundle unbundle` stores the objects from the bundle in the current repository and prints the refs defined by the bundle. The official manual describes this subcommand as plumbing intended to be used by `git fetch`; it does not itself create the normal remote-tracking refs you would expect from a fetch. Use `git fetch` when you want the higher-level ref update workflow.

bash
git -C recipient bundle unbundle backup.bundle
git -C recipient cat-file -t <advertised-object-id>

A self-contained bundle can be unbundled into an otherwise empty repository. An incremental bundle can only be unbundled when its prerequisites are already available; the local verifier was tested to reject the incremental bundle in an unrelated empty repository.

Clone from or fetch from a bundle

Bundles are valid read-only sources for Git's normal clone and fetch mechanisms. Cloning from a self-contained bundle bootstraps a repository. Fetching from an incremental bundle can update a destination when that destination already has the required prerequisite history.

bash
git clone backup.bundle restored
git -C recipient fetch ../update.bundle HEAD:refs/remotes/bundle/main
git -C recipient rev-parse refs/remotes/bundle/main

The exact refspec matters when an incremental bundle advertises `HEAD` rather than `refs/heads/main`. In local verification, the fetch used the advertised `HEAD` ref and mapped it explicitly to `refs/remotes/bundle/main`. This demonstrates the distinction between the refs stored in the bundle and the refs you choose to update locally.

Quick check

Which operation is the higher-level choice when you want a bundle to update a destination ref?

Start with a recipient repository that already satisfies the bundle's prerequisites.git fetch ../update.bundle HEAD:refs/remotes/bundle/main

Feed refs to bundle creation on standard input

The create command can also read the revision/ref arguments from standard input with `--stdin`. This is useful when a script has already selected the refs to package and avoids constructing one very long command line.

bash
printf '%s\n' main | git bundle create stdin.bundle --stdin
git bundle verify stdin.bundle

The stdin form was executed locally and verified as a self-contained bundle. It does not change the prerequisite model: the refs and revision arguments supplied to the command still determine what is packaged.

Progress, quiet mode, and bundle version

The `create` command accepts `--progress` and `--quiet` to control progress reporting. `--version=<version>` selects the bundle format version. These options do not change the fundamental bundle model: the revision arguments still determine which refs and objects are transported.

bash
git bundle create --progress backup.bundle main
git bundle create --quiet backup.bundle main
git bundle create --version=2 backup-v2.bundle main

The local verifier executed all three forms. Do not confuse output-control options with transport semantics: they do not make an incomplete prerequisite set safe, and they do not turn a bundle into a writable remote.

Bundle versus archive

`git bundle` and `git archive` both produce files, but they transport different things. A bundle preserves Git objects and refs for Git-aware consumption. An archive exports the files represented by a tree for ordinary file distribution. Use the bundle when the recipient needs Git history; use the archive when the recipient needs a snapshot of files rather than repository history.

Safety and state transitions

Creating a bundle does not move your branch or rewrite history. Verification reads the bundle and checks repository prerequisites. Unbundling adds Git objects to the receiving object database but does not by itself establish the normal branch/ref updates of a fetch. Cloning or fetching from a bundle can create or update refs in the destination according to the chosen clone/fetch operation. Treat bundle files as transport artifacts: keep their prerequisite assumptions and advertised refs documented alongside the file.

Practice what you learned

Use the dedicated Git code-completion exercise for this lesson.

Official source boundary

This lesson uses the official Git `git-bundle` and `gitformat-bundle` documentation for bundle semantics and the official Git command documentation for bundle consumption through clone/fetch. No third-party documentation is used for Git command semantics.

Was this page helpful?

Mark this learning resource complete to track your learning progress.