为什么在 Git Bash 中执行 git diff 命令时,Windows 系统有时会出现 10 秒的延迟
这是 Windows Defender 的行为分析功能,排除规则无法解决此问题
简而言之:在 Windows 系统中,git diff
、git log
和 git show
等 Git 命令会随机出现 10 秒的卡顿。这是因为 Microsoft Defender 防病毒软件在分析 Git 如何启动其页面器(而非扫描文件——这就是为什么排除规则无效)。分析完成后,同一命令会立即运行约 30 秒,随后再次变慢。解决方法:为特定命令禁用页面器或手动管道传输。
谜团
数月来,我一直被 Windows 11 上的一个奇怪 Git 性能问题困扰:
git diff
在显示任何内容前会冻结 10 秒- 立即再次运行:瞬间完成
- 等待一分钟后再次运行:10 秒
- 但
git diff | cat
始终瞬间完成
该模式在 git log
、git blame
以及任何使用分页器的 Git 命令中均一致。大约 30 秒后,延迟再次出现。

调查
未能解决的方法
当然,我最初认为是操作系统文件缓存或杀毒软件文件扫描导致的:
- 将 git.exe 添加到 Windows Defender 排除项
- 将 less.exe 添加到排除项
- 将整个 Git 安装文件夹添加到排除列表
- 将我的仓库文件夹添加到排除列表
结果:没有改善。首次运行时仍存在 10 秒延迟。
第一个线索:不仅仅是 Git
打开 Windows 终端后发现,该模式不仅限于 Git:
- PowerShell 标签页:始终即时
- 第一个 Git Bash 标签页:打开需 10 秒
- 紧接着打开第二个 Git Bash 标签页:立即打开
- 等待 30 秒后打开另一个 Git Bash 标签页:再次出现 10 秒延迟
这并非 Git 的问题,而是关于 Windows 上的 Unix 风格进程创建。
关键证据:进程模式
使用不同分页器进行测试证实了这是模式问题:
# Cold start
git -c core.pager=less diff # 10 seconds
git -c core.pager=head show # Instant! (cached)
# After cache expires (~30 seconds)
git -c core.pager=head diff # 10 seconds
git -c core.pager=less show # Instant! (cached)
具体启动的程序并不重要。Windows Defender正在分析Git如何创建子进程的模式。
真凶:PTY模拟
当Git在Windows上启动分页器时,它会:
- 分配一个伪终端(PTY)对
- 设置双向 I/O 重定向
- 通过此复杂控制台配置启动分页器
这种 Unix 风格的 PTY 模式触发了 Microsoft Defender 杀毒软件的行为分析。启动 Git Bash 时也会发生同样的情况(因为它需要 PTY 模拟)。
PowerShell 不会触发此问题,因为它使用原生 Windows 控制台 API。
为何排除规则无效
文件排除规则可阻止扫描文件内容以检测已知恶意软件签名。
行为分析监控进程交互方式:进程创建模式、I/O 重定向、PTY 分配。无法“排除”特定行为模式。
Windows Defender 检测到:“进程创建伪终端并以重定向 I/O 方式启动子进程”这看起来可疑。经过 10 秒分析后,它确定:“这是安全的 Git 行为”。缓存批准约 30 秒(在我的测试中观察到)。
10 秒超时
延迟与 Microsoft Defender 杀毒软件文档中记录的“云阻断超时”完全匹配,即等待云端对可疑行为做出裁决的时间。默认值:10 秒。[1]
自行测试
以下是显示约30秒缓存的精确测试:
$ sleep 35; time git diff; sleep 20; time git diff; sleep 35; time git diff
real 0m10.105s
user 0m0.015s
sys 0m0.000s
real 0m0.045s
user 0m0.015s
sys 0m0.015s
real 0m10.103s
user 0m0.000s
sys 0m0.062s
即使树中没有变化(即空输出),冷启动时仍存在延迟。
35秒后:慢(10秒)。20秒后:快(缓存)。35秒后:再次变慢。
解决方案
1. 禁用 git diff 的分页器
配置 Git 跳过 diff 的分页器:
git config --global pager.diff false
# Then pipe manually when you need pagination:
# git diff | less
2. 手动管道
完全跳过 Git 的内部分页器:
git diff --color=always | less -R
3. 常用命令的别名
alias gd='git diff --color=always | less -R'
4. 使用 PowerShell 替代 Git Bash
PowerShell 使用原生 Windows 控制台 API,完全避免 PTY 模拟。Git 命令仍可正常工作,但终端功能可能有所不同。
5. 切换至 WSL2
真实 Linux PTY 替代模拟 = 不会触发行为分析
*环境:Windows 11 24H2,Git for Windows 2.49.0
*更新: * PowerShell 也受到影响。Git for Windows 会为分页器创建 PTY,无论调用它的 shell 是哪个:
PS > foreach ($sleep in 35, 20, 35) {
Start-Sleep $sleep
$t = Get-Date
git diff
"After {0}s wait: {1:F1}s" -f $sleep, ((Get-Date) - $t).TotalSeconds
}
After 35s wait: 10.2s
After 20s wait: 0.1s
After 35s wait: 10.3s
更新 2: 感谢 u/bitzap_sr 明确了 Defender 实际看到的内容:MSYS2 使用 Windows 命名管道实现 PTY。因此,从 Defender 的角度来看,它正在分析 Git 创建具有复杂双向 I/O 的命名管道并 spawning 一个子进程,这就是可疑模式。
更新 3(周日): 延迟已经改变!今天,在周日,我现在看到的是 ~2 秒,而不是前几天看到的 10 秒:
$ sleep 35; time git diff; sleep 20; time git diff; sleep 35; time git diff
real 0m2.195s
user 0m0.000s
sys 0m0.031s
real 0m0.114s
user 0m0.030s
sys 0m0.047s
real 0m2.204s
user 0m0.062s
sys 0m0.000s
相同的模式(慢→缓存→慢),但速度快得多。这看起来像是实际的云分析已经完成,而不是触发了10秒的超时。无论这是巧合还是与该问题获得的关注度有关,这都是一项显著的改进。行为分析仍然会发生,但至少不再超时了。
这就是原因。我的员工强制我使用一台被严格限制的笔记本电脑,上面安装了大量无法禁用的
垃圾软件安全软件。我发现每次在MSYS2或Git Bash终端中操作时,都会出现随机卡顿现象。
也许我可以申请使用WSL,如果这样能解决问题的话。
你的情况可能是最常见的,即被锁定的Windows系统搭配无法控制的安全软件。
好消息是,这只影响特定场景(Git调用分页器)。常规命令如
git add
、git commit
、git push
不受影响。首先考虑简单的针对性修复:
git config --global pager.diff false
等,对于受此 10 秒延迟影响但通常不需要分页器的常见命令。对于git log
,我建议创建一个明确将输出管道传输到分页器的别名以绕过此问题。Windows 上的 Docker Desktop 优先使用 WSL2,因此如果需要,您可以从这个方向入手。
如果我直接安装 Arch Linux 并每次双系统启动,当他们过来时,我只需说这是 Windows(尝试制作一些类似 Windows 的主题)?
在没有管理员权限且无法访问BitLocker密钥的情况下,重新分区一个BitLocker加密的SSD祝你好运。
你可以从USB驱动器启动,但如果Linux系统尝试更改任何BIOS设置,BitLocker可能会在下次重启时检测到并拒绝继续启动过程。届时你可能需要向IT部门解释情况……
如果他们加密了驱动器,那这事就别提了,算了!USB启动很糟糕,因为你得依赖数据传输速度,太糟糕了
你有Windows许可证的订阅吗?
创建一个Hyper-V虚拟机并在其中编码。
对于那些好奇为什么
git diff | less
能避免10秒延迟的人:当你显式地使用管道时,shell会在两个独立的进程之间建立一个简单的管道。Git写入标准输出,less从标准输入读取,仅此而已。
但当Git自己启动分页器时,它会创建一个伪终端,建立双向I/O,并管理分页器作为子进程。这就是触发Defender行为分析的原因。
需要注意的是,从 Defender 这样的原生(非 msys2/cygwin)进程的角度来看,Git Bash(原 msys2,原 cygwin)的 PTY 被视为 Windows 的命名管道。如果原生进程通过命名管道以类似方式重定向 I/O 来启动子进程,结果可能相同。我认为 Defender 并不了解 msys2/cygwin PTY 的相关信息。
老天爷啊,这几乎是我在 2010 年停止使用 Windows 的主要原因。
我可以补充一点,当我第一次执行新编译的 .exe 文件时,Defender 会在扫描过程中添加一个短暂的延迟。排除规则(不扫描特定文件夹/驱动器)会被忽略。
有没有人知道其他常见的 Git 命令可能会受到影响?即使在最简单的拉取、检出、提交、推送操作中,我也注意到大量延迟(单个命令耗时5-10秒),这些似乎与杀毒软件和进程启动相关。我之前遇到过ps1提示符问题,同样会启动过多进程导致Windows系统变慢,但问题依然存在。使用Windows 11系统,配备16GB内存,运行于Citrix VDI环境。
10秒的页面器延迟只是一个具体问题。您遇到的其他延迟(拉取、检出、提交、推送)可能不同,这些涉及实际文件操作,而杀毒软件可能会通过扫描来减慢这些操作。
对于这些问题,排除项应有所帮助:
我记录的行为分析延迟仅影响页面器生成,无法通过排除项解决。但您看到的文件扫描延迟绝对可以解决。
此外,请检查是否有多个安全产品在扫描相同的操作。
感谢您的分享!我认为我在使用Python时遇到了类似问题。在Windows系统中使用multiprocessing.pool时性能极差,我始终无法确定原因(我推测可能是Windows Defender导致的)。最终我放弃并切换到Linux系统,问题神奇地解决了。
你在 Windows 终端中运行 Git Bash 吗?
是的,我使用 Windows 终端与 Git Bash。但这不是终端问题,延迟无论使用哪个终端都会发生。
在故障排除过程中,我测试了:
所有终端均显示相同的10秒延迟模式。这是因为Git启动进程的方式,而非终端的显示方式。
PowerShell呢?我有点困惑,想确认使用PowerShell是否能避免这个问题。
编辑:算了,我看到你说不行
禁用分页器有什么缺点吗?这是为了绕过一个不再那么相关的限制而保留的遗留功能,还是会让情况变得更糟?
分页器提供功能。没有它,你会失去这些功能。但原帖作者提议了其他调用分页器的方法,这些方法不会受到速度变慢的影响。
分页器会显示输出内容的开头,并允许您通过滚动或搜索在输出内容中导航。如果没有分页器,您将看到输出内容的结尾,并需要使用终端功能进行滚动(例如滚动条)。通常终端滚动操作会更加笨拙。
尝试后,我实际上非常高兴禁用了分页器。之前我总是按住空格键将所有内容从分页器中取出,以便能用鼠标滚轮正常滚动。现在它终于按我预期那样工作了。
坦白说,Git默认使用分页器似乎在配置上有点(非常轻微的)越界
解决方案:不要使用Git Bash,直接在PowerShell中使用Git。我从未遇到过这些问题
你试过为Git创建进程豁免而不是文件豁免吗?
好点子。我的帖子中没有明确说明这一点。
我已经为git.exe、less.exe和bash.exe设置了进程豁免:
仍然出现10秒延迟。进程排除不起作用,就像路径排除不起作用一样。行为分析似乎在与这些排除机制不同的层面上运行。
被分析的模式(PTY创建与子进程生成)似乎会触发云端检查,无论是否存在排除规则。
当我不在VPN上时,Windows上的Git会出现严重的延迟,因此无法访问广告控制器
我不是开玩笑。Windows上的Git会在域中检查广告
直到我看到(4. 使用PowerShell …)时,我才明白你在说什么。我从不在Windows上使用Bash,它太糟糕了。