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.
-
I would assume something is timing out, but it *might* potentially also be multiplied by the number of buffers you have open, as at various times (including when you commit) magit will do some processing on all open buffers (there's an open issue about this), which can be very noticeable even when magit is otherwise fast. It might be worthwhile repeating the test in a new Emacs instance with minimal buffers open, and see if that improves the performance at all? – phils Jun 02 '13 at 15:56
-
I don't know about minutes but definitely something is wrong with magit on windows. It appears to be something to do with asynchrony. I've profiled it and I'm getting very strange results. I'll continue to look until I can fix it. – nic ferrier May 07 '15 at 15:37
-
I just profiled it a bit... it seems that magit is calling process-file (which is synchronous) on git *a lot*. That makes it quite slow. In particular it calls rev-parse 5 times for a single stash of a file. That seems excessive. – nic ferrier May 07 '15 at 15:49
5 Answers
M-x customize-var
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.

- 3,891
- 2
- 23
- 35

- 398
- 1
- 7
-
3This actually helped me on OS X too, I was using zsh and zsh's github plugin in oh-my-zsh bundle which wraps git as a hub command. – ustun Aug 08 '13 at 12:04
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

- 826
- 8
- 5
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?

- 3,558
- 3
- 32
- 71

- 1,573
- 13
- 14
-
How did you profile this call? It's taking > 30 seconds for me to do almost anything with magit on Windows and I'd like to see what is so slow. – Tom Purl Feb 19 '16 at 15:42
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

- 1,477
- 4
- 18
- 35
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)
)

- 31
- 4
-
By the way i started out using WSL emacs with X (X410 with Windows 10 and "native" with Windows 11, but these days i mainly run in the terminal just because it's more versatile. – djc Jun 30 '22 at 16:04