Git Bundle

Learn via video courses
Topics Covered

Overview

Git bundles utility allows us to convert the Git repository or Git objects into a single file that can be shared offline with other computers. This bundle can be easily cloned using git clone or git fetch commands. The Git bundle is different from Git Archive as the Git bundle contains the Git metadata and version information which is absent in the Git Archive.

Pre-requisites

  • Basic Git Commands
  • Git remote repository

Introduction to Git Bundle

Git Bundles provide the offline transfer of Git objects. These objects can be accessed by the user without an active server present. It acts just like a Git repository and lets the user run commands as well.

Git Bundles can be used to create full backups of the repository or only a single branch. Git commands such as git clone, git fetch, git remote, etc. that fetch or read remote repositories can also be used to operate on Git Bundles. But writing on bundles is not possible i.e. we cannot use the git push command on a bundle.

The Git Bundle command creates a single file that essentially contains the entire repository. This file contains branches, history, tags, in short everything you can find in a repository. Once the Bundle is generated, it can be cloned or forked using standard Git commands in offline mode. It makes sharing the repository or part of the repository easy and fast.

Synopsis

Various forms of Git Bundle commands are given below along with their options. We will be looking at each of them in detail in the article.

BUNDLE FORMAT

A Bundle file in Git has a .pack Extention. The header of the Bundle file indicates the references contained within the bundle.

Bundles can either be self-contained bundles that can be unbundled in a repository with no command history or they can be created using exclusions i.e. providing negative revisions to exclude objects need in the earlier parts of the history.

OPTIONS

  • create [options] <file> <git-rev-list-args> It is used to create a Bundle file named file. It requires <git-rev-list-args> i.e. list of arguments that defines the list contents of the bundle. We can specify options such as --progress, --quite, etc.
  • verify <file> list-heads <file> To check the validity of the bundle file and to cleanly apply it to the current repository, verification is used. It checks the format of the bundle file, checks that the prerequisite commits exist and that these required commits are completely linked to the current repository. The Git bundle returns the list of missing commits along with information about the additional capabilities such as object filter is also printed.
  • list-heads <file> It lists or prints the references defined in the bundle command. It is further followed by the list of references that matches the given references printed in the output.
  • unbundle <file><git-rev-list-args> It is used to unpack the previously generated bundle. This command is usually intended to be called directly by Git fetch command.
  • <git-rev-list-args> A list of arguments is to be passed along with the Git create command which is acceptable to the git rev-parse and git ref-list. This list of arguments specifies objects and references to transport. There is no explicit limit that defines the maximum number of references and objects that may be packed.
  • [<refname>…] A list of all the available references is not desired therefore, to limit these a list of only required references is used. This is usually used by the git fetch command as it expects only references asked for.
  • --progress The status of the progress is reported by default on the standard error stream. The progress status is forced by the flag even if the standard error stream is detached from the terminal. Only if -q is used then it will not report to the standard error stream.
  • --all-progress On using --stdout the progress report is generated during the write-out phase and is displayed after the write-out phase during the object count and compression phases. This is because the output stream may be pointing to another command that may want to display its progress in the output and thus, the outputs of the commands mixed together won't be useful anymore. It is similar to the --progress flag except that this flag forces progress reports for the write-out phase.
  • --all-progress-implied This flag is used to imply an --all-progress option whenever the progress display is activated. It doesn't force any progress display on its own as in the case of --all-progress.
  • --version=<version> The version option is used to specify the version of the Bundle. By default, the oldest supported format is used based on the hash algorithm in use. Version 2 bundle is the oldest format, it can be used with SHA-1 repositories. Whereas Version 3, the newer version contains capabilities that permit extensions.
  • -q --quiet The --quite flag doesn't let the command report its progress on the standard error stream. It suppresses the output summary.

Git Bundle Range of Commits

Let us take an example of a repository that has a newbranch which is two commits ahead of the master branch.

The git log command shows the list of commits. We can see that the head is on the branch newbranch.

git-log-command-held-on-newbranch

We can use this same range selection syntax using the git bundle command.

range-selection-using-git-bundle-command

Finally, we can transfer the patch. bundle file into the root directory containing the origin repo.

Can You Push to a Git Bundle?

We are allowed to clone and fetch the git repository from the bundle file using commands, but we cannot push something into a Git Bundle file.

The Bundle file is actually a compressed binary file and therefore cannot be used to run the commands like Git push. Though we can unbundle it, push the changes or files to it and again bundle it to a .pack file with the help of Git commands.

How to Use Git Bundle?

Let us take an example of a repository having files, commits, and branches.

Use Git Bundle for Files and Their History

The repository is having a branch called newBranch that has a few files and commits and the master branch also has its files and commits. To bundle the entire repository we will be using the git bundle create command.

To bundle the entire repository we will be using the --all flag:

entire-repository-using-all-flag

To bundle only a single branch from a repository:

bundle-only-single-branch-from-repository

Here in the example above we have bundled the contents of the master branch.

This bundle can be copied to the target computer using a thumb drive or any other device. Once it is copied it can be cloned using the git clone command.

Use Git Bundle to Clone a New Repository

Now as we have already seen how we can bundle Git objects, let us now explore how we can unbundle these files to form back the repository.

To clone a bundle navigate to the directory containing the bundle and clone the repository using the git clone command.

clone-bundle-navigate-to-directory-using-git-clone-command

This generates the working copy of the entire repository but if you wish to make changes to only a few branches and send it back to the original repository, then we can use the new range of commits, copying it to the origin computer and fetching the new commits from the bundle file. Later the new commits can be merged into the master branch.

Git Archive vs. Git Bundle

  • Git Archive - Git archive is a command that creates an archive of the file of a Git repository. It basically combines all the files in a single file that can be extracted to reproduce individual files. It doesn't contain the history of the version details of the project.
  • Git Bundles - Git bundles also convert the entire Git repository into a single file that can be easily shared and updated by the user. It contains information about the versions and history of the Git repository.

Let us now compare Git Bundles and Git Archive in detail:

Similarities: They both convert the git repository or part of the Git repository into a single file as specified using the Git command. Both of these commands let the user transfer files in a single unit in offline mode.

Differences:

Column 1Column 2
Git bundle contains the version information along with project files.Git archive doesn't contain the version information, it only contains project files.
It contains a .git folder that contains the version details and the Git metadata.Git Archive doesn't have a .git folder.
It lets the user use the Git repository and Git objects offline with the commands like git clone, git fetch, and git remote, etc. in their local computer.It contains a .zip file that can be extracted to get the final project's copy.

Conclusion

  • Git bundle provides the functionality of offline transfer of the Git repository from one device to another. Bundles are used to create full backups of the repositories or only of the single branch contained in a single file.
  • Git Bundle create command converts Git objects into a single file of .pack Extention.
  • Git Bundle commands lets us create a bundle, verify a bundle file, list the references defined in the bundle command and unbundle the repository in the given folder.
  • It can be used to bundle a few specified commits in a file.
  • We can use commands like git clone, git fetch, and git remote but we cannot use git push on a bundle. Though to add any updates to an existing bundle we can always clone it, make changes to the repository and bundle it again.
  • Git archive and Git Bundle both converts the Git repository into a single file. But Git Archive doesn't contain the Git metadata or version information. Whereas, Bundle contains all the version history as well as the .git file in it.