1 Commits

Author SHA1 Message Date
Tim Pope
f61beed747 Add packed-ref handling 2015-12-01 04:04:55 -05:00
2 changed files with 136 additions and 151 deletions

View File

@@ -221,9 +221,10 @@ that are part of Git repositories).
*fugitive-:Gbrowse* *fugitive-:Gbrowse*
:Gbrowse Open the current file, blob, tree, commit, or tag :Gbrowse Open the current file, blob, tree, commit, or tag
in your browser at the upstream hosting provider. in your browser at the upstream hosting provider
If a range is given, it is appropriately appended to indicated by the "origin" remote. If a range is
the URL as an anchor. given, it is appropriately appended to the URL as an
anchor.
Upstream providers can be added by installing an Upstream providers can be added by installing an
appropriate Vim plugin. For example, GitHub can be appropriate Vim plugin. For example, GitHub can be
@@ -232,11 +233,8 @@ that are part of Git repositories).
support for GitHub is currently included, but that is support for GitHub is currently included, but that is
slated to be removed.) slated to be removed.)
The hosting provider is determined by looking at the If no upstream support is available, a local instance
remote for the current or specified branch and falls of git-instaweb will be started and used instead.
back to "origin". In the special case of a "."
remote, a local instance of git-instaweb will be
started and used.
:Gbrowse {revision} Like :Gbrowse, but for a given |fugitive-revision|. A :Gbrowse {revision} Like :Gbrowse, but for a given |fugitive-revision|. A
useful value here is -, which ties the URL to the useful value here is -, which ties the URL to the

View File

