Skip to content
Search

Git:Bundle

lastmod 2025-02-14created 2023-12-138 edits

Earlier we covered the usual ways of transferring Git data over a network (HTTP, SSH, etc.). There is one more method that is not commonly used but is quite useful.

Git has something called a “Bundle”. It packs data into a single file. This can be useful in many situations. For example: when the network is down and you need to send changes to a colleague, when you are on a business trip and cannot connect to the local network for security reasons, when the network interface hardware is broken, when you suddenly cannot reach the shared server, or when you need to email changes to someone but do not want to send as many as 40 commits with format-patch.

This is exactly when git bundle comes to the rescue. The bundle command wraps up everything you would normally send with git push into a single binary file. You send this file to someone by email or USB, and they unpack it (Unbundle) into another repository.

 즉, 데이터를 한 파일에 몰아넣는 기능. 즉, 백업. 오프라인 환경에 리모트 변경사항을 적용할 때도 유용하다.

Usage

Bundle all commits of the master branch -> i.e., a full backup of a specific branch.

git bundle create repo.bundle HEAD master

Clone from a bundle:

git clone repo.bundle repo

Bundle only a specific commit range:

git bundle create commits.bundle master ^9a466c5

Check whether the bundle can be applied to the current workspace:

git bundle verify ../commits.bundle

Check the branches included in the bundle:

git bundle list-heads ../commits.bundle

Fetch from the bundle's master branch into the other-master branch.

git fetch ../commits.bundle master:other-master

Examples

How to commit the latest changes to another computer that is offline

Log on the offline remote machine:

[11:55:05] aaa@aaa-desktop:~/Project/ddrm (main)
$ git log10a
* e1ffc3d (HEAD -> main, origin/main, origin/HEAD) Add algorithm v2.1
* 4cb9831 (tag: 0.0.16) Bump version
* a82cb41 Trivial commit
* 1571e7b Update ground truth
* 48240a1 Add redis-cli scripts
* a9b6f8b Raise NotFoundContours instead of ValueError in ImgprocBase.find_plate_v1
* 1a5ece7 Update NVR information
* a2fe7b9 Fix layer name conflict
* 30c113b Update README
* bf0e344 Update perspective points

My current workspace:

[11:58:58] your@your-Desktop:~/Project/ddrm (main)
$ git log20a
* f73606f (HEAD -> main) Record release videos
* 9aaa3a4 Create count_nonzero_lines
* ab3c5d4 Upgrade requirements: cvlayer>=0.26.0
* 1699c28 (tag: 0.0.18, origin/main, origin/HEAD) Bump version
* 99b9e53 Update ko manual
* ede6632 Update DEFAULT_BREAK_OUT_COUNT value: 60 -> 100
* fd591b0 Increased readability of the Calibration Info Box
* a97a889 (tag: 0.0.17) Bump version
* c221381 Remove unused script: redis-cli-flushall
* 4cc77ea Implement plate break-out feature
* bd4ee27 Update cam4s area_filter_min: 60000 -> 50000
* c530378 Add apps: ls, rls, put, get
* b5e43f1 Update default variables
* 8129c96 Apply settings approx_epsilon
* 13b1e37 Update constant variables
* e1ffc3d Add algorithm v2.1
* 4cb9831 (tag: 0.0.16) Bump version
* a82cb41 Trivial commit
* 1571e7b Update ground truth
* 48240a1 Add redis-cli scripts

We need to get everything from e1ffc3d to f73606f (HEAD) on the main branch.

git bundle create offline.bundle e1ffc3d..main

The <git-rev-list-args> parameter used as e1ffc3d..main must be verifiable with git log.

$ git log --oneline e1ffc3d..main
f73606f (HEAD -> main) Record release videos
9aaa3a4 Create count_nonzero_lines
ab3c5d4 Upgrade requirements: cvlayer>=0.26.0
1699c28 (tag: 0.0.18, origin/main, origin/HEAD) Bump version
99b9e53 Update ko manual
ede6632 Update DEFAULT_BREAK_OUT_COUNT value: 60 -> 100
fd591b0 Increased readability of the Calibration Info Box
a97a889 (tag: 0.0.17) Bump version
c221381 Remove unused script: redis-cli-flushall
4cc77ea Implement plate break-out feature
bd4ee27 Update cam4s area_filter_min: 60000 -> 50000
c530378 Add apps: ls, rls, put, get
b5e43f1 Update default variables
8129c96 Apply settings approx_epsilon
13b1e37 Update constant variables

After copying the bundle file to the remote machine, check that it is a valid Git Bundle.

[12:18:50] aaa@aaa-desktop:~/Project/ddrm (main)
$ git bundle verify offline.bundle
The bundle contains this ref:
f73606fea28e53770617a91db89f325b45a11d07 refs/heads/main
The bundle requires this ref:
e1ffc3d07bf14673c7639c29f5a2f03dff95417d
offline.bundle is okay

Let's check the list of branches included in the bundle:

[12:19:06] aaa@aaa-desktop:~/Project/ddrm (main)
$ git bundle list-heads ./offline.bundle
f73606fea28e53770617a91db89f325b45a11d07 refs/heads/main

<span style="color:red;">[Error example] FYI, fetching into a branch that already exists gives an error...

[12:18:57] aaa@aaa-desktop:~/Project/ddrm (main)
$ git fetch ./offline.bundle main:main
fatal: Refusing to fetch into current branch refs/heads/main of non-bare repository

So create a new branch called other-main and fetch into it:

[12:20:12] aaa@aaa-desktop:~/Project/ddrm (main)
$ git fetch  ./offline.bundle  main:other-main
Receiving objects: 100% (138/138), 3.15 MiB | 44.12 MiB/s, done.
Resolving deltas: 100% (80/80), completed with 28 local objects.
From ./offline.bundle
 * [new branch]      main       -> other-main

Then rebase or merge:

[12:21:06] aaa@aaa-desktop:~/Project/ddrm (main)
$ git rebase other-main
First, rewinding head to replay your work on top of it...
Fast-forwarded main to other-main.

Check that other-main and main are at the same position:

[12:21:06] aaa@aaa-desktop:~/Project/ddrm (main)
$ git log30a
* f73606f (HEAD -> main, other-main) Record release videos
* 9aaa3a4 Create count_nonzero_lines
* ab3c5d4 Upgrade requirements: cvlayer>=0.26.0
...

Delete the unneeded other-main branch:

[12:21:10] aaa@aaa-desktop:~/Project/ddrm (main)
$ git branch -d other-main
Deleted branch other-main (was f73606f).

Script for simple use

When there is a new workspace (New) and a legacy workspace (Old):

When the common point of Old and New is origin/HEAD, and HEAD is where the additional commits were made in the new workspace (New),

In the new workspace (New) that has the latest version:

git bundle create offline.bundle origin/HEAD..HEAD

After copying the "offline.bundle" file (assume it was copied to ~/Downloads/offline.bundle), in the legacy workspace (Old):

## [Optionsl] 확인부터 하는게 안전하긴 하다:
git bundle verify ~/Downloads/offline.bundle

## [Optionsl] 브랜치 목록 확인. 아마도 "HEAD" 가 될 것이다.
git bundle list-heads ~/Downloads/offline.bundle
## "7e00d08f73777d66077f4f20ef8331e581bb49d4 HEAD" 이런 느낌으로 출력될듯

git fetch ~/Downloads/offline.bundle HEAD:offline
git rebase offline
git branch -d offline

See also

Favorite site

author Zer0 sitemap