在git中清理垃圾提交

15

我有一些由git subtree创建的提交,我想进行垃圾回收(更多是为了理解可以回收什么和为什么可以回收,而不是出于实际目的)。

我已经检查过这些提交,并没有被以下方式引用:

# In any reflog
> git reflog --all --no-abbrev-commit | grep <hash>
(no output)

# In any branch, local or remote
> git branch --contains <hash>
(no output)
> git branch -r --contains <hash>
(no output)

# In any tag
> git tag --contains <hash>
(no output)

# In the current index
> git rev-list HEAD | grep <hash>
(no output)

# In references from filter-branch
> ls .git/refs/original/
(the folder does not exist)

这些是 git gc 文档 列出的可能包含引用的地方。

即使在运行了 git gc 之后,给定的提交仍然存在。

我是否遗漏了什么?或者是否有任何 git 管道命令可以检查所有这些引用?

2个回答

20

每次当我想删除一些松散的物品时,我都会使用以下命令:

rm -rf .git/refs/original/*
git reflog expire --all --expire-unreachable=0
git repack -A -d
git prune

1
太棒了,缺少的是重新打包。即使是无法访问的对象,如果与可访问的对象一起打包,也不会被处理掉。所以 repack 将它们分开,然后 git prunegit gc 会妥善处理它们。 - Maic López Sáenz
即使使用 git prune,我的代码库仍然有松散的对象。如果你遇到这种情况,git gc 文档指出它会尽最大努力保持安全,并保留任何可能的引用。请确保清理 /refs/logsFETCH_HEAD 和其他可能在 .git 文件夹中找到的缓存。然后重新运行 git gc --prune=now 就可以解决问题了。 - jsgoupil

6

提交记录(或一般对象)直到它们被解压成松散的对象并保持至少2周后才会被实际删除。您可以使用git gc --prune=now来跳过这2周的延迟。

通常,Git会将对象打包到一起形成packfile。这比拥有松散对象提供了更好的压缩和效率。每当执行git gc时,通常都会发生这种情况。然而,如果一个对象没有被引用,则git gc将其解压回到一个松散对象中。

一旦解压,git gc将自动清理旧的未引用的松散对象。这由--prune=<date>标志控制,默认为2周前,因此它会修剪任何旧的未引用的对象,其年龄超过2周。通过指定--prune=now,您正在请求git gc修剪任何早于现在的对象,这基本上意味着修剪任何存在的未引用对象。


1
尝试过这个,但提交仍未被收集。 - Maic López Sáenz
2
@LopSae:你尝试运行git fsck --unreachable命令以确保你的提交真的是不可达的了吗? - Lily Ballard
1
刚试了一下,但没有显示出来,这意味着它可以从某个地方访问,但我找不到它的来源。 - Maic López Sáenz
1
@LopSae:你可以尝试使用 git describe --all --contains <hash> - Lily Ballard
1
是的,我替换了响应中的“哈希”,只是为了不让注释混乱。 - Maic López Sáenz
显示剩余4条评论

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