Offline repository sync using git bundle

Posted on Mon 11 June 2012 in Tools

Keeping git repositories in sync is usually and easily done using git pull and git push. However, for those rare times when you don’t have network connectivity (or limited connectivity) and still need to transfer the contents of a repository to somewhere else, there’s git bundle.

The bundle command creates an archive from one or more objects in a repository. I usually just take the entire master branch. For advanced cases, see the man page. For a simple case, do as follows.

In the source repository, use git bundle to create the archive:

$ git bundle create /path/to/file.bundle refs/heads/master
Counting objects: 935, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (712/712), done.
Writing objects: 100% (935/935), 1.72 MiB, done.
Total 935 (delta 441), reused 585 (delta 202)

Note that uncommitted changes won’t be included, since they are not pointed to by the tree reference (master in this case). Now transfer the archive to its destination. In the destination repository, do:

$ git ls-remote /path/to/file.bundle
e615fea0972f6eccb870cfe67e146a8e21f3ee7d        refs/heads/master

The refs/heads/master reference won’t do in the destination repository, as there is such a reference already. Therefore, we need to fetch with a mapping:

$ git fetch /path/to/file.bundle refs/heads/master:refs/remotes/master
From /path/to/file.bundle
* [new branch]      master     -> master

Finally, we can merge into our existing master branch:

$ git merge refs/remotes/master
Updating aaf4c61..e615fea
Checking out files: 100% (442/442), done.
...

That’s all there is to it (for the simple case)! Happy bundling!

Update (2012-06-12): Changed the bundle-creating command to use refs/heads/master instead of just master as tree reference, as the latter may be ambiguous.