git 结账到分行需要很长时间

git checkout to a branch takes long time

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

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

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

Runs a number of housekeeping tasks within the current repository, such as compressing file revisions (to reduce disk space and increase performance) and removing unreachable objects which may have been created from prior invocations of git add.

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

虽然 Git 2.20 和 2.21 提高了 git checkout 性能(见下一节),但自 Git 2.23(2019 年 8 月)起,您应该使用 git switch instead .

使用 Git 2.24(2019 年第 4 季度)git switch 获得性能回升。
确实对OP使用的git checkout -b有影响。

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

checkout: add simple check for 'git checkout -b'

The 'git switch' command was created to separate half of the behavior of 'git checkout'.

It specifically has the mode to do nothing with the index and working directory if the user only specifies to create a new branch and change HEAD to that branch.
This is also the behavior most users expect from 'git checkout -b', but for historical reasons it also performs an index update by scanning the working directory.
This can be slow for even moderately-sized repos.

A performance fix for 'git checkout -b' was introduced by fa655d8 (checkout: optimize "git checkout -b <new_branch>" 2018-08-16, Git v2.20.0-rc0).
That change includes details about the config setting checkout.optimizeNewBranch when the sparse-checkout feature is required.
The way this change detected if this behavior change is safe was through the skip_merge_working_tree() method.
This method was complex and needed to be updated as new options were introduced.

This behavior was essentially reverted by 65f099b ("switch: no worktree status unless real branch switch happens" 2019-03-29, Git v2.23.0-rc0).
Instead, two members of the checkout_opts struct were used to distinguish between 'git checkout' and 'git switch':

* `switch_branch_doing_nothing_is_ok`
* `only_merge_on_switching_branches`

These settings have opposite values depending on if we start in cmd_checkout or cmd_switch.

The message for 65f099b includes "Users of big repos are encouraged to move to switch."
Making this change while 'git switch' is still experimental is too aggressive.

Create a happy medium between these two options by making 'git checkout -b <branch>' behave just like 'git switch', but only if we read exactly those arguments.
This must be done in cmd_checkout to avoid the arguments being consumed by the option parsing logic.

This differs from the previous change by fa655d8 in that the config option checkout.optimizeNewBranch remains deleted.
This means that 'git checkout -b' will ignore the index merge even if we have a sparse-checkout file.
While this is a behavior change for 'git checkout -b', it matches the behavior of 'git switch -c'.


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

"git checkout -b newbranch [HEAD]" 不必像检查与 HEAD 不同的提交那样做。
尝试优化这种特殊情况。

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

checkout: optimize "git checkout -b <new_branch>"

Skip merging the commit, updating the index and working directory if and only if we are creating a new branch via "git checkout -b <new_branch>."
Any other checkout options will still go through the former code path.

If sparse_checkout is on, require the user to manually opt in to this optimized behavior by setting the config setting checkout.optimizeNewBranch to true as we will no longer update the skip-worktree bit in the index, nor add/remove files in the working directory to reflect the current sparse checkout settings.

For comparison, running "git checkout -b <new_branch>" on a large repo takes:

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

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

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

参见 commit 8424bfd, commit 91e3d7c (23 Jan 2019) by Ben Peart (benpeart)
(由 Junio C Hamano -- gitster -- in commit 5ad3550 合并,2019 年 2 月 5 日)

checkout: fix regression in checkout -b on intitial checkout

When doing a 'checkout -b', do a full checkout including updating the working tree when doing the initial checkout.
As the new test involves an filesystem access, do it later in the sequence to give chance to other cheaper tests to leave early.
This fixes the regression in behavior caused by fa655d8 (checkout: optimize "git checkout -b <new_branch>", 2018-08-16, Git 2.20).