git - 如何撤消“git repack -ad”?

时间:2010-01-12 21:51:16

标签: git version-control

我有一个git存储库,我已经打包了git repack -a -d,这将所有对象重新打包成一个大文件。这节省了空间。但是我想要撤消这个,并将那个大包文件转换为所有小目标文件。

我想这样做的原因是将git存储库备份到远程服务器。我做了备份(重新包装前)。在远程服务器上安装git是非常重要的,所以我打算使用rsync来复制文件。然而,rsync并不聪明,基本上想要再次复制。如果我可以“解压缩”此存储库,则可以更快地复制。

3 个答案:

答案 0 :(得分:5)

git-unpack-objects会解压缩对象,但只能在包含该包的仓库中解压缩:

制作一个新的空仓库:

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

将对象写入:

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

拉入必要的分支/标签:

git pull ../old-repo

或者,如果您喜欢冒险,可以尝试使用new-repo中的对象目录替代旧目录。

答案 1 :(得分:4)

实际上,如果首先重命名或移动包文件,git-unpack-objects将正常工作。它旨在将传入包添加到存储库,添加所有尚未存在的对象。只需将包文件移动到git无法找到的文件名,就会使其所有对象都不可用。

基本上:

mv .git/objects/pack .git/objects/pack.old
for i in .git/objects/pack.old/pack-*.pack; do
    git-unpack-objects < $i && rm $i ${i%pack}idx
done
rmdir .git/objects/pack.old

但是,请注意,打包文件 小于松散的对象(因为松散的对象不会相互进行delta压缩),而Linus最初的目的是做什么你正在做(只有松散的物体并使用rsync),他很快发现它不可行。

正确的方法是重新打包一次(使用激进的参数来最小化大小),然后创建一个.keep文件(如果$ipack-*.pack,你想要touch ${i%pack}keep })。这将使创建的包文件“神圣”,并且永远不会被删除或重新打包。

然后你可以在“剩余”包上使用rsync,直到它变得足够大以保证捆绑到第二个.keep shunk。

第三种方法是使用git-bundle创建一个仅包含自上次备份以来的增量的包。

答案 2 :(得分:1)

你可以尝试做一个

fast-export | fast-import
进入一个新的回购。有可能不会触发任何包装。 否则,您可以调整pack的配置(man git config,搜索pack。*)