commit 6b546f37d04f4598fc2f7cd273f709158a78bc88 (tree)
parent dfd7be22948765ac56de1c559694d689d2e98ea3
Author: Tim Pope <code@tpope.net>
Date: Sun, 29 Aug 2021 16:30:14 -0400
Better HTTP redirect detection
These HTTP headers may have other :GBrowse applications, so if we're
parsing them, we may as well hang onto them.
Diffstat:
1 file changed, 45 insertions(+), 11 deletions(-)
diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim
@@ -918,6 +918,8 @@ function! fugitive#RevParse(rev, ...) abort
throw 'fugitive: failed to parse revision ' . a:rev
endfunction
+" Section: Git config
+
function! s:ConfigTimestamps(dir, dict) abort
let files = ['/etc/gitconfig', '~/.gitconfig',
\ len($XDG_CONFIG_HOME) ? $XDG_CONFIG_HOME . '/git/config' : '~/.config/git/config']
@@ -1168,7 +1170,39 @@ function! fugitive#SshHostAlias(authority) abort
return (len(user) ? user . '@' : '') . get(c, 'hostname', host) . (port =~# '^\%(22\)\=$' ? '' : ':' . port)
endfunction
-let s:redirects = {}
+function! s:CurlResponse(result) abort
+ let a:result.headers = {}
+ for line in a:result.exit_status ? [] : remove(a:result, 'stdout')
+ let header = matchlist(line, '^\([[:alnum:]-]\+\):\s\(.\{-\}\)'. "\r\\=$")
+ if len(header)
+ let k = tolower(header[1])
+ if has_key(a:result.headers, k)
+ let a:result.headers[k] .= ', ' . header[2]
+ else
+ let a:result.headers[k] = header[2]
+ endif
+ elseif empty(line)
+ break
+ endif
+ endfor
+endfunction
+
+let s:remote_headers = {}
+
+function! fugitive#RemoteHttpHeaders(remote) abort
+ if a:remote !~# '^https\=://.' || !s:executable('curl')
+ return {}
+ endif
+ if !has_key(s:remote_headers, a:remote)
+ let url = a:remote . '/info/refs?service=git-upload-pack'
+ let exec = s:JobExecute(
+ \ ['curl', '--disable', '--silent', '--max-time', '5', '-X', 'GET', '-I',
+ \ url], {}, [function('s:CurlResponse')], {})
+ call fugitive#Wait(exec)
+ let s:remote_headers[a:remote] = exec.headers
+ endif
+ return s:remote_headers[a:remote]
+endfunction
function! fugitive#ResolveRemote(remote) abort
let scp_authority = matchstr(a:remote, '^[^:/]\+\ze:\%(//\)\@!')
@@ -1182,15 +1216,11 @@ function! fugitive#ResolveRemote(remote) abort
elseif authority !~# ':'
return authority . ':' . path
endif
- elseif a:remote =~# '^https\=://' && s:executable('curl')
- if !has_key(s:redirects, a:remote)
- let s:redirects[a:remote] = matchstr(join(s:JobExecute(
- \ ['curl', '--disable', '--silent', '--max-time', '5', '-I',
- \ a:remote . '/info/refs?service=git-upload-pack'], {}, [], {}).stdout, "\n"),
- \ 'Location: \zs\S\+\ze/info/refs?')
- endif
- if len(s:redirects[a:remote])
- return s:redirects[a:remote]
+ elseif a:remote =~# '^https\=://'
+ let headers = fugitive#RemoteHttpHeaders(a:remote)
+ let loc = matchstr(get(headers, 'location', ''), '^https\=://.\{-\}\ze/info/refs?')
+ if len(loc)
+ return loc
endif
elseif a:remote =~# '^ssh://'
let authority = matchstr(a:remote, '[^/?#]*', 6)
@@ -7125,7 +7155,11 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
if empty(remote) || remote ==# '.'
let remote = s:Remote(dir)
endif
- let remote_url = fugitive#RemoteUrl(remote, dir)
+ if remote =~# ':'
+ let remote_url = remote
+ else
+ let remote_url = fugitive#RemoteUrl(remote, dir)
+ endif
let raw = empty(remote_url) ? remote : remote_url
let git_dir = s:GitDir(dir)