‹ back home

Working with Git inside Vim

2026-01-03 #git #vim

My workflow since time immemorial has been to use a code editor (Vim/Neovim) to edit code, and then the git command line tool to operate on the repository. This flow included switching to the command line for git add -p or git diff.

Each time I made a small tweak on an existing change, I had to switch back to the terminal and git add -p, skip irrelevant changes, and stage the one I want.

At some point I thought to myself “you can do better”. In recent months, I added two sets of keyboard mappings which have dramatically changed how I work.

Jump to changes

The set of mappings is:

nnoremap <expr> ]c &diff ? ']c' : '<Cmd>Gitsigns next_hunk<CR>'
nnoremap <expr> [c &diff ? '[c' : '<Cmd>Gitsigns prev_hunk<CR>'

These two are symmetrical: ]c jumps to the next change in the current file and [c jumps to the previous change in the current file (using gitsigns.nvim). The mapping is a bit long/complex because it intentionally avoids overriding the default behaviour when in diff mode.

This makes reviewing and potentially operating on changes in a file fast and straightforward.1

Stage changes

The second set of mappings is:

nnoremap <buffer> <Leader>ga <Cmd>Gitsigns stage_hunk<CR>
xnoremap <buffer> <Leader>ga :Gitsigns stage_hunk<CR>

The first of these mappings stages the current hunk (contiguous range of changed lines) to be committed. The second mapping applies only in visual mode (e.g.: when text is selected) and only stages the selection.

This lets me easily stage changes to be committed from the editor, without having to jump to the terminal. The main annoyance of jumping to the terminal and using git add -p was that I have to search for these changes again, while I already have my cursor on them in the editor!

I also still use git add -p when staging large amounts of changes in bulk. I use whichever would be faster, given the state of changes.

Other operations

I only really use those two mappings for git operations inside the code editor. It also shows lines which have been added/changed/removed on the left next to sign numbers. Everything else I still do via the git command line tool.

For my own usage, I don’t see much value in doing things like git checkout, git commit, git fetch, git rebase, etc in the editor. I’ve seen plenty of full-blown git integration in code editors, and I do not find these more convenient than my current approach. In addition, they typically lack support for a lot of the non-basic features that I’ve come to rely upon over the years.

Perhaps there are more specific git operations which would be convenient inside the code editor. At this time, I don’t know of any and can’t think of any. A few more years of use might tell.


  1. [ and ] are somewhat common for jumping to previous and next instances of something. For example [d and ]d jump to the previous or next diagnostic, [s and ]s jump across spelling mistakes, etc. ↩︎

Have comments or want to discuss this topic?
Send an email to my public inbox: ~whynothugo/public-inbox@lists.sr.ht.
Or feel free to reply privately by email: hugo@whynothugo.nl.

— § —