commit d48fc4a5ec2d03537a130e7e0537410e31f90d5a (tree)
parent c98daaacfe18df84a354c6f4a80a6b7787c0cf33
Author: Tim Pope <code@tpope.net>
Date: Wed, 19 Dec 2018 14:15:55 -0500
Cache config queries
Does not support includeIf directives or a system config outside of
/etc/gitconfig for cache expiration.
Diffstat:
2 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim
@@ -327,10 +327,48 @@ function! fugitive#RevParse(rev, ...) abort
call s:throw('rev-parse '.a:rev.': '.hash)
endfunction
-function! fugitive#Config(name, ...) abort
- let cmd = fugitive#Prepare(a:0 ? a:1 : get(b:, 'git_dir', ''), '--no-literal-pathspecs', 'config', '--get', '--', a:name)
- let out = matchstr(system(cmd), "[^\n]*")
- return v:shell_error ? '' : out
+function! s:ConfigTimestamps(dir, dict) abort
+ let files = ['/etc/gitconfig', '~/.gitconfig',
+ \ len($XDG_CONFIG_HOME) ? $XDG_CONFIG_HOME . '/git/config' : '~/.config/git/config']
+ if len(a:dir)
+ call add(files, fugitive#Find('.git/config', a:dir))
+ endif
+ call extend(files, get(a:dict, 'include.path', []))
+ return join(map(files, 'getftime(expand(v:val))'), ',')
+endfunction
+
+let s:config = {}
+function! fugitive#Config(...) abort
+ let dir = get(b:, 'git_dir', '')
+ let name = ''
+ if len(a:000) >= 2
+ let dir = a:000[1]
+ let name = a:000[0]
+ elseif len(a:000) == 1 && a:000[0] =~# '^[[:alnum:]-]\+\.'
+ let name = a:000[0]
+ elseif len(a:000) == 1
+ let dir = a:000[0]
+ endif
+ let key = len(dir) ? dir : '_'
+ if has_key(s:config, key) && s:config[key][0] ==# s:ConfigTimestamps(dir, s:config[key][1])
+ let dict = s:config[key][1]
+ else
+ let dict = {}
+ let lines = split(system(FugitivePrepare(['config', '--list', '-z'], dir)), "\1")
+ if v:shell_error
+ return {}
+ endif
+ for line in lines
+ let key = matchstr(line, "^[^\n]*")
+ if !has_key(dict, key)
+ let dict[key] = []
+ endif
+ call add(dict[key], strpart(line, len(key) + 1))
+ endfor
+ let s:config[dir] = [s:ConfigTimestamps(dir, dict), dict]
+ lockvar! dict
+ endif
+ return len(name) ? get(get(dict, name, []), 0, '') : dict
endfunction
function! s:Remote(dir) abort
diff --git a/plugin/fugitive.vim b/plugin/fugitive.vim
@@ -72,8 +72,14 @@ function! FugitivePrepare(...) abort
return call('fugitive#Prepare', a:000)
endfunction
-function! FugitiveConfig(key, ...) abort
- return fugitive#Config(a:key, FugitiveGitDir(a:0 ? a:1 : -1))
+function! FugitiveConfig(...) abort
+ if len(a:000) == 2
+ return fugitive#Config(a:000[1], FugitiveGitDir(a:000[2]))
+ elseif len(a:000) == 1 && a:000[0] !~# '^[[:alnum:]-]\+\.'
+ return fugitive#Config(FugitiveGitDir(a:000[0]))
+ else
+ return call('fugitive#Config', a:000)
+ endif
endfunction
function! FugitiveRemoteUrl(...) abort