mirror of
https://github.com/tpope/vim-fugitive.git
synced 2025-11-08 11:33:47 -05:00
Add packed-ref handling
This commit is contained in:
@@ -298,49 +298,86 @@ function! s:repo_bare() dict abort
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:repo_disambiguate(spec) dict abort
|
||||||
|
if a:spec =~# '^:[0-3]:\|^:\=/\|^:\=$\|^\x\{40\}$'
|
||||||
|
return a:spec
|
||||||
|
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
|
||||||
|
let head = s:sub(a:spec, '[:~^].*|\@\{.*', '')
|
||||||
|
let rest = strpart(a:spec, len(head))
|
||||||
|
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
|
function! s:repo_translate(spec) dict abort
|
||||||
if a:spec ==# '.' || a:spec ==# '/.'
|
let spec = self.disambiguate(a:spec)
|
||||||
return self.bare() ? self.dir() : self.tree()
|
if spec =~# '^/\=\.git$' && self.bare()
|
||||||
elseif a: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 =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(self.dir(a:spec))
|
|
||||||
return self.dir(a:spec)
|
|
||||||
elseif filereadable(self.dir('refs/'.a:spec))
|
|
||||||
return self.dir('refs/'.a:spec)
|
|
||||||
elseif filereadable(self.dir('refs/tags/'.a:spec))
|
|
||||||
return self.dir('refs/tags/'.a:spec)
|
|
||||||
elseif filereadable(self.dir('refs/heads/'.a:spec))
|
|
||||||
return self.dir('refs/heads/'.a:spec)
|
|
||||||
elseif filereadable(self.dir('refs/remotes/'.a:spec))
|
|
||||||
return self.dir('refs/remotes/'.a:spec)
|
|
||||||
elseif filereadable(self.dir('refs/remotes/'.a:spec.'/HEAD'))
|
|
||||||
return self.dir('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
|
||||||
@@ -359,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)
|
||||||
|
|||||||
Reference in New Issue
Block a user