gitsigns.nvim

repository·main·Indexed 27 days ago

https://github.com/lewis6991/gitsigns.nvim

A Neovim plugin providing deep buffer integration for Git, featuring visual indicators (signs) for changes, hunk-level staging and resetting, inline and popup diff previews, and line-level blame information. Requires Neovim >= 0.9.0 and a recent version of Git.

Tokens
2.8K
Snippets
5
Records
13
Agent score
92%

What's inside gitsigns.nvim

  1. Integrate Gitsigns with Statusline and Trouble.nvim

    main

    Statusline Integration

    You can display Git status in your statusline using buffer variables:

    • b:gitsigns_status: A formatted string (uses config.status_formatter).
    • b:gitsigns_status_dict: A dictionary containing added, removed, changed, and head.
    • b:gitsigns_head: The current branch name.

    Example Vimscript for statusline:

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

    Trouble.nvim Integration

    If trouble.nvim is installed, Gitsigns will automatically use it to display the results of :Gitsigns setqflist or :Gitsigns setloclist instead of the standard Neovim quickfix/location lists.

  2. Format commit messages using the project guidelines

    main

    When creating or amending commits, follow these formatting rules:

    • Subject Format: Use <type>(<scope>): <verb phrase>.
    • Subject Length: Keep the subject line under 72 characters.
    • Body: Include a detailed body explaining the problem and the solution.
    • Line Wrapping: Wrap both body and footer lines at 72 characters.
    • Issue Resolution: When a commit resolves a specific issue, add a footer such as Resolves #1525.
    • Multi-line Messages: When scripting git commit, use git commit -F <file> for multi-line messages. If using the -m flag, pass actual line breaks instead of literal \n characters.
  3. Install and configure gitsigns.nvim

    main

    Install gitsigns.nvim using your preferred Neovim package manager. While no setup is strictly required for basic functionality, you can pass an options object to require('gitsigns').setup() to customize signs, blame behavior, and diff settings.

    Requirements:

    • Neovim >= 0.9.0
    • A recent version of Git
    require('gitsigns').setup {
      -- Example configuration
      signs = {
        add          = { text = '┃' },
        change       = { text = '┃' },
        delete       = { text = '_' },
        topdelete    = { text = '‾' },
        changedelete = { text = '~' },
        untracked    = { text = '┆' },
      },
      signs_staged_enable = true,
      current_line_blame = false,
      word_diff = false,
    }
  4. Prepare code and documentation before committing

    main

    Use the following Makefile commands to ensure code quality and documentation consistency before committing changes:

    • Format and build: make build formats Lua sources and regenerates documentation.
    • Documentation check: make doc regenerates help docs, while make doc-check regenerates them and fails if there is any drift.
    • Static analysis: make emmylua-check runs an optional static analysis pass.
    make build
    make doc
    make doc-check
    make emmylua-check
  5. Run the functional test suite

    main

    To run functional tests, you must first raise the file descriptor limit to avoid failures. Use the following command patterns:

    • Run all functional tests: ulimit -n 1024; make test [FILTER=pattern] (where pattern is an optional filter).
    • Run against specific Neovim versions: Use make test-010, make test-011, make test-012, or make test-nightly.

    Always prefix these commands with ulimit -n 1024 in the sandbox environment.

    ulimit -n 1024; make test [FILTER=pattern]
    # Or for specific versions:
    ulimit -n 1024; make test-010
    ulimit -n 1024; make test-nightly
  6. Configure hunk and blame settings via setup()

    main

    The setup() function accepts several configuration keys to control plugin behavior:

    Signs Configuration

    • signs: Table defining text for add, change, delete, topdelete, changedelete, and untracked states.
    • signs_staged: Table defining text for staged changes.
    • signs_staged_enable: Boolean to enable/disable staged signs.
    • signcolumn: Boolean to enable the sign column.
    • numhl: Boolean to enable number highlighting.
    • linehl: Boolean to enable line highlighting.

    Blame Configuration

    • current_line_blame: Boolean to enable virtual text blame for the current line.
    • current_line_blame_opts: Table for blame appearance:
      • virt_text: Boolean.
      • virt_text_pos: 'eol' | 'overlay' | 'right_align'.
      • delay: Integer (ms).
      • ignore_whitespace: Boolean.
      • virt_text_priority: Integer.
      • use_focus: Boolean.
    • current_line_blame_formatter: String format for blame text (e.g., '<author>, <author_time:%R> - <summary>').
    • blame_formatter: Custom formatter (defaults to nil).

    Diff and Other Settings

    • word_diff: Boolean to enable intra-line word diff.
    • watch_gitdir: Table with follow_files boolean.
    • auto_attach: Boolean to automatically attach to buffers.
    • attach_to_untracked: Boolean.
    • max_file_length: Integer (lines) to disable plugin for very large files.
    • preview_config: Table for nvim_open_win options (e.g., style, relative, row, col).
  7. Set up Gitsigns keymaps using on_attach

    main

    Gitsigns recommends using the on_attach callback in your setup() call to define buffer-local keymaps. This ensures mappings are only active when the plugin is attached to a buffer.

    Example implementation for navigation, hunk actions, and toggles:

    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.preview_hunk_inline)
        map('n', '<leader>hb', function()
          gitsigns.blame_line({ full = true })
        end)
        map('n', '<leader>hd', gitsigns.diffthis)
    
        -- Toggles
        map('n', '<leader>tb', gitsigns.toggle_current_line_blame)
        map('n', '<leader>tw', gitsigns.toggle_word_diff)
    
        -- Text object
        map({'o', 'x'}, 'ih', gitsigns.select_hunk)
      end
    }
  8. Show hunks in Quickfix or Location List

    main

    You can populate the quickfix or location list with Git hunks using the following commands:

    • :Gitsigns setqflist: Set the quickfix list.
    • :Gitsigns setloclist: Set the location list.

    Use the target argument to specify the scope:

    • target=all: Show hunks for the whole repository.
    • target=attached: Show hunks for attached buffers.
    • target=[integer]: Show hunks for a specific buffer ID.
  9. Use Gitsigns commands for hunk and blame actions

    main

    Gitsigns provides several commands to interact with Git hunks and blame information:

    Hunk Actions

    • :Gitsigns stage_hunk: Stage the current hunk (works in visual mode for partial hunks).
    • :Gitsigns reset_hunk: Reset the current hunk.
    • :Gitsigns preview_hunk: Show hunk in a popup.
    • :Gitsigns preview_hunk_inline: Show hunk preview inline.
    • :Gitsigns nav_hunk next/prev: Navigate between hunks.
    • :Gitsigns stage_buffer: Stage the entire buffer.
    • :Gitsigns reset_buffer: Reset the entire buffer.

    Blame and Diff

    • :Gitsigns blame: Show buffer blame.
    • :Gitsigns blame_line: Show current line blame in a popup.
    • :Gitsigns toggle_current_line_blame: Toggle virtual text blame.
    • :Gitsigns diffthis [REVISION]: Show diff of current buffer with index or specific revision.
    • :Gitsigns toggle_word_diff: Toggle intra-line word diff.
    • :Gitsigns change_base <REVISION>: Change the revision used for signs.
    • :Gitsigns show <REVISION>: Edit the current buffer at a specific revision.
  10. Execute gitsigns actions via command line

    main

    The gitsigns.nvim CLI allows you to run actions, attach/detach, or debug functions directly from the command line. When running a command without a specific function name, an interactive selection menu (via vim.ui.select) will appear to let you choose from available actions.

    Arguments passed to the command are automatically parsed into Lua types:

    • 'true'/'false' becomes boolean true/false.
    • 'nil' becomes nil.
    • Numeric strings (e.g., '100') become numbers.
    • Other strings (e.g., 'HEAD~300') remain strings.