Skip to content

Commit

Permalink
Use minimal file paths.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
airblade committed Feb 26, 2014
1 parent 973c19e commit 7e8d2fb
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 14 deletions.
4 changes: 2 additions & 2 deletions autoload/diff.vim
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ 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())
let blob_file = tempname()
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
Expand Down
32 changes: 20 additions & 12 deletions autoload/utility.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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

0 comments on commit 7e8d2fb

Please sign in to comment.