@@ -123,9 +123,7 @@ let s:abstract_prototype = {}
function! fugitive#is_git_dir(path) abort function! fugitive#is_git_dir(path) abort
let path = s:sub(a:path, '[\/]$', '') . '/' let path = s:sub(a:path, '[\/]$', '') . '/'
return getfsize(path.'HEAD') > 10 && ( return isdirectory(path.'objects') && isdirectory(path.'refs') && getfsize(path.'HEAD') > 10
\ isdirectory(path.'objects') && isdirectory(path.'refs') ||
\ getftype(path.'commondir') ==# 'file')
endfunction endfunction
function! fugitive#extract_git_dir(path) abort function! fugitive#extract_git_dir(path) abort
@@ -267,14 +265,9 @@ function! s:configured_tree(git_dir) abort
let config = readfile(config_file,'',10) let config = readfile(config_file,'',10)
call filter(config,'v:val =~# "^\\s*worktree *="') call filter(config,'v:val =~# "^\\s*worktree *="')
if len(config) == 1 if len(config) == 1
let worktree = matchstr(config[0], '= *\zs.*') let s:worktree_for_dir[a:git_dir] = matchstr(config[0], '= *\zs.*')
let s:dir_for_worktree[s:worktree_for_dir[a:git_dir]] = a:git_dir
endif endif
elseif filereadable(a:git_dir . '/gitdir')
let worktree = fnamemodify(readfile(a:git_dir . '/gitdir')[0], ':h')
endif
if exists('worktree')
let s:worktree_for_dir[a:git_dir] = worktree
let s:dir_for_worktree[s:worktree_for_dir[a:git_dir]] = a:git_dir
endif endif
endif endif
if s:worktree_for_dir[a:git_dir] =~# '^\.' if s:worktree_for_dir[a:git_dir] =~# '^\.'
@@ -305,55 +298,86 @@ function! s:repo_bare() dict abort
endif endif
endfunction endfunction
function! s:repo_translate(spec) dict abort function! s:repo_disambiguate(spec) dict abort
let refs = self.dir('refs/') if a:spec =~# '^:[0-3]:\|^:\=/\|^:\=$\|^\x\{40\}$'
if filereadable(self.dir('commondir')) return a:spec
let refs = simplify(self.dir(get(readfile(self.dir('commondir'), 1), 0, ''))) . '/refs/' elseif a:spec =~# '^:'
return ':0' . a:spec
elseif a:spec ==# '^\.'
return '/' . a:spec
elseif a:spec =~# '^[^:~^]*\.\.'
let before = self.qualify_ref(matchstr(a:spec, '.\{-\}\ze\.\.'))
let after = self.qualify_ref(matchstr(a:spec, '\.\.\.\=\zs.*'))
if before =~# '^/' || after =~# '^/'
return '/' . a:spec
else
return before . matchstr(a:spec, '\.\.\.\=') . after
endif
endif endif
if a:spec ==# '.' || a:spec ==# '/.' let head = s:sub(a:spec, '[:~^].*|\@\{.*', '')
return self.bare() ? self.dir() : self.tree() let rest = strpart(a:spec, len(head))
elseif a:spec =~# '^/\=\.git$' && self.bare() if head ==# '@'
return 'HEAD'.rest
endif
if head =~# "[[?*\001-\037\177]".'\|\%([./]\|\.lock\)\%(/\|$\)'
return '/' . a:spec
endif
let packed = {}
if filereadable(self.dir('packed-refs'))
for [v, k] in map(readfile(self.dir('packed-refs')), 'split(v:val, " ")')
let packed[k] = v
endfor
endif
for pattern in ['%s', 'refs/%s', 'refs/tags/%s', 'refs/heads/%s', 'refs/remotes/%s', 'refs/remotes/%s/HEAD']
let ref = printf(pattern, head)
if filereadable(self.dir(ref)) || has_key(packed, ref)
return ref . rest
endif
endfor
let tag = matchstr(head, '.*\ze-\d\+-g\x\+$')
if !empty(tag) && (filereadable(self.dir('refs/tags/'.tag)) || has_key(packed, ref))
return head . rest
endif
if head =~# '^\x\{4,40\}$'
try
return self.rev_parse(head) . rest
catch /^fugitive:/
endtry
endif
return '/' . a:spec
endfunction
function! s:repo_translate(spec) dict abort
let spec = self.disambiguate(a:spec)
if spec =~# '^/\=\.git$' && self.bare()
return self.dir() return self.dir()
elseif a:spec =~# '^/\=\.git/' elseif spec =~# '^/\=\.git/'
return self.dir(s:sub(a:spec, '^/=\.git/', '')) return self.dir(s:sub(spec, '^/=\.git/', ''))
elseif a:spec =~# '^/' elseif spec =~# '^/'
return self.tree().a:spec return self.tree().spec
elseif a:spec =~# '^:[0-3]:' elseif spec =~# '^:[0-3]:'
return 'fugitive://'.self.dir().'//'.a:spec[1].'/'.a:spec[3:-1] return 'fugitive://'.self.dir().'//'.spec[1].'/'.spec[3:-1]
elseif a:spec ==# ':' elseif spec ==# ':'
if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(self.dir())] ==# self.dir('') && filereadable($GIT_INDEX_FILE) if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(self.dir())] ==# self.dir('') && filereadable($GIT_INDEX_FILE)
return fnamemodify($GIT_INDEX_FILE,':p') return fnamemodify($GIT_INDEX_FILE,':p')
else else
return self.dir('index') return self.dir('index')
endif endif
elseif a:spec =~# '^:/' elseif spec =~# '^:/'
let ref = self.rev_parse(matchstr(a:spec,'.[^:]*')) let ref = self.rev_parse(matchstr(spec,'.[^:]*'))
return 'fugitive://'.self.dir().'//'.ref return 'fugitive://'.self.dir().'//'.ref
elseif a:spec =~# '^:'
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
elseif a:spec ==# '@'
return self.dir('HEAD')
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(refs . '../' . a:spec)
return simplify(refs . '../' . a:spec)
elseif filereadable(refs.a:spec)
return refs.a:spec
elseif filereadable(refs.'tags/'.a:spec)
return refs.'tags/'.a:spec
elseif filereadable(refs.'heads/'.a:spec)
return refs.'heads/'.a:spec
elseif filereadable(refs.'remotes/'.a:spec)
return refs.'remotes/'.a:spec
elseif filereadable(refs.'remotes/'.a:spec.'/HEAD')
return refs.'remotes/'.a:spec,'/HEAD'
else
try
let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
let path = s:sub(matchstr(a:spec,':.*'),'^:','/')
return 'fugitive://'.self.dir().'//'.ref.path
catch /^fugitive:/
return self.tree(a:spec)
endtry
endif endif
let ref = matchstr(spec,'[^:]*')
let path = s:sub(matchstr(spec,':.*'),'^:','/')
if empty(path) && ref !~# '[~^]'
if filereadable(self.dir(ref))
return self.dir(ref)
else
return self.dir('packed-refs')
endif
endif
return 'fugitive://'.self.dir().'//'.self.rev_parse(ref).path
endfunction endfunction
function! s:repo_head(...) dict abort function! s:repo_head(...) dict abort
@@ -372,7 +396,7 @@ function! s:repo_head(...) dict abort
return branch return branch
endfunction endfunction
call s:add_methods('repo',['dir','tree','bare','translate','head']) call s:add_methods('repo',['dir','tree','bare','disambiguate','translate','head'])
function! s:repo_git_command(...) dict abort function! s:repo_git_command(...) dict abort
let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir) let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
@@ -1271,7 +1295,7 @@ function! s:Grep(cmd,bang,arg) abort
try try
execute cd.'`=s:repo().tree()`' execute cd.'`=s:repo().tree()`'
let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n', '--no-color') let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n', '--no-color')
let &grepformat = '%f:%l:%m,%m %f match%ts,%f' let &grepformat = '%f:%l:%m,%f'
exe a:cmd.'! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|') exe a:cmd.'! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
let list = a:cmd =~# '^l' ? getloclist(0) : getqflist() let list = a:cmd =~# '^l' ? getloclist(0) : getqflist()
for entry in list for entry in list
@@ -1419,9 +1443,6 @@ function! s:Edit(cmd,bang,...) abort
catch /^fugitive:/ catch /^fugitive:/
return 'echoerr v:errmsg' return 'echoerr v:errmsg'
endtry endtry
if file !~# '^fugitive:'
let file = s:sub(file, '/$', '')
endif
if a:cmd ==# 'read' if a:cmd ==# 'read'
return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.') return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
else else
@@ -2187,18 +2208,11 @@ endfunction
" Section: Gbrowse " Section: Gbrowse
call s:command("-bar -bang -range=0 -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)") call s:command("-bar -bang -range -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
function! s:Browse(bang,line1,count,...) abort function! s:Browse(bang,line1,count,...) abort
try try
let validremote = '\.\|\.\=/.*\|[[:alnum:]_-]\+\%(://.\{-\}\)\=' let rev = a:0 ? substitute(join(a:000, ' '),'@[[:alnum:]_-]*\%(://.\{-\}\)\=$','','') : ''
if a:0
let remote = matchstr(join(a:000, ' '),'@\zs\%('.validremote.'\)$')
let rev = substitute(join(a:000, ' '),'@\%('.validremote.'\)$','','')
else
let remote = ''
let rev = ''
endif
if rev ==# '' if rev ==# ''
let expanded = s:buffer().rev() let expanded = s:buffer().rev()
elseif rev ==# ':' elseif rev ==# ':'
@@ -2209,11 +2223,10 @@ function! s:Browse(bang,line1,count,...) abort
let full = s:repo().translate(expanded) let full = s:repo().translate(expanded)
let commit = '' let commit = ''
if full =~# '^fugitive://' if full =~# '^fugitive://'
let commit = matchstr(full,'://.*//\zs\w\w\+') let commit = matchstr(full,'://.*//\zs\w\+')
let path = matchstr(full,'://.*//\w\+\zs/.*') let path = matchstr(full,'://.*//\w\+\zs/.*')
if commit =~ '..' if commit =~ '..'
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':')) let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
let branch = matchstr(expanded, '^[^:]*')
else else
let type = 'blob' let type = 'blob'
endif endif
@@ -2231,9 +2244,6 @@ function! s:Browse(bang,line1,count,...) abort
let type = 'blob' let type = 'blob'
endif endif
endif endif
if type ==# 'tree' && !empty(path)
let path = s:sub(path, '/\=$', '/')
endif
if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1])) if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
let body = readfile(s:repo().dir(path[5:-1]))[0] let body = readfile(s:repo().dir(path[5:-1]))[0]
if body =~# '^\x\{40\}$' if body =~# '^\x\{40\}$'
@@ -2245,54 +2255,35 @@ function! s:Browse(bang,line1,count,...) abort
endif endif
endif endif
let merge = '' if a:0 && join(a:000, ' ') =~# '@[[:alnum:]_-]*\%(://.\{-\}\)\=$'
if path =~# '^\.git/refs/remotes/.' let remote = matchstr(join(a:000, ' '),'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$')
if empty(remote) elseif path =~# '^\.git/refs/remotes/.'
let remote = matchstr(path, '^\.git/refs/remotes/\zs[^/]\+') let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+')
endif
let merge = matchstr(path, '^\.git/refs/remotes/[^/]\+/\zs.\+')
let branch = ''
let path = '.git/refs/heads/'.merge
elseif path =~# '^\.git/refs/heads/.'
let branch = path[16:-1]
elseif !exists('branch')
let branch = s:repo().head()
endif
if !empty(branch)
let r = s:repo().git_chomp('config','branch.'.branch.'.remote')
let m = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1]
if r ==# '.' && !empty(m)
let r2 = s:repo().git_chomp('config','branch.'.m.'.remote')
if r2 !~# '^\.\=$'
let r = r2
let m = s:repo().git_chomp('config','branch.'.m.'.merge')[11:-1]
endif
endif
if empty(remote)
let remote = r
endif
if r ==# '.' || r ==# remote
let merge = m
if path =~# '^\.git/refs/heads/.'
let path = '.git/refs/heads/'.merge
endif
endif
endif
if empty(commit) && path !~# '^\.git/'
if a:line1 && !a:count && !empty(merge)
let commit = merge
else
let commit = s:repo().rev_parse('HEAD')
endif
endif
if empty(remote)
let remote = '.'
let raw = s:repo().git_chomp('config','remote.origin.url')
else else
let raw = s:repo().git_chomp('config','remote.'.remote.'.url') let remote = 'origin'
let branch = matchstr(rev,'^[[:alnum:]/._-]\+\ze[:^~@]')
if branch ==# '' && path =~# '^\.git/refs/\w\+/'
let branch = s:sub(path,'^\.git/refs/\w+/','')
endif
if filereadable(s:repo().dir('refs/remotes/'.branch))
let remote = matchstr(branch,'[^/]\+')
let rev = rev[strlen(remote)+1:-1]
else
if branch ==# ''
let branch = matchstr(s:repo().head_ref(),'\<refs/heads/\zs.*')
endif
if branch != ''
let remote = s:repo().git_chomp('config','branch.'.branch.'.remote')
if remote =~# '^\.\=$'
let remote = 'origin'
elseif rev[0:strlen(branch)-1] ==# branch && rev[strlen(branch)] =~# '[:^~@]'
let rev = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1] . rev[strlen(branch):-1]
endif
endif
endif
endif endif
let raw = s:repo().git_chomp('config','remote.'.remote.'.url')
if raw ==# '' if raw ==# ''
let raw = remote let raw = remote
endif endif
@@ -2301,7 +2292,7 @@ function! s:Browse(bang,line1,count,...) abort
let url = call(Handler, [{ let url = call(Handler, [{
\ 'repo': s:repo(), \ 'repo': s:repo(),
\ 'remote': raw, \ 'remote': raw,
\ 'revision': 'No longer provided', \ 'revision': rev,
\ 'commit': commit, \ 'commit': commit,
\ 'path': path, \ 'path': path,
\ 'type': type, \ 'type': type,
@@ -2312,13 +2303,10 @@ function! s:Browse(bang,line1,count,...) abort
endif endif
endfor endfor
if empty(url) && raw ==# '.' if empty(url)
call s:throw("Instaweb failed to start") call s:throw("Instaweb failed to start and '".remote."' is not a supported remote")
elseif empty(url)
call s:throw('"'.remote."' is not a supported remote")
endif endif
let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
if a:bang if a:bang
if has('clipboard') if has('clipboard')
let @* = url let @* = url
@@ -2354,7 +2342,7 @@ function! s:github_url(opts, ...) abort
if repo ==# '' if repo ==# ''
return '' return ''
endif endif
let path = substitute(a:opts.path, '^/', '', '') let path = a:opts.path
if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0 if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0
let root = 'http://' . s:sub(repo,':','/') let root = 'http://' . s:sub(repo,':','/')
else else
@@ -2368,22 +2356,28 @@ function! s:github_url(opts, ...) abort
return root . '/commits/' . branch return root . '/commits/' . branch
endif endif
elseif path =~# '^\.git/refs/tags/' elseif path =~# '^\.git/refs/tags/'
return root . '/releases/tag/' . path[15:-1] return root . '/releases/tag/' . matchstr(path,'[^/]\+$')
elseif path =~# '^\.git/refs/remotes/[^/]\+/.' elseif path =~# '^\.git/refs/.'
return root . '/commits/' . matchstr(path,'remotes/[^/]\+/\zs.*') return root . '/commits/' . matchstr(path,'[^/]\+$')
elseif path =~# '.git/\%(config$\|hooks\>\)' elseif path =~# '.git/\%(config$\|hooks\>\)'
return root . '/admin' return root . '/admin'
elseif path =~# '^\.git\>' elseif path =~# '^\.git\>'
return root return root
endif endif
if a:opts.commit =~# '^\d\=$' if a:opts.revision =~# '^[[:alnum:]._-]\+:'
let commit = a:opts.repo.rev_parse('HEAD') let commit = matchstr(a:opts.revision,'^[^:]*')
elseif a:opts.commit =~# '^\d\=$'
let local = matchstr(a:opts.repo.head_ref(),'\<refs/heads/\zs.*')
let commit = a:opts.repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
if commit ==# ''
let commit = local
endif
else else
let commit = a:opts.commit let commit = a:opts.commit
endif endif
if get(a:opts, 'type', '') ==# 'tree' || a:opts.path =~# '/$' if a:opts.type == 'tree'
let url = substitute(root . '/tree/' . commit . '/' . path, '/$', '', 'g') let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
elseif get(a:opts, 'type', '') ==# 'blob' || a:opts.path =~# '[^/]$' elseif a:opts.type == 'blob'
let url = root . '/blob/' . commit . '/' . path let url = root . '/blob/' . commit . '/' . path
if get(a:opts, 'line2') && a:opts.line1 == a:opts.line2 if get(a:opts, 'line2') && a:opts.line1 == a:opts.line2
let url .= '#L' . a:opts.line1 let url .= '#L' . a:opts.line1
@@ -2397,9 +2391,6 @@ function! s:github_url(opts, ...) abort
endfunction endfunction
function! s:instaweb_url(opts) abort function! s:instaweb_url(opts) abort
if a:opts.remote !=# '.'
return ''
endif
let output = a:opts.repo.git_chomp('instaweb','-b','unknown') let output = a:opts.repo.git_chomp('instaweb','-b','unknown')
if output =~# 'http://' if output =~# 'http://'
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:opts.repo.dir(),':t') let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:opts.repo.dir(),':t')
@@ -2418,8 +2409,10 @@ function! s:instaweb_url(opts) abort
endif endif
let url .= ';h=' . a:opts.repo.rev_parse(a:opts.commit . (a:opts.path == '' ? '' : ':' . a:opts.path)) let url .= ';h=' . a:opts.repo.rev_parse(a:opts.commit . (a:opts.path == '' ? '' : ':' . a:opts.path))
else else
if a:opts.type ==# 'blob' && empty(a:opts.commit) if a:opts.type ==# 'blob'
let url .= ';h='.a:opts.repo.git_chomp('hash-object', '-w', a:opts.path) let tmp = tempname()
silent execute 'write !'.a:opts.repo.git_command('hash-object','-w','--stdin').' > '.tmp
let url .= ';h=' . readfile(tmp)[0]
else else
try try
let url .= ';h=' . a:opts.repo.rev_parse((a:opts.commit == '' ? 'HEAD' : ':' . a:opts.commit) . ':' . a:opts.path) let url .= ';h=' . a:opts.repo.rev_parse((a:opts.commit == '' ? 'HEAD' : ':' . a:opts.commit) . ':' . a:opts.path)
@@ -2558,8 +2551,6 @@ function! s:BufReadIndex() abort
nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff('Gvdiff')<CR> nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff('Gvdiff')<CR>
nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR> nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR> xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
nnoremap <buffer> <silent> P :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
xnoremap <buffer> <silent> P :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
nnoremap <buffer> <silent> q :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR> nnoremap <buffer> <silent> q :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR>
nnoremap <buffer> <silent> r :<C-U>edit<CR> nnoremap <buffer> <silent> r :<C-U>edit<CR>
nnoremap <buffer> <silent> R :<C-U>edit<CR> nnoremap <buffer> <silent> R :<C-U>edit<CR>
@@ -2901,7 +2892,7 @@ function! s:cfile() abort
elseif getline('.') =~# '^[+-]' && search('^@@ -\d\+,\d\+ +\d\+,','bnW') elseif getline('.') =~# '^[+-]' && search('^@@ -\d\+,\d\+ +\d\+,','bnW')
let type = getline('.')[0] let type = getline('.')[0]
let lnum = line('.') - 1 let lnum = line('.') - 1
let offset = 0 let offset = -1
while getline(lnum) !~# '^@@ -\d\+,\d\+ +\d\+,' while getline(lnum) !~# '^@@ -\d\+,\d\+ +\d\+,'
if getline(lnum) =~# '^[ '.type.']' if getline(lnum) =~# '^[ '.type.']'
let offset += 1 let offset += 1
@@ -2993,11 +2984,7 @@ function! fugitive#cfile() abort
let pre = '' let pre = ''
let results = s:cfile() let results = s:cfile()
if empty(results) if empty(results)
let cfile = expand('<cfile>') return expand('<cfile>')
if &includeexpr =~# '\<v:fname\>'
sandbox let cfile = eval(substitute(&includeexpr, '\C\<v:fname\>', '\=string(cfile)', 'g'))
endif
return cfile
elseif len(results) > 1 elseif len(results) > 1
let pre = '+' . join(map(results[1:-1], 'escape(v:val, " ")'), '\|') . ' ' let pre = '+' . join(map(results[1:-1], 'escape(v:val, " ")'), '\|') . ' '
endif endif