Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a git repository backup with bundle where there is no linkage after cloning

Tags:

git

Is there a way to create a backup using git bundle where there is no linkage to the bundle file after cloning from the backup? I'd like to backup my repositories to a single file with all history and restore them, exactly, later.

At the moment, I'm creating a backup using the following methodology:

$ mkdir here                  
$ cd here                                                                       
$ git init                                                                      
Initialized empty Git repository in /tmp/here/.git/                             
$ touch stuff                                                                   
$ git add stuff                                                                 
$ git commit -m "This is a file"                                                
[master (root-commit) c867bcf] This is a file                                   
 1 file changed, 0 insertions(+), 0 deletions(-)                                
 create mode 100644 stuff                                                       
$ git bundle create myrepo.bundle --all                                         
Counting objects: 3, done.                                                      
Writing objects: 100% (3/3), 212 bytes | 212.00 KiB/s, done.                    
Total 3 (delta 0), reused 0 (delta 0)

Alright, so at this point we have a bundle with a simple repository. Now, when we try to copy this repository from the bundle:

$ cd ..
$ mkdir there                                                                   
$ cd there                                                                      
/tmp/there $ git clone ../here/myrepo.bundle .                                  
Cloning into '.'...                                                             
Receiving objects: 100% (3/3), done.                                            
/tmp/there $ git remote -v                                                      
origin→ /tmp/there/../here/myrepo.bundle (fetch)                                
origin→ /tmp/there/../here/myrepo.bundle (push)

This shows that we have a link to the original bundle files, which I don't want. I also tried to create a mirror, but the problem remains the same:

$ cd ..                                                                         
$ mkdir there                                                                   
$ cd there                                                                      
$ git clone --mirror ../here/myrepo.bundle ./.git                               
Cloning into bare repository './.git'...                                        
Receiving objects: 100% (3/3), done.                                            
$ git config --bool core.bare false                                             
$ git reset --hard HEAD                                                         
HEAD is now at c867bcf This is a file                                           
/tmp/there $ git remote -v                                                      
origin→ /tmp/there/../here/myrepo.bundle (fetch)                                
origin→ /tmp/there/../here/myrepo.bundle (push) 

Although we could just copy the entire repository as is to back things up, I really only want to backup a single file that only contains the files currently under revision. I've been backing up the directories and it's been causing a mess with all of the leftover files. As such, I'd really only like to archive a single file, which is why I'm using bundle, and I'd like the recovery from the backup to be clean as in no linkages at all to the bundle file. Thanks for the help.

like image 882
wyer33 Avatar asked Jan 21 '18 20:01

wyer33


1 Answers

Instead of cloning from the bundle, create a new repository and fetch using a wildcard refspec. I have added a second branch feature and a tag v1.0 to the example to make this more illustrative:

$ mkdir there
$ git init .
$ git fetch --update-head-ok ../here/myrepo.bundle '*:*'
Receiving objects: 100% (5/5), done.
From ../here/myrepo.bundle
 * [new tag]         v1.0       -> v1.0
 * [new branch]      master     -> master
 * [new branch]      feature    -> feature
$ git checkout

The *:* refspec will fetch all remote refs into equally named local refs, creating them if they don't exist. The --update-head-ok argument is needed since git init will create a master branch which is likely also present in the remote.

Since this is a fetch with a direct URL, no remotes are needed at all. Note that this would work equally for any kind of source repo URL, not just for bundles.

The equality of the refs of the old and new repository can be checked by comparing the output of git show-ref in both repositories, they should be identical.

like image 166
mmlr Avatar answered Oct 24 '22 06:10

mmlr