" Location: autoload/fugitive.vim " Maintainer: Tim Pope if exists('g:autoloaded_fugitive') finish endif let g:autoloaded_fugitive = 1 if !exists('g:fugitive_git_executable') let g:fugitive_git_executable = 'git' endif " Section: Utility function! s:function(name) abort return function(substitute(a:name,'^s:',matchstr(expand(''), '\d\+_'),'')) endfunction function! s:sub(str,pat,rep) abort return substitute(a:str,'\v\C'.a:pat,a:rep,'') endfunction function! s:gsub(str,pat,rep) abort return substitute(a:str,'\v\C'.a:pat,a:rep,'g') endfunction function! s:winshell() abort return &shell =~? 'cmd' || exists('+shellslash') && !&shellslash endfunction function! s:shellesc(arg) abort if a:arg =~ '^[A-Za-z0-9_/.-]\+$' return a:arg elseif s:winshell() return '"'.s:gsub(s:gsub(a:arg, '"', '""'), '\%', '"%"').'"' else return shellescape(a:arg) endif endfunction function! s:fnameescape(file) abort if exists('*fnameescape') return fnameescape(a:file) else return escape(a:file," \t\n*?[{`$\\%#'\"|!<") endif endfunction function! s:tempname() abort let temp = resolve(tempname()) if has('win32') let temp = fnamemodify(fnamemodify(temp, ':h'), ':p').fnamemodify(temp, ':t') endif return temp endfunction function! s:throw(string) abort let v:errmsg = 'fugitive: '.a:string throw v:errmsg endfunction function! s:warn(str) abort echohl WarningMsg echomsg a:str echohl None let v:warningmsg = a:str endfunction function! s:shellslash(path) abort if s:winshell() return tr(a:path, '\', '/') else return a:path endif endfunction function! s:PlatformSlash(path) abort if exists('+shellslash') && !&shellslash return tr(a:path, '/', '\') else return a:path endif endfunction let s:executables = {} function! s:executable(binary) abort if !has_key(s:executables, a:binary) let s:executables[a:binary] = executable(a:binary) endif return s:executables[a:binary] endfunction function! s:UserCommand() abort return get(g:, 'fugitive_git_command', g:fugitive_git_executable) endfunction function! s:System(cmd) abort try return system(a:cmd) catch /^Vim\%((\a\+)\)\=:E484:/ let opts = ['shell', 'shellcmdflag', 'shellredir', 'shellquote', 'shellxquote', 'shellxescape', 'shellslash'] call filter(opts, 'exists("+".v:val) && !empty(eval("&".v:val))') call map(opts, 'v:val."=".eval("&".v:val)') call s:throw('failed to run `' . a:cmd . '` with ' . join(opts, ' ')) endtry endfunction function! s:Prepare(dir, ...) abort let args = ['--git-dir=' . a:dir] + (a:000) return g:fugitive_git_executable . ' ' . join(map(args, 's:shellesc(v:val)')) endfunction let s:git_versions = {} function! fugitive#GitVersion(...) abort if !has_key(s:git_versions, g:fugitive_git_executable) let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\\ze\n") endif return s:git_versions[g:fugitive_git_executable] endfunction function! s:Tree(...) abort return FugitiveTreeForGitDir(a:0 ? a:1 : get(b:, 'git_dir', '')) endfunction function! s:TreeChomp(...) abort let args = copy(type(a:1) == type([]) ? a:1 : a:000) let dir = a:0 > 1 && type(a:1) == type([]) ? a:2 : b:git_dir let tree = s:Tree(dir) let pre = '' if empty(tree) let args = ['--git-dir=' . dir] . args elseif s:cpath(tree) !=# s:cpath(getcwd()) if fugitive#GitVersion() =~# '^[01]\.' let pre = 'cd ' . s:shellesc(tree) . (s:winshell() ? ' & ' : '; ') else let args = ['-C', tree] + args endif endif return s:sub(s:System(pre . g:fugitive_git_executable . ' ' . \ join(map(args, 's:shellesc(v:val)'))), '\n$', '') endfunction function! fugitive#RevParse(rev, ...) abort let hash = system(s:Prepare(a:0 ? a:1 : b:git_dir, 'rev-parse', '--verify', a:rev))[0:-2] if !v:shell_error && hash =~# '^\x\{40\}$' return hash endif call s:throw('rev-parse '.a:rev.': '.hash) endfunction function! fugitive#Config(name, ...) abort let cmd = s:Prepare(a:0 ? a:1 : get(b:, 'git_dir', ''), 'config', '--get', a:name) let out = matchstr(system(cmd), "[^\r\n]*") return v:shell_error ? '' : out endfunction function! s:Remote(dir) abort let head = FugitiveHead(0, a:dir) let remote = len(head) ? fugitive#Config('branch.' . head . '.remote') : '' let i = 10 while remote ==# '.' && i > 0 let head = matchstr(fugitive#Config('branch.' . head . '.merge'), 'refs/heads/\zs.*') let remote = len(head) ? fugitive#Config('branch.' . head . '.remote') : '' let i -= 1 endwhile return remote =~# '\.\=$' ? 'origin' : remote endfunction function! fugitive#RemoteUrl(...) abort let dir = a:0 > 1 ? a:2 : get(b:, 'git_dir', '') let remote = !a:0 || a:1 =~# '^\.\=$' ? s:Remote(dir) : a:1 if fugitive#GitVersion() =~# '^[01]\.\|^2\.[0-6]\.' return fugitive#Config('remote.' . remote . '.url') endif let cmd = s:Prepare(dir, 'remote', 'get-url', remote) let out = substitute(system(cmd), "\n$", '', '') return v:shell_error ? '' : out endfunction function! s:recall() abort let rev = s:sub(s:buffer().rev(), '^/', '') if rev ==# ':' return matchstr(getline('.'),'^.\=\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$\|^\d\{6} \x\{40\} \d\t\zs.*') elseif s:buffer().type('tree') let file = matchstr(getline('.'), '\t\zs.*') if empty(file) && line('.') > 2 let file = s:sub(getline('.'), '/$', '') endif if !empty(file) && rev !~# ':$' return rev . '/' . file else return rev . file endif endif return rev endfunction function! s:map(mode, lhs, rhs, ...) abort let flags = (a:0 ? a:1 : '') . (a:rhs =~# '' ? '' : '