Git Bundle
git bundle packs a repository, or part of one, into a single file for offline transfer or incremental replication.
git bundle writes a repository, or a selected range of commits, into one file.
Unlike git archive, which exports a tree with no history at all, a bundle
contains real commits, and unlike a clone, a bundle does not need a network.
That makes it the tool for three jobs: moving history somewhere with no network, replicating a repository incrementally, and archiving the history of a project whose server is going away.
Creating one
git bundle create repo.bundle --all # everything, all branches
git bundle create feature.bundle main..feature # commits since main
git bundle create v1.bundle v1.0.0..v1.4.0 # a release range
A range bundle is the interesting case: it starts from a commit the receiver already has, so it carries only what is new.
Verifying it
git bundle verify repo.bundle
verify checks the file is a valid bundle and that the prerequisites are
present. Run it after transferring — a truncated bundle on a USB stick is the
failure mode you are guarding against.
Using it
git clone repo.bundle recovered-repo # clone from the file
git fetch repo.bundle 'refs/heads/*:refs/heads/*' # into an existing repo
Cloning a bundle is how you get a repository back with its full history when there is no server to get it from. A bare repository containing one bundle directly is a legitimate remote, and the usual mirror or backup target.
A bundle is not a backup
This is the mistake worth naming. A bundle contains the objects you named and nothing else, and it knows nothing about uncommitted work, stashes, or unreachable objects. Two specific consequences:
git bundle create --alldoes not include local branches you have not pushed if you did not name them, and never includes stashes.- Losing the repository means losing everything the bundle does not contain.
For actually keeping history safe, a remote you can clone from, or git clone --mirror to another machine, is a better answer. Bundles are for transport and
for archive.
In a mirror
git clone --mirror https://github.com/owner/repo.git repo.git
git -C repo.git bundle create backup.bundle --all
That is a reasonable way to archive a project. Combine it with a fetch immediately before the bundle, and the archive reflects the remote at that moment.