" 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:Uniq(list) abort let i = 0 let seen = {} while i < len(a:list) let str = string(a:list[i]) if has_key(seen, str) call remove(a:list, i) else let seen[str] = 1 let i += 1 endif endwhile return a:list 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:Slash(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 function! s:cpath(path, ...) abort if exists('+fileignorecase') && &fileignorecase let path = s:PlatformSlash(tolower(a:path)) else let path = s:PlatformSlash(a:path) endif return a:0 ? path ==# s:cpath(a:1) : path 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 if type(a:dir) == type([]) let args = ['--git-dir=' . (a:0 ? a:1 : get(b:, 'git_dir', ''))] + a:dir else let args = ['--git-dir=' . a:dir] + (a:000) endif 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 let s:commondirs = {} function! fugitive#CommonDir(dir) abort if empty(a:dir) return '' endif if !has_key(s:commondirs, a:dir) if getfsize(a:dir . '/HEAD') < 10 let s:commondirs[a:dir] = '' elseif filereadable(a:dir . '/commondir') let dir = get(readfile(a:dir . '/commondir', 1), 0, '') if dir =~# '^/\|^\a:/' let s:commondirs[a:dir] = dir else let s:commondirs[a:dir] = simplify(a:dir . '/' . dir) endif else let s:commondirs[a:dir] = a:dir endif endif return s:commondirs[a:dir] 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#Prepare(cmd, ...) abort let dir = a:0 ? a:1 : get(b:, 'git_dir', '') let tree = s:Tree(dir) let args = type(a:cmd) == type([]) ? join(map(copy(a:cmd), 's:shellesc(v:val)')) : a:cmd let pre = '' if empty(tree) let args = s:shellesc('--git-dir=' . dir) . ' ' . args elseif fugitive#GitVersion() =~# '^[01]\.' let pre = 'cd ' . s:shellesc(tree) . (s:winshell() ? ' & ' : '; ') else let args = '-C ' . s:shellesc(tree) . ' ' . args endif return pre . g:fugitive_git_executable . ' ' . args endfunction function! fugitive#Head(...) abort let dir = a:0 > 1 ? a:2 : get(b:, 'git_dir', '') if empty(dir) || !filereadable(dir . '/HEAD') return '' endif let head = readfile(dir . '/HEAD')[0] if head =~# '^ref: ' return substitute(head, '\C^ref: \%(refs/\%(heads/\|remotes/\|tags/\)\=\)\=', '', '') elseif head =~# '^\x\{40\}$' let len = a:0 ? a:1 : 0 return len < 0 ? head : len ? head[0:len-1] : '' else return '' endif 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:map(mode, lhs, rhs, ...) abort let flags = (a:0 ? a:1 : '') . (a:rhs =~# '' ? '' : '