lewis6991
gitsigns.nvim
Lua

Git integration for buffers

Last updated Jul 9, 2026
7.0k
Stars
292
Forks
41
Issues
+16
Stars/day
Attention Score
98
Language breakdown
No language data available.
โ–ธ Files click to expand
README

gitsigns.nvim

CI Version LuaRocks License: MIT Dotfyle

Deep buffer integration for Git

๐Ÿ‘€ Preview

| Hunk Actions | Line Blame | | --- | ----------- | | | |

โœจ Features

Signs

- Adds signs to the sign column to indicate added, changed, and deleted lines.

image

- Supports different signs for staged changes.

image

- Add counts to signs.

image

Hunk Actions

- Stage/unstage hunks with :Gitsigns stage_hunk. - Reset hunks with :Gitsigns reset_hunk. - Also works on partial hunks in visual mode. - Preview hunks inline with :Gitsigns previewhunkinline

image

- Preview hunks in popup with :Gitsigns preview_hunk

image

- Navigate between hunks with :Gitsigns nav_hunk next/prev.

Blame

- Show blame of current buffer using :Gitsigns blame.

image

- Show blame information for the current line in popup with :Gitsigns blame_line.

image

- Show blame information for the current line in virtual text.

image

- Enable with setup({ currentlineblame = true }). - Toggle with :Gitsigns togglecurrentline_blame

Diff

- Change the revision for the signs with :Gitsigns change_base <REVISION>. - Show the diff of the current buffer with the index or any revision with :Gitsigns diffthis <REVISION>. - Show intra-line word-diff in the buffer.

image

- Enable with setup({ word_diff = true }). - Toggle with :Gitsigns toggleworddiff.

Show hunks Quickfix/Location List

- Set the quickfix/location list with changes with :Gitsign setqflist/setloclist.

image

Can show hunks for: - whole repository (target=all) - attached buffers (target=attached) - a specific buffer (target=[integer]).

Text Object

- Select hunks as a text object. - Can use vim.keymap.set({'o', 'x'}, 'ih', '<Cmd>Gitsigns select_hunk<CR>')

Status Line Integration

Use b:gitsignsstatus or b:gitsignsstatusdict. b:gitsignsstatus is formatted using config.statusformatter. b:gitsignsstatus_dict is a dictionary with the keys added, removed, changed and head.

Example:

set statusline+=%{get(b:,'gitsigns_status','')}

For the current branch use the variable b:gitsigns_head.

Show different revisions of buffers

- Use :Gitsigns show <REVISION> to :edit the current buffer at <REVISION>

๐Ÿ“‹ Requirements

  • Neovim >= 0.9.0
[!TIP]
If your version of Neovim is too old, then you can use a past [release].
[!WARNING]
If you are running a development version of Neovim (aka master), then
breakage may occur if your build is behind latest.
  • Newish version of git. Older versions may not work with some features.

๐Ÿ› ๏ธ Installation & Usage

Install using your package manager of choice. No setup required.

Optional configuration can be passed to the setup function. Here is an example with most of the default settings:

require('gitsigns').setup {
  signs = {
    add          = { text = 'โ”ƒ' },
    change       = { text = 'โ”ƒ' },
    delete       = { text = '_' },
    topdelete    = { text = 'โ€พ' },
    changedelete = { text = '~' },
    untracked    = { text = 'โ”†' },
  },
  signs_staged = {
    add          = { text = 'โ”ƒ' },
    change       = { text = 'โ”ƒ' },
    delete       = { text = '_' },
    topdelete    = { text = 'โ€พ' },
    changedelete = { text = '~' },
    untracked    = { text = 'โ”†' },
  },
  signsstagedenable = true,
  signcolumn = true,  -- Toggle with :Gitsigns toggle_signs
  numhl      = false, -- Toggle with :Gitsigns toggle_numhl
  linehl     = false, -- Toggle with :Gitsigns toggle_linehl
  worddiff  = false, -- Toggle with :Gitsigns toggleword_diff
  watch_gitdir = {
    follow_files = true
  },
  auto_attach = true,
  attachtountracked = false,
  currentlineblame = false, -- Toggle with :Gitsigns togglecurrentline_blame
  currentlineblame_opts = {
    virt_text = true,
    virttextpos = 'eol', -- 'eol' | 'overlay' | 'right_align'
    delay = 1000,
    ignore_whitespace = false,
    virttextpriority = 100,
    use_focus = true,
  },
  currentlineblameformatter = '<author>, <authortime:%R> - <summary>',
  blame_formatter = nil, -- Use default
  sign_priority = 6,
  update_debounce = 100,
  status_formatter = nil, -- Use default
  maxfilelength = 40000, -- Disable if file is longer than this (in lines)
  preview_config = {
    -- Options passed to nvimopenwin
    style = 'minimal',
    relative = 'cursor',
    row = 0,
    col = 1
  },
}

