git 尽管提交非常小,但在大型代码库上推送会永远持续下去——为什么,这是可以修复的吗?

git push is taking forever on large codebase despite very small commit -- why, and is that fixable?

(很抱歉,如果之前有人回答过这个问题——我找不到这个具体问题,其他人都出于不相关的原因遇到了这个问题。请随时指出我错过的问题。)

由于提交了大量大文件,我正在使用一个非常大的存储库。我最近对它进行了浅层克隆(深度=1),然后在 master 上进行了很大的更改。然后我分支,做了一个小的提交,然后推送到那个新分支。将它向上推送需要很长时间,即使它只是在远程 (Bitbucket) 已经知道的提交之上添加一个小提交(15 kb,一个文件受影响)。我看到的消息如下所示:

silasbarta$ git push origin HEAD
Counting objects: 21034, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (11817/11817), done.
Writing objects:   4% (967/21034), 406.50 MiB | 1.36 MiB/s

运行 git gc 没有改变这个。

为什么它需要处理所有这些对象?它应该只需要知道我的提交差异和对先前提交哈希的引用,它已经在原点上了,对吧?

在某些情况下,使用浅克隆时发送方 Git 没有意识到接收方 Git 已经拥有大部分文件。这是因为一个 Git 了解另一个 Git 的方式是通过哈希 ID。浅克隆与哈希 ID 混淆:提交 a123456 说它有 b789abc 作为父项,然后有一个特殊记录说 ... 但我们没有 b789abc。 Git 然后假装 a123456 毕竟不是 a123456

有些情况本可以更好地处理,但事实并非如此。使用稍深的克隆 (--depth 2) 可能 可以避免这种情况,但这里并不能真正保证。 Git 的代码在确定它可以省略的内容方面有一点不完善,以便使通常的情况更快。