Magit takes enormously long time to commit a file. Absolutely disproportional to any other task - can take several minutes, or else I give up and commit it from the shell. Is there any reason to it? How can I debug it?
Interestingly, if I kill *magit-process*
buffer (the one which has to interact with git process), and then continue with the task, then everything works. But there are no error messages in that buffer, just the command itself.
M-x customize-variable
RET magit-git-executable
RET
Change the value to the full path to your git executable. For example I set mine to c:/cygwin/bin/git.exe
. Before I did that, magit was painfully slow... now it's just a little bit slow.
The magit didn't speed up very much, if only add the git.exe path.
The best way is add all git related command path with following configuration[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 is important for Magit, setenv is used by eshell.
In my environment (Windows 7 x64), magit-status only cost about 2s rather than 1~2 mins.
[1] https://lists.gnu.org/archive/html/emacs-devel/2012-05/msg00269.html
It's slow because of a combination of the way it's written and Windows being slightly slower than unix systems to start processes.
Magit heavily depends on synchronous processes to display the status page. Here's some output I constructed from a single stage-item
run:
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
(note: this is already optimized, I've removed the worst redundant calls).
You can see here that magit is calling git for each of those argument sets and it's taking 1 second and so many microseconds. In the worst case (the stash list
) nearly 3 seconds. It all adds up and makes it very slow.
A lot of those calls could probably be cached. But the difficult thing would be when to uncache them. That would require a lot of change to magit to do well.
Alternately would there be a way of batching them up so they're quicker? Maybe. Can't think of such a way right now. Perhaps a special git executable could make that available?
Changing magit-git-executable didn't do anything for me. I ended up using WSL, installing X on it and a thin XServer on Windows. it actually works really, really well and is much faster than "native" Windows10, Cygwin and MingSYS
Some good step-by-step instructions are here: https://github.com/hubisan/emacs-wsl
Even when using emacs with WSL2, setting the executable to the full path helped my magit performance a lot.
To test this, you can use ielm:
M-x ielm
then at the elisp repl type:
(setq magit-git-executable
(locate-file "git" exec-path))
If that helps, then you can add the above lines to your ~/.emacs.d/init.el
or any file it loads, making sure the above setq
gets loaded after magit is loaded (with (require 'magit)
)
© 2022 - 2024 — McMap. All rights reserved.