Fix new-line signs for untracked repo files with square brackets.

Before the plugin tries to diff a file, it checks whether git is
tracking the file.  If git isn't tracking the file, it stops there and
doesn't display any signs.  If git is tracking the file, the plugin
remembers so next time it can skip the check.

When I introduced asynchronous diffing for NeoVim (18b78361), I made a
refactoring mistake which caused the plugin on second and subsequent
runs [to always think git is tracking a file][1].

The non-realtime diffs – the ones you get when you save a buffer –
basically run `git diff FILE`.  With an untracked file git returns
nothing and exits successfully.  So although the plugin erroneously
thinks git is tracking the file, it gets an error-free, empty diff back
and so removes any and all signs.  Which means that the bug doesn't make
any difference.

However the realtime diffs write the buffer's contents to a temporary
file, and write the file as staged in the index to a temporary file,
then run `git diff FILE1 FILE2`.  To write the staged version of the
file we use `git show :FILE > TMPFILE`.

When `FILE` isn't known to git, `git show :FILE` exits with an error.
Unless, that is, [the filename contains square brackets and you're using
git v2.5.0+][2], in which case git exits successfully with empty output.

So if you're using git v2.5.0+, and you're editing an untracked file in
a repository, and the filename contains square brackets, the plugin will
think: git is tracking the file; the realtime diff is successful; the
file in the index is empty; so every line in the the working copy must
be an addition; hence a `+` sign on every line.

[1]: 18b7836168/autoload/gitgutter/diff.vim (L119-L121)
[2]: http://comments.gmane.org/gmane.comp.version-control.git/285686

Closes #325.
This commit is contained in:
Andy Stewart
2016-04-22 15:04:32 +01:00
parent 65025c9f31
commit d282c33789
5 changed files with 16 additions and 4 deletions

View File

@@ -56,6 +56,8 @@ endfunction
function! gitgutter#handle_diff(diff) function! gitgutter#handle_diff(diff)
call setbufvar(gitgutter#utility#bufnr(), 'gitgutter_tracked', 1)
call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(a:diff)) call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(a:diff))
let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks()) let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())

View File

@@ -123,10 +123,6 @@ function! gitgutter#diff#run_diff(realtime, preserve_full_diff)
endif endif
end end
if !tracked
call setbufvar(bufnr, 'gitgutter_tracked', 1)
endif
if g:gitgutter_async && has('nvim') && !a:preserve_full_diff if g:gitgutter_async && has('nvim') && !a:preserve_full_diff
let cmd = gitgutter#utility#command_in_directory_of_file(cmd) let cmd = gitgutter#utility#command_in_directory_of_file(cmd)
" Note that when `cmd` doesn't produce any output, i.e. the diff is empty, " Note that when `cmd` doesn't produce any output, i.e. the diff is empty,

View File

@@ -0,0 +1,10 @@
source helper.vim
let tmpfile = '[un]trackedFileWithinRepo.tmp'
call system('touch '.tmpfile)
execute 'edit '.tmpfile
normal ggo*
doautocmd CursorHold
call DumpSigns('untrackedFileSquareBracketsWithinRepo')
call system('rm '.tmpfile)

View File

@@ -3,6 +3,8 @@ source helper.vim
let tmpfile = 'untrackedFileWithinRepo.tmp' let tmpfile = 'untrackedFileWithinRepo.tmp'
call system('touch '.tmpfile) call system('touch '.tmpfile)
execute 'edit '.tmpfile execute 'edit '.tmpfile
normal ggo*
doautocmd CursorHold
call DumpSigns('untrackedFileWithinRepo') call DumpSigns('untrackedFileWithinRepo')
call system('rm '.tmpfile) call system('rm '.tmpfile)

View File

@@ -0,0 +1,2 @@
--- Signs ---