diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 20722af..ccf0702 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -330,7 +330,8 @@ function! s:repo_bare() dict abort endfunction function! s:repo_translate(spec, ...) dict abort - let rev = a:spec + let rev = substitute(a:spec, '//\+', '/', 'g') + let rev = substitute(rev, '[:/]\zs\.\%(/\|$\)', '', 'g') let dir = self.git_dir let tree = s:Tree(dir) if rev ==# '.' @@ -383,8 +384,8 @@ function! s:repo_translate(spec, ...) dict abort return a:0 && a:1 ? s:PlatformSlash(f) : f endfunction -function! s:Generate(rev) abort - return fugitive#repo().translate(a:rev, 1) +function! s:Generate(rev, ...) abort + return fugitive#repo(a:0 ? a:1 : b:git_dir).translate(a:rev, 1) endfunction function! s:repo_head(...) dict abort @@ -506,6 +507,43 @@ function! fugitive#Path(url, ...) abort return substitute(file, '^/', a:1, '') endfunction +function! s:RemoveDot(path, ...) abort + if a:path !~# '^\./' + return a:path + endif + let dir = a:0 ? a:1 : get(b:, 'git_dir', '') + let cdir = fugitive#CommonDir(dir) + if len(filter(['', '/tags', '/heads', '/remotes'], 'getftime(cdir . "/refs" . v:val . a:path[1:-1]) >= 0')) || + \ a:path =~# 'HEAD$' && filereadable(dir . a:path[1:-1]) || + \ a:path =~# '^\./refs/' && filereadable(cdir . a:path[1:-1]) + return a:path + endif + return a:path[2:-1] +endfunction + +function! s:Expand(rev, ...) abort + let dir = a:0 ? a:1 : get(b:, 'git_dir', '') + if a:rev =~# '^:[0-3]$' + let file = a:rev . fugitive#Path(@%, a:rev, dir) + elseif a:rev =~# '^-' + let file = 'HEAD^{}' . a:rev[1:-1] . fugitive#Path(@%, ':', dir) + elseif a:rev =~# '^@{' + let file = 'HEAD'.a:rev. fugitive#Path(@%, ':', dir) + elseif a:rev =~# '^[~^]' + let commit = substitute(s:DirCommitFile(@%), '^\d\=$', 'HEAD') + let file = commit . a:rev . fugitive#Path(@%, ':', dir) + else + let file = a:rev + endif + return s:sub(substitute(file, + \ '\([%#]\)$\|\\\([[:punct:]]\)','\=len(submatch(2)) ? submatch(2) : fugitive#Path(expand(submatch(1)), "./", dir)','g'), + \ '\.\@<=/$','') +endfunction + +function! s:ExecExpand(cmd, ...) abort + return substitute(a:cmd, '\\\@' - let file = s:Relative(':0:') + elseif empty(s:DirCommitFile(@%)[1]) && fugitive#Path(@%, './', a:dir) !~# '^\./\.git\>' + let file = fugitive#Path(@%, ':0:', a:dir) else - let file = s:Relative('./') + let file = fugitive#Path(@%, './', a:dir) endif - return [s:Expand(file), join(pre)] + return [s:Expand(file, a:dir), join(pre)] endfunction function! s:Edit(cmd, bang, mods, args, ...) abort + let dir = b:git_dir let mods = a:mods ==# '' ? '' : a:mods if &previewwindow && get(b:,'fugitive_type', '') ==# 'index' && a:cmd ==# 'edit' let winnrs = filter([winnr('#')] + range(1, winnr('$')), 's:UsableWin(v:val)') @@ -2121,9 +2137,9 @@ function! s:Edit(cmd, bang, mods, args, ...) abort return echo endif - let [file, pre] = s:EditParse(a:000) + let [file, pre] = s:EditParse(a:000, dir) try - let file = s:Generate(file) + let file = s:Generate(file, dir) catch /^fugitive:/ return 'echoerr v:errmsg' endtry @@ -2145,13 +2161,13 @@ function! s:Read(count, line1, line2, range, bang, mods, args, ...) abort let delete = '' endif if a:bang - let args = s:gsub(a:args, '\\@