Git slows down Emacs to Death - How to Fix this? Git slows down Emacs to Death - How to Fix this? git git

Git slows down Emacs to Death - How to Fix this?


There's a built-in profiler called ELP. You can try something like M-x elp-instrument-package, enter "vc", and then try finding a file. Afterwards, M-x elp-results will show you a profile report.

(Note that if the time is instead being spent in non-vc-related functions, this technique will not show it, but you can instrument further packages if you like.)


You can try to profile the opening of your file to see exactly what takes so much time.


I had the same problem with using windows git 2.10 from mingw emacs 25.1.1.

Using the following to test:

(progn  ;; make sure the buffer is not already open  (elp-instrument-function 'find-file-other-window)  (elp-instrument-function 'vc-git-registered)  (elp-instrument-function 'vc-git-mode-line-string)  (elp-instrument-function 'vc-git-find-file-hook)  (find-file-other-window "my-file-in-a-git-repo")  (elp-results)  (elp-restore-all))

Gave the following profile:

find-file-other-window   1           1.1076142     1.1076142vc-git-mode-line-string  1           0.6396082     0.6396082vc-git-find-file-hook    1           0.2652034     0.2652034vc-git-registered        1           0.1872024     0.1872024

The vc-git-mode-line-string function takes a while. This shows something like Git:mybranch in the mode line of your window. I don't care enough about that to wait for it every time, so I overwrite the implementation to just return "Git":

(defun vc-git-mode-line-string (file)  "Overwritten default vc-git-el implementation. Return a stringfor `vc-mode-line' to put in the mode line for FILE."  "Git")

The vc-git-find-file-hook function will open a pretty conflict editing mode if you're opening a conflicted file. The implementation was first calling vc-git-conflicted-files which takes a while, and then doing a rather trivial check whether any lines start with <<<<<<<. I simply swapped the two, and now the implementation takes about 0.0 seconds in most cases.

(defun vc-git-find-file-hook ()  "Overwritten default vc-git-el implementation. Activate`smerge-mode' if there is a conflict."  (when (and buffer-file-name             ;; FIRST check whether this file looks like a conflicted file             (save-excursion               (goto-char (point-min))               (re-search-forward "^<<<<<<< " nil 'noerror))             ;; THEN ask git if it really is a conflict             (vc-git-conflicted-files buffer-file-name))    (vc-file-setprop buffer-file-name 'vc-state 'conflict)    (smerge-start-session)    (when vc-git-resolve-conflicts      (add-hook 'after-save-hook 'vc-git-resolve-when-done nil 'local))    (vc-message-unresolved-conflicts buffer-file-name)))

Results:

find-file-other-window   1           0.2838039     0.2838039vc-git-registered        1           0.2682037     0.2682037vc-git-find-file-hook    1           0.0           0.0vc-git-mode-line-string  1           0.0           0.0