NOTE [2021-02-01]: This package was removed from MELPA.
NOTE [2020-11-24]: This repository is no longer maintained. This package is now a part of evil-collection.
This library configures Magit and Evil to play well with each other. For some background see Issue #1.
Note: I intend to track the latest commits to the master branch of the magit repo, meaning the keybindings here are potentially ahead of the last stable release of magit. Once the code in evil-magit stabilizes, I may switch to primarily tracking the stable release of magit and secondarily track the latest commits to master. Any help is welcomed.
- [2019-09-04] Don’t use 
evil-next-visual-lineandevil=previous-visual-line. See Issue #70. - [2019-06-16] Added 
evil-magit-stage-untracked-file-with-intentatI. See Issue #67. - [2019-02-15] Added 
forge-dispatchat@. - [2018-05-22] Added 
evil-magit-use-z-for-folds. See docstring for more information. - [2018-03-13] Added basic evil support for 
magit-list-repositories. - [2016-07-27] Moved submodules popup to ’ and added the new subtree popup at “. This is not mnemonic in any way but easy to reach and keeps the two keys together.
 - [2016-03-24] Moved 
magit-diff-less-contextto = to fix conflict with moved revert. - [2016-03-21] Moved revert commands from 
oandOto-and_. Rationale is that you are subtracting a commit. This makes room foroandOto be reset and the new reset popup command. Think of resetting to an “old” state.¯\_(ツ)_/¯ - Added 
evil-magit-want-horizontal-movement. Usehandlfor movement like vim, movinghtoH,ltoL, andLtoC-l. - Added 
evil-magit-toggle-text-modeonC-t. This is a quick way to enter text mode in a magit buffer, which allows arbitrary movement, copying, etc. UseC-tto return to the previous magit mode. - When 
evil-magit-use-y-for-yankis non nil,C-wwill prefix the evil window switching functions from magit buffers. evil-magit-use-y-for-yankis now the default. It has worked well for me so far, and I’ve had good feedback, but please let me know if you see issues. You can use the original behavior with(setq evil-magit-use-y-for-yank nil). See the table below for a summary of differences.
Everything is contained in evil-magit.el, so you may download and load that file directly.
Evil and Magit are both required. After requiring those packages, the following will setup the new key bindings for you.
;; optional: this is the evil state that evil-magit will use
;; (setq evil-magit-state 'normal)
;; optional: disable additional bindings for yanking text
;; (setq evil-magit-use-y-for-yank nil)
(require 'evil-magit)This package assumes that you either use the global variant of evil mode (e.g.,
  through (evil-mode 1)), or at least have evil-local-mode (the local variant)
  enabled in the magit buffers you want these bindings to take effect in. When
  evil is disabled in a magit buffer, this package will not affect the default key
  bindings (with one minor exception).
evil-magit-use-y-for-yank enables evil’s visual state for linewise selection,
  and as a consequnce y will yank text from the buffer.
With this enabled which it is by default evil-magit uses v and V to select
  by line. Selection in magit occurs linewise, so this choice is to avoid
  confusion that might arise if someone thought they could stage part of a line
  with v for example.
Text mode can be toggled with evil-magit-toggle-text-mode (triggered with
  C-t or \). This takes nearly any magit buffer out of the related magit mode
  and puts it into text-mode. This allows free movement in the buffer using the
  standard evil movement and selection commands, making it easy to for example
  copy arbitrary text in the buffer. It also effectively prevents magit keys from
  shadowing evil ones, so f runs evil-find-char instead of
  magit-fetch-popup, allowing all vim related movement commands to be used in
  magit buffers. You can think of this if you like as another state for evil-magit
  to be in.
Several requests have been made to allow selecting and copying arbitrary text in the magit buffers, but there are many conflicts between evil bindings and magit bindings and there is no elegant solution to this problem in my opinion. Text mode is the best that I have come up with.
The basic key binding scheme for evil-magit (EM) is described in the following tables. Blank columns indicate that the key is carried over from the left.
| Category | Default | EM w/o yank opt | w/ yank opt (default) | w/ horiz move | w/ folds | 
|---|---|---|---|---|---|
| cherry pick | a/A | ||||
| branch | b | ||||
| bisect | B | ||||
| commit | c | ||||
| diff | d/D | ||||
| ediff | e/E | ||||
| fetch | f | ||||
| pull | F | ||||
| refresh | g | gr/gR (g in popup) | |||
| help | h/? | H/? | |||
| ignore | i/I | ||||
| intent to stage | I | ||||
| jump | j | g | |||
| delete | k | x | |||
| untrack | K | X | |||
| log | l/L | L/C-l | |||
| merge | m | ||||
| remote | M | ||||
| next section | n | C-j | |||
| next section sibling | M-n | gj or ] | |||
| submodule | o | ’ | |||
| subtree | O | ” | |||
| prev section | p | C-k | |||
| prev section sibling | M-p | gk or [ | |||
| push | P | P or p | |||
| quit | q | q or ESC | |||
| rebase | r | ||||
| rename | R | ||||
| stage | s/S | ||||
| tag | t | ||||
| notes | T | ||||
| unstage | u/U | ||||
| revert | v/V | -/_ | |||
| am | w | ||||
| patch | W | ||||
| reset | x/X | o/O | |||
| show-refs | y | yr (y in popup) | |||
| cherry | Y | ||||
| stash | z/Z | Z | |||
| git-cmd | : | ¦ | |||
| run | ! | ||||
| forge | @ | ||||
| diff less/more context | -/+ | = / + | |||
| copy section info | C-w | ys | |||
| copy buffer info | M-w | yb | 
| Command | EM w/o yank opt | EM w/ yank opt (default) | w/ horiz move | 
|---|---|---|---|
| evil-goto-line | G | ||
| evil-next-visual-line | j | ||
| evil-previous-visual-line | k | ||
| evil-backward-char | under M-x | h | |
| evil-forward-char | under M-x | l | |
| evil-search-next | n | ||
| evil-search-previous | N | ||
| set-mark-command | v or V | C-SPC | |
| evil-visual-line | under M-x | v or V | |
| evil-ex | : | ||
| evil-search-forward | / | ||
| evil-scroll-page-up | C-b | ||
| evil-scroll-down | C-d | ||
| evil-scroll-page-down | C-f | ||
| evil-scroll-up | C-u (if C-u scrolls) | ||
| evil-emacs-state | C-z | ||
| evil-yank-line | under M-x | yy | |
| evil-window-map | under M-x | C-w | |
| evil-magit-toggle-text-mode | C-t/\ | 
Any other bindings are meant to be consistent with these.
Use evil-magit-revert to revert changes made by evil-magit to the default
  evil+magit behavior.
Some may want ? to search backward instead of launching the popup which is
  also bound to h. To get this behavior, add the following line after (require
  'evil-magit) in your configuration.
(evil-define-key evil-magit-state magit-mode-map "?" 'evil-search-backward)Most (but not all) magit bindings are in magit-mode-map, so other commands can
  be bound in this way too.
Typically, to prevent evil-magit from overriding the default behavior with evil
  and magit loaded, you should bind the respective key to nil after loading
  evil-magit. For example, to make escape behave as default
(evil-define-key* evil-magit-state magit-mode-map [escape] nil)These are the third-party packages that conflict with these bindings and will probably need to be disabled in magit buffers for evil-magit to work properly.
Given the complexity of magit key bindings combined with the complexity of git itself, it is possible that there are some rough edges where the current binding is not the expected one in a buffer. It will be very helpful for you to report any such instances.