4.5 Completion, Confirmation and the Selection

4.5.1 Action Confirmation

By default many actions that could potentially lead to data loss have to be confirmed. This includes many very common actions, so this can quickly become annoying. Many of these actions can be undone and if you have thought about how to undo certain mistakes, then it should be safe to disable confirmation for the respective actions.

The option magit-no-confirm can be used to tell Magit to perform certain actions without the user having to confirm them. Note that while this option can only be used to disable confirmation for a specific set of actions, the next section explains another way of telling Magit to ask fewer questions.

User Option: magit-no-confirm

The value of this option is a list of symbols, representing actions that do not have to be confirmed by the user before being carried out.

By default many potentially dangerous commands ask the user for confirmation. Each of the below symbols stands for an action which, when invoked unintentionally or without being fully aware of the consequences, could lead to tears. In many cases there are several commands that perform variations of a certain action, so we don’t use the command names but more generic symbols.

  • Applying changes:
    • discard Discarding one or more changes (i.e., hunks or the complete diff for a file) loses that change, obviously.
    • reverse Reverting one or more changes can usually be undone by reverting the reversion.
    • stage-all-changes, unstage-all-changes When there are both staged and unstaged changes, then un-/staging everything would destroy that distinction. Of course that also applies when un-/staging a single change, but then less is lost and one does that so often that having to confirm every time would be unacceptable.
  • Files:
    • delete When a file that isn’t yet tracked by Git is deleted, then it is completely lost, not just the last changes. Very dangerous.
    • trash Instead of deleting a file it can also be move to the system trash. Obviously much less dangerous than deleting it.

      Also see option magit-delete-by-moving-to-trash.

    • resurrect A deleted file can easily be resurrected by "deleting" the deletion, which is done using the same command that was used to delete the same file in the first place.
    • untrack Untracking a file can be undone by tracking it again.
    • rename Renaming a file can easily be undone.
  • Sequences:
    • reset-bisect Aborting (known to Git as "resetting") a bisect operation loses all information collected so far.
    • abort-cherry-pick Aborting a cherry-pick throws away all conflict resolutions which have already been carried out by the user.
    • abort-revert Aborting a revert throws away all conflict resolutions which have already been carried out by the user.
    • abort-rebase Aborting a rebase throws away all already modified commits, but it’s possible to restore those from the reflog.
    • abort-merge Aborting a merge throws away all conflict resolutions which have already been carried out by the user.
    • merge-dirty Merging with a dirty worktree can make it hard to go back to the state before the merge was initiated.
  • References:
    • delete-unmerged-branch Once a branch has been deleted, it can only be restored using low-level recovery tools provided by Git. And even then the reflog is gone. The user always has to confirm the deletion of a branch by accepting the default choice (or selecting another branch), but when a branch has not been merged yet, also make sure the user is aware of that.
    • delete-pr-remote When deleting a branch that was created from a pull-request and if no other branches still exist on that remote, then magit-branch-delete offers to delete the remote as well. This should be safe because it only happens if no other refs exist in the remotes namespace, and you can recreate the remote if necessary.
    • drop-stashes Dropping a stash is dangerous because Git stores stashes in the reflog. Once a stash is removed, there is no going back without using low-level recovery tools provided by Git. When a single stash is dropped, then the user always has to confirm by accepting the default (or selecting another). This action only concerns the deletion of multiple stashes at once.
  • Publishing:
    • set-and-push When pushing to the upstream or the push-remote and that isn’t actually configured yet, then the user can first set the target. If s/he confirms the default too quickly, then s/he might end up pushing to the wrong branch and if the remote repository is configured to disallow fixing such mistakes, then that can be quite embarrassing and annoying.
  • Edit published history:

    Without adding these symbols here, you will be warned before editing commits that have already been pushed to one of the branches listed in magit-published-branches.

    • amend-published Affects most commands that amend to "HEAD".
    • rebase-published Affects commands that perform interactive rebases. This includes commands from the commit transient that modify a commit other than "HEAD", namely the various fixup and squash variants.
    • edit-published Affects the commands magit-edit-line-commit and magit-diff-edit-hunk-commit. These two commands make it quite easy to accidentally edit a published commit, so you should think twice before configuring them not to ask for confirmation.

    To disable confirmation completely, add all three symbols here or set magit-published-branches to nil.

  • Various:
    • stash-apply-3way When a stash cannot be applied using git stash apply, then Magit uses git apply instead, possibly using the --3way argument, which isn’t always perfectly safe. See also magit-stash-apply.
    • kill-process There seldom is a reason to kill a process.
  • Global settings:

    Instead of adding all of the above symbols to the value of this option, you can also set it to the atom ‘t’, which has the same effect as adding all of the above symbols. Doing that most certainly is a bad idea, especially because other symbols might be added in the future. So even if you don’t want to be asked for confirmation for any of these actions, you are still better of adding all of the respective symbols individually.

    When magit-wip-before-change-mode is enabled, then the following actions can be undone fairly easily: discard, reverse, stage-all-changes, and unstage-all-changes. If and only if this mode is enabled, then safe-with-wip has the same effect as adding all of these symbols individually.

