This repository is a fork of emacsorphanage/git-gutter. The upstream repository is in the Emacs orphanage, and nobody merges its pull requests. In this fork I review the pull requests that are open upstream, merge the ones that work, and fix the CI. The goal is to become the maintainer of the upstream repository and to push this work there.
Each pull request is merged with its author's commits unchanged, so that it shows as merged upstream once this work reaches the upstream repository. Fixes to a pull request are separate commits after the author's.
The changes, including the pull requests merged so far, are listed in CHANGELOG.md. The first release from this fork is 0.94.0.
From 0.94.0 on, this project follows Semantic Versioning and records its changes in CHANGELOG.md, in the format of Keep a Changelog.
The public API consists of the commands, the user options (defcustom)
and faces, the variables git-gutter:view-diff-function,
git-gutter:clear-function and git-gutter:init-function, and the
git-gutter-hunk structure; git-gutter-fringe uses the last two groups.
MELPA builds the upstream repository, so M-x package-install installs
upstream's version. To use this fork with Emacs 29 or higher:
(package-vc-install
'(git-gutter :url "https://github.com/alberti42/fork-git-gutter"))With straight.el:
(straight-use-package
'(git-gutter :host github :repo "alberti42/fork-git-gutter"))git-gutter.el is an Emacs port of the Sublime Text plugin
GitGutter.
- Asynchronous updating
- Live updating
- Support multiple VCS
- Support Tramp
- Work without
vc-mode
- Emacs 27.1 or higher
- Git(1.7.0 or higher)
To install this fork, see Installing this fork. The instructions below install the upstream version.
You can install git-gutter.el from MELPA with package.el
(M-x package-install git-gutter), with el-get,
or with another package manager of your choice
git-gutter.el provides a global minor-mode(global-git-gutter-mode)
and minor-mode(git-gutter-mode).
If you want to use git-gutter for files in git repository. You add
following s-exp in your configuration file(~/.emacs.d/init.el or
~/.emacs).
(global-git-gutter-mode +1)Other case, you want to use git-gutter for some files, you can use git-gutter-mode.
Following example of enabling git-gutter for some mode.
(add-hook 'ruby-mode-hook 'git-gutter-mode)
(add-hook 'python-mode-hook 'git-gutter-mode)git-gutter.el provides following commands.
Obsoleted interfaces will be removed when 1.0 released.
Jump to next hunk
Jump to previous hunk
Move to end of current hunk
Mark current hunk.
Set the start revision from which git-gutter performs the diffs.
You can also set the variable git-gutter:start-revision as a
directory-local variable.
Popup current diff hunk(alias git-gutter:popup-diff)
git-gutter:next-hunk and git-gutter:previous-hunk update content
of buffer popuped by git-gutter:popup-diff to current hunk.
Show the current hunk above the current line, in the buffer itself. The hunk disappears at the next key press.
Stage current hunk. You can use this command like git add -p.
This command is supported only for git.
Revert current hunk
Show changes from last commit or Update change information. Please execute this command if diff information is not be updated.
Update git-gutter information of buffers in all visible window.
(require 'git-gutter)
;; If you enable global minor mode
(global-git-gutter-mode t)
;; If you enable git-gutter-mode for some modes
(add-hook 'ruby-mode-hook 'git-gutter-mode)
(global-set-key (kbd "C-x C-g") 'git-gutter)
(global-set-key (kbd "C-x v =") 'git-gutter:popup-hunk)
;; Jump to next/previous hunk
(global-set-key (kbd "C-x p") 'git-gutter:previous-hunk)
(global-set-key (kbd "C-x n") 'git-gutter:next-hunk)
;; Stage current hunk
(global-set-key (kbd "C-x v s") 'git-gutter:stage-hunk)
;; Revert current hunk
(global-set-key (kbd "C-x v r") 'git-gutter:revert-hunk)
;; Mark current hunk
(global-set-key (kbd "C-x v SPC") #'git-gutter:mark-hunk)Using directory-local variables, you can set the start revision for diffs for any file in the current directory:
;;; .dir-locals.el
((prog-mode . ((git-gutter:start-revision . "my-branch"))))If you set git-gutter:update-interval to a number larger than 0,
git-gutter compares the unsaved buffer with the original version each
time Emacs has been idle for that many seconds, for example after you
stop typing. With 0.1, the signs follow your edits. The default, nil,
means no live updates:
(custom-set-variables
'(git-gutter:update-interval 0.1))A live update writes the buffer to a temporary file and runs diff on
it asynchronously. The original version is read from the version
control system once, and again after each full update, for example when
you save the buffer.
You can stop timer by git-gutter:cancel-update-timer and starts by git-gutter:start-update-timer.
You can change the signs and those faces.
(custom-set-variables
'(git-gutter:modified-sign " ") ;; two space
'(git-gutter:added-sign "++") ;; multiple character is OK
'(git-gutter:deleted-sign "--"))
(set-face-background 'git-gutter:modified "purple") ;; background color
(set-face-foreground 'git-gutter:added "green")
(set-face-foreground 'git-gutter:deleted "red")You can change minor-mode name in mode-line to set git-gutter:lighter.
Default is " GitGutter"
;; first character should be a space
(custom-set-variables
'(git-gutter:lighter " GG"))Emacs has char-width function which returns character width.
git-gutter.el uses it for calculating character length of the signs.
But char-width does not work for some full-width characters.
So you should explicitly specify window width, if you use full-width
character.
(custom-set-variables
'(git-gutter:window-width 2)
'(git-gutter:modified-sign "☁")
'(git-gutter:added-sign "☀")
'(git-gutter:deleted-sign "☂"))git-gutter.el supports following version control systems
- Git(1.7.0 or higher)
- Mercurial
- Subversion(1.8 or higher)
- Bazaar
- Jujutsu
You can set backends which git-gutter.el will be used.
Default value of git-gutter:handled-backends is '(git). If you want to use
git-gutter.el for other VCS, please change value of git-gutter:handled-backends as below.
;; Use for 'Git'(`git`), 'Mercurial'(`hg`), 'Bazaar'(`bzr`), 'Subversion'(`svn`) and 'Jujutsu'(`jj`) projects
(custom-set-variables
'(git-gutter:handled-backends '(git hg bzr svn jj)))git-gutter.el uses the first backend in git-gutter:handled-backends
that recognizes the file's directory. A jj repository created with
jj git init also contains a .git directory, so git recognizes it too.
To use jj there, put jj before git:
(custom-set-variables
'(git-gutter:handled-backends '(jj git)))With jj, the signs show the changes of the working-copy commit, that is,
the difference from its parent @-. git-gutter:set-start-revision
takes a jj revision, such as @--.
diff information is updated at hooks in git-gutter:update-hooks.
(add-to-list 'git-gutter:update-hooks 'focus-in-hook)If you use global-git-gutter-mode, you may want some modes to disable
git-gutter-mode. You can make it by setting git-gutter:disabled-modes
to non-nil.
;; inactivate git-gutter-mode in asm-mode and image-mode
(custom-set-variables
'(git-gutter:disabled-modes '(asm-mode image-mode)))Default is nil.
Emacs folds long line if truncate-lines is nil. If git-gutter:visual-line is
non-nil, git-gutter puts sign by visual lines.
(custom-set-variables
'(git-gutter:visual-line t))Default bahavior is that signs are put by logical lines.
value of git-gutter:visual-line is nil.
git-gutter.el can view unchanged information by setting git-gutter:unchanged-sign.
Like following.
(custom-set-variables
'(git-gutter:unchanged-sign " "))
(set-face-background 'git-gutter:unchanged "yellow")Default value of git-gutter:unchanged-sign is nil.
With git, git-gutter.el can mark lines whose changes are staged, that
is, already in the index, with their own sign and face. Set
git-gutter:staged-sign:
(custom-set-variables
'(git-gutter:staged-sign "*"))
(set-face-foreground 'git-gutter:staged "cyan")A line that is staged and then changed again shows the modified sign.
git-gutter:stage-hunk and git-gutter:revert-hunk do nothing on a
staged hunk, and git-gutter:statistic does not count it.
Staged signs cost a second git diff process on every update. They are
not shown when git-gutter:start-revision is set, and live updating
(git-gutter:update-interval above 0) removes them until the next
update, for example when you save the buffer.
Default value of git-gutter:staged-sign is nil.
git-gutter.el can display an additional separator character at the right of the changed
signs. This is mostly useful when running emacs in a console.
(custom-set-variables
'(git-gutter:separator-sign "|"))
(set-face-foreground 'git-gutter:separator "yellow")Default value of git-gutter:separator-sign is nil.
Please set git-gutter:always-show-separator to non-nil, if you want to show
separator always.
Many modern themes — for example the built-in modus-operandi and
modus-vivendi (see https://github.com/protesilaos/modus-themes) — give the
line-number column a background color that differs from the main buffer
background. git-gutter places its change indicators in that same left-margin
area, so when a theme colors the line numbers, the gutter should share that
background for the column to look uniform.
git-gutter uses a dedicated face for each type of change: git-gutter:added
for added lines, git-gutter:modified for modified lines, and
git-gutter:deleted for deleted lines. On those rows, the sign character
configured under Look and feel (e.g. git-gutter:added-sign)
is drawn in the foreground color of the corresponding face, against that face's
background color.
How the remaining rows — those with no changes — get their background depends on your Emacs version.
Emacs 31.1 introduced a new basic face called margin (see
bug #80693). The
display engine fills every empty cell in the left and right window margins
with this face's background. Content written into the margin (such as a
git-gutter sign) is drawn with its own face, but where that face does not
specify a background of its own, it inherits from the margin face. So,
configuring margin once yields a visually uniform gutter column background,
without any per-package further customization.
Note that the line-number area is a separate display column with its own
face (line-number); the margin face does not affect it. Most users will
want the two backgrounds to match visually, when the line numbers are displayed.
This is something themes can arrange and the example below does explicitly.
The margin face was added in May 2026, so it will take time before third-party
themes ship explicit support — until then, customizing it yourself is the way to go.
To match the line-number column without hardcoding a color:
(defun my/margin-update-face ()
(let ((bg (face-background 'line-number nil t)))
(when bg
(set-face-background 'margin bg))))
(add-hook 'enable-theme-functions (lambda (&rest _) (my/margin-update-face)))
(my-margin-update-face)With this in place, you do not need to set git-gutter:unchanged-sign or
git-gutter:always-show-separator just to fill the gutter background — and
on large files you should actively avoid them for that purpose, because
each requires git-gutter to install an overlay on every line of the buffer.
That cost becomes prohibitive on files with tens of thousands of lines (e.g.
Emacs' own xdisp.c); the margin face approach moves the work to the C
display loop, where it costs nothing per line.
If you want a visual gap between the change indicator and the buffer text,
the right approach on 31.1+ is to widen the gutter — for example
(setq git-gutter:window-width 2) — and let the margin face fill the
extra column for free. git-gutter:unchanged-sign and
git-gutter:separator-sign retain their original meaning only when you
actually want a visible character drawn on every unchanged line.
Before the margin face existed, an unwritten margin cell fell back to the
default frame or terminal background. git-gutter had no way to influence
cells it did not render into, so a uniform gutter background required filling
those cells via git-gutter itself, using git-gutter:unchanged (when
git-gutter:unchanged-sign is set) or git-gutter:separator (when
git-gutter:always-show-separator is non-nil).
Important gotcha: git-gutter:window-width reserves space for the gutter
column in every buffer, but on unchanged rows nothing is written into that space
unless one of the two signs above is configured. A cell that is reserved but
never written falls back to the default frame or terminal background — so
setting a background color on git-gutter:unchanged or git-gutter:separator
has no visible effect unless the corresponding sign is also set (even a single
space " "). Once a sign is in place, those two faces control the background
of every cell not covered by a diff sign, making them the key to a visually
uniform column.
To keep the gutter background in sync with the active theme without hardcoding
a color, derive it from the line-number face:
(defun my-git-gutter-update-faces ()
(let ((bg (face-background 'line-number nil t)))
(when bg
;; All gutter cells share the same background as the line-number column.
(dolist (face '(git-gutter:added git-gutter:modified git-gutter:deleted
git-gutter:unchanged git-gutter:separator))
(set-face-background face bg))
;; Make unchanged and separator invisible by matching foreground to background.
(dolist (face '(git-gutter:unchanged git-gutter:separator))
(set-face-foreground face bg)))))
;; Re-run after every theme change (Emacs 29+).
(add-hook 'enable-theme-functions (lambda (&rest _) (my-git-gutter-update-faces)))
(my-git-gutter-update-faces)On Emacs 31.1+, themes should set the background of the margin face —
typically matching line-number's background, or a related accent. This
single setting covers every margin cell in every buffer.
For backward compatibility with Emacs ≤30.x, themes that include explicit
support for git-gutter should additionally set the background of
git-gutter:unchanged and git-gutter:separator to the same color. Leaving
these backgrounds unspecified is the most common cause of a broken-looking
gutter column on those older Emacs versions: an empty stripe drawn in the
frame's default background, mismatched against the line-number column.
Hide gutter when there are no changes if git-gutter:hide-gutter is non-nil.
(Default is nil)
(custom-set-variables
'(git-gutter:hide-gutter t))You can pass git diff option to set git-gutter:diff-option.
;; ignore all spaces
(custom-set-variables
'(git-gutter:diff-option "-w"))git-gutter.el always asks you whether commit/revert or not. If you don't want,
please set git-gutter:ask-p to nil.
;; Don't ask me!!
(custom-set-variables
'(git-gutter:ask-p nil));; Don't need log/message.
(custom-set-variables
'(git-gutter:verbosity 0))Default value is 4(0 is lowest, 4 is highest).
Run hook git-gutter-mode-on-hook when git-gutter-mode is turn on, and
run hook git-gutter-mode-off-hook when git-gutter-mode is turn off.
git-gutter.el provides some statistic API. This is useful for knowing how much
code you changed etc. To display them in mode-line is also useful.
Count unstaged hunks in current buffer.
Count unstaged hunks in all buffers
Return statistic unstaged hunks in current buffer. Return value is dot-list. First element is total added lines, second element is total deleted lines.
GitGutter is Sublime Text plugin.
Vim version of GitGutter
diff-hl is similar tool based on vc.
Fork of git-gutter.el. Some features which are not provided git-gutter.el provides.
However git-gutter-plus updates diff information synchronously.
An add-on to git-gutter.el that draws the signs in the fringe instead
of the margin, so it works only in graphical frames. It is a separate
package in the Emacs orphanage, last changed in 2021, and is not
maintained with this fork; it shows no staged signs.




