Git - 推送一个大型项目的远程分支非常慢

15

我们公司正在转向使用Git。我们有一个相当大的项目,其中一些资源较大,并且已经被版本控制(约500MB)。

今天我们试图将一个分支推送到远程服务器,但很惊讶地发现Git似乎要上传整个项目。我本以为Git只会像正常推送到主分支一样,仅发送4-5个文本文件的差异部分。难道远程分支不是这样工作的吗?我们使用了git push origin some_branch_name命令,在这种情况下有更好的命令使用吗?我们不应该在Git中存储大型资源吗?如果不是,人们通常如何处理这种情况?还有没有更好的方式让一名开发人员与另一名开发人员共享正在进行的工作,而不将更改提交到主分支?目前,我们需要花费大约15分钟来推送一个远程分支,这实在无法接受。我们做错了什么?


你尝试过 git push origin HEAD:some_branch_name 吗? - devang
1
同样的结果。我正在测试一个删除了一个文件的分支。运行几分钟后,它会显示“Writing objects: 17% (8153/46698), 192.53 MiB | 2.46 MiB/s”。 - herbrandson
1
你上次在本地仓库运行 git gc 是什么时候?我不确定这是否是问题的原因(例如,我不知道为什么会导致向网络写入更多数据),但我已经看到它显著加速了各种 git 操作。 - rra
1
@rra 'git gc' 没有帮助。 - herbrandson
2个回答

2

你能更新一下你的帖子吗?

为了更好地了解你的项目,可以发布以下前10个参赛作品:

git log --decorate=short --oneline --graph --all

如果大型资源是二进制文件,那么它们不应该存储在Git中。如果这些二进制资源被更新,Git则必须在内部完全复制它们,但压缩算法不喜欢这样做并将其发送到服务器。至于要怎么处理这些资源,这取决于具体情况,你需要详细说明。
听起来好像你有几个开发人员在同一个远程库上工作,这是正确的吗?如果是这样,没有开发人员应该直接提交到主分支(在我看来无论如何都不应该这样做)。每个开发人员都可以拥有自己命名的分支。例如,开发人员John可以在john/下创建所有自己的分支。这将有助于保持工作流清洁。
此外,Git不使用增量。每次更改时,它都会完整地存储文件。这可能看起来效率低下,但使用的压缩方法可以将文件大小保持到最小,并帮助加快检出和扫描日志历史的速度。阅读Git Basics的第一部分以获得可视化的解释。

5
这并不能解释为什么Git在只有少量文件更改时推送整个存储库(或者感觉像是推送整个存储库),事实上有很多二进制文件也不应该使得推送变慢(如果没有任何更改)。 - grahamrhay
我认为这可能与此有关 https://dev59.com/9l4b5IYBdhLWcg3wchTs ?执行 git fetch 可以快速设置传输。或者类似的操作。 - Phil Martin

1
另一个因素可以解释git push的性能不佳:
在处理引用的旧值和新值列表时,"git push"曾经检查对象名称和引用名称之间的歧义,但这是不必要的(因为它知道正在提供原始对象名称)。

查看提交 a4544b3(2018年11月6日)由Derrick Stolee (derrickstolee)提交。
协助者:Jeff King (peff)
(由Junio C Hamano -- gitster --提交 1373999中合并,2018年11月19日)

pack-objects: 忽略模糊对象警告

git push 进程在运行过程中会运行多个进程,其中包括 git send-pack,它调用 git pack-objects 并使用对象 ID 将已知的 have/wants 传递到 stdin 中。

然而,默认设置下的 core.warnAmbiguousRefs 要求 git pack-objects 检查与 refs.c 中的 ref_rev_parse_rules 数组匹配的 ref 名称。
这意味着每个对象都会触发至少六次“文件存在?”查询。

当有大量 refs 时,这可能会显著增加!
我观察到一个简单的 push 在检查这些路径上花费了三秒钟。

Git 2.20(2018年第4季度)已经修复了这个问题。


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