Backing up Git repos with git bundle

Git bundle was designed as a secondary method to the patch refs.

Scenario you want to pass over to a colleague a set of commits before pushing them to remote "git push origin master ...", so you can do one of two things:

  1. Export each commit as a patch - pass the patches via e-mail the other side apply patches and commit to the remote repo.
    git format-patch master --stdout > fix_empty_poster.patch
    
  2. Use git bundle to export a binary [blob] holding the whole commit history [ commit => tree => blob ] of the git objects + their snapshot in time.
      git bundle create my_repo.bundle --all
    

    you could optionally specify SHA1's or revisions like so:
      git bundle create my_repo.bundle master ^SHA-1

Now isn't the title backing up git ? - well, what I did is use git bundle to backup repositories and the reason I found this most efficient is that the backup is one file [ so a simple git clone dosen't cut it !]

An exmaple of git bundle execution, verification & restore:

hagzag-HPZW520:chef-intro-repo(master) $ git bundle create ../chef-intro-repo2.bundle master ^2c7146fdd
Counting objects: 59, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (24/24), done.
Writing objects: 100% (53/53), 16.05 KiB, done.
Total 53 (delta 22), reused 50 (delta 19)

hagzag-HPZW520:chef-intro-repo(master) $ git bundle verify ../chef-intro-repo2.bundle
The bundle contains 1 ref
e0951a40daece16892cee2d831fc26d9bafbb5e6 refs/heads/master
The bundle requires this ref
2c7146fdd7dd3186afa228c54a7123306ec5a1a1 
../chef-intro-repo2.bundle is okay

Create a full repo bundle (--all)

hagzag-HPZW520:chef-intro-repo(master) $ git bundle create ../chef-intro-repo3.bundle --all
Counting objects: 374, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (180/180), done.
Writing objects: 100% (374/374), 90.98 KiB, done.
Total 374 (delta 124), reused 374 (delta 124)
hagzag-HPZW520:chef-intro-repo(master) $ cd ../

create a clean repository and switch into it:

hagzag-HPZW520:backup $ git init chef-intro-repo3
Initialized empty Git repository in /tmp/backup/chef-intro-repo3/.git/
hagzag-HPZW520:backup $ cd chef-intro-repo3/

Recover from the created bundle:

hagzag-HPZW520:chef-intro-repo3(master) $ git pull ../chef-intro-repo3.bundle
Receiving objects: 100% (374/374), 90.98 KiB, done.
Resolving deltas: 100% (124/124), done.
From ../chef-intro-repo3.bundle
 * branch            HEAD       -> FETCH_HEAD

Verify folder content:

hagzag-HPZW520:chef-intro-repo3(master) $ ll
total 48
drwxrwxr-x 2 hagzag hagzag  4096 May 13 21:12 certificates
-rw-rw-r-- 1 hagzag hagzag   156 May 13 21:12 chefignore
drwxrwxr-x 2 hagzag hagzag  4096 May 13 21:12 config
drwxrwxr-x 5 hagzag hagzag  4096 May 13 21:12 cookbooks
drwxrwxr-x 2 hagzag hagzag  4096 May 13 21:12 data_bags
drwxrwxr-x 2 hagzag hagzag  4096 May 13 21:12 environments
-rw-rw-r-- 1 hagzag hagzag 10850 May 13 21:12 LICENSE
-rw-rw-r-- 1 hagzag hagzag  2171 May 13 21:12 Rakefile
-rw-rw-r-- 1 hagzag hagzag  3521 May 13 21:12 README.md
drwxrwxr-x 2 hagzag hagzag  4096 May 13 21:12 roles

Verify git log

hagzag-HPZW520:chef-intro-repo3(master) $ git log --oneline -n 5
e0951a4 Import sudo version 2.0.4
9f2fc33 Update recipe to support synamic service name resolution ...
fc54694 Update cookbooks/ntp/README.md
a61df3b Update cookbooks/ntp/README.md
d983fb8 Update cookbooks/ntp/README.md

Compare with the original repository:

hagzag-HPZW520:chef-intro-repo3(master) $ cd ../chef-intro-repo
hagzag-HPZW520:chef-intro-repo(master) $ git log --oneline -n 5
e0951a4 Import sudo version 2.0.4
9f2fc33 Update recipe to support synamic service name resolution ...
fc54694 Update cookbooks/ntp/README.md
a61df3b Update cookbooks/ntp/README.md
d983fb8 Update cookbooks/ntp/README.md

Walla !

 

For my Local git repositories [the ones I do not have a remote for on Github/BitBucket due to customer regulations] - I do the following backup daily:

 

#!/bin/bash 

projects_dir=~/Projects
backup_base_dir=/tmp/backup

test -d ${backup_base_dir} || mkdir -p ${backup_base_dir}

pushd $projects_dir
  for repo in `find $projects_dir -type d -name .git`; do
    cd $repo/..
    this_repo=`basename $PWD`
    git bundle create ${backup_base_dir}/${this_repo}.bundle --all
    cd -
  done
popd

A reference to git bundle: http://git-scm.com/blog/2010/03/10/bundles.html

Hope you find this info useful - over & out, HP

Thank you for your interest!

We will contact you as soon as possible.

Send us a message

Oops, something went wrong
Please try again or contact us by email at info@tikalk.com