【问题标题】:git checkout to a branch takes long timegit checkout 到一个分支需要很长时间
【发布时间】:2018-07-27 04:06:00
【问题描述】:

我在 Ubuntu 17.10 上使用 git(版本 2.14.1)。每当我从 master 创建一个分支并尝试签出到它(或从它到 master)时,这需要很多时间,大约几分钟,有时将近 10 分钟。没错,我有几 GB 的数据,但据我了解,整个数据实际上并没有被复制,而是只保存了更改。那么这背后的问题可能是什么?

【问题讨论】:

  • 如果我结帐到新创建的分支,为什么内容会改变?
  • master 和你的分支之间是否有重大变化?也许这篇值得一读:stackoverflow.com/questions/15296473/…
  • data doesn't actually get copied and instead only the changes are saved --- 你是什么意思?提交文件的保存快照,而不是差异。
  • 我意识到这只会发生在特定的机器上,而不会发生在其他机器上。在这台机器上,所有的 git 操作都很慢。这台机器有 I7 处理器和 8GB RAM,但这种情况仍在发生。
  • @Peaceful 当您在该 PC 上切换分支时,CPU 百分比是否有很大变化(或没有变化)?而且git版本在其他机器上也是2.14.1,切换时间正常吗?

标签: git version-control git-branch git-checkout


【解决方案1】:

您应该运行 git gc 以提高性能。

git gc 的目的有两个:删除松散对象和打包对象以更有效地使用磁盘空间。

在当前存储库中运行许多内务处理任务,例如压缩文件修订(以减少磁盘空间并提高性能)和删除可能从之前调用 git add 创建的无法访问的对象。

https://git-scm.com/docs/git-gc

【讨论】:

    【解决方案2】:

    虽然 Git 2.20 和 2.21 提高了 git checkout 的性能(请参阅下面的下一节),但从 Git 2.23(2019 年 8 月)开始,您应该使用 git switch instead

    随着 Git 2.24(2019 年第四季度)git switch 的性能恢复。
    确实对 OP 使用的git checkout -b 有影响。

    参见Derrick Stolee (derrickstolee)commit 3136776(2019 年 8 月 29 日)。
    (由 Junio C Hamano -- gitster -- 合并于 commit 3ff6af7,2019 年 9 月 30 日)

    checkout: 为 'git checkout -b' 添加简单检查

    创建“git switch”命令是为了分隔“git checkout”的一半行为。

    如果用户只指定创建一个新分支并将HEAD更改为该分支,则它特别具有对索引和工作目录不执行任何操作的模式 分支。
    这也是大多数用户对“git checkout -b”所期望的行为,但由于历史原因,它还通过扫描工作目录来执行索引更新。
    这可能很慢 strong> 适用于中等规模的存储库。

    fa655d8 引入了针对“git checkout -b”的性能修复(checkout:优化“git checkout -b <new_branch>”2018-08-16,Git v2.20.0-rc0)。
    当需要稀疏结帐功能时,该更改包括有关配置设置 checkout.optimizeNewBranch 的详细信息。
    如果此行为更改是安全的,则此更改检测的方法是通过 skip_merge_working_tree() 方法。
    这种方法很复杂,需要随着新选项的引入而更新。

    65f099b 基本上恢复了这种行为(“switch:除非发生真正的分支切换,否则没有工作树状态”2019-03-29,Git v2.23.0-rc0)。
    相反,checkout_opts struct 的两个成员用于区分“git checkout”和“git switch”:

    * `switch_branch_doing_nothing_is_ok`
    * `only_merge_on_switching_branches`
    

    根据我们是从cmd_checkout 还是cmd_switch 开始,这些设置具有相反的值。

    65f099b 的消息包括“鼓励大回购的用户转而使用。
    在“git switch”仍处于试验阶段时进行此更改过于激进。

    通过使“git checkout -b <branch>”的行为类似于“git switch”,在这两个选项之间创建一个快乐的媒介,但前提是我们准确地阅读了这些参数。
    这必须在cmd_checkout 中完成,以避免选项解析逻辑消耗参数。

    这与 fa655d8 之前的更改不同,配置选项 checkout.optimizeNewBranch 仍然被删除。
    这意味着即使我们有一个稀疏签出文件,“git checkout -b”也会忽略索引合并。
    虽然这是“git checkout -b”的行为更改,但它与“git switch -c”的行为相匹配。


    Git 2.20(2018 年第四季度)将提高 git checkout 速度:

    git checkout -b newbranch [HEAD]”不应该像检查与 HEAD 不同的提交一样多。
    尝试优化这种特殊情况。

    参见Ben Peart (benpeart)commit fa655d8(2018 年 8 月 16 日)。
    (由 Junio C Hamano -- gitster -- 合并于 commit 0faaf7e,2018 年 9 月 17 日)

    checkout:优化“git checkout -b <new_branch>

    当且仅当我们通过“git checkout -b <new_branch>.”创建新分支时,才跳过合并提交、更新索引和工作目录
    任何其他结帐选项仍将通过以前的代码路径。

    如果sparse_checkout 已打开,则要求用户通过将配置设置checkout.optimizeNewBranch 设置为true 来手动选择加入此优化行为,因为我们将不再更新索引中的skip-worktree 位,也不会添加/删除工作目录中的文件以反映当前的稀疏签出设置。

    为了比较,在大型回购上运行“git checkout -b <new_branch>”需要:

    14.6 seconds - without this patch
    0.3 seconds - with this patch
    

    Git 2.21(2019 年第一季度)进一步优化了 git checkout,因为 git checkout -b <new> [HEAD]" 用于从当前提交创建一个新分支并检查它应该是索引中的空操作,并且工作树在正常情况,但有些极端情况确实需要更新索引和工作树。

    在“git clone --no-checkout”之后立即运行它就是其中之一 早期优化错误启动的情况 已修复。

    参见Ben Peart (benpeart)commit 8424bfdcommit 91e3d7c(2019 年 1 月 23 日)。
    (由 Junio C Hamano -- gitster -- 合并到 commit 5ad3550,2019 年 2 月 5 日)

    checkout:在初始结帐时修复 checkout -b 中的回归

    在执行“checkout -b”时,请进行完整的结帐,包括更新工作 初次结帐时的树。
    由于新测试涉及文件系统访问,因此请按顺序稍后执行,以便其他更便宜的测试有机会提前离开。
    这修复了由fa655d8checkout:优化“git checkout -b <new_branch>”,2018-08-16,Git 2.20)引起的行为回归。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 2013-09-07
      • 2020-08-26
      • 2014-10-09
      • 2012-11-26
      • 2019-12-27
      相关资源
      最近更新 更多