diff --git a/autoload/diff.vim b/autoload/diff.vim index f5fbbe1..2367390 100644 --- a/autoload/diff.vim +++ b/autoload/diff.vim @@ -4,17 +4,25 @@ let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@' function! diff#run_diff(realtime, use_external_grep) + let cmd = 'git ls-files --error-unmatch' . utility#discard_stdout_and_stderr() . ' ' . shellescape(utility#file()) . ' && ' + if a:realtime let blob_name = ':./' . fnamemodify(utility#file(),':t') let blob_file = tempname() - let cmd = 'git show ' . blob_name . ' > ' . blob_file . ' && diff -U0 ' . g:gitgutter_diff_args . ' ' . blob_file . ' - ' + 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 . ' ' . shellescape(utility#file()) + let cmd .= 'git diff --no-ext-diff --no-color -U0 ' . g:gitgutter_diff_args . ' ' . shellescape(utility#file()) endif + if a:use_external_grep && s:grep_available - let cmd .= s:grep_command + " grep exits with 1 when no matches are found. However we want to treat + " non-matches as non-erroneous behaviour; so we append ` || :`. + let cmd .= s:grep_command . ' || :' endif + let cmd = utility#escape(cmd) + if a:realtime if &fileformat ==# "dos" let eol = "\r\n" @@ -28,6 +36,13 @@ function! diff#run_diff(realtime, use_external_grep) else let diff = system(utility#command_in_directory_of_file(cmd)) endif + + if v:shell_error + " A shell error indicates the file is not tracked by git (unless something + " bizarre is going on). + throw 'git-diff failed' + endif + return diff endfunction diff --git a/autoload/utility.vim b/autoload/utility.vim index 2db11d9..5ce00f4 100644 --- a/autoload/utility.vim +++ b/autoload/utility.vim @@ -1,7 +1,7 @@ let s:file = '' function! utility#is_active() - return g:gitgutter_enabled && utility#exists_file() && utility#is_tracked_by_git() + return g:gitgutter_enabled && utility#exists_file() endfunction function! utility#current_file() @@ -64,12 +64,6 @@ function! utility#command_in_directory_of_file(cmd) return substitute(utility#cmd_in_dir, "'", '"', 'g') endfunction -function! utility#is_tracked_by_git() - let cmd = utility#escape('git ls-files --error-unmatch' . utility#discard_stdout_and_stderr() . ' ' . shellescape(utility#file())) - call system(utility#command_in_directory_of_file(cmd)) - return !v:shell_error -endfunction - function! utility#differences(hunks) return len(a:hunks) != 0 endfunction diff --git a/plugin/gitgutter.vim b/plugin/gitgutter.vim index a3e1837..7daf185 100644 --- a/plugin/gitgutter.vim +++ b/plugin/gitgutter.vim @@ -55,26 +55,30 @@ command GitGutterAll call GitGutterAll() function! GitGutter(file, realtime) call utility#set_file(a:file) if utility#is_active() - if !a:realtime || utility#has_fresh_changes(a:file) - let diff = diff#run_diff(a:realtime || utility#has_unsaved_changes(a:file), 1) - let s:hunks = diff#parse_diff(diff) - let modified_lines = diff#process_hunks(s:hunks) + try + if !a:realtime || utility#has_fresh_changes(a:file) + let diff = diff#run_diff(a:realtime || utility#has_unsaved_changes(a:file), 1) + let s:hunks = diff#parse_diff(diff) + let modified_lines = diff#process_hunks(s:hunks) - if g:gitgutter_signs - if g:gitgutter_sign_column_always - call sign#add_dummy_sign() - else - if utility#differences(s:hunks) - call sign#add_dummy_sign() " prevent flicker + if g:gitgutter_signs + if g:gitgutter_sign_column_always + call sign#add_dummy_sign() else - call sign#remove_dummy_sign() + if utility#differences(s:hunks) + call sign#add_dummy_sign() " prevent flicker + else + call sign#remove_dummy_sign() + endif endif + call sign#update_signs(a:file, modified_lines) endif - call sign#update_signs(a:file, modified_lines) - endif - call utility#save_last_seen_change(a:file) - endif + call utility#save_last_seen_change(a:file) + endif + catch /git-diff failed/ + call hunk#reset() + endtry else call hunk#reset() endif