25

I'm trying to use vimdiff as a diff tool for Git but, for some reason, the files are always open in read-only mode. It makes sense for the original file but not for the ones that I have modified (since I haven't committed them yet).

This is my current .gitconfig:

[diff]
        tool = vimdiff
[merge]
        tool = vimdiff
[difftool]
        prompt = false

Any idea what could be causing this?

laurent
  • 88,262
  • 77
  • 290
  • 428

3 Answers3

22

The deafult command that git uses for vimdiff is: (found by inspecting process list)

vim -R -f -d -c "wincmd l" -c 'cd "$GIT_PREFIX"' "$LOCAL" "$REMOTE"

You can override this (to not use -R, readonly mode) by setting the difftool.vimdiff.cmd variable.

$ git config --global difftool.vimdiff.cmd 'vim -f -d -c "wincmd l" -c '\''cd "$GIT_PREFIX"'\'' "$LOCAL" "$REMOTE"'

The quoting is tricky. I would copy-paste it.

gfe
  • 157
  • 5
bukzor
  • 37,539
  • 11
  • 77
  • 111
  • this maybe some error, directly add "set noreadonly" in your vimrc file. – liuyang1 Sep 30 '14 at 09:31
  • @Procras: I think you accidentally a word. – bukzor Sep 30 '14 at 18:36
  • @alexis you still missed starting double quote for last word. please add it to make copy/paste safe for further users – ZuBB Aug 07 '16 at 11:56
  • @ZuBB yes!, thanks. I can't edit the old comment so I'll write it here again: I just put `[difftool "vimdiff"] cmd = vim -f -d -c 'wincmd l' -c 'cd "$GIT_PREFIX"' "$LOCAL" "$REMOTE"` in ~/.gitconfig – alexis Aug 08 '16 at 02:34
18

That's the default desired behaviour for vimdiff. You can unset using :set noro.

Or in your .vimrc config, add this:

" Default to not read-only in vimdiff
set noro
laurent
  • 88,262
  • 77
  • 290
  • 428
Shunya
  • 2,785
  • 2
  • 18
  • 17
  • Do you know if there's any way to set up vimdiff so that this option is always on? – laurent Aug 31 '13 at 13:02
  • 4
    In your vimrc file, construct the following line: set noro – Shunya Sep 01 '13 at 11:59
  • @Laurent, while I was going thro some help on vim, I found this URL (it might help you). Please check the bottom of the page which says "Change read/only files to read/write when they are edited" URL : http://vim.wikia.com/wiki/Setting_file_attributes_without_reloading_a_buffer. I guess this should be part of your vimrc configuration file. Please update if this works fine.. – Shunya Sep 02 '13 at 09:32
  • thanks but actually the `noro` option is exactly what I was looking for, as I prefer being able to edit the diff by default (I often do some clean-up on the changed files before committing). – laurent Sep 02 '13 at 12:27
  • 4
    Would you consider expanding this answer to explain why it's the default desired behavior? – amcnabb Mar 21 '14 at 17:54
  • 8
    Read-only is not a default behavior of vimdiff. Try it: `vimdiff thisfile thatfile`. Git passes -R (Read-only mode) when invoking vimdiff. Is there a way to tell git to not do that? – bukzor Aug 11 '14 at 21:24
  • What happens if you remove the read only option and accidentally edit a file in a previous commit? – BAdhi Dec 07 '16 at 04:13
  • 2
    @BAdhi _"What happens if you remove the read only option and accidentally edit a file in a previous commit?"_ It doesn't matter, because it's just a copy of the file in a tmp dir. It is impossible to change a previous git commit. – wisbucky Apr 27 '18 at 16:44
  • It's from the past though but still relevant. This answer has been chosen too fast as "The answer". As @bukzor has mentioned, what it says about vimdiff's default behaviour is not true. but it's luckily one of those non-100%-correct solutions which "works!". The complete answer could be the one from wisbucky bellow. – roxch Oct 29 '20 at 08:46
8

The reason this happens is because git invokes vimdiff with the -R (readonly) option. There are several solutions to be able to write to the file:

  1. Use :w! in vim. That will force write even though it was opened as readonly.

  2. You can edit ~/.gitconfig to override the vimdiff command without -R

    [difftool "vimdiff"]
    cmd = vimdiff "$LOCAL" "$REMOTE"
    
  3. You can edit ~/.vimrc to always make vimdiff writeable. (This will affect all vimdiff, not just git.)

    if &diff
        set noreadonly
    endif
    
wisbucky
  • 33,218
  • 10
  • 150
  • 101