How to backup a local Git repository?
[Just leaving this here for my own reference.]
My bundle script called git-backup
looks like this
#!/usr/bin/env ruby
if __FILE__ == $0
bundle_name = ARGV[0] if (ARGV[0])
bundle_name = `pwd`.split('/').last.chomp if bundle_name.nil?
bundle_name += ".git.bundle"
puts "Backing up to bundle #{bundle_name}"
`git bundle create /data/Dropbox/backup/git-repos/#{bundle_name} --all`
end
Sometimes I use git backup
and sometimes I use git backup different-name
which gives me most of the possibilities I need.
The way I do this is to create a remote (bare) repository (on a separate drive, USB Key, backup server or even github) and then use push --mirror
to make that remote repo look exactly like my local one (except the remote is a bare repository).
This will push all refs (branches and tags) including non-fast-forward updates. I use this for creating backups of my local repository.
The man page describes it like this:
Instead of naming each ref to push, specifies that all refs under
$GIT_DIR/refs/
(which includes but is not limited torefs/heads/
,refs/remotes/
, andrefs/tags/
) be mirrored to the remote repository. Newly created local refs will be pushed to the remote end, locally updated refs will be force updated on the remote end, and deleted refs will be removed from the remote end. This is the default if the configuration optionremote.<remote>.mirror
is set.
I made an alias to do the push:
git config --add alias.bak "push --mirror github"
Then, I just run git bak
whenever I want to do a backup.
The other official way would be using git bundle
That will create a file that supports git fetch
and git pull
to update your second repo.
Useful for incremental backup and restore.
But if you need to backup everything (because you do not have a second repo with some older content already in place), the backup is a bit more elaborate to do, as mentioned in my other answer, after Kent Fredric's comment:
$ git bundle create /tmp/foo master
$ git bundle create /tmp/foo-all --all
$ git bundle list-heads /tmp/foo
$ git bundle list-heads /tmp/foo-all
(It is an atomic operation, as opposed to making an archive from the .git
folder, as commented by fantabolous)
Warning: I wouldn't recommend Pat Notz's solution, which is cloning the repo.
Backup many files are always more tricky than backing up or updating... just one.
If you look at the history of edits of the OP Yar answer, you would see that Yar used at first a clone --mirror
, ... with the edit:
Using this with Dropbox is a total mess.
You will have sync errors, and you CANNOT ROLL A DIRECTORY BACK IN DROPBOX.
Usegit bundle
if you want to back up to your dropbox.
Yar's current solution uses a git bundle
.
I rest my case.