Magit在Windows中极慢。我该如何优化?


15

我被迫将Windows 10用于一个项目。是的,我宁愿使用GNU / Linux。为了保持理智,我尝试将Windows视为Emacs的引导程序:)

不幸的是,Magit(我最喜欢的Emacs部分之一,它也弥补了Windows上缺少良好的命令行)的速度令人难以忍受。我有一个SSD,16 GB的RAM和一个四核i7,但是在小型存储库上执行需要八秒钟magit-status。然后,当我要进行另一个更改时,每个文件大约需要5秒钟。

这是我尝试过的:

  • $ git config --global core.preloadindex true
  • $ git config --global core.fscache true
  • $ git config --global gc.auto 256
  • 将整个项目添加到Windows Defender(我唯一的AV)排除列表中
  • 设置为magit-git-executable我下载的常规msysgit(https://git-for-windows.github.io/)。我检查了一下,git status这花费了不到1秒的时间。我知道这样magit-status做的确更多,但这太多了。

任何人都可以提出一些方法来加快速度吗?我无法想象像这样在Windows上使用Magit的人。

有人建议这个问题是重复的,但他们问:

我在努力理解为什么Emacs在Ubuntu上的启动时间比Windows短得多。有人知道答案吗?

我至少知道为什么Emacs,Git和Magit在Windows上速度较慢的一些原因。我在问我如何优化Magit以减少工作量或缓存结果等,即使这是以功能为代价的。


git-status不到1秒?它应该基本上是瞬时的。有没有明显的延迟?
PythonNut

git从命令行运行等效命令是否存在相同的问题?
elethan '16

我认为magit的默认选择magit-git-executable可能会快一些(in cmdbin实际上是包装器,如果executable-find返回其中一个,则magit会尝试将其设置magit-git-executable为“真实” git)。小型存储库需要8秒,这听起来还是有些不对劲,在这里(Windows 8)大约需要0.8s来进行magit的回购。
npostavs


1
另外,为获得更准确的时间,您可以设置magit-refresh-verboset
保姆

Answers:


11

实际上,我对此进行了大量研究,从根本上来说,问题是git for Windows 很烂

这是上游错误:https : //github.com/git-for-windows/git/issues/596,它需要有人用C重写Shell脚本,以便不再进行命令分叉。对我来说,它是真正的杀手interactive(我可以启动一个交互式的基地,去喝茶,回来,读一些新闻,喝茶,然后也许就完成了。)它比很多人还差很多认为是这样),但一般的类似于状态的通话也足以打断工作进度。

另一种可能是更新jGit以支持magit使用的命令,然后在nailgun中运行它以减少JVM启动时间,我启动了一个线程来讨论此问题:http : //dev.eclipse.org/mhonarc/lists/ jgit-dev / msg03064.html

您可能需要阅读/programming/4485059以获得某些潜在的加速效果,但说实话,您几乎不会注意到它们。

您可以在magit中做的事情是遵循作者的建议,magit-status为分期设置最低费用

;; WORKAROUND https://github.com/magit/magit/issues/2395
(define-derived-mode magit-staging-mode magit-status-mode "Magit staging"
  "Mode for showing staged and unstaged changes."
  :group 'magit-status)
(defun magit-staging-refresh-buffer ()
  (magit-insert-section (status)
    (magit-insert-untracked-files)
    (magit-insert-unstaged-changes)
    (magit-insert-staged-changes)))
(defun magit-staging ()
  (interactive)
  (magit-mode-setup #'magit-staging-mode))

因此,您知道有经验的C或Java开发人员能够帮助您解决git或jGit的两种解决方案吗?


我不太确定问题是Shell脚本还是C,因为magit-status它花费的时间也很长,而且我不认为status使用许多Shell脚本。
保姆

1
并且感谢您提供的“最小” magit-status代码,它似乎对我有所帮助(它将我的magit-refresh时间减少到2-3秒)。
保姆

这正是我想要的。谢谢!
小屋

1
是的,magit-staging需要几秒钟对我来说太。足以打扰我的思想,但不足以破坏我的一天。
fommil '16

2
之所以magit-status缓慢,是因为它呼唤了git大约10或20次。与GNU平台相比,在Windows上启动新进程非常慢。shell脚本是这种情况的极端情况(因为几乎每个语句都是一个新过程)
fommil

2

最近call-processmagit-status出于其他原因查看了来自的呼叫列表,在我看来,其中一些可以被缓存。magit-status在Magit的回购上,以下建议从1.9秒缩短到1.3秒(我之前在评论中提到的0.8秒的测量是针对另一台(更快的)计算机的)。如果您已经magit-staging从其他答案中使用过,则可能不会有太大帮助:我看到从0.16秒减少到0.12秒(但这仅比测量噪声大)。

警告:这并不涉及更新缓存,因此可能会出错(特别是如果您对git配置不满意的话)。

(defvar-local magit-git--git-dir-cache nil)
(defvar-local magit-git--toplevel-cache nil)
(defvar-local magit-git--cdup-cache nil)

(defun memoize-rev-parse (fun &rest args)
  (pcase (car args)
    ("--git-dir"
     (unless magit-git--git-dir-cache
       (setq magit-git--git-dir-cache (apply fun args)))
     magit-git--git-dir-cache)
    ("--show-toplevel"
     (unless magit-git--toplevel-cache
       (setq magit-git--toplevel-cache (apply fun args)))
     magit-git--toplevel-cache)
    ("--show-cdup"
     (let ((cdup (assoc default-directory magit-git--cdup-cache)))
       (unless cdup
         (setq cdup (cons default-directory (apply fun args)))
         (push cdup magit-git--cdup-cache))
       (cdr cdup)))
    (_ (apply fun args))))

(advice-add 'magit-rev-parse-safe :around #'memoize-rev-parse)

(defvar-local magit-git--config-cache (make-hash-table :test 'equal))

(defun memoize-git-config (fun &rest keys)
  (let ((val (gethash keys magit-git--config-cache :nil)))
    (when (eq val :nil)
      (setq val (puthash keys (apply fun keys) magit-git--config-cache)))
    val))

(advice-add 'magit-get :around #'memoize-git-config)
(advice-add 'magit-get-boolean :around #'memoize-git-config)

您为什么不只使用melpa.org/#/memoize软件包?
fommil '16

1
@fommil:我需要记住一些参数的每个缓冲区的rev-parse 。在粗略地看了备忘录包之后,我看不到这样做的方法。它还说它不能处理记忆nil
npostavs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.