Handle non-ASCII paths.

This prevents git-ls-files from escaping "unusual" characters in
pathnames.  When this happened, gitgutter would feed the escaped name
back to git-show but git-show would not recognise it.

This commit makes git-ls-files use the -z option to output pathnames
verbatim.  These pathnames also become null terminated so we have to
ensure we remove the null terminator too.

Closes #562.
This commit is contained in:
Andy Stewart
2018-11-17 11:24:36 +00:00
parent 0597380f6b
commit 947737c76f
2 changed files with 21 additions and 2 deletions

View File

@@ -115,7 +115,7 @@ function! gitgutter#utility#set_repo_path(bufnr) abort
" * -2 - not tracked by git
call gitgutter#utility#setbufvar(a:bufnr, 'path', -1)
let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' ls-files --error-unmatch --full-name -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' ls-files --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
if g:gitgutter_async && gitgutter#async#available()
if has('lambda')
@@ -202,8 +202,13 @@ function! s:exists_file(bufnr) abort
return filereadable(s:abs_path(a:bufnr, 0))
endfunction
" Get rid of any trailing new line or SOH character.
"
" git ls-files -z produces output with null line termination.
" Vim's system() replaces any null characters in the output
" with SOH (start of header), i.e. ^A.
function! s:strip_trailing_new_line(line) abort
return substitute(a:line, '\n$', '', '')
return substitute(a:line, '[[:cntrl:]]$', '', '')
endfunction
function! gitgutter#utility#windows()

View File

@@ -191,6 +191,20 @@ function Test_filename_leading_dash()
endfunction
function Test_filename_umlaut()
call system('touch -- fixtüre.txt && git add -- fixtüre.txt')
edit fixtüre.txt
normal ggo*
call s:trigger_gitgutter()
let expected = [
\ 'line=1 id=3000 name=GitGutterLineAdded',
\ 'line=2 id=3001 name=GitGutterLineAdded'
\ ]
call assert_equal(expected, s:signs('fixtüre.txt'))
endfunction
" FIXME: this test fails when it is the first (or only) test to be run
function Test_follow_symlink()
let tmp = 'symlink'