4.1 Modes and Buffers

Magit provides several major-modes. For each of these modes there usually exists only one buffer per repository. Separate modes and thus buffers exist for commits, diffs, logs, and some other things.

Besides these special purpose buffers, there also exists an overview buffer, called the status buffer. It’s usually from this buffer that the user invokes Git commands, or creates or visits other buffers.

In this manual we often speak about "Magit buffers". By that we mean buffers whose major-modes derive from magit-mode.

M-x magit-toggle-buffer-lock

This command locks the current buffer to its value or if the buffer is already locked, then it unlocks it.

Locking a buffer to its value prevents it from being reused to display another value. The name of a locked buffer contains its value, which allows telling it apart from other locked buffers and the unlocked buffer.

Not all Magit buffers can be locked to their values; for example, it wouldn’t make sense to lock a status buffer.

There can only be a single unlocked buffer using a certain major-mode per repository. So when a buffer is being unlocked and another unlocked buffer already exists for that mode and repository, then the former buffer is instead deleted and the latter is displayed in its place.

4.1.1 Switching Buffers

Function: magit-display-buffer buffer &optional display-function

This function is a wrapper around display-buffer and is used to display any Magit buffer. It displays BUFFER in some window and, unlike display-buffer, also selects that window, provided magit-display-buffer-noselect is nil. It also runs the hooks mentioned below.

If optional DISPLAY-FUNCTION is non-nil, then that is used to display the buffer. Usually that is nil and the function specified by magit-display-buffer-function is used.

Variable: magit-display-buffer-noselect

When this is non-nil, then magit-display-buffer only displays the buffer but forgoes also selecting the window. This variable should not be set globally, it is only intended to be let-bound, by code that automatically updates "the other window". This is used for example when the revision buffer is updated when you move inside the log buffer.

User Option: magit-display-buffer-function

The function specified here is called by magit-display-buffer with one argument, a buffer, to actually display that buffer. This function should call display-buffer with that buffer as first and a list of display actions as second argument.

Magit provides several functions, listed below, that are suitable values for this option. If you want to use different rules, then a good way of doing that is to start with a copy of one of these functions and then adjust it to your needs.

Instead of using a wrapper around display-buffer, that function itself can be used here, in which case the display actions have to be specified by adding them to display-buffer-alist instead.

To learn about display actions, see (elisp)Choosing Window.

Function: magit-display-buffer-traditional buffer

This function is the current default value of the option magit-display-buffer-function. Before that option and this function were added, the behavior was hard-coded in many places all over the code base but now all the rules are contained in this one function (except for the "noselect" special case mentioned above).

Function: magit-display-buffer-same-window-except-diff-v1

This function displays most buffers in the currently selected window. If a buffer’s mode derives from magit-diff-mode or magit-process-mode, it is displayed in another window.

Function: magit-display-buffer-fullframe-status-v1

This function fills the entire frame when displaying a status buffer. Otherwise, it behaves like magit-display-buffer-traditional.

Function: magit-display-buffer-fullframe-status-topleft-v1

This function fills the entire frame when displaying a status buffer. It behaves like magit-display-buffer-fullframe-status-v1 except that it displays buffers that derive from magit-diff-mode or magit-process-mode to the top or left of the current buffer rather than to the bottom or right. As a result, Magit buffers tend to pop up on the same side as they would if magit-display-buffer-traditional were in use.

Function: magit-display-buffer-fullcolumn-most-v1

This function displays most buffers so that they fill the entire height of the frame. However, the buffer is displayed in another window if (1) the buffer’s mode derives from magit-process-mode, or (2) the buffer’s mode derives from magit-diff-mode, provided that the mode of the current buffer derives from magit-log-mode or magit-cherry-mode.

User Option: magit-pre-display-buffer-hook

This hook is run by magit-display-buffer before displaying the buffer.

Function: magit-save-window-configuration

This function saves the current window configuration. Later when the buffer is buried, it may be restored by magit-restore-window-configuration.

User Option: magit-post-display-buffer-hook

This hook is run by magit-display-buffer after displaying the buffer.

Function: magit-maybe-set-dedicated

This function remembers if a new window had to be created to display the buffer, or whether an existing window was reused. This information is later used by magit-mode-quit-window, to determine whether the window should be deleted when its last Magit buffer is buried.

4.1.2 Naming Buffers

User Option: magit-generate-buffer-name-function

The function used to generate the names of Magit buffers.

Such a function should take the options magit-uniquify-buffer-names as well as magit-buffer-name-format into account. If it doesn’t, then should be clearly stated in the doc-string. And if it supports %-sequences beyond those mentioned in the doc-string of the option magit-buffer-name-format, then its own doc-string should describe the additions.

Function: magit-generate-buffer-name-default-function mode

This function returns a buffer name suitable for a buffer whose major-mode is MODE and which shows information about the repository in which default-directory is located.

This function uses magit-buffer-name-format and supporting all of the %-sequences mentioned the documentation of that option. It also respects the option magit-uniquify-buffer-names.

User Option: magit-buffer-name-format

The format string used to name Magit buffers.

