Dealing With Git Conflicts Using Vim and Vcs-jump
vcs-jump
is a Vim plugin created by Greg Hurrell that “allows you to jump to useful places within a Git or Mercurial repository: diff hunks, merge conflicts, and grep results”.
I find it specially useful to resolve merge conflicts when rebasing or merging branches in git repos. Before I discovered this plugin, my merge/rebase workflow used to look like this:
- Run
git checkout my-feature-branch
. - Run
git rebase master
. - Get a
CONFLICT
warning 😖. - Run
git status
to clearly see which files have merge conflicts (I know they are listed when the rebase fails, but the output is so bloated with info messages that I get overwhelmed). - Open Vim, open the first conflicted file, search for the first conflict marker, fix the conflict, then search for more conflicts. Once I’m done with the current file, open the next one and repeat.
- Close Vim and run
git status again
, check the list of conflicted files and try to guess if I’ve resolved every conflict 🤷♂️. If I see a file which I know I didn’t fix, I go back to 5. - Run
git add -u && git rebase --continue
.
Usually at step 5, once I fix the conflicts in the first file, I can’t remember the next file name, so I start to go back and forth between steps 4 and 5. Also, when I have to resolve a complex conflict, I sometimes forget that the current file might have additional conflicts and I forget to search for the next conflict marker. So I find myself revisiting files and searching for conflict markers again 😅.
Enter vcs-jump
I discovered vcs-jump
watching one of Greg’s Vim screencasts (if you use Vim, check his YouTube channel, he’s uploaded lots of really interesting videos!), and I immediately saw how it would improve my git rebase workflow.
So I installed it and, to streamline my rebasing sessions even more, I created a fish shell abbreviation, vimerge
, which expands to vim -c ‘VcsJump merge’
(in plain English: “open Vim and run the `VcsJump merge` command”).
Now my work flow looks like this:
- Run
git checkout my-feature-branch
. - Run
git rebase master
. - Get a
CONFLICT
warning 😖. - Run
vimerge
. This opens the first conflicted file and populates Vim’s quickfix list with the location of each conflict marker in every file 😀. The quickfix window has the focus, so I just hit enter and then my cursor moves to the first conflict in the first file 🙌. - Resolve the conflict. Every time I want to go to the next one, I just run the
:cnext
command (or use Tim Pope’s vim-unimpaired mapping,]q
), until no more conflicts are left to fix. - Close Vim and run
git add -u && git rebase --continue
(I’m sure I’ve resolved every conflict now! 😄).
Little things matter
These might seem like a tiny improvement, but I can assure you that for me it’s been a game changer! I know it sounds far fetched, but resolving merge conflicts can get really tricky sometimes, and now I can focus on the actual conflict resolution and forget about the more mechanical part of the task (find the next conflict, the next file, check that every conflict has been resolved).
If you use Vim, give it a try. I hope you find it as useful as I do 🙂.