user1283719
user1283719

Reputation: 561

restoring git repository from bundle backup

i created backups of my git repository like in How to backup a local Git repository? proposed with

git bundle create /tmp/foo-all --all

I can see all refs are in there, including a remote ref created by git-svn. Now I can't figure out how to restore this bundle to a local repository again. I am quite quite sure i've done it already once. I tried git-clone but that gives me a just a repository with my backup bundle as remote repo.

I also tried

git init
git bundle unbundle /tmp/foo --all 

but this just lists all references...

Verifying the bundle gives:

$ git bundle verify $somewhere/foo.bundle 
The bundle contains 12 refs
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/master
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/heads/xxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx refs/remotes/git-svn
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx HEAD
The bundle requires these 0 ref
$somewhere/foo.bundle is okay

Upvotes: 55

Views: 71365

Answers (6)

VonC
VonC

Reputation: 1329622

git bundle unbundle /tmp/foo --all 

but this just lists all references...

Actually, it now can do more than that:

Git 2.34 (Q4 2021) adds progress display to "git bundle unbundle"(man)".

In addition to git bundle verify mentioned in this answer, it will show you at least what is going on.

See commit d941cc4, commit f46c46e, commit 7366096 (05 Sep 2021), and commit 0834257 (26 Aug 2021) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit 67fc02b, 20 Sep 2021)

bundle: show progress on "unbundle"

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

The "unbundle" command added in 2e0afaf ("Add git-bundle: move objects and references by archive", 2007-02-22, Git v1.5.1-rc1 -- merge) did not show progress output, even though the underlying API learned how to show progress in be042af ("Teach progress eye-candy to fetch_refs_from_bundle()", 2011-09-18, Git v1.7.8-rc0 -- merge).

Now we'll show "Unbundling objects" using the new --progress-title option togit index-pack"(man), to go with its existing "Receiving objects" and "Indexing objects" (which it shows when invoked with "--stdin", and with a pack file, respectively).

Unlike "git bundle create"(man) we don't handle "--quiet" here, nor "--all-progress" and "--all-progress-implied".
Those are all specific to "create" (and "verify", in the case of "--quiet").

The structure of the existing documentation is a bit unclear, e.g. the documentation for the "--quiet" option added in 79862b6 ("bundle-create: progress output control", 2019-11-10, Git v2.25.0-rc0 -- merge listed in batch #2) only describes how it works for "create", and not for "verify".
That and other issues in it should be fixed, but I'd like to avoid untangling that mess right now.
Let's just support the standard "--no-progress" implicitly here, and leave cleaning up the general behavior of "git bundle"(man) for a later change.

git bundle now includes in its man page:

'git bundle' unbundle [--progress] <file> [<refname>...]

"git bundle unbundle"(man) outside a repository triggered a BUG() unnecessarily: that has been corrected with Git 2.47 (Q4 2024), batch 7.

See commit 96a9a3e, commit 7298bcc (13 Aug 2024) by Patrick Steinhardt (pks-t).
(Merged by Junio C Hamano -- gitster -- in commit b772c9c, 21 Aug 2024)

builtin/bundle: have unbundle check for repo before opening its bundle

Reported-by: ArcticLampyrid
Suggested-by: Jeff King
Signed-off-by: Patrick Steinhardt

The git bundle unbundle(man) subcommand requires a repository to unbundle the contents into.
As thus, the subcommand checks whether we have a startup repository in the first place, and if not it dies.

This check happens after we have already opened the bundle though.
This causes a segfault when running outside of a repository starting with c8aed5e ("repository: stop setting SHA1 as the default object hash", 2024-05-07, Git v2.46.0-rc0 -- merge listed in batch #9) because we have no hash function set up, but we do try to parse refs advertised by the bundle's header.

And:

bundle: default to SHA1 when reading bundle headers

Helped-by: brian m. carlson
Signed-off-by: Patrick Steinhardt

We hit a segfault when trying to open a bundle via git bundle list-heads(man) when running outside of a repository.
This is caused by c8aed5e ("repository: stop setting SHA1 as the default object hash", 2024-05-07, Git v2.46.0-rc0 -- merge listed in batch #9), which stopped setting the default object hash so that the_hash_algo is a NULL pointer when running outside of any repo.

This is only a symptom of a deeper issue though.
Bundles default to the SHA1 object format unless they advertise an "@object-format=" header.
Consequently, it has been wrong in the first place to use the object format used by the current repository when parsing bundles.
The consequence is that trying to open a bundle that uses a different object hash than the current repository will fail:

$ git bundle list-heads sha1.bundle
error: unrecognized header: ee4b540943284700a32591ad09f7e15bdeb2a10c HEAD (45)

Fix the bug by defaulting to the SHA1 object hash.
We already handle the "@object-format=" header as expected, so we don't need to adapt this part.

Upvotes: 0

JamesTBennett
JamesTBennett

Reputation: 2311

This should be the answer git clone -b main <bundleName.bundle>

Upvotes: 7

anton_rh
anton_rh

Reputation: 9223

I tried git-clone but that gives me a just a repository with my backup bundle as remote repo.

Bundle doesn't store original repository URL. You have to specify it manually:

git clone foo.bundle
cd foo
git remote set-url origin url-to-original-repository

Now you can fetch from and push to original repository.

Upvotes: 3

masterdany88
masterdany88

Reputation: 5351

I newer version of git is enough to do:

git clone bundle.file

the whole commands:

mkdir ~/git
cd ~/git
git clone /path/to/bundle.file

It will restore completely Your's git bare repository content (which will compile as it is normal source). You don't need any other file. The bundle file is enough.

It is wise to always verify You bundle file before unbundle as follow:

git bundle verify /path/to/bundle.file 

Upvotes: 43

fbicknel
fbicknel

Reputation: 1383

Short answer:

$ git bundle verify $somewhere/foo.bundle
$ git clone $somewhere/foo.bundle
Cloning into 'foo'...
Receiving objects: 100% (10133/10133), 82.03 MiB | 74.25 MiB/s, done.
Resolving deltas: 100% (5436/5436), done.
$ cd foo
$ git status
...

Lazy Badger said this, but it's in the last paragraph. :)

Upvotes: 58

Lazy Badger
Lazy Badger

Reputation: 97395

Bundle contain not files, but deltas, you need the base in order to recreate the file content. You have to clone first, unbundle later. Init instead of clone allowed only in case, where bundle requires 0 refs

Don't ignore git bundle verify before unbundling

git-bundle(1) - Linux man page

Used to check that a bundle file is valid and will apply cleanly to the current repository. This includes checks on the bundle format itself as well as checking that the prerequisite commits exist and are fully linked in the current repository. git bundle prints a list of missing commits, if any, and exits with a non-zero status.

If you are creating the repository, then you can clone from the bundle as if it were a remote repository instead of creating an empty repository and then pulling or fetching objects from the bundle

Upvotes: 11

Related Questions