I use vim as my primary editor.

I would also like to use vim to diff files and modify the files while doing the diff to fix easy changes (rather than most diff techniques which are a cycle of diff/fix/diff/fix).

Additionally are there easy ways to integrate vim into diff tools used by source control tools/sites (I am specifically thinking of git but I am sure other people would be interested in integration with other source control tools/sites).

  • 1
    you should try vim-fugitive it adds the commands :Gdiff and :Gvdiff both commands lets you see the side by side diff of the current buffer if your current buffer is managed by git. It also heps you to resolve conflicts in a three window layout when you have merge conflicts on some files
    – rbernabe
    Mar 23 '17 at 4:31
  • I have this simple function in my bashrc vd () { diff $@ > /dev/null ; if [[ $? -eq 1 ]] ; then ; vimdiff -c 'windo set syntax=off' $@ ; fi ; } and I invoke it with vd file1 file2. It uses diff to determine whether the files differ and only opens vimdiff if that is so. Otherwise, I stay in the shell. I also disable syntax highlighting in Vim because I find it distracting when diffing. Only works with two files.
    – Rolf
    Oct 6 '17 at 6:10

vim has this functionality built in (with the correct command line flag).

vim -d <file1> <file2>

This opens each file in a view and highlights the differences.
Any code that is identical is folded away so you do not need to look at identical code or scroll through huge chunks of identical code.

But there is also a wrapper application vimdiff that correctly invokes vim with the correct flags.

vimdiff source1.cpp source2.cpp

If you are using git you can set up an external diff tool. So it is easy to set up vimdiff to be the diff tool for git.

git config --global diff.tool vimdiff

When using vimdiff you can edit either side and diff highlighting keeps pace to show you the differences.

Note: When editing from a git diff. If you try and edit the repository stored version of the file your changes will be discarded when you exit (git does not trust you with the original so you are diffing against a tmp copy) but you can edit the local copy to your hearts content and save it over you current version.

Some basic commands that are useful in vimdiff

dp             diffput: puts changes under the cursor into the other file
                        making them identical (thus removing the diff).
