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* *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.
indicated by the "origin" remote. If a range is If a range is given, it is appropriately appended to
given, it is appropriately appended to the URL as an the URL as an anchor.
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
@ -233,8 +232,11 @@ 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.)
If no upstream support is available, a local instance The hosting provider is determined by looking at the
of git-instaweb will be started and used instead. 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 :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

@ -2176,11 +2176,18 @@ endfunction
" Section: Gbrowse " 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 function! s:Browse(bang,line1,count,...) abort
try 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 ==# '' if rev ==# ''
let expanded = s:buffer().rev() let expanded = s:buffer().rev()
elseif rev ==# ':' elseif rev ==# ':'
@ -2195,6 +2202,7 @@ function! s:Browse(bang,line1,count,...) abort
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
@ -2215,9 +2223,6 @@ function! s:Browse(bang,line1,count,...) abort
if type ==# 'tree' && !empty(path) if type ==# 'tree' && !empty(path)
let path = s:sub(path, '/\=$', '/') let path = s:sub(path, '/\=$', '/')
endif 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])) 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\}$'
@ -2229,35 +2234,54 @@ function! s:Browse(bang,line1,count,...) abort
endif endif
endif endif
if a:0 && join(a:000, ' ') =~# '@[[:alnum:]_-]\+\%(://.\{-\}\)\=$' let merge = ''
let remote = matchstr(join(a:000, ' '),'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$') if path =~# '^\.git/refs/remotes/.'
elseif path =~# '^\.git/refs/remotes/.' if empty(remote)
let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+') 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+/','')
endif endif
if filereadable(s:repo().dir('refs/remotes/'.branch)) let merge = matchstr(path, '^\.git/refs/remotes/[^/]\+/\zs.\+')
let remote = matchstr(branch,'[^/]\+') let branch = ''
let rev = rev[strlen(remote)+1:-1] let path = '.git/refs/heads/'.merge
else elseif path =~# '^\.git/refs/heads/.'
if branch ==# '' let branch = path[16:-1]
let branch = matchstr(s:repo().head_ref(),'\<refs/heads/\zs.*') 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 branch != '' endif
let remote = s:repo().git_chomp('config','branch.'.branch.'.remote') if empty(remote)
if remote =~# '^\.\=$' let remote = r
let remote = 'origin' endif
elseif rev[0:strlen(branch)-1] ==# branch && rev[strlen(branch)] =~# '[:^~@]' if r ==# '.' || r ==# remote
let rev = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1] . rev[strlen(branch):-1] let merge = m
endif if path =~# '^\.git/refs/heads/.'
let path = '.git/refs/heads/'.merge
endif endif
endif endif
endif endif
let raw = s:repo().git_chomp('config','remote.'.remote.'.url') 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 ==# '' if raw ==# ''
let raw = remote let raw = remote
endif endif
@ -2266,7 +2290,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': rev, \ 'revision': 'No longer provided',
\ 'commit': commit, \ 'commit': commit,
\ 'path': path, \ 'path': path,
\ 'type': type, \ 'type': type,
@ -2277,8 +2301,10 @@ function! s:Browse(bang,line1,count,...) abort
endif endif
endfor endfor
if empty(url) if empty(url) && raw ==# '.'
call s:throw("Instaweb failed to start and '".remote."' is not a supported remote") call s:throw("Instaweb failed to start")
elseif empty(url)
call s:throw('"'.remote."' is not a supported remote")
endif endif
let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))') let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
@ -2360,6 +2386,9 @@ 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')