Git's in-depth analysis of git bundle packaging without appropriate network or shareable warehouse

$ git log
commit 9a466c572fe88b195efd356c3f2bbeccdb504102
Author: Scott Chacon <kody@gmail.com>
Date:   Wed Mar 10 07:34:10 2010 -0800

    second commit

commit b1ec3248f39900d2a406049d762aa68e9641be25
Author: Scott Chacon <kody@gmail.com>
Date:   Wed Mar 10 07:34:01 2010 -0800

    first commit
  • If you want to send this warehouse to others but do not have the permission of other warehouses, or you are too lazy to create a new warehouse, you can package it with the git bundle create command:
$ git bundle create repo.bundle HEAD master
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 441 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
  • Then there will be a file named repo.bundle, which contains all the data needed to rebuild the master branch of the warehouse. When using the bundle command, you need to list all references or submitted intervals that you want to package. If you want this warehouse to be cloned elsewhere, you should add a HEAD reference as in the example. We can send the repo. Bundle file to others by mail or U SB flash drive.
  • On the other hand, if someone passes us a repo.bundle file and wants to work on this project, you can clone a directory from this binary file, just like cloning from a URL:
$ git clone repo.bundle repo
Cloning into 'repo'...
...
$ cd repo
$ git log --oneline
9a466c5 second commit
b1ec324 first commit
  • If the HEAD reference is not included during packaging, you also need to specify a - b master or other introduced branches after the command, otherwise Git does not know which branch should be checked out.
  • Now suppose that three revisions have been submitted, and the new submission should be sent back in a package by mail or U SB flash drive:
$ git log --oneline
71b84da last commit - second repo
c99cf5b fourth commit - second repo
7011d3d third commit - second repo
9a466c5 second commit
b1ec324 first commit
  • First, we need to confirm that the submission interval we want to be packaged is different from the network protocol. The network protocol will automatically calculate the minimum data set to be transmitted, and we need to calculate it manually. Of course, you can package the whole warehouse as above, but it's best to package only the part of the changes, that is, the three submissions we just made locally.
  • In order to achieve this goal, we need to calculate the difference. There are many ways to specify a submission interval. We can use methods such as "origin/master... Master" or "master ^origin/master" to obtain the three submissions in the master branch rather than in the original warehouse. You can use the log command to test:
$ git log --oneline master ^origin/master
71b84da last commit - second repo
c99cf5b fourth commit - second repo
7011d3d third commit - second repo
  • In this way, we can get the submission list we want to be packaged. Let's package these submissions by using the git bundle create command, adding the desired file name and the submission interval to be packaged:
$ git bundle create commits.bundle master ^9a466c5
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (9/9), 775 bytes, done.
Total 9 (delta 0), reused 0 (delta 0)
  • Now there will be a commit.bundle file in the directory. If you send this file to our partner, she can import this file into the original warehouse, even if other work has been submitted to the warehouse during this period.
  • When she gets the package, she can check the contents of the package before importing it into the warehouse. The bundle verify command can check whether the file is a legal Git package and has a common ancestor to import:
$ git bundle verify ../commits.bundle
The bundle contains 1 ref
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
The bundle requires these 1 ref
9a466c572fe88b195efd356c3f2bbeccdb504102 second commit
../commits.bundle is okay
  • If the packaging tool packages only the last two submissions instead of three, the original warehouse cannot import the package because the package lacks the necessary submission records. At this time, the output of verify is similar to:
$ git bundle verify ../commits-bad.bundle
error: Repository lacks these prerequisite commits:
error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 third commit - second repo
  • Our first package is legal, so we can extract submissions from this package. If you want to see which branches can be imported into the package here, there is also a command to list these top branches:
$ git bundle list-heads ../commits.bundle
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
  • The verify subcommand can also know which tops can be pulled in. The purpose of this function is to see which can be pulled in, so you can use the fetch or pull command to import submissions from the package. Here, we need to take the master branch from the package to the other master branch in our warehouse:
$ git fetch ../commits.bundle master:other-master
From ../commits.bundle
 * [new branch]      master     -> other-master
  • You can see that the submission has been imported into the other master branch and our own Submission on the master branch during this period:
$ git log --oneline --decorate --graph --all
* 8255d41 (HEAD, master) third commit - first repo
| * 71b84da (other-master) last commit - second repo
| * c99cf5b fourth commit - second repo
| * 7011d3d third commit - second repo
|/
* 9a466c5 second commit
* b1ec324 first commit
  • Therefore, when there is no suitable network or shareable warehouse, git bundle is very suitable for sharing or network type operation.

Posted by cafrow on Mon, 20 Sep 2021 13:15:43 -0700