Git Bundle: Move Git History Offline
Create, inspect, verify, and consume Git bundle files for offline transfer, full backups, and incremental history exchange.
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.
git bundle create backup.bundle --all
git bundle verify backup.bundle
git bundle list-heads backup.bundleQuick 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.
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.
git tag cutoff <commit-the-recipient-already-has>
git bundle create update.bundle cutoff..main
git bundle verify update.bundleAn 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.
git bundle list-heads backup.bundle
git bundle list-heads backup.bundle refs/heads/main
git ls-remote backup.bundleThe 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.
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.
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.
git clone backup.bundle restored
git -C recipient fetch ../update.bundle HEAD:refs/remotes/bundle/main
git -C recipient rev-parse refs/remotes/bundle/mainThe 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.
printf '%s\n' main | git bundle create stdin.bundle --stdin
git bundle verify stdin.bundleThe 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.
git bundle create --progress backup.bundle main
git bundle create --quiet backup.bundle main
git bundle create --version=2 backup-v2.bundle mainThe 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.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.