什么影响Git结账时间?

我有一个小型存储库和一个大型存储库(包含许多二进制文件).

现在,当我在小型存储库中检出分支时,工作目录会立即切换到新内容.

现在在大型存储库中,它可能需要10-15秒.我的理论是,在后一种情况下,git需要时间:

>删除当前工作目录
>从内部git DB中提取新的工作目录 – 基本上意味着解压缩很多二进制文件.

但是我没有找到任何支持这个的文件?什么决定了当地的结账时间,它是否如上所述那么简单?

最佳答案

The more the number of changes, longer the git checkout operation takes.

是.从外部的角度来看,就这么简单.

为了更好地理解内部结构,首先看一下这个excellent answer,了解内部程序的摘要,然后是git checkout.

为了更加迂腐并开始深入挖掘,这里是一个“典型”git checkout的配置文件,涉及10,000个文件大约需要7s(在本地Linux内核git存储库中切换分支):

time strace -c git checkout master  > git-checkout-strace.txt
Checking out files: 100% (10651/10651), done.
Switched to branch 'master'
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 27.21    0.067416           4     18336           write
 25.83    0.063994           6     10229         7 unlink
 14.88    0.036865           3     11182      1775 open
  8.28    0.020507           2     12136       689 lstat
  7.97    0.019744        6581         3         1 futex
  5.53    0.013699           1      9409           close
  5.21    0.012910           1      8913           fstat
  2.96    0.007327          15       480       273 rmdir
  ...
  ...
  ...
(skipping the rest of  long list that accounts for the remaining 1% time)
------ ----------- ----------- --------- --------- ----------------
100.00    0.247793                 71970      2767 total

real    0m7.148s
user    0m2.606s
sys     0m4.137s

一些有趣的事实:

>最耗时的系统调用是open(),write()和unlink().
它们组合在一起,占系统调用时间的2/3.
>系统调用实际上只花了0.24s(总共7.14s).
>另外在strace -r下运行git checkout将显示任意2个连续系统调用之间的时间间隔.

运行strace -r git checkout master> git的结帐-strace的,intervals.txt
 然后是awk'{print $1}’git-checkout-strace-relative-timestamps.txt |分类
在排序列表的末尾找到系统调用之间的大间隔.

0.000167 rename(".git/index.lock", ".git/index") = 0
0.462548 brk(0x38ac000)            = 0x38ac000

上面的代码片段表明git在重命名index.lock但在决定请求更多内存(malloc() – > brk)之前,正在忙着做几乎半秒钟的事情(确切地说是0.462548s)

在典型的git checkout运行中,当git看起来在用户空间中忙而不发出任何系统调用时,你会发现六个这样的实例.记下它们以供进一步检查.

一旦你对这种理解水平感到满意,
接下来继续看看actual implementation of git checkout.

掌握了执行过程中git在哪里停滞的知识,您可以简单地查找上面的实例周围的实现,这些实现已被记录下来以便进一步检查以了解更多关于git正在做什么的信息.

点赞