4.5.2 Completion and Confirmation

Many Magit commands ask the user to select from a list of possible things to act on, while offering the most likely choice as the default. For many of these commands the default is the thing at point, provided that it actually is a valid thing to act on. For many commands that act on a branch, the current branch serves as the default if there is no branch at point.

These commands combine asking for confirmation and asking for a target to act on into a single action. The user can confirm the default target using RET or abort using C-g. This is similar to a y-or-n-p prompt, but the keys to confirm or abort differ.

At the same time the user is also given the opportunity to select another target, which is useful because for some commands and/or in some situations you might want to select the action before selecting the target by moving to it.

However you might find that for some commands you always want to use the default target, if any, or even that you want the command to act on the default without requiring any confirmation at all. The option magit-dwim-selection can be used to configure certain commands to that effect.

Note that when the region is active then many commands act on the things that are selected using a mechanism based on the region, in many cases after asking for confirmation. This region-based mechanism is called the "selection" and is described in detail in the next section. When a selection exists that is valid for the invoked command, then that command never offers to act on something else, and whether it asks for confirmation is not controlled by this option.

Also note that Magit asks for confirmation of certain actions that are not coupled with completion (or the selection). Such dialogs are also not affected by this option and are described in the previous section.

User Option: magit-dwim-selection

This option can be used to tell certain commands to use the thing at point instead of asking the user to select a candidate to act on, with or without confirmation.

The value has the form ((COMMAND nil|PROMPT DEFAULT)...).

4.5.3 The Selection

If the region is active, then many Magit commands act on the things that are selected using a mechanism based on the region instead of one single thing. When the region is not active, then these commands act on the thing at point or read a single thing to act on. This is described in the previous section — this section only covers how multiple things are selected, how that is visualized, and how certain commands behave when that is the case.

Magit’s mechanism for selecting multiple things, or rather sections that represent these things, is based on the Emacs region, but the area that Magit considers to be selected is typically larger than the region and additional restrictions apply.

Magit makes a distinction between a region that qualifies as forming a valid Magit selection and a region that does not. If the region does not qualify, then it is displayed as it is in other Emacs buffers. If the region does qualify as a Magit selection, then the selection is always visualized, while the region itself is only visualized if it begins and ends on the same line.

For a region to qualify as a Magit selection, it must begin in the heading of one section and end in the heading of a sibling section. Note that if the end of the region is at the very beginning of section heading (i.e., at the very beginning of a line) then that section is considered to be inside the selection.

This is not consistent with how the region is normally treated in Emacs — if the region ends at the beginning of a line, then that line is outside the region. Due to how Magit visualizes the selection, it should be obvious that this difference exists.

Not every command acts on every valid selection. Some commands do not even consider the location of point, others may act on the section at point but not support acting on the selection, and even commands that do support the selection of course only do so if it selects things that they can act on.

