1

I am a on and off spacemacs user for a long time but I have recently started working on some bigger projects and so I started investing some more time into improving my workflow and in particular I have started using the git layer to get some neat magit commands which are much more convenient than running everything in command line.

However I have a problem when I use magit: at startup everything works fine but the more I use it the more every command starts taking time until it becomes practically unusable. When I reach this point, I can restart emacs and it starts working quickly again for a while, but soon enough the problem comes back. I am running everything on ubuntu 20.04 and I haven't been able to find anything online about this problem. It seems like magit and helm combine badly on windows leading to slow behavior, so I tried with the ivy layer instead of helm, but that did not solve it.

Here is what the profiler looks like, when i tried to stage a hunk in the project, after having kept emacs running for some time:

- command-execute                                               21876  81%
 - call-interactively                                           21876  81%
  - funcall-interactively                                       21876  81%
   - magit-stage                                                19915  74%
    - magit-apply-hunk                                          19915  74%
     - magit-apply-patch                                        19915  74%
      - magit-refresh                                           19899  74%
       - magit-refresh-buffer                                   19899  74%
        - apply                                                 19875  74%
         - magit-status-refresh-buffer                          19819  74%
          - magit-run-section-hook                              19810  73%
           - apply                                              19810  73%
            - magit-insert-unpushed-to-upstream-or-recent              19006  70%
             - magit-insert-unpushed-to-upstream                19006  70%
              - magit-insert-log                                18991  70%
               - magit-git-wash                                 18991  70%
                + #<compiled 0x1d3fb1d>                         18986  70%
                + magit-git-insert                                  5   0%
                magit-log-insert-child-count                        4   0%
            + magit-insert-unpulled-from-upstream                 436   1%
            + magit-insert-unstaged-changes                       168   0%
            + magit-insert-stashes                                 76   0%
            + magit-insert-status-headers                          62   0%
            + magit-insert-staged-changes                          62   0%
          + magit-section-show                                      9   0%
         + magit-section-goto-successor                            56   0%
      + magit-run-git-with-input                                   16   0%
   + spacemacs/helm-M-x-fuzzy-matching                           1244   4%
   + magit-next-line                                              384   1%
   + magit-previous-line                                          329   1%
   + magit-section-toggle                                           4   0%
+ magit-todos--async-when-done                                   4584  17%
+ redisplay_internal (C function)                                 130   0%
+ global-hl-line-highlight                                         78   0%
+ timer-event-handler                                              45   0%
+ ...                                                              30   0%
+ magit-section-update-highlight                                   20   0%
  evil--jump-hook                                                   4   0%
+ winner-save-old-configurations                                    3   0%
+ evil-repeat-post-hook                                             2   0%

Apparently the problem is with the compiled command which I have no idea what it is. Maybe it is worth mentioning that the project I am working on is pretty big (~100 branches and as many tags) albeit only a few of them are actually present locally. I also have an almost vanilla configuration of spacemacs, with only various layers installed but almost no custom settings, I am just loading the custom emacs mode for contributing to the software frama-c (file frama-c-recommended.el at the following address)

Why does it becomes so slow, and how to fix that?

EDIT: I didn't see that I could explore the compiled item, so here is more complete result of the profiler

