1

After making a commit in magit, magit will leave around a magit-diff buffer containing just:

 Staged changes
(empty)
[back]

This is pretty useless and clutters up my buffers, and I'd just like that buffer to be killed off not just after a commit but whenever magit is done with it and empties it out like this.

This question is similar to How to kill ediff's buffers on quit?, only the accepted answer there (to use the ediff-quit-hook) won't work here because there's no corresponding magit-diff-quit-hook, as far as I can see.

Any help is greatly appreciated.

2
  • Probably you could customize magit-bury-buffer-function (which is what q in magit buffers ends up calling).
    – npostavs
    Commented Sep 27, 2017 at 0:07
  • I wonder if the messages below are still valid in the current version of magit... Do we have any new and simpler way to close all magit buffers when que quit magit-status buffer? Commented May 29, 2020 at 15:55

4 Answers 4

4

This answer takes the other answers and the comments into account, offering better ways of doing the same things. Your original question was about deleting the diff buffer after committing, though the other answers concentrated on doing something when quitting the status buffer. So I will do that first too, but later also tell you how to do something when you are done committing.


All that magit-mode-bury-buffer does is (funcall magit-bury-buffer-function kill-buffer). So there is no need to bind another home-made command to replace it or to advice it - just use the existing option intended to tweak the quitting behavior: magit-bury-buffer-function. This is also documented in the manual.

This command's primary purpose is to make the previously current buffer "go away", but you can also use it to do something to other buffers.

Here is how to get to other relevant buffers:

  • magit-mode-get-buffers lists the other Magit buffers belonging to the current repository.
  • magit-mode-get-buffer returns a particular buffer belonging to the current repository, matching the provided arguments.

To do something when you press C-c C-c in a commit message buffer use with-editor-post-finish-hook (a pre variant also exists, as do two cancel variants). These hooks are primarily intended for package authors who use the with-editor library (like git-commit.el does), so they are a bit under-documented and odd to use. To add something to such a hook for the benefit of git-commit-mode do something like:

(add-hook 'git-commit-setup-hook
          (lambda ()
            (add-hook 'with-editor-post-finish-hook
                      (lambda ()
                        ...)   ; your stuff here
                      nil t))) ; the t is important

But use named functions instead of lambdas.

1
  • Thank you so much! That seemed to work for C-c C-c, but what would I need to use if I wanted to do the same thing after C-c C-k (aborting from the commit message buffer)?
    – izkon
    Commented Sep 29, 2017 at 18:34
1

Here is the working solution I ultimately wound up using. It is based on tarsius' advice, who deserves all the credit.

(defun kill-magit-diff-buffer-in-current-repo (&rest _)
  "Delete the magit-diff buffer related to the current repo"
  (let ((magit-diff-buffer-in-current-repo
         (magit-mode-get-buffer 'magit-diff-mode)))
    (kill-buffer magit-diff-buffer-in-current-repo)))
;;
;; When 'C-c C-c' is pressed in the magit commit message buffer,
;; delete the magit-diff buffer related to the current repo.
;;
(add-hook 'git-commit-setup-hook
          (lambda ()
            (add-hook 'with-editor-post-finish-hook
                      #'kill-magit-diff-buffer-in-current-repo
                      nil t))) ; the t is important
2
  • I mean use (add-function 'magit-bury-buffer-function :after #'kill-magit-diff-buffers) rather than (advice-add 'magit-mode-bury-buffer ...). (It makes no practical difference with current magit though)
    – npostavs
    Commented Sep 28, 2017 at 13:00
  • "I think..." -- M-x rgrep is your friend.
    – tarsius
    Commented Sep 29, 2017 at 11:39
0

I had the same problem and I fixed it changing the "q" keybinding in magit-mode-map to run (magit-mode-bury-buffer t), which kills the buffer when burying it

To test it within the current session:

(define-key magit-mode-map 
   (kbd "q") 
   (lambda() (interactive) (magit-mode-bury-buffer t)))

You can add it to your startup config with use-package

(use-package magit
   :ensure t
   :config (define-key magit-mode-map 
             (kbd "q") 
             (lambda() (interactive) (magit-mode-bury-buffer t))))
15
  • This is not working for me. Don't we want to bury the magit-diff buffer instead of the magit-status buffer (which is where I run the q command from after I do a commit)?
    – izkon
    Commented Sep 27, 2017 at 20:20
  • Ahh, ok, I misunderstood the question. What happened to me is that after working with magit there were many *magit-xxxx* buffers with the diffs, status, and logs of my git session. Those buffers would clutter my buffer list, and that clutter is what I cleaned up with my suggestion. In any case, if you switch to the *magit-diff* buffer you could press "q" and kill it.
    – Martín
    Commented Sep 27, 2017 at 21:23
  • The thing is that I want the magit-diff buffer to be open up until the time that I issue the magit-commit command from the magit-status buffer by typing c c there. I don't want to have to have to manually switch to the magit-diff buffer to manually kill it off first. Rather, I want the magit-diff buffer automatically killed off whenever magit is finished with it (the killing of that buffer upon a magit-commit being just a special case of this).
    – izkon
    Commented Sep 27, 2017 at 22:32
  • Hmm, maybe our workflows are different. I usually do a magit-status and stage what I want to commit, then do a c c and the magit-diff buffer appears. I switch to the diff buffer to review it, then back to write the commit message, C-c C-c and the message buffer goes away. In that moment you want to add a hook to kill the diff buffer, I just hit "q" until all magit buffers disappear.
    – Martín
    Commented Sep 27, 2017 at 23:02
  • The way I work is this: If I want to do a commit, I usually just type c c from magit-status and answer y to magit's question of "Nothing staged. Stage and commit everything?" as usually that's exactly what I want to do and I don't want to waste time with manually staging individual bits. Sometimes I do individually stage parts (such as when I've made too many changes to logically commit them all together at once). Then magit will open a new magit-diff window and another window where I can enter in my commit log message. (To be continued in next comment...)
    – izkon
    Commented Sep 27, 2017 at 23:29
0

For general reference - extending izkon's solution to also work when canceling (C-c C-k):

    (defun kill-magit-diff-buffer-in-current-repo (&rest _)
      "Delete the magit-diff buffer related to the current repo"
      (let ((magit-diff-buffer-in-current-repo (magit-mode-get-buffer 'magit-diff-mode)))
        (kill-buffer magit-diff-buffer-in-current-repo)))
    ;;
    ;; When 'C-c C-c' or 'C-c C-l' are pressed in the magit commit message buffer,
    ;; delete the magit-diff buffer related to the current repo.
    ;;    
    (add-hook 'git-commit-setup-hook
              (lambda ()
                (add-hook 'with-editor-post-finish-hook #'kill-magit-diff-buffer-in-current-repo
                          nil t)
                (add-hook 'with-editor-post-cancel-hook #'kill-magit-diff-buffer-in-current-repo
                          nil t)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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