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.
虽然 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).
我在 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.
虽然 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 settingcheckout.optimizeNewBranch
when the sparse-checkout feature is required.
The way this change detected if this behavior change is safe was through theskip_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 thecheckout_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
orcmd_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 incmd_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 settingcheckout.optimizeNewBranch
to true as we will no longer update theskip-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 incheckout -b
on intitial checkoutWhen 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).