Another method to share the repository history between repositories is to use the git bundle
command. A Git bundle is a series of commits that can work as a remote repository, but without having the full history of a repository included in the bundle.
We'll use a fresh clone of the offline-sharing
repository as follows:
$ git clone https://github.com/dvaske/offline-sharing.git $ cd offline-sharing $ git checkout master
First, we'll create a root bundle, as shown in the following command, so that the history in the bundle forms a complete history and the initial commit is also included:
$ git bundle create myrepo.bundle master Counting objects: 12, done. Delta compression using up to 8 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (12/12), 1.88 KiB | 0 bytes/s, done. Total 12 (delta 1), reused 0 (delta 0)
We can verify the bundle content with git bundle verify
:
$ git bundle verify myrepo.bundle The bundle contains this ref: 1e42a2dfa3a377d412efd27a77b973c75935c62a refs/heads/master The bundle records a complete history. myrepo.bundle is okay
To make it easy to remember which commit we included as the latest commit in the bundle, we create a tag that points to this commit; the commit is also pointed to by the master
branch:
$ git tag bundleForOtherRepo master
We have created the root bundle that contains the initial commits of the repository history. We can now create a second bundle that contains the history from the tag we just created to the tip of the develop
branch. Note that in the following command, we use the same name for the bundle file, myrepo.bundle
, and this will overwrite the old bundle file:
$ git bundle create myrepo.bundle bundleForOtherRepo..develop Counting objects: 12, done. Delta compression using up to 8 threads. Compressing objects: 100% (9/9), done. Writing objects: 100% (9/9), 1.47 KiB | 0 bytes/s, done. Total 9 (delta 2), reused 0 (delta 0)
It might seem strange to overwrite the bundle file just after creating it, but there is some sense in naming the bundle files by the same name. As you will also see in the next recipe, when using a bundle file, you add it to your repository as a remote, the URL being the file path of the bundle. The first time you do this is with the root bundle file and the URL. The file path of the bundle file will be stored as the URL of the remote repository. So, the next time you need to update the repository, you just overwrite the bundle file and perform fetch
from the repository.
If we verify the bundle, we can see which commit needs to exist in the target repository before the bundle can be used:
$ git bundle verify myrepo.bundle The bundle contains this ref: c131c8bb2bf8254e46c013bfb33f4a61f9d4b40e refs/heads/develop The bundle requires this ref: ead7de45a504ee19cece26daf45d0184296f3fec myrepo.bundle is okay
We can check the history and see that the ead7de4
commit is where develop
is branched off so it makes sense that this commit is the basis for the bundle we have just created:
$ gitk master develop
The previous command gives the following output:
The bundle
command creates a binary file with the history of the specified commit range included. When creating the bundle as a range of commits that does not include the initial commit in the repository (for example, bundleForOtherRepo..develop
), it is important to make sure the range matches the history in the repository where the bundle is going to be used.