Theory of Operation

Git allows you to make bundle files, which are binary archives of commits. Mirrors can fetch from these bundles, just as if they were regular remotes.

Complete bundles of some repositories are very large. This makes them inconvenient to transfer. Fortunately, bundles can be incremental: i.e., they can contain only a range of commits. As long as your bundle has commits in common with the mirror, then the mirror can fetch it and be updated.

Creating bundles which are minimal—yet still contain enough commits to do the job—is a non-trivial process. It requires a careful pruning of the history, which is difficult to do without knowing what the destination already has.

git-teleport solves this problem by keeping a record of all the "refs" it has already sent. Refs are named objects, like branches and tags. You can list the refs in any repository with

git show-ref -d

When selecting commits (and tags) to bundle, one can use an old list of refs to tell git: "Bundle everything EXCEPT commits reachable from X, Y, and Z." If the destination repository already contains commits g00d, b33f, and a tag 1.0.0, then you can exclude these with something like

git bundle create repo.bundle --all ^g00d ^b33f ^1.0.0 ...

See git help rev-list for more information about how commits are specified.

Git-teleport saves the output of show-ref to keep a record of what has already been transferred. It provides this list to future calls to bundle. This makes future updates much, much smaller. Git-teleport also provides automation for mirroring many repositories at once.