什么影响Git签出时间?

什么影响Git签出时间?,git,Git,我有一个小型存储库和一个大型存储库(包含大量二进制文件) 现在,当我在小型存储库中签出分支时,工作目录会立即切换到新内容 现在,在大型存储库中,这可能需要10-15秒。我的理论是,在后一种情况下,git需要时间: 删除当前工作目录 从内部git DB中提取新的工作目录-基本上意味着解压缩大量二进制文件 但我还没有找到任何支持这一点的文档?是什么决定了本地结账时间,它是否像上面所说的那样简单 更改的数量越多,git checkout操作所需的时间越长 对。从外部来看,它就这么简单 为了更好地理解内

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

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

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

  • 删除当前工作目录
  • 从内部git DB中提取新的工作目录-基本上意味着解压缩大量二进制文件
  • 但我还没有找到任何支持这一点的文档?是什么决定了本地结账时间,它是否像上面所说的那样简单

    更改的数量越多,
    git checkout
    操作所需的时间越长

    对。从外部来看,它就这么简单

    为了更好地理解内部结构,首先看一下内部过程的摘要,然后是
    git checkout


    为了更加迂腐并开始深入挖掘,下面是一个“典型的”
    git签出的概要文件,涉及10000个文件,耗时约7秒(在本地Linux内核git存储库中切换分支):

    一些有趣的事实:

  • 最耗时的系统调用是
    open()
    write()
    unlink()

    它们加在一起占了系统调用时间的2/3

  • 只有0.24秒(总共7.14秒)用于系统调用

  • 同时,在
    strace-r
    下运行
    git checkout
    将显示任何两个连续系统调用之间的时间间隔

  • 运行
    strace-r git checkout master>git checkout strace interval.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()
    -->
    brk
    ),忙了将近半秒钟(确切地说是0.462548秒)

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

    一旦您对这种理解水平感到满意,
    接下来继续查看


    掌握了git在执行过程中暂停的确切位置后,您只需查找上面记录下来供进一步检查的实例周围的实现,就可以了解git在做什么。

    这是git性能本身的问题。Joshua Redstone不久前写了这篇关于git性能的文章。这是他的同事写的关于它发生的原因对于这个特定的git操作,这不是一个清晰/简单的答案,但也许回答什么需要时间并不简单?
    0.000167 rename(".git/index.lock", ".git/index") = 0
    0.462548 brk(0x38ac000)            = 0x38ac000