For information on configuring Neovim via lua please see [nvim-lua-guide].

๐ŸŽน Keymaps

Gitsigns provides an on_attach callback which can be used to setup buffer mappings.

Here is a suggested example:

require('gitsigns').setup{
  ...
  on_attach = function(bufnr)
    local gitsigns = require('gitsigns')

local function map(mode, l, r, opts) opts = opts or {} opts.buffer = bufnr vim.keymap.set(mode, l, r, opts) end

-- Navigation map('n', ']c', function() if vim.wo.diff then vim.cmd.normal({']c', bang = true}) else gitsigns.nav_hunk('next') end end)

map('n', '[c', function() if vim.wo.diff then vim.cmd.normal({'[c', bang = true}) else gitsigns.nav_hunk('prev') end end)

-- Actions map('n', '<leader>hs', gitsigns.stage_hunk) map('n', '<leader>hr', gitsigns.reset_hunk)

map('v', '<leader>hs', function() gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') }) end)

map('v', '<leader>hr', function() gitsigns.reset_hunk({ vim.fn.line('.'), vim.fn.line('v') }) end)

map('n', '<leader>hS', gitsigns.stage_buffer) map('n', '<leader>hR', gitsigns.reset_buffer) map('n', '<leader>hp', gitsigns.preview_hunk) map('n', '<leader>hi', gitsigns.previewhunkinline)

map('n', '<leader>hb', function() gitsigns.blame_line({ full = true }) end)

map('n', '<leader>hd', gitsigns.diffthis)

map('n', '<leader>hD', function() gitsigns.diffthis('~') end)

map('n', '<leader>hQ', function() gitsigns.setqflist('all') end) map('n', '<leader>hq', gitsigns.setqflist)

-- Toggles map('n', '<leader>tb', gitsigns.togglecurrentline_blame) map('n', '<leader>tw', gitsigns.toggleworddiff)

-- Text object map({'o', 'x'}, 'ih', gitsigns.select_hunk) end }

๐Ÿ”— Plugin Integrations

[vim-fugitive]

When viewing revisions of a file (via :0Gclog for example), Gitsigns will attach to the fugitive buffer with the base set to the commit immediately before the commit of that revision. This means the signs placed in the buffer reflect the changes introduced by that revision of the file.

[trouble.nvim]

If installed and enabled (via config.trouble; defaults to true if installed), :Gitsigns setqflist or :Gitsigns setloclist will open Trouble instead of Neovim's built-in quickfix or location list windows.

๐Ÿšซ Non-Goals

Implement every feature in [vim-fugitive]

This plugin is actively developed and by one of the most well regarded vim plugin developers. Gitsigns will only implement features of this plugin if: it is simple, or, the technologies leveraged by Gitsigns (LuaJIT, Libuv, Neovim's API, etc) can provide a better experience.

Support for other VCS

There aren't any active developers of this plugin who use other kinds of VCS, so adding support for them isn't feasible. However a well written PR with a commitment of future support could change this.

๐Ÿ”Œ Similar plugins

  • [mini.diff]
  • [coc-git]
  • [vim-gitgutter]
  • [vim-signify]
[mini.diff]: https://github.com/echasnovski/mini.diff [coc-git]: https://github.com/neoclide/coc-git [diff-linematch]: https://github.com/neovim/neovim/pull/14537 [luv]: https://github.com/luvit/luv/blob/master/docs.md [nvim-lua-guide]: https://neovim.io/doc/user/lua-guide.html [release]: https://github.com/lewis6991/gitsigns.nvim/releases [trouble.nvim]: https://github.com/folke/trouble.nvim [vim-fugitive]: https://github.com/tpope/vim-fugitive [vim-gitgutter]: https://github.com/airblade/vim-gitgutter [vim-signify]: https://github.com/mhinz/vim-signify [virtual lines]: https://github.com/neovim/neovim/pull/15351 [lspsaga.nvim]: https://github.com/glepnir/lspsaga.nvim
๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท lewis6991/gitsigns.nvim ยท Updated daily from GitHub