Error using the :GDiff command of fugitive.vim using gvim for windows and msys git 1.7.0.2
I've been using git along with fugitive.vim to manage code when I'm on windows. However, I've run into a problem. According to the documentation, the :GDiff command should a diff wi开发者_运维问答ndow and allow me to stage only parts of a file. However, when I issue the command in a file with changes, I get the following error message:
Is this a problem with windows? vim? fugitive? msysgit? file permissions? Anybody know?
I had the same problem - here's how I fixed it.
By default, Vim will try to store swap files beside the original. Fugitive creates a buffer that does not correspond to any real file path, so Vim barfs when it tries to create the swap file. The solution is to make sure that Vim has a path it can write to.
Here's how I fixed this:
if has("win32") || has("win64")
set directory=$TMP
else
set directory=~/tmp
end
Here's the original issue on GitHub: https://github.com/tpope/vim-fugitive/issues/9
EDIT:
As fow points out below, it's probably better to use something like the following:
set directory+=,~/tmp,$TMP
Vim should use the first path it can.
I do not have a Windows machine, but I was able to reproduce and isolate this problem on a Mac OS X 10.6 system.
Either create C:\TMP
or C:\TEMP
(:help 'directory'
says both are in the default value of the directory
option on Windows builds of Vim), or add an existing directory to the value of the directory
option.
I use a Vim-specific temporary directory under my home directory (again, no Windows here) and add two trailing slashes (~/tmp/.vim-swaps//
). This kind of setting centralizes the swap files but gives them unique names based on the directories of the files being edited. See “Advantages” and “Disadvantages” in :help :swapname
as well as the
“if a directory ends in two path separators” bit in :help 'directory'
.
Use ^=
to prepend1 your directory (so that it is always used, if it exists):
set directory^=C:\\some\\existing\\directory//
Or, use +=
to append your directory (so that it is only used if it exists and no other applicable directory
entries exist):
set directory+=C:\\some\\existing\\directory//
Charles’ answer suggests that $TMP
(a reference to an environment variable) might be a good value for Windows:
set directory+=$TMP//
The root cause is related to the default value of the directory
option combined with the pathname of :Gdiff
’s index “pseudo” file.
The buffer for the index side of a :Gdiff
view uses a special pathname that looks like fugitive:///path/to/repository/.git//0/path/to/file/under/repository
(fugitive captures reads and writes to so named buffers and redirects them to the index by invoking Git “plumbing” commands).
The first entry in directory
is usually .
. This means that Vim will try to put the swapfile in the same directory as the edited file (i.e. foo/bar.txt
will try to use foo/.bar.swp
). If this preferred swapfile can not be created, then subsequent entries from directory
will be tried.
With .
as the first directory
, the preferred swapfile for fugitive:///path/to/repository/.git//0/path/to/file/under/repository
will be fugitive:///path/to/repository/.git//0/path/to/file/under/.repository.swp
. The leading components of this pathname (fugitive:
, path
, to
, etc.) probably do not exist, so Vim will go on to the next entry from directory
. If none of the other directory
entries are usable for creating swap files (e.g. they do not exist), then you get error E302.
I was able to reproduce your problem on a Unix-y system by using set directory=.,~/no-such-dir,/var/no-such-dir,/no-such-dir
(i.e. taking the default Unix value and changing occurrences of tmp
to no-such-dir
). None of the “no-such-dir” directories actually existed. I got the same error when I use :Gdiff
.
1
:help :set^=
only says “add”, but the code shows that set listopt^=…
prepends similar to how set listopt+=…
appends (as the latter is documented to do). Both should automatically insert commas as needed (though there may have been bugs in this area).
That may be related to the issue 428 of msysgit mentioned in my SO answer.
Try patching the cmd/git.cmd
as I describe in my previous answer and see if this help.
Baring that, 2 options remains:
- either a locking problem (the file is locked by a process): an utility like process monitor or process explorer might help to see if it is the case (and what handle exactly there is on that swap file)
- or a Git issue. One good trick is then to install the net-installer of msysgit, which will build the latest version of Git on your Windows. You can then try and see if the problem persists with that updated version.
Note: third option, trying to downgrade Git, again to rule out any link with that tool.
BTW same error I got, when I tried to :gdiff unsaved file - when i saved it (:w) it works!
精彩评论