Overhaul :Gbrowse remote handling

This commit is contained in:
Tim Pope 2015-12-26 19:53:07 -05:00
parent 9ce67cdc93
commit 18d6d1ab82
2 changed files with 68 additions and 37 deletions

View File

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

View File

@ -2176,11 +2176,18 @@ endfunction
" Section: Gbrowse
call s:command("-bar -bang -range -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
call s:command("-bar -bang -range=0 -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
function! s:Browse(bang,line1,count,...) abort
try
let rev = a:0 ? substitute(join(a:000, ' '),'@[[:alnum:]_-]\w\+\%(://.\{-\}\)\=$','','') : ''
let validremote = '\.\|\.\=/.*\|[[: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 ==# ''
let expanded = s:buffer().rev()
elseif rev ==# ':'
@ -2195,6 +2202,7 @@ function! s:Browse(bang,line1,count,...) abort
let path = matchstr(full,'://.*//\w\+\zs/.*')
if commit =~ '..'
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
let branch = matchstr(expanded, '^[^:]*')
else
let type = 'blob'
endif
@ -2215,9 +2223,6 @@ function! s:Browse(bang,line1,count,...) abort
if type ==# 'tree' && !empty(path)
let path = s:sub(path, '/\=$', '/')
endif
if empty(commit) && path !~# '^\.git/'
let commit = s:repo().rev_parse('HEAD')
endif
if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
let body = readfile(s:repo().dir(path[5:-1]))[0]
if body =~# '^\x\{40\}$'
@ -2229,35 +2234,54 @@ function! s:Browse(bang,line1,count,...) abort
endif
endif
if a:0 && join(a:000, ' ') =~# '@[[:alnum:]_-]\+\%(://.\{-\}\)\=$'
let remote = matchstr(join(a:000, ' '),'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$')
elseif path =~# '^\.git/refs/remotes/.'
let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+')
else
let remote = 'origin'
let branch = matchstr(rev,'^[[:alnum:]/._-]\+\ze[:^~@]')
if branch ==# '' && path =~# '^\.git/refs/\w\+/'
let branch = s:sub(path,'^\.git/refs/\w+/','')
let merge = ''
if path =~# '^\.git/refs/remotes/.'
if empty(remote)
let remote = matchstr(path, '^\.git/refs/remotes/\zs[^/]\+')
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.*')
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 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]
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
let raw = s:repo().git_chomp('config','remote.'.remote.'.url')
endif
if raw ==# ''
let raw = remote
endif
@ -2266,7 +2290,7 @@ function! s:Browse(bang,line1,count,...) abort
let url = call(Handler, [{
\ 'repo': s:repo(),
\ 'remote': raw,
\ 'revision': rev,
\ 'revision': 'No longer provided',
\ 'commit': commit,
\ 'path': path,
\ 'type': type,
@ -2277,8 +2301,10 @@ function! s:Browse(bang,line1,count,...) abort
endif
endfor
if empty(url)
call s:throw("Instaweb failed to start and '".remote."' is not a supported remote")
if empty(url) && raw ==# '.'
call s:throw("Instaweb failed to start")
elseif empty(url)
call s:throw('"'.remote."' is not a supported remote")
endif
let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
@ -2360,6 +2386,9 @@ function! s:github_url(opts, ...) abort
endfunction
function! s:instaweb_url(opts) abort
if a:opts.remote !=# '.'
return ''
endif
let output = a:opts.repo.git_chomp('instaweb','-b','unknown')
if output =~# 'http://'
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:opts.repo.dir(),':t')