在Windows上提交时,Magit非常缓慢。

10

Magit提交一个文件需要非常长的时间。 与任何其他任务绝对不成比例-可能需要数分钟,否则我就放弃并从shell中提交它。 有什么原因吗? 我该如何调试它? 有趣的是,如果我杀死* magit-process *缓冲区(必须与git进程交互的缓冲区),然后继续进行任务,那么一切都正常。 但是,在该缓冲区中没有错误消息,只有命令本身。


我会认为某些东西超时了,但也有可能是由于您打开的缓冲区数量而导致的乘法,因为在各种时间(包括提交时),magit将对所有打开的缓冲区进行一些处理(有一个关于此问题的未解决问题),即使 magit 在其他方面很快,这也可能非常明显。值得重复测试,在新的Emacs实例中打开最少的缓冲区,看看是否能改善性能? - phils
我不知道具体是分钟问题还是Windows上的Magit出了些问题。它似乎与异步有关。我已经对其进行了剖析,得到了非常奇怪的结果。我会继续查找直到解决它。 - nic ferrier
我刚刚对它进行了一些性能分析...看起来magit在大量调用同步的进程文件(process-file)操作git。这让它变得相当慢。特别是对于一个文件的单个存储,它会调用rev-parse 5次。这似乎有些过度了。 - nic ferrier
5个回答

10

M-x customize-var RET magit-git-executable RET

将值更改为您的git可执行文件的完整路径。例如,我将我的设置为c:/cygwin/bin/git.exe。在这之前,magit非常缓慢...现在只是有点慢。


3
这对我在 OS X 上的使用也有帮助,我正在使用 zsh 和 oh-my-zsh 捆绑包中的 zsh 的 GitHub 插件,该插件将 git 包装成 hub 命令。 - ustun

5

如果只添加git.exe路径,magit速度不会有太大提升。

最好的方法是使用以下配置添加所有与git相关的命令路径[1]:

(if (eq system-type 'windows-nt)
    (progn
      (setq exec-path (add-to-list 'exec-path "C:/Program Files (x86)/Git/bin"))
      (setenv "PATH" (concat "C:\\Program Files (x86)\\Git\\bin;" (getenv "PATH")))))

exec-path对Magit非常重要,setenv在eshell中使用。

在我的环境中(Windows 7 x64),magit-status只需要大约2秒钟而不是1-2分钟。

[1] https://lists.gnu.org/archive/html/emacs-devel/2012-05/msg00269.html


4
由于编写方式和Windows启动进程比Unix系统稍慢,因此它的速度较慢。
Magit在显示状态页面时严重依赖同步进程。以下是我从单个stage-item运行中构建的一些输出:
magit-cmd-output git.exe (--no-pager symbolic-ref -q HEAD) (0 1 153000 0) {refs/heads/master}
magit-cmd-output git.exe (--no-pager config branch.master.remote) (0 1 149000 0) {}
magit-cmd-output git.exe (--no-pager config --bool branch.master.rebase) (0 1 155000 0) {}
magit-cmd-output git.exe (--no-pager config branch.master.merge) (0 1 155000 0) {}
magit-cmd-output git.exe (--no-pager log --max-count=1 --abbrev-commit --abbrev=7 --pretty=oneline) (0 1 168000 0) {}
magit-cmd-output git.exe (--no-pager stash list) (0 2 831000 0) {}
magit-cmd-output git.exe (--no-pager config status.showUntrackedFiles) (0 1 177000 0) {}
magit-cmd-output git.exe (--no-pager ls-files --others -t --exclude-standard) (0 1 195000 0) {? thehangover.jpg? tugofwar.jpg? tugogwar.jpg? typists.jpg}
magit-cmd-output git.exe (--no-pager diff-files) (0 1 158000 0) {}
magit-cmd-output git.exe (--no-pager mktree) (0 1 157000 0) {4b825dc642cb6eb9a060e54bf8d69288fbee4904}
magit-cmd-output git.exe (--no-pager diff-index --cached 4b825dc642cb6eb9a060e54bf8d69288fbee4904) (0 1 156000 0) {:000000

(注意:此处已经进行了优化,我已经删除了最糟糕的冗余调用。)

您可以看到,在每个参数集中,magit都会调用git,并且需要1秒和许多微秒的时间。在最坏的情况下(stash list),需要近3秒钟。所有这些都会导致速度变得非常慢。

很多这些调用可能可以缓存。但难点在于何时取消缓存。这需要对magit进行大量更改才能做到良好。

或者还有一种批处理它们以使其更快的方法吗?也许。目前无法想到这样的方式。也许一个特殊的git可执行文件可以提供这个功能?


你是如何分析这个调用的?在Windows上,使用magit几乎做任何事情都需要超过30秒,我想知道是什么导致了这么慢。 - Tom Purl

2

我曾经尝试过更改magit-git-executable,但没有起到作用。最终,我使用了WSL,在其上安装了X,并在Windows上安装了一个轻量级的XServer。实际上,它非常好用,比“本地”Windows 10、Cygwin和MingSYS都要快得多。

这里有一些很好的逐步说明: https://github.com/hubisan/emacs-wsl


0

即使在使用WSL2的情况下,将可执行文件设置为完整路径也极大地提高了我的magit性能。

要测试这一点,您可以使用ielm:

M-x ielm

然后在elisp repl中输入:

(setq magit-git-executable 
    (locate-file "git" exec-path))

如果这有所帮助,你可以将上述行添加到你的~/.emacs.d/init.el或任何它加载的文件中,确保上述setq在magit被加载后(使用(require 'magit))被加载。

顺便提一下,我最开始使用的是带有 X 的 WSL Emacs(在 Windows 10 上使用 X410,在 Windows 11 上使用“本地”),但现在我主要在终端中运行,因为它更加灵活。 - djc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接