do             diffget: (o => obtain). The change under the cursor is replaced
                        by the content of the other file making them identical.

]c             Jump to the next diff
[c             Jump to the previous diff

Other vim settings I use to work with highliting with vimdiff

if &diff
    highlight! link DiffText MatchParen

This turns off highlighting on the bits of code that are changed. So the line that is changed is highlighted so I can spot the changes, but the actual text that has changed stands out on the line (as it is not highlighted).

  • 54
    You can also use the :diffthis command to initiate a diff when Vim is already running.
    – Rich
    Feb 10 '15 at 11:15
  • 15
    And :diffoff to turn it off. I think a link to vim's documentation would be beneficial: vimdoc.sourceforge.net/htmldoc/diff.html
    – Cody Poll
    Feb 12 '15 at 4:49
  • 1
    For me even after git config --global diff.tool vimdiff, git diff still shows everything like if I change nothing.
    – Hi-Angel
    Sep 1 '16 at 15:17
  • 4
    try git difftool Sep 1 '16 at 16:25
  • 1
    There is also :diffupdate which will refresh the diff view after changes: ```` :diffupdate ```` Feb 1 '19 at 19:24

If you are editing an open file and want to compare it to another file without closing the current one:

Open the new file in split screen:

For vertical split:

:vs otherFile

or horizontal split:

:split otherFile

Switch cursors to different split screen:

ctrl+w ctrl+w

Invoke "diff mode" in file:


Switch to other file and invoke "diff mode":


To turn off "diff mode":

  • 9
    To avoid switching between the buffers you can use :windo diffthis too
    – statox
    Oct 2 '18 at 14:50
  • 1
    @statox: works for diffoff as well, so :windo diffthis and :windo diffoff to start and stop diff for two open windows. Or abbreviated :windo difft and diffo!.
    – Wolfson
    Oct 5 '20 at 13:14
  • If starting with one open file File1, you can also use :vert diffs File2 to open File2 in a vertical split on the right and diff it with File1.
    – Wolfson
    Oct 5 '20 at 13:17

For NeoVim, you can setup your ~/.gitconfig with the following commands

git config --global merge.tool nvim
git config --global mergetool.keepBackup false
git config --global mergetool.nvim.cmd $'nvim -d $LOCAL $REMOTE $MERGED -c \'$wincmd w\' -c \'wincmd J\''

Your ~/.gitconfig should then look like:

    tool = nvim

    keepBackup = false

[mergetool "nvim"]
    cmd = nvim -d $LOCAL $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J'

Refer to Nvim documentation: diff for more info on how to configure it to your liking.

  • Can you explain a bit more about the last command? Is there a Linux alternative? Also worth noting that keeping the .orig file or not (i.e. mergetool.keepbackup is a matter of preference.
    – Colin
    Nov 16 '21 at 9:04

You can place below mentioned setting in .gitconfig file found in %homepath% (or %userprofile%) directory of the currently logged in user:

    tool = vimdiff

This will enable git bash tool to start using vimdiff as the external diff tool as well.


Following is my git config:


editor = vim
tool = vimdiff
tool = vimdiff
conflictstyle = diff3
prompt = 0

I can see only three situations to use vim as a difftool. They are briefly described below:

  • For git difftool, put the following in your ~/.gitconfig:

    editor = vim
    tool = vimdiff
    tool = vimdiff
    conflictstyle = diff3
  • To open vim as a diff-tool for two file, you can do the following:

    vimdiff file1.ext file2.ext      # for vim
    nvim -d file1.ext file2.ext      # for neovim
  • To get diff view for the buffers that are currently active, i.e. all the buffers that have a window assigned to them in the currently active tabpage, you can do the following:

    :windo diffthis                " to get diff view
    :windo diffoff                 " to remove diff view

For more information, see :h diff

  • 2
    if only one file open yet: :vert diffs File2 to diff with File2.
    – Wolfson
    Oct 6 '20 at 13:39

here's what I do:

  • open a window with first file (or text contents if you're pasting data)
  • open next file/window using :vnew (to have both windows side by side) or :new (to have the windows top and bottom). if you have a specific file to open in the second window, you can include the path like this: :vnew /path/to/secondfile.txt
  • use F8 to toggle a custom function which turns diff mode on and off

here's the custom function that's in my ~/.vimrc:

nmap <silent> <F8> :call ToggleDiff()<CR>
imap <silent> <F8> <C-O>:call ToggleDiff()<CR>
function ToggleDiff ()
    if (&diff)
        set nodiff noscrollbind
        " enable diff options in both windows; balance the sizes, too
        wincmd =
        set diff scrollbind nowrap number
        wincmd w
        set diff scrollbind nowrap number
        wincmd w
  • you can use the command :diffthis and diffoff! so you don't have to set all diff options yourself (e.g. cursorbind is also set by diffmode) Apr 17 '19 at 16:49

I have adopted by .vimrc with some useful commands in diff mode (lower part). If you edit in normal mode the setting are reset (upper part). You can copy it simply in your .vimrc file.

nmap <silent> <F2> :exec &nu==&rnu? "se nu!" : "se rnu!"<CR>
inoremap <Esc>Oq 1
inoremap <Esc>Or 2
inoremap <Esc>Os 3
inoremap <Esc>Ot 4
inoremap <Esc>Ou 5
inoremap <Esc>Ov 6
inoremap <Esc>Ow 7
inoremap <Esc>Ox 8
inoremap <Esc>Oy 9
inoremap <Esc>Op 0
inoremap <Esc>On .
inoremap <Esc>OQ /
inoremap <Esc>OR *
inoremap <Esc>Ol +
inoremap <Esc>OS -
inoremap <Esc>OM <Enter>
nnoremap <Esc>OQ B                      "       /
nnoremap <Esc>OR E                      "       *
if &diff
        map <Esc>Oq zc                  "       1       close a fold
        map <Esc>Or <down>              "       2       cursor down
        map <Esc>Os ]c                  "       3       next diff
        nmap <Esc>Ot <left>             "       4       curosor left
        nnoremap <Esc>Ou <c-w>w         "       5       jump to next file
        map <Esc>Ov <right>             "       6       cursor right
        map <Esc>Ow zo                  "       7       open a fold
        map <Esc>Ox <up>                "       8       curosor right
        map <Esc>Oy [c                  "       9       prefious diff
        map <Esc>Op 0                   "       0       0
        nmap <Esc>On .                  "       .       .
        nmap <Esc>OQ B                  "       /       back one word
        nmap <Esc>OR E                  "       *       end of word
        nmap <Esc>Ol dp                 "       -       diffput
        nmap <Esc>OS do                 "       +       diffget
        nmap <Esc>OM :diffupdate        "       Enter

Of course, you can change my settings. If you want to put another command on "0", change the command right after "Op" e.g. with "za" which toggles between fold and unfold:

    nmap <Esc>Op za                   "       0       0

Please be aware of the different use of "map" and "nmap" depending on the key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.