4

Sometimes, though seemingly not in a consistent way, some modes that use version control information do not get updated correctly after git commands are run (e.g.,diff-hl-mode or git-gutter-mode indicate uncommitted changes though those changes have already been committed, or vc-mode-line will show the name of a branch that I am no longer on).

It seems to be different behaviors that trigger it, but two cases where I made note of what I did to trigger the behavior are:

  1. Doing a git rebase from a terminal outside of emacs
  2. Creating and checking out a new branch through the magit interface.

When this happens, it seems like magit is always up to speed and displays the correct information, as does git status from the command line of course. However, the mode-line and sometimes other packages like diff-hl-mode are one branch change or one commit behind.

I hope this is enough information to give someone some idea as to what could be going on. What I would like to know specifically is:

  1. What is causing this behavior? The symptoms as described here may be too vague at the moment, but I will try to add more details as I have them. My guess is that either a mode is not updating correctly when vc information changes, or a mode that is changing vc information is not letting other modes know in the right way - but I could be way off.

  2. When this happens, how can I refresh version control information so that various modes that use the information will displays correctly? Restarting emacs has always worked, but it would be nice to not have to resort to that.

Thank you!

elethan
  • 4,755
  • 3
  • 29
  • 56
  • Pressing `g` in the Magic status buffer seems to help. Also, https://github.com/dgutov/diff-hl/issues/60 could be relevant. – Dmitry Jan 07 '16 at 00:46

1 Answers1

5

When using diff-hl and magit => v2.4.0 you have to add this:

(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)

As far as the information in the mode-line is concerned, I would recommend just ignoring that (or even removing it completely). The function which updates that is actually fairly inefficient, so one could say it is a good thing it isn't called more often.

Magit once contained a function which updated the VC mode-line information whenever it updated its own buffers. That was more efficient than the original, but still rather slow.

Here's the definition.

(defun magit-refresh-vc-mode-line ()
  "Update the information displayed by `vc-mode' in the mode-line.
Like `vc-mode-line' but simpler, more efficient, and less buggy."
  (setq vc-mode
        (if vc-display-status
            (magit-with-toplevel
              (let* ((rev (or (magit-get-current-branch)
                              (magit-rev-parse "--short" "HEAD")))
                     (msg (cl-letf (((symbol-function #'vc-working-revision)
                                     (lambda (&rest _) rev)))
                            (vc-default-mode-line-string
                             'Git buffer-file-name))))
                (propertize
                 (concat " " msg)
                 'mouse-face 'mode-line-highlight
                 'help-echo (concat (get-text-property 0 'help-echo msg)
                                    "\nCurrent revision: " rev
                                    "\nmouse-1: Version Control menu")
                 'local-map vc-mode-line-map)))
          " Git"))
  (force-mode-line-update))

There no longer is a hook which is run for every file-visiting buffer belonging to a repository for which Magit is refreshing its own buffers, so you would have to write a function which you could add to magit-post-refresh-hook, which would then call magit-refresh-vc-mode-line in the appropriate buffers. diff-hl-margin-post-refresh might serve as inspiration.

But see The biggest performance improvement to Emacs I've made in years. Refreshing VC's mode-line information even more often might very well achieve the opposite. ;-)

tarsius
  • 25,298
  • 4
  • 69
  • 109