mirror of
https://github.com/airblade/vim-gitgutter.git
synced 2025-11-09 03:53:47 -05:00
Use minimal file paths.
Since we start all external commands by cd'ing to the current file's directory, we can use the file's name instead of its full path. The exception is `git show :FILE` where we must use a path relative to the repo root for maximum git compatibility. It turns out `git rev-parse` takes a `--show-prefix` argument which makes our relative path calculation far simpler. Minimising files paths has these benefits: - Easier to inspect the generated commands. - Less opportunity for escaping problems. - Eliminates possible mismatches betwen absolute paths generated by git and absolute paths generated by Vim (crops up with msys/msys2 on Windows). Thanks to @suxpert for helping with this.
This commit is contained in:
@@ -5,7 +5,7 @@ let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
|
||||
|
||||
function! diff#run_diff(realtime, use_external_grep)
|
||||
" Wrap compound command in parentheses to make Windows happy.
|
||||
let cmd = '(git ls-files --error-unmatch ' . utility#shellescape(utility#file()) . ' && ('
|
||||
let cmd = '(git ls-files --error-unmatch ' . utility#shellescape(utility#filename()) . ' && ('
|
||||
|
||||
if a:realtime
|
||||
let blob_name = ':' . utility#shellescape(utility#file_relative_to_repo_root())
|
||||
@@ -13,7 +13,7 @@ function! diff#run_diff(realtime, use_external_grep)
|
||||
let cmd .= 'git show ' . blob_name . ' > ' . blob_file .
|
||||
\ ' && diff -U0 ' . g:gitgutter_diff_args . ' ' . blob_file . ' - '
|
||||
else
|
||||
let cmd .= 'git diff --no-ext-diff --no-color -U0 ' . g:gitgutter_diff_args . ' ' . utility#shellescape(utility#file())
|
||||
let cmd .= 'git diff --no-ext-diff --no-color -U0 ' . g:gitgutter_diff_args . ' ' . utility#shellescape(utility#filename())
|
||||
endif
|
||||
|
||||
if a:use_external_grep && s:grep_available
|
||||
|
||||
@@ -4,10 +4,6 @@ function! utility#is_active()
|
||||
return g:gitgutter_enabled && utility#exists_file()
|
||||
endfunction
|
||||
|
||||
function! utility#slash()
|
||||
return !exists("+shellslash") || &shellslash ? '/' : '\'
|
||||
endfunction
|
||||
|
||||
" A replacement for the built-in `shellescape(arg)`.
|
||||
"
|
||||
" Recent versions of Vim handle shell escaping pretty well. However older
|
||||
@@ -37,6 +33,14 @@ function! utility#file()
|
||||
return s:file
|
||||
endfunction
|
||||
|
||||
function! utility#filename()
|
||||
return fnamemodify(s:file, ':t')
|
||||
endfunction
|
||||
|
||||
function! utility#directory_of_file()
|
||||
return fnamemodify(s:file, ':h')
|
||||
endfunction
|
||||
|
||||
function! utility#exists_file()
|
||||
return filereadable(utility#file())
|
||||
endfunction
|
||||
@@ -65,18 +69,18 @@ function! utility#buffer_contents()
|
||||
endfunction
|
||||
|
||||
function! utility#file_relative_to_repo_root()
|
||||
let repo_root_for_file = getbufvar(s:file, 'gitgutter_repo_root')
|
||||
if empty(repo_root_for_file)
|
||||
let dir = system(utility#command_in_directory_of_file('git rev-parse --show-toplevel'))
|
||||
let repo_root_for_file = substitute(dir, '\n$', '', '') . utility#slash()
|
||||
call setbufvar(s:file, 'gitgutter_repo_root', repo_root_for_file)
|
||||
let file_path_relative_to_repo_root = getbufvar(s:file, 'gitgutter_repo_relative_path')
|
||||
if empty(file_path_relative_to_repo_root)
|
||||
let dir_path_relative_to_repo_root = system(utility#command_in_directory_of_file('git rev-parse --show-prefix'))
|
||||
let dir_path_relative_to_repo_root = utility#strip_trailing_new_line(dir_path_relative_to_repo_root)
|
||||
let file_path_relative_to_repo_root = dir_path_relative_to_repo_root . utility#filename()
|
||||
call setbufvar(s:file, 'gitgutter_repo_relative_path', file_path_relative_to_repo_root)
|
||||
endif
|
||||
return substitute(s:file, repo_root_for_file, '', '')
|
||||
return file_path_relative_to_repo_root
|
||||
endfunction
|
||||
|
||||
function! utility#command_in_directory_of_file(cmd)
|
||||
let directory_of_file = utility#shellescape(fnamemodify(utility#file(), ':h'))
|
||||
return 'cd ' . directory_of_file . ' && ' . a:cmd
|
||||
return 'cd ' . utility#shellescape(utility#directory_of_file()) . ' && ' . a:cmd
|
||||
endfunction
|
||||
|
||||
function! utility#highlight_name_for_change(text)
|
||||
@@ -90,3 +94,7 @@ function! utility#highlight_name_for_change(text)
|
||||
return 'GitGutterLineModifiedRemoved'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function utility#strip_trailing_new_line(line)
|
||||
return substitute(a:line, '\n$', '', '')
|
||||
endfunction
|
||||
|
||||
Reference in New Issue
Block a user