Vim Fugitive Plugin

A powerful way to use Git inside Vim.

GitHub: vim-fugitive

Tips

  • compare current file on another branch with :Gdiff [branch]
  • show commits touching visual selection with '<,'>Gclog
  • push specific commit from status window with - on git commit hash
  • open commit in browser with :GBrowse
  • rename the current file with :Grname

Fixup & Autosquash workflow

  1. Make changes, and stage them
  2. Open commits with :Glog
  3. Press Enter on the commit to fixup to
  4. Press cf after the committer line to create a fixup commit
  5. Press rf to perform an interactive rebase using autosquash https://github.com/tpope/vim-fugitive/issues/303

Setup

You can see how I use fugitive in my vim config here.

Installation

-- using lazy.nvim
require('lazy').setup({
  'tpope/vim-fugitive',
  'cedarbaum/fugitive-azure-devops.vim', -- :Gbrowse Azure DevOps Repos
  'shumphrey/fugitive-gitlab.vim',       -- :Gbrowse for GitLab
)}

Configuration

vim.keymap.set('n', '<leader>gs', ':Git<CR>', { silent = true })
vim.keymap.set('n', '<leader>gr', ':Gread<CR>', { silent = true })
vim.keymap.set('n', '<leader>gw', ':Gwrite<CR>:Gstatus<CR>', { silent = true })
vim.keymap.set('n', '<leader>gc', ':Gwrite<CR>:Git commit -v<CR>', { silent = true })
vim.keymap.set('n', '<leader>gl', ':G log --oneline<CR>', { silent = true })
vim.keymap.set('n', '<leader>gll', ':Gclog<CR>', { silent = true })
vim.keymap.set('n', '<leader>ge', ':Gedit<CR>', { silent = true })
vim.keymap.set('n', '<leader>gd', ':Git difftool<CR>', { silent = true })
vim.keymap.set('n', '<leader>gD', ':Git difftool -y<CR>', { silent = true })
vim.keymap.set('n', '<leader>gm', ':Git mergetool<CR>', { silent = true })
vim.keymap.set('n', '<leader>gb', ':Git blame<CR>', { silent = true })
vim.keymap.set('n', '<leader>gF', ':Git fetch<CR>', { silent = true })
vim.keymap.set('n', '<leader>gL', ':Git pull<CR>', { silent = true })
vim.keymap.set('n', '<leader>gP', ':Git! push<CR>', { silent = true })
vim.keymap.set('n', '<leader>gB', ':GBrowse<CR>', { silent = true })
vim.keymap.set('n', '<leader>gg', ':Glcd<CR>', { silent = true })
vim.keymap.set('n', '<leader>gG', ':lcd %:h<CR>', { silent = true })

Customization

Here are some useful customizations for fugitive.

-- override mappings in fugitive windows
vim.cmd([[
  " commit without triggering husky hooks
  autocmd FileType fugitive nmap <buffer> cn :G commit -n<CR>
 
  " navigate between chunks in status window
  autocmd FileType fugitive nmap <buffer> <localleader>gn ]c
  autocmd FileType fugitive nmap <buffer> <localleader>gp [c
  " navigate between chunks in diff mode
  autocmd User FugitiveBlob,FugitiveStageBlob nmap <buffer> <localleader>gn ]c
  autocmd User FugitiveBlob,FugitiveStageBlob nmap <buffer> <localleader>gp [c
 
  " disable mappings to avoid breaking diff screen
  autocmd User FugitiveBlob,FugitiveStageBlob nmap <buffer> <S-l> <nop>
  autocmd User FugitiveBlob,FugitiveStageBlob nmap <buffer> <S-h> <nop>
 
  " save commit message more quickly
  autocmd FileType gitcommit nmap <CR> ZZ
]])