From 626541edeb74ca2d6692bcbb3d69b7428d535724 Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Sat, 23 Apr 2022 08:25:46 +0100 Subject: [PATCH] Heeds git's "assume unchanged" bit I.e. does not diff files which should be assumed unchanged. See: git update-index --[no-]assume-unchanged -- git ls-files -v Closes #826. --- README.mkd | 1 + autoload/gitgutter.vim | 2 ++ autoload/gitgutter/diff.vim | 4 ++++ autoload/gitgutter/utility.vim | 25 +++++++++++++++++++------ test/test_gitgutter.vim | 9 +++++++++ 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/README.mkd b/README.mkd index 0b49493..408bb2f 100644 --- a/README.mkd +++ b/README.mkd @@ -18,6 +18,7 @@ Features: * Stage partial hunks. * Provides a hunk text object. * Diffs against index (default) or any commit. +* Heeds git's "assume unchanged" bit. * Allows folding all unchanged text. * Provides fold text showing whether folded lines have been changed. * Can load all hunk locations into quickfix list or the current window's location list. diff --git a/autoload/gitgutter.vim b/autoload/gitgutter.vim index bbc1c99..7686686 100644 --- a/autoload/gitgutter.vim +++ b/autoload/gitgutter.vim @@ -44,6 +44,8 @@ function! gitgutter#process_buffer(bufnr, force) abort let diff = gitgutter#diff#run_diff(a:bufnr, g:gitgutter_diff_relative_to, 0) catch /gitgutter not tracked/ call gitgutter#debug#log('Not tracked: '.gitgutter#utility#file(a:bufnr)) + catch /gitgutter assume unchanged/ + call gitgutter#debug#log('Assume unchanged: '.gitgutter#utility#file(a:bufnr)) catch /gitgutter diff failed/ call gitgutter#debug#log('Diff failed: '.gitgutter#utility#file(a:bufnr)) call gitgutter#hunk#reset(a:bufnr) diff --git a/autoload/gitgutter/diff.vim b/autoload/gitgutter/diff.vim index 0ed77ed..794cd14 100644 --- a/autoload/gitgutter/diff.vim +++ b/autoload/gitgutter/diff.vim @@ -77,6 +77,10 @@ function! gitgutter#diff#run_diff(bufnr, from, preserve_full_diff) abort throw 'gitgutter not tracked' endif + if gitgutter#utility#repo_path(a:bufnr, 0) == -3 + throw 'gitgutter assume unchanged' + endif + " Wrap compound commands in parentheses to make Windows happy. " bash doesn't mind the parentheses. let cmd = '(' diff --git a/autoload/gitgutter/utility.vim b/autoload/gitgutter/utility.vim index f0eb27d..f2c1a4c 100644 --- a/autoload/gitgutter/utility.vim +++ b/autoload/gitgutter/utility.vim @@ -108,6 +108,7 @@ endfunction " * non-empty string - path " * -1 - pending " * -2 - not tracked by git +" * -3 - assume unchanged function! gitgutter#utility#repo_path(bufnr, shellesc) abort let p = gitgutter#utility#getbufvar(a:bufnr, 'path', '') return a:shellesc ? gitgutter#utility#shellescape(p) : p @@ -116,9 +117,13 @@ endfunction let s:set_path_handler = {} -function! s:set_path_handler.out(buffer, path) abort - let path = s:strip_trailing_new_line(a:path) - call gitgutter#utility#setbufvar(a:buffer, 'path', path) +function! s:set_path_handler.out(buffer, listing) abort + let [status, path] = split(s:strip_trailing_new_line(a:listing)) + if status =~ '[[:lower:]]' + call gitgutter#utility#setbufvar(a:buffer, 'path', -3) + else + call gitgutter#utility#setbufvar(a:buffer, 'path', path) + endif if type(self.continuation) == type(function('tr')) call self.continuation() @@ -140,9 +145,10 @@ function! gitgutter#utility#set_repo_path(bufnr, continuation) abort " * non-empty string - path " * -1 - pending " * -2 - not tracked by git + " * -3 - assume unchanged call gitgutter#utility#setbufvar(a:bufnr, 'path', -1) - let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' '.g:gitgutter_git_args.' ls-files --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr))) + let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' '.g:gitgutter_git_args.' ls-files -v --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr))) if g:gitgutter_async && gitgutter#async#available() && !has('vim_starting') let handler = copy(s:set_path_handler) @@ -151,11 +157,18 @@ function! gitgutter#utility#set_repo_path(bufnr, continuation) abort return 'async' endif - let path = gitgutter#utility#system(cmd) + let listing = gitgutter#utility#system(cmd) + if v:shell_error call gitgutter#utility#setbufvar(a:bufnr, 'path', -2) + return + endif + + let [status, path] = split(s:strip_trailing_new_line(listing)) + if status =~ '[[:lower:]]' + call gitgutter#utility#setbufvar(a:bufnr, 'path', -3) else - call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path)) + call gitgutter#utility#setbufvar(a:bufnr, 'path', path) endif endfunction diff --git a/test/test_gitgutter.vim b/test/test_gitgutter.vim index f9aac59..595c254 100644 --- a/test/test_gitgutter.vim +++ b/test/test_gitgutter.vim @@ -1126,3 +1126,12 @@ function Test_foldtext() call assert_equal(0, gitgutter#fold#is_changed()) call assert_equal('+- 3 lines: a', gitgutter#fold#foldtext()) endfunction + + +function Test_assume_unchanged() + call system("git update-index --assume-unchanged fixture.txt") + unlet b:gitgutter.path " it was already set when fixture.txt was loaded in SetUp() + normal ggo* + call s:trigger_gitgutter() + call s:assert_signs([], 'fixture.txt') +endfunction