git - 如何撤销 "git repack -ad" 命令?

5
我有一个使用git repack -a -d打包的Git存储库,这将所有对象打包成一个大文件,从而节省空间。然而,我想撤销此操作,并将该大包文件转换为所有小对象文件。
我之所以要这样做是为了将Git存储库备份到远程服务器。我在备份(重新打包之前)时安装了Git。在远程服务器上安装Git并不容易,因此我打算使用rsync复制文件。但是rsync并不聪明,它基本上会再次复制东西。如果我可以“解压缩”这个存储库,可能会更快地复制。

1
即使您可以解包它,我怀疑您是否能将其放入与之前完全相同的一组包/对象中。 - Nicolás
这是真的 - 当对象数量增长时,git 偶尔会自动产生一个 pack,因此您最终将被迫移动一个新的 pack。 - Josh Lee
如果不完全相同,我会很高兴。能够改进事情将是很好的。 - Amandasaurus
3个回答

7

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中的对象目录来替换旧的目录。


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

然而,请注意,打包文件比散装对象要小得多(因为散装对象不会相互进行增量压缩),尽管Linus最初想要做的正是你正在做的事情(仅使用散装对象并使用rsync),但他很快发现这是行不通的。
正确的做法是重新打包一次(使用激进的参数以最小化大小),然后创建一个.keep文件(如果$ipack-*.pack,则需要执行touch ${i%pack}keep)。 这将使创建的打包文件“神圣化”,永远不会被删除或重新打包。
然后,您可以在“剩余”的打包文件上使用rsync,直到它变得足够大以需要捆绑到第二个.keep块中。
第三种方法是使用git-bundle制作仅包含自上次备份以来的增量的打包文件。

1

你可以尝试做一个

fast-export | fast-import

将其放入一个新的存储库中。很可能不会触发任何打包操作。 否则,您可以调整打包配置(man git config,搜索pack.*)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接