At least the following %-sequences are supported:

  • %m

    The name of the major-mode, but with the -mode suffix removed.

  • %M

    Like %m but abbreviate magit-status-mode as magit.

  • %v

    The value the buffer is locked to, in parentheses, or an empty string if the buffer is not locked to a value.

  • %V

    Like %v, but the string is prefixed with a space, unless it is an empty string.

  • %t

    The top-level directory of the working tree of the repository, or if magit-uniquify-buffer-names is non-nil an abbreviation of that.

  • %x

    If magit-uniquify-buffer-names is nil "*", otherwise the empty string. Due to limitations of the uniquify package, buffer names must end with the path.

The value should always contain %m or %M, %v or %V, and %t. If magit-uniquify-buffer-names is non-nil, then the value must end with %t or %t%x. See issue #2841.

User Option: magit-uniquify-buffer-names

This option controls whether the names of Magit buffers are uniquified. If the names are not being uniquified, then they contain the full path of the top-level of the working tree of the corresponding repository. If they are being uniquified, then they end with the basename of the top-level, or if that would conflict with the name used for other buffers, then the names of all these buffers are adjusted until they no longer conflict.

This is done using the uniquify package; customize its options to control how buffer names are uniquified.

4.1.3 Quitting Windows

q (magit-mode-bury-buffer)

This command buries or kills the current Magit buffer. The function specified by option magit-bury-buffer-function is used to bury the buffer when called without a prefix argument or to kill it when called with a single prefix argument.

When called with two or more prefix arguments then it always kills all Magit buffers, associated with the current project, including the current buffer.

User Option: magit-bury-buffer-function

The function used to actually bury or kill the current buffer.

magit-mode-bury-buffer calls this function with one argument. If the argument is non-nil, then the function has to kill the current buffer. Otherwise it has to bury it alive. The default value currently is magit-mode-quit-window.

Function: magit-restore-window-configuration kill-buffer

Bury or kill the current buffer using quit-window, which is called with KILL-BUFFER as first and the selected window as second argument.

Then restore the window configuration that existed right before the current buffer was displayed in the selected frame. Unfortunately that also means that point gets adjusted in all the buffers, which are being displayed in the selected frame.

Function: magit-mode-quit-window kill-buffer

Bury or kill the current buffer using quit-window, which is called with KILL-BUFFER as first and the selected window as second argument.

Then, if the window was originally created to display a Magit buffer and the buried buffer was the last remaining Magit buffer that was ever displayed in the window, then that is deleted.

4.1.4 Automatic Refreshing of Magit Buffers

After running a command which may change the state of the current repository, the current Magit buffer and the corresponding status buffer are refreshed. The status buffer can be automatically refreshed whenever a buffer is saved to a file inside the respective repository by adding a hook, like so:

(with-eval-after-load 'magit-mode
  (add-hook 'after-save-hook 'magit-after-save-refresh-status t))

Automatically refreshing Magit buffers ensures that the displayed information is up-to-date most of the time but can lead to a noticeable delay in big repositories. Other Magit buffers are not refreshed to keep the delay to a minimum and also because doing so can sometimes be undesirable.

Buffers can also be refreshed explicitly, which is useful in buffers that weren’t current during the last refresh and after changes were made to the repository outside of Magit.

g (magit-refresh)

This command refreshes the current buffer if its major mode derives from magit-mode as well as the corresponding status buffer.

If the option magit-revert-buffers calls for it, then it also reverts all unmodified buffers that visit files being tracked in the current repository.

G (magit-refresh-all)

This command refreshes all Magit buffers belonging to the current repository and also reverts all unmodified buffers that visit files being tracked in the current repository.

The file-visiting buffers are always reverted, even if magit-revert-buffers is nil.

User Option: magit-refresh-buffer-hook

This hook is run in each Magit buffer that was refreshed during the current refresh - normally the current buffer and the status buffer.

User Option: magit-refresh-status-buffer

When this option is non-nil, then the status buffer is automatically refreshed after running git for side-effects, in addition to the current Magit buffer, which is always refreshed automatically.

Only set this to nil after exhausting all other options to improve performance.

Function: magit-after-save-refresh-status

This function is intended to be added to after-save-hook. After doing that the corresponding status buffer is refreshed whenever a buffer is saved to a file inside a repository.

Note that refreshing a Magit buffer is done by re-creating its contents from scratch, which can be slow in large repositories. If you are not satisfied with Magit’s performance, then you should obviously not add this function to that hook.

4.1.5 Automatic Saving of File-Visiting Buffers

File-visiting buffers are by default saved at certain points in time. This doesn’t guarantee that Magit buffers are always up-to-date, but, provided one only edits files by editing them in Emacs and uses only Magit to interact with Git, one can be fairly confident. When in doubt or after outside changes, type g (magit-refresh) to save and refresh explicitly.

User Option: magit-save-repository-buffers

This option controls whether file-visiting buffers are saved before certain events.

If this is non-nil then all modified file-visiting buffers belonging to the current repository may be saved before running commands, before creating new Magit buffers, and before explicitly refreshing such buffers. If this is dontask then this is done without user intervention. If it is t then the user has to confirm each save.

