巨型代码库进行git push非常缓慢

5
我遇到了与这个问题相同的情况-git push is very slow for a branch,但那里的答案并不适用于我的情况。我正在使用一个非常大的公司GitHub仓库。我的操作如下:
1)从主分支拉取
2)创建新分支
3)提交
4)推送分支以创建拉取请求。
当我在第四步中推送分支时,它想要写入100万个对象,这需要大约3GB,而我所做的提交只是更改了一行。如果我去GitHub UI,并在UI中使用与(2)中相同的名称创建一个分支,然后将其推送到该分支,则推送时间少于一秒。不用说,主分支和我的分支之间的更改非常小(未添加或删除大文件)。
我应该怎么做才能使Git仅推送相关数据而不是整个仓库呢?
Windows版本为Git 2.17.0。

如果你运行 git show --name-status <你的分支>,会有多少个文件? - max630
在什么时候运行这个? - Buzzy
在第三步之后,提交。 - max630
好的...这也取决于您的tty输出:https://twitter.com/33asr/status/1097165302125789184 - VonC
对于一个大型的代码库,现在(2019年第一季度)使用Git For Windows 2.21版本,可以通过设置pack.sparse参数来提高推送性能。请参见我的回答 - VonC
2个回答

5
您可以尝试以下方法进行推送:

这个选项来自于这些补丁, 并且在提交d5d2e93中实现,其中包括以下评论:

这些改进将在超大型Windows代码库中获得更大的益处。

这对您的情况应该很有帮助。

请查看探索Git push性能的新前沿,作者为Derrick Stolee

git push通常会显示如下内容:

$ git push origin topic
Enumerating objects: 3670, done.
Counting objects: 100% (2369/2369), done.
Delta compression using up to 8 threads
Compressing objects: 100% (546/546), done.
Writing objects: 100% (1378/1378), 468.06 KiB | 7.67 MiB/s, done.
Total 1378 (delta 1109), reused 1096 (delta 832)
remote: Resolving deltas: 100% (1109/1109), completed with 312 local objects.
To https://server.info/fake.git
* [new branch] topic -> topic

"枚举"的意思是:
Git构建一个包含您尝试推送的提交以及服务器需要理解该提交的所有提交、树和blob(统称为对象)的打包文件。它找到一组提交、树和blob,使得每个可达对象都在集合中或已知存在于服务器上。
目标是找到正确的“边界”。

https://devblogs.microsoft.com/devops/wp-content/uploads/sites/6/2019/05/sparse-push-commit-walk.png

无趣的提交是有趣的提交的直接父级,它们形成了边界

原文:

为了确定哪些树和blob是有趣的,旧算法首先确定了所有无趣的树和blob。

从边界中的每个无趣提交开始,从其根树递归地遍历并将所有可达的树和blob标记为无趣。此遍历跳过已标记为无趣的树,以避免重新访问可能很大的图的部分。

https://devblogs.microsoft.com/devops/wp-content/uploads/sites/6/2019/05/sparse-push-old-algorithm.png

新的算法

旧算法是递归的:它接受一棵树并对所有子树运行算法。

新算法使用路径来缩小树遍历的范围。它也是递归的,但它接受一组树。
当我们开始算法时,树集包含不感兴趣和感兴趣提交的根树。

https://devblogs.microsoft.com/devops/wp-content/uploads/sites/6/2019/05/sparse-push-new-algorithm.png

新的树遍历递归地探索包含有趣和无趣树的路径。
B中的树内,我们有名为FG的子树。
两组都有有趣和无趣的路径,所以我们递归进入每个集合。这继续到B/FB/GB/F集合不会递归到B/F/MB/F/N,而B/G集合不会递归到B/G/X但不包括B/G/Y

0

听起来像是行尾问题。

如果你在 Windows 机器上检出一个仓库,Unix(LF)行尾符将被转换为 Windows(CR LF)行尾符。
当你提交时,Git 将认为所有文件都已更新,因为所有行尾符都已更改。

你可以使用以下命令配置 Git 来管理此问题:

git config --global core.autocrlf true


1
“因为所有的行结尾都会改变”,但只有在您使用某个编辑器打开文件并覆盖它们时才会发生,对吗? 对我来说似乎不是这种情况。 - Frax
我认为如果你在Windows系统上检出一个仓库,Git会转换所有文件的结尾,无论是否打开这些文件。尝试使用git checkout mastergit status命令。假设你没有在主分支上进行任何更改,所以如果Git状态中列出了所有文件被修改,则文件结尾可能已经发生了变化。 - barro32
@barro32 实际上它是在幕后完成的,因此文件不会被标记为已更改。 - Buzzy

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