- command-execute                                               21876  81%
 - call-interactively                                           21876  81%
  - funcall-interactively                                       21876  81%
   - magit-stage                                                19915  74%
    - magit-apply-hunk                                          19915  74%
     - magit-apply-patch                                        19915  74%
      - magit-refresh                                           19899  74%
       - magit-refresh-buffer                                   19899  74%
        - apply                                                 19875  74%
         - magit-status-refresh-buffer                          19819  74%
          - magit-run-section-hook                              19810  73%
           - apply                                              19810  73%
            - magit-insert-unpushed-to-upstream-or-recent              19006  70%
             - magit-insert-unpushed-to-upstream                19006  70%
              - magit-insert-log                                18991  70%
               - magit-git-wash                                 18991  70%
                - #<compiled 0x1d3fb1d>                         18986  70%
                 - apply                                        18986  70%
                  - magit-log-wash-log                          18986  70%
                   - magit-wash-sequence                        18986  70%
                    - #<compiled 0x1957ab9>                     18986  70%
                     - apply                                    18986  70%
                      - magit-log-wash-rev                      15956  59%
                       - jit-lock-after-change                   6011  22%
                        - run-hook-with-args                     6003  22%
                           font-lock-extend-jit-lock-region-after-change               2984  11%
                       - put-text-property                       3008  11%
                        - jit-lock-after-change                  3000  11%
                         - run-hook-with-args                    3000  11%
                            font-lock-extend-jit-lock-region-after-change               1552   5%
                       - magit-delete-line                       2325   8%
                        - jit-lock-after-change                  2189   8%
                         - run-hook-with-args                    2189   8%
                            font-lock-extend-jit-lock-region-after-change               1461   5%
                         magit-format-ref-labels                   20   0%
                       + magit-section                             16   0%
                       + run-hook-with-args-until-success                 12   0%
                       + eieio-oref                                12   0%
                       + magit-insert-child-count                   8   0%
                       + eieio-oset                                 4   0%
                       + magit-log-format-margin                    4   0%
                + magit-git-insert                                  5   0%
                magit-log-insert-child-count                        4   0%
            + magit-insert-unpulled-from-upstream                 436   1%
            + magit-insert-unstaged-changes                       168   0%
            + magit-insert-stashes                                 76   0%
            + magit-insert-status-headers                          62   0%
            + magit-insert-staged-changes                          62   0%
          + magit-section-show                                      9   0%
         + magit-section-goto-successor                            56   0%
      + magit-run-git-with-input                                   16   0%
   + spacemacs/helm-M-x-fuzzy-matching                           1244   4%
   + magit-next-line                                              384   1%
   + magit-previous-line                                          329   1%
   + magit-section-toggle                                           4   0%
+ magit-todos--async-when-done                                   4584  17%
+ redisplay_internal (C function)                                 130   0%
+ global-hl-line-highlight                                         78   0%
+ timer-event-handler                                              45   0%
+ ...                                                              30   0%
+ magit-section-update-highlight                                   20   0%
  evil--jump-hook                                                   4   0%
+ winner-save-old-configurations                                    3   0%
+ evil-repeat-post-hook                                             2   0%
1
  • For clarity, are you saying that this is only slow if you're using Spacemacs?
    – phils
    Jul 20 at 23:11
2

I'm not Magit guy. But looks you need avoid calling magit-refresh.

The easiest way is to turn on magit-inhibit-refresh. Here is definition of magit-apply-patch,

enter image description here

Disable magit-refresh inside magit-apply-patch temporarily,

(defun my-magit-apply-patch-hack (orig-func &rest args)
  (let* ((magit-inhibit-refresh t))
    (apply orig-func args)))
(advice-add 'magit-apply-patch :around #'my-magit-apply-patch-hack)

Or you can advice the caller of magit-apply-patch. Similar to the above code.

Or you can toggle the flag globally by M-x my-toggle-magit-refresh,

(defun my-toggle-magit-fresh ()
  "Toggle magit refresh flag."
  (interactive)
  (setq magit-inhibit-refresh (not magit-inhibit-refresh))
  (message "magit-inhibit-refresh=%s" magit-inhibit-refresh))
6
  • magit-inhibit-refresh looks like an internal use var which is sometimes let-bound to temporarily prevent Magit from initiating a refresh when doing so would not be productive. It's not a user option intended to be set globally, and I believe it won't be very helpful to do that (refreshing is kinda important).
    – phils
    Jul 21 at 4:04
  • You can always manually M-x magit-refresh any time (the hotkey is g in magit-status-mode). Everyone has her own workflow. If someone want to batch stage multiple files without magit-refresh, then they have the freedom to change this flag temporarily.
    – chen bin
    Jul 21 at 4:41
  • @phils , Lots of people are using gnu.org/software/emacs/manual/html_node/elisp/… to override the function's internal logic. That's even more radical than setting a global boolean flag used by a function. In Emacs, the software freedom is always fully respected. Users could do whatever they want to solve their own problems.
    – chen bin
    Jul 21 at 4:56
  • If you've set a non-nil inhibit-magit-refresh then that manual M-x magit-refresh won't do anything (which was partly my point). You can certainly arrange that it's not inhibited for certain commands, but in the absence of your edit showing any way to do so, I didn't think the original answer was helpful. You most likely want to let-bind the var in your advice example (otherwise you'd need to account for errors).
    – phils
    Jul 21 at 5:30
  • @phils, if you read the original question, OP's analysis has given the command and the bottleneck. My answer is just howto. It cuts off the 70% cpu computing time (according to OP's data), so the answer is helpful. magit-stage and other commands should be much faster and is still functional.
    – chen bin
    Jul 21 at 6:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.