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.

izkon
  • 1,798
  • 10
  • 23
  • Probably you could customize `magit-bury-buffer-function` (which is what `q` in magit buffers ends up calling). – npostavs Sep 27 '17 at 00:07

5 Answers5

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.

tarsius
  • 25,298
  • 4
  • 69
  • 109
  • 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 Sep 29 '17 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
izkon
  • 1,798
  • 10
  • 23
  • 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 Sep 28 '17 at 13:00
  • "I think..." -- `M-x rgrep` is your friend. – tarsius Sep 29 '17 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))))
Martín
  • 416
  • 2
  • 8
  • 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 Sep 27 '17 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 Sep 27 '17 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 Sep 27 '17 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 Sep 27 '17 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 Sep 27 '17 at 23:29
  • Often all the changes will be visible on the screen at once and I won't have to switch from the window containing commit log to the window containing the `magit-diff` buffer as I can just glance over the latter to confirm they're the changes I want. Then I'll write the log message and complete the commit by typing `C-c C-c` and that will close the window containing the `magit-diff` buffer (but keep the buffer open) and switch the current window back to `magit-status` which I'll close with `q`. – izkon Sep 27 '17 at 23:35
  • The problem is the `magit-diff` buffer sticks around after all this (even if it's not displayed in any of my windows). I want to basically clean up after magit (since magit doesn't fully clean up after itself) and have the `magit-diff` buffer automatically be deleted whenever magit is done with it. – izkon Sep 27 '17 at 23:37
  • Check out [this answer](https://emacs.stackexchange.com/questions/16546/magit-show-git-hook-output), looks like there is a variable to block the diff buffer from opening: `(setq magit-diff-auto-show nil)` and a hook to the commit function. You could add a hook to the commit that checks the buffer list and closes all buffers that start with magit-diff. – Martín Sep 27 '17 at 23:43
  • `describe-variable` (`C-h v`) can not find `magit-diff-auto-show`, and I can't find it anywhere in magit's source. Perhaps it's a variable that used to exist, but no longer does. Anyway, I'm not sure how it would help to block the diff buffer from opening in the first place, as I do want to see it. I just want it to be deleted after magit is done with it. – izkon Sep 28 '17 at 01:14
  • Regarding the commit hook, I'm not sure which commit hook you mean. Maybe you mean I should advise the `magit-commit` command, and delete the magit-diff buffer myself after `magit-commit` command runs. I think I might try that, but there are a couple of problems with doing it that way: first, it might interfere with whatever magit might do with the `magit-diff` buffer after `magit-commit` runs, and second that if I happen to have two diffs running at the same time (perhaps in two different emacsclient sessions), deleting all the `magit-diff` buffers could cause problems. – izkon Sep 28 '17 at 01:16
  • On the other hand, I guess to deal with the case when two or more `magit-diff` buffers exist, my magit-diff-buffer-killing function could detect that situation and either refuse to kill either or let the user choose which one to kill. – izkon Sep 28 '17 at 01:25
  • The variable to inhibit the diff while committing was apparently renamed to `magit-commit-show-diff`. The hook I was referring to is `git-commit-mode-hook` which runs after entering or leaving `git-commit-mode` – Martín Sep 28 '17 at 01:36
  • Thanks, I'll try putting a function that deletes all `magit-diff` buffers in to `git-commit-mode-hook` and see if that works. – izkon Sep 28 '17 at 02:07
  • It looks like that `git-commit-mode-hook` is only called by magit once: upon starting the commit (when the buffer in which the user is expected to add a log message appears). Unfortunately, that's too soon to delete the magit-diff buffers, as I still need to see them before I complete (or abort) the commit. – izkon Sep 28 '17 at 02:43
  • Great! I am glad you figured it out. That's what I love about emacs, you can customize almost everything. – Martín Sep 28 '17 at 14:09
0

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?

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)))
Drew
  • 75,699
  • 9
  • 109
  • 225
MT.
  • 145
  • 5