views:

89

answers:

2

I have a git repository that i have packed with git repack -a -d, this repacked all the objects into one big file. This saves space. However I want to undo this, and turn that one big pack file into all the little object files.

The reason I want to do this is to backup the git repository to a remote server. I did a backup (before repacking). Installing git on the remote server is nontrivial, so I was going to use rsync to copy the files. However rsync is not this clever and will basically want to copy things again. If I can 'unpack' this repository, it might make it quicker to copy.

+5  A: 

git-unpack-objects will unpack the objects, but only inside a repo that doesn't contain the pack:

Make a new, empty repo:

mkdir new-repo; cd new-repo; git init

Write the objects in:

git unpack-objects < ../old-repo/.git/objects/pack/pack-XXX.pack

Pull the necessary branches/tags in:

git pull ../old-repo

Or, if you're adventurous, you could attempt to use the objects directory in new-repo as a replacement for the old one.

jleedev
+3  A: 

Actually, git-unpack-objects will work just fine if you first rename or move the pack file. It's designed to add an incoming pack to a repository, adding all objects that aren't already there. Just moving the pack file to a file name where git can't find it will make all its objects unfindable.

Basically:

mv .git/objects/pack .git/objects/pack.old for i in .git/objects/pack.old/pack-*.pack; do git-unpack-objects

However, be aware that a pack file is much smaller than the loose objects (because loose objects don't do delta-compression against each other), and while Linus originally intended to do exactly what you're doing (loose objects only and use rsync), he quickly found that it was unworkable.

The right way to do it is to repack once (with aggressive parameters to minimize the size) and then create a .keep file (if $i is pack-*.pack, you want to touch ${i%pack}keep). This will make the created pack file "sacred" and it will never be removed or repacked.

Then you can use rsync on the "leftover" pack, until it gets big enough to warrant bundling into a second .keep shunk.

A third way to do it would be to use git-bundle to make a pack containing just the deltas since the last backup.

Cypherpunks