4.1.6 Automatic Reverting of File-Visiting Buffers

By default Magit automatically reverts buffers that are visiting files that are being tracked in a Git repository, after they have changed on disk. When using Magit one often changes files on disk by running Git, i.e., "outside Emacs", making this a rather important feature.

For example, if you discard a change in the status buffer, then that is done by running git apply --reverse ..., and Emacs considers the file to have "changed on disk". If Magit did not automatically revert the buffer, then you would have to type M-x revert-buffer RET RET in the visiting buffer before you could continue making changes.

User Option: magit-auto-revert-mode

When this mode is enabled, then buffers that visit tracked files are automatically reverted after the visited files change on disk.

User Option: global-auto-revert-mode

When this mode is enabled, then any file-visiting buffer is automatically reverted after the visited file changes on disk.

If you like buffers that visit tracked files to be automatically reverted, then you might also like any buffer to be reverted, not just those visiting tracked files. If that is the case, then enable this mode instead of magit-auto-revert-mode.

User Option: magit-auto-revert-immediately

This option controls whether Magit reverts buffers immediately.

If this is non-nil and either global-auto-revert-mode or magit-auto-revert-mode is enabled, then Magit immediately reverts buffers by explicitly calling auto-revert-buffers after running Git for side-effects.

If auto-revert-use-notify is non-nil (and file notifications are actually supported), then magit-auto-revert-immediately does not have to be non-nil, because the reverts happen immediately anyway.

If magit-auto-revert-immediately and auto-revert-use-notify are both nil, then reverts happen after auto-revert-interval seconds of user inactivity. That is not desirable.

User Option: auto-revert-use-notify

This option controls whether file notification functions should be used. Note that this variable unfortunately defaults to t even on systems on which file notifications cannot be used.

User Option: magit-auto-revert-tracked-only

This option controls whether magit-auto-revert-mode only reverts tracked files or all files that are located inside Git repositories, including untracked files and files located inside Git’s control directory.

User Option: auto-revert-mode

The global mode magit-auto-revert-mode works by turning on this local mode in the appropriate buffers (but global-auto-revert-mode is implemented differently). You can also turn it on or off manually, which might be necessary if Magit does not notice that a previously untracked file now is being tracked or vice-versa.

User Option: auto-revert-stop-on-user-input

This option controls whether the arrival of user input suspends the automatic reverts for auto-revert-interval seconds.

User Option: auto-revert-interval

This option controls how many seconds Emacs waits for before resuming suspended reverts.

User Option: auto-revert-buffer-list-filter

This option specifies an additional filter used by auto-revert-buffers to determine whether a buffer should be reverted or not.

This option is provided by Magit, which also advises auto-revert-buffers to respect it. Magit users who do not turn on the local mode auto-revert-mode themselves, are best served by setting the value to magit-auto-revert-repository-buffer-p.

However the default is nil, so as not to disturb users who do use the local mode directly. If you experience delays when running Magit commands, then you should consider using one of the predicates provided by Magit - especially if you also use Tramp.

Users who do turn on auto-revert-mode in buffers in which Magit doesn’t do that for them, should likely not use any filter. Users who turn on global-auto-revert-mode, do not have to worry about this option, because it is disregarded if the global mode is enabled.

User Option: auto-revert-verbose

This option controls whether Emacs reports when a buffer has been reverted.

The options with the auto-revert- prefix are located in the Custom group named auto-revert. The other, Magit-specific, options are located in the magit group.

Risk of Reverting Automatically

For the vast majority of users, automatically reverting file-visiting buffers after they have changed on disk is harmless.

If a buffer is modified (i.e., it contains changes that haven’t been saved yet), then Emacs will refuse to automatically revert it. If you save a previously modified buffer, then that results in what is seen by Git as an uncommitted change. Git will then refuse to carry out any commands that would cause these changes to be lost. In other words, if there is anything that could be lost, then either Git or Emacs will refuse to discard the changes.

However, if you use file-visiting buffers as a sort of ad hoc "staging area", then the automatic reverts could potentially cause data loss. So far I have heard from only one user who uses such a workflow.

An example: You visit some file in a buffer, edit it, and save the changes. Then, outside of Emacs (or at least not using Magit or by saving the buffer) you change the file on disk again. At this point the buffer is the only place where the intermediate version still exists. You have saved the changes to disk, but that has since been overwritten. Meanwhile Emacs considers the buffer to be unmodified (because you have not made any changes to it since you last saved it to the visited file) and therefore would not object to it being automatically reverted. At this point an Auto-Revert mode would kick in. It would check whether the buffer is modified and since that is not the case it would revert it. The intermediate version would be lost. (Actually you could still get it back using the undo command.)

If your workflow depends on Emacs preserving the intermediate version in the buffer, then you have to disable all Auto-Revert modes. But please consider that such a workflow would be dangerous even without using an Auto-Revert mode, and should therefore be avoided. If Emacs crashes or if you quit Emacs by mistake, then you would also lose the buffer content. There would be no autosave file still containing the intermediate version (because that was deleted when you saved the buffer) and you would not be asked whether you want to save the buffer (because it isn’t modified).