How to git bundle a complete repo
Asked Answered
F

4

180

I need to transfer a complete repo to a new non-networked machine, preferable as a single file entity. The git bundle allows a git fetch, git pull style operation in a sneakernet environment but appears to assume that you already have a working version of the repo on the destination machine.

What is the right invocation to:

  1. Bundle all the branches in the current repo
  2. Start up the new repo on the destination directory, i.e. get the root commit correctly installed

I've sent a patch upstream to clarify:

`git clone` can use any bundle created without negative refspecs
(e.g., `new`, but not `old..new`).
If you want to match `git clone --mirror`, which would clone other
refs such as `refs/remotes/*`, use `--all`.
If you want to provide the same set of refs that a clone directly
from the source repository would get, use `--branches --tags` for
the `<git-rev-list-args>`.

So $ git bundle create repo.bundle --branches --tags best matches cloning.

$ git bundle create repo.bundle --all will provide a mirror image of your source machine, including its remote refs.

Franko answered 3/8, 2012 at 9:7 Comment(0)
R
282

What is the right invocation to:

  • Bundle all the branches in the current repo

Simple:

$ git bundle create repo.bundle --all

Here repo.bundle is the name of bundle file you want to create. Note that --all would not include remote-tracking branches... just like ordinary clone wouldn't either.

  • Start up the new repo on the destination directory, i.e. get the root commit correctly installed

First, clone is just init + fetch (+ administrativia).

Second, you can use bundle file everywhere the repository URL can be used, so you can simply clone from a bundle file:

$ git clone repo.bundle

This would create repo as a git repository.

