我注意到git difftool非常慢。每次diff调用之间都会出现大约1..2秒的延迟。

为了进行基准测试,我编写了一个自定义difftool命令:

#!/bin/sh
echo $0 $1 $2

并将Git配置为在我的~/.gitconfig中使用此工具
[diff]
    tool = mydiff
[difftool "mydiff"]
    prompt = false
    cmd = "~/mydiff \"$LOCAL\" \"$REMOTE\""

我在Git来源上对其进行了测试:
$ git clone https://github.com/git/git.git
$ cd git
$ git rev-parse HEAD
1bc8feaa7cc752fe3b902ccf83ae9332e40921db
$ git diff head~10 --stat --name-only | wc -l
23

当我用git difftool计时259b5e6d33时,结果太慢了:
$ time git difftool 259b5
mydiff /dev/null Documentation/RelNotes/2.6.3.txt
...
mydiff /tmp/mY2T6l_upload-pack.c upload-pack.c

real    0m10.381s
user    0m1.997s
sys     0m6.667s

通过尝试一个更简单的脚本,它可以更快:
$ time git diff --name-only --stat 259b5 | xargs -n1 -I{} sh -c 'git show 259b5:{} > {}.tmp && ~/mydiff {} {}.tmp'
mydiff Documentation/RelNotes/2.6.3.txt Documentation/RelNotes/2.6.3.txt.tmp
mydiff upload-pack.c upload-pack.c.tmp

real    0m1.149s
user    0m0.472s
sys     0m0.821s

我错过了什么?

这是我得到的结果
| Cygwin | Debian | Ubuntu | Method   |
| ------ | ------ | ------ | -------- |
| 10.381 |  2.620 | 0.580  | difftool |
|  1.149 |  0.567 | 0.210  | custom   |

对于Cygwin结果,我测量了ojis_code花费2.8s,git-difftool花费7.5s。后者长98行。我不明白为什么这么慢。

最佳答案

使用on the msysgit GitHub发现的一些技术,我将其范围缩小了一些。

对于差异文件中的每个文件,git-difftool--helper重新运行以下内部命令:

12:44:46.941239 git.c:351               trace: built-in: git 'config' 'diff.tool'
12:44:47.359239 git.c:351               trace: built-in: git 'config' 'difftool.bc.cmd'
12:44:47.933239 git.c:351               trace: built-in: git 'config' '--bool' 'mergetool.prompt'
12:44:48.797239 git.c:351               trace: built-in: git 'config' '--bool' 'difftool.prompt'
12:44:49.696239 git.c:351               trace: built-in: git 'config' 'difftool.bc.cmd'
12:44:50.135239 git.c:351               trace: built-in: git 'config' 'difftool.bc.path'
12:44:50.422239 git.c:351               trace: built-in: git 'config' 'mergetool.bc.path'
12:44:51.060239 git.c:351               trace: built-in: git 'config' 'difftool.bc.cmd'
12:44:51.452239 git.c:351               trace: built-in: git 'config' 'difftool.bc.cmd'

请注意,在这种特殊情况下,执行这些操作大约需要4.5秒。在我的整个日志中,这是一个非常一致的模式。

还要注意,其中一些是重复的-git config difftool.bc.cmd被调用了4次!

现在,可能的补救措施:
  • 通过将所有与diff相关的部分移到.gitconfig文件的顶部,我将这些命令的执行时间减少了一半。说真的它仍然很引人注目,但现在大约是2秒而不是4.5秒。
  • 确保从实时病毒扫描中都排除了Program Files下的Git文件夹和用户配置文件(.gitconfig所在的位置)。
  • 从根本上讲,Git需要在解析和获取配置值时更加高效。理想情况下,它将在每次循环时缓存这些内容,而不是从config重新请求(和重新解析...)。甚至可以为整个命令执行而缓存。
  • 08-26 12:45