什么影响Git结账时间?

时间:2015-08-18 14:51:17

标签: git

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

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

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

  1. 删除当前工作目录
  2. 从内部git DB中提取新的工作目录 - 基本上意味着解压缩了很多二进制文件。
  3. 但是我还没有找到任何支持此文件的文件?什么决定了当地的结账时间,它是否如上所述那么简单?

1 个答案:

答案 0 :(得分:2)

  

更改次数越多,git checkout操作的时间就越长。

是。从外部角度来看, IS 就这么简单。

为了更好地了解内部情况,请先查看此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

一些有趣的事实:

  1. 最耗时的系统调用是open()write()unlink()
    它们结合在一起,占系统调用时间的2/3。

  2. 系统调用实际上只花了0.24s(总共7.14s)。

  3. 同时在git checkout下运行strace -r将显示任意两次连续系统调用之间的时间间隔。

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

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

    上面的代码片段表明git在重命名index.lock之后但在决定请求更多内存(malloc() - >之前,正忙着做了近半秒钟(准确地说是0.462548秒) ; brk

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

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

    了解git在执行期间确切停滞的位置,你可以简单地查找上面实例的实现,记下来进行进一步检查以了解更多关于git正在做什么。