Raychel answered 3/8, 2012 at 12:14 Comment(16)
Thanks, the --all options isn't in my man page for bundle (I'm looking at version 1.7.6.msysgit.0), nor is the use of the .bundle file in the URLs section for clone. It gives me greater confidence to recommend its use.Franko
The synopsis for create command is git bundle create <file> <git-rev-list-args>. Running man git-rev-list (or man git-log) would give you --all. But I agree that it should be more visible in the bundle command documentation.Cadaver
I see that the bundle man page, under Specifying References, says that it "will only package refs that are shown by git show-ref", which doesn't include [list] the git-rev-list options.Franko
@Philip Oakley: The git-rev-list-args is how you select refs that are shown by git show-ref command.Cadaver
--all did include remote-tracking branches for me (git 2.1.4). I could see refs/remotes/origin/* with git bundle list-heads bundlefile or git ls-remote bundlefile. Although getting them back from the bundle is little tricky.Nam
@Alex, how did you do it though? I can see the branches with your method and i can checkout the commits but i have not found a way to checkout the branches themselves.Unmeet
@Unmeet I never did it. I just know that they are stored in the bundle and can be reconstructed with some script. Still missing in the bundle file is the remotes. You have a refs/remotes/origin/master in the bundle but the origin URL is lost. This is exactly why I just tar xz my minified git repos instead of bundling them -- to preserve the remotes.Nam
can any one tell me how to bundle only the last 3 commits ?Laubin
@Ben.Bean: you can bundle the last 3 commits in the same way as you would list them (with git log), for example with git bundle create last-3-commits.bundle -3 master HEAD (or something like that), or master~3..master, etc.Cadaver
@JakubNarębski, I tried your command like git bundle create latest.bundle -3 develop HEAD, it created file as latest.bundle but when i tried to unbundle it using git clone latest.undle its throwing errors Cloning into 'last-3-commits'... error: Repository lacks these prerequisite commits: error: 3f2d2d3647de90fdfaed5a604473d9cabce78aa2 error: 31921433b6c52ed2ae87a9e8cedacc22bc97b170 fatal: bad object d1f94ed93b2df5a133118bf9f851adb6baa95911 fatal: remote did not send all necessary objects Laubin
@Ben.Bean: this simply means that last 3 commits are not enough - you need more than that. Simplest thing would be to check the date of latest commit in the repository you want to unbundle in, and pack --since that date (with some slack, just in case).Cadaver
@PhilipOakley funny that it still isn't seven years later. But then, git-fast-export also mentions --all in the examples but doesn't mention it in the section where arguments are discussed ...Incubate
@Incubate I tried to send in a doc patch but it was rejected as somehow obvious or bad public-inbox.org/git/[email protected]Franko
@PhilipOakley I lack the words (and not just because I am not a native speaker of English) ... thanks for the update.Incubate
How can I prevent it from messing up references? For instance, refs/heads/4.1 is changed to refs/remotes/origin/4.1, and some other references are simply dropped.Allometry
OK, https://mcmap.net/q/12983/-how-to-create-a-git-repository-backup-with-bundle-where-there-is-no-linkage-after-cloning gives the solution (the issue is actually when "restoring" the repository from the bundle, not creating the bundle): git init ., then git fetch --update-head-ok /path/to/bundle '*:*'. I've checked that the output of git log --all --date=iso-local -m --name-status --decorate=full --graph --date-order is the same.Allometry
D
49

First clone the repository, and include the --mirror option.

git clone --mirror [email protected]:path/repo.git

This ensures all remote branched are also local branches ready for bundeling.

Then run

git bundle create repo.bundle --all as described by the answer from Jakub Narębski

Dolphin answered 8/12, 2015 at 14:21 Comment(1)
not sure if it's just me, but after running git bundle create --all - the submodules aren't thereCrossing
B
4

I would suggest you tar or zip the .git folder and simply unpack it in the new location and then do git reset --hard HEAD. Everything required for all the branches is under .git and all you should need to do is adjust any remotes in the .git/config file or remove them.

tar cf myrepo.tgz .git
cp myrepo.tgz [USB_STICK]
... move to new machine ...
mkdir myrepo && cd myrepo
tar xpf [USB_STICK]/myrepo.tgz
git reset --hard HEAD
Badenpowell answered 3/8, 2012 at 9:16 Comment(2)
One caveat is that you'll need to look at the .git/config file to check if the original repo owner had any user specific stuff in there.Reverential
@patthoyts: Given that it's disconnected, there'd be no remotes ;-) It does look like bundle is (may be) missing an option, and maybe clone (need to think about cloning from a bundle)Franko
L
4

With Git 2.34 (Q4 2021), git bundle create is further clarified:

See commit 1d9c8da, commit 0bb92f3, commit 9ab80dd, commit 5c8273d (31 Jul 2021) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit f19b275, 24 Aug 2021)

bundle doc: elaborate on object prerequisites

Signed-off-by: Ævar Arnfjörð Bjarmason

Split out the discussion bout "object prerequisites" into its own section, and add some more examples of the common cases.

See 2e0afaf ("Add git-bundle: move objects and references by archive", 2007-02-22, Git v1.5.1-rc1 -- merge) for the introduction of the documentation being changed here.

git bundle now includes in its man page:

OBJECT PREREQUISITES

When creating bundles it is possible to create a self-contained bundle that can be unbundled in a repository with no common history, as well as providing negative revisions to exclude objects needed in the earlier parts of the history.

Feeding a revision such as new to git bundle create will create a bundle file that contains all the objects reachable from the revision new. That bundle can be unbundled in any repository to obtain a full history that leads to the revision new:

$ git bundle create full.bundle new

A revision range such as old..new will produce a bundle file that will require the revision old (and any objects reachable from it) to exist for the bundle to be "unbundle"-able:

$ git bundle create full.bundle old..new

A self-contained bundle without any prerequisites can be extracted into anywhere, even into an empty repository, or be cloned from (i.e., new, but not old..new).

git bundle now includes in its man page:

The 'git bundle verify' command can be used to check whether your recipient repository has the required prerequisite commits for a bundle.

Larvicide answered 1/11, 2021 at 17:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.