【问题标题】:git push is very slow for a huge repogit push 对于一个巨大的仓库来说非常慢
【发布时间】:2018-11-12 22:31:00
【问题描述】:

我遇到了与 - git push is very slow for a branch 相同的问题 但那里的答案不适合我的情况。

我正在与一个拥有非常大的 repo 的公司 GitHub 合作。我的流程如下:

1) 从主服务器拉取

2) 创建新分支

3) 提交

4) 推送分支以创建拉取请求。

在 (4) 上推送分支时,它想要写入超过 1,000,000 个对象,而我所做的提交仅更改 1 行,这需要大约 3gb。

如果我转到 GitHub UI 并从 UI 创建一个与 (2) 中同名的分支,然后推送到该分支,推送时间不到一秒。不用说master和我的分支之间的变化很小(没有添加或删除大文件)。

如何让 Git 只推送相关数据而不推送整个 repo?

Windows 版本 2.17.0 上的 Git

【问题讨论】:

  • 如果你运行git show --name-status <your branch>,有多少个文件?
  • 什么时候运行这个?
  • 第三步之后,提交
  • 嗯...它还取决于您的 tty 输出:twitter.com/33asr/status/1097165302125789184
  • 对于大型 repo,您​​现在(2019 年第一季度)拥有 Git For Windows 2.21 的配置 pack.sparse,它可以帮助提高推送的性能。见my answer below

标签: git github


【解决方案1】:

这听起来像是一个行尾问题。

如果您在 Windows 机器上签出 repo,则 Unix (LF) 行结尾将转换为 Windows (CR LF)。
当你提交时,Git 会认为所有文件都已更新,因为所有的行尾都将发生变化。

您可以使用以下命令配置 Git 为您管理:

git config --global core.autocrlf true

【讨论】:

  • “因为所有的行尾都会改变”,好吧,只有当你用一些会覆盖它们的编辑器打开文件时,对吧?听起来对我来说不是这样。
  • 我认为,如果您在 Windows 系统上签出 repo,Git 将转换所有文件结尾,无论是否打开文件。试试git checkout mastergit status。大概您没有对 master 进行任何更改,因此如果所有文件都在 Git 状态中列为正在修改,那么文件结尾可能已经更改。
  • @barro32 实际上它是在幕后完成的,因此文件不会被标记为已更改。
【解决方案2】:

你可以尝试同样的推送:

此选项来自those paches,并在commit d5d2e93中实现,其中包含注释:

这些改进将在超级 大型 Windows 存储库。

这对你来说应该很有趣。

参见Derrick Stolee中的“Exploring new frontiers for Git push performance

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,这样每个可访问对象要么在集合中,要么已知在服务器上。

目标是找到正确的“边界”

作为有趣提交的直接父级的无趣提交构成了边界

旧:

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

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

旧算法是递归的:它需要一棵树并在所有子树上运行该算法。

新算法使用路径来缩小树遍历的范围。它也是递归的,但它需要一组树。
当我们开始算法时,这组树包含了无趣提交和有趣提交的根树。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多