This is the main reason why the selection must include the section at point. Even if a selection exists, the invoked command may disregard it, in which case it may act on the current section only. It is much safer to only act on the current section but not the other selected sections than it is to act on the current section instead of the selected sections. The latter would be much more surprising and if the current section always is part of the selection, then that cannot happen.

Variable: magit-keep-region-overlay

This variable controls whether the region is visualized as usual even when a valid Magit selection or a hunk-internal region exists. See the doc-string for more information.

4.5.4 The hunk-internal region

Somewhat related to the Magit selection described in the previous section is the hunk-internal region.

Like the selection, the hunk-internal region is based on the Emacs region but causes that region to not be visualized as it would in other Emacs buffers, and includes the line on which the region ends even if it ends at the very beginning of that line.

Unlike the selection, which is based on a region that must begin in the heading of one section and ends in the section of a sibling section, the hunk-internal region must begin inside the body of a hunk section and end in the body of the same section.

The hunk-internal region is honored by "apply" commands, which can, among other targets, act on a hunk. If the hunk-internal region is active, then such commands act only on the marked part of the hunk instead of on the complete hunk.

4.5.5 Support for Completion Frameworks

The built-in option completing-read-function specifies the low-level function used by completing-read to ask a user to select from a list of choices. Its default value is completing-read-default. Alternative completion frameworks typically activate themselves by substituting their own implementation.

Mostly for historic reasons Magit provides a similar option named magit-completing-read-function, which only controls the low-level function used by magit-completing-read. This option also makes it possible to use a different completing mechanism for Magit than for the rest of Emacs, but doing that is not recommend.

You most likely don’t have to customize the magit-specific option to use an alternative completion framework. For example, if you enable ivy-mode, then Magit will respect that, and if you enable helm-mode, then you are done too.

User Option: magit-completing-read-function

The value of this variable is the low-level function used to perform completion by code that uses magit-completing-read (as opposed to the built-in completing-read).

The default value, magit-builtin-completing-read, is suitable for the standard completion mechanism, ivy-mode, and helm-mode at least.

The built-in completing-read and completing-read-default are not suitable to be used here. magit-builtin-completing-read performs some additional work, and any function used in its place has to do the same.

Function: magit-builtin-completing-read prompt choices &optional predicate require-match initial-input hist def

This function performs completion using the built-in completing-read and does some additional magit-specific work.

Function: magit-completing-read prompt choices &optional predicate require-match initial-input hist def fallback

This is the function that Magit commands use when they need the user to select a single thing to act on. The arguments have the same meaning as for completing-read, except for FALLBACK, which is unique to this function and is described below.

Instead of asking the user to choose from a list of possible candidates, this function may just return the default specified by DEF, with or without requiring user confirmation. Whether that is the case depends on PROMPT, this-command and magit-dwim-selection. See the documentation of the latter for more information.

If it does read a value in the minibuffer, then this function acts similar to completing-read, except for the following:

  • COLLECTION must be a list of choices. A function is not supported.
  • If REQUIRE-MATCH is nil and the user exits without a choice, then nil is returned instead of an empty string.
  • If REQUIRE-MATCH is any, then do not require a match but do require non-empty input (or non-nil DEFAULT, since that is substituted for empty input).
  • If REQUIRE-MATCH is non-nil and the users exits without a choice, an user-error is raised.
  • FALLBACK specifies a secondary default that is only used if the primary default DEF is nil. The secondary default is not subject to magit-dwim-selection — if DEF is nil but FALLBACK is not, then this function always asks the user to choose a candidate, just as if both defaults were nil.
  • format-prompt is called on PROMPT and DEF (or FALLBACK if DEF is nil). This appends ": " to the prompt and may also add the default to the prompt, using the format specified by minibuffer-default-prompt-format and depending on magit-completing-read-default-prompt-predicate.

4.5.6 Additional Completion Options

User Option: magit-list-refs-sortby

For many commands that read a ref or refs from the user, the value of this option can be used to control the order of the refs. Valid values include any key accepted by the --sort flag of git for-each-ref. By default, refs are sorted alphabetically by their full name (e.g., "refs/heads/master").