@@ -1272,39 +1272,82 @@ function! s:UrlParse(url) abort
12721272 return url
12731273endfunction
12741274
1275- function ! s: ResolveRemote (url) abort
1275+ function ! s: RemoteResolve (url, flags ) abort
12761276 let remote = s: UrlParse (a: url )
1277- if remote.scheme = ~# ' ^https\=$'
1277+ if remote.scheme = ~# ' ^https\=$' && index ( a: flags , ' :nohttp ' ) < 0
12781278 let headers = fugitive#RemoteHttpHeaders (remote.scheme . ' ://' . remote.authority . remote.path )
12791279 let loc = matchstr (get (headers, ' location' , ' ' ), ' ^https\=://.\{-\}\ze/info/refs?' )
12801280 if len (loc )
12811281 let remote = s: UrlParse (loc )
12821282 else
1283- let remote.http_headers = headers
1283+ let remote.headers = headers
12841284 endif
12851285 elseif remote.scheme == # ' ssh'
12861286 let remote.authority = fugitive#SshHostAlias (remote.authority)
12871287 endif
12881288 return remote
12891289endfunction
12901290
1291- function ! fugitive#ResolveRemote (url) abort
1292- let remote = s: ResolveRemote (a: url )
1293- if remote.scheme == # ' file' || remote.scheme == # ' '
1294- return remote.path
1295- elseif remote.path = ~# ' ^/'
1296- return remote.scheme . ' ://' . remote.authority . remote.path
1297- elseif remote.path = ~# ' ^\~'
1298- return remote.scheme . ' ://' . remote.authority . ' /' . remote.path
1299- elseif remote.scheme == # ' ssh' && remote.authority !~# ' :'
1300- return remote.authority . ' :' . remote.path
1291+ function ! s: ConfigLengthSort (i1, i2) abort
1292+ return len (a: i2 [0 ]) - len (a: i1 [0 ])
1293+ endfunction
1294+
1295+ function ! s: RemoteCallback (config, into, flags, cb ) abort
1296+ if a: into .remote_name = ~# ' ^\.\=$'
1297+ let a: into .remote_name = s: RemoteDefault (a: config )
1298+ endif
1299+ let url = a: into .remote_name
1300+
1301+ if url == # ' .git'
1302+ let url = s: GitDir (a: config )
1303+ elseif url !~# ' :\|^/\|^\a:[\/]\|^\.\.\=/'
1304+ let url = FugitiveConfigGet (' remote.' . url . ' .url' , a: config )
1305+ endif
1306+ let instead_of = []
1307+ for [k , vs ] in items (fugitive#ConfigGetRegexp (' ^url\.\zs.\{-\}\ze\.insteadof$' , a: config ))
1308+ for v in vs
1309+ call add (instead_of, [v , k ])
1310+ endfor
1311+ endfor
1312+ call sort (instead_of, ' s:ConfigLengthSort' )
1313+ for [orig, replacement] in instead_of
1314+ if strpart (url, 0 , len (orig)) == # orig
1315+ let url = replacement . strpart (url, len (orig))
1316+ break
1317+ endif
1318+ endfor
1319+ if index (a: flags , ' :noresolve' ) < 0
1320+ call extend (a: into , s: RemoteResolve (url, a: flags ))
1321+ else
1322+ call extend (a: into , s: UrlParse (url))
1323+ endif
1324+ let a: into .user = matchstr (a: into .authority, ' .\{-\}\ze@' , ' ' , ' ' )
1325+ let a: into .host = substitute (a: into .authority, ' .\{-\}@' , ' ' , ' ' )
1326+ let a: into .hostname = substitute (a: into .host, ' :\d\+$' , ' ' , ' ' )
1327+ let a: into .port = matchstr (a: into .host, ' :\zs\d\+$' , ' ' , ' ' )
1328+ if a: into .path = ~# ' ^/'
1329+ let a: into .url = a: into .scheme . ' ://' . a: into .authority . a: into .path
1330+ elseif a: into .path = ~# ' ^\~'
1331+ let a: into .url = a: into .scheme . ' ://' . a: into .authority . ' /' . a: into .path
1332+ elseif a: into .scheme == # ' ssh' && a: into .authority !~# ' :'
1333+ let a: into .url = a: into .authority . ' :' . a: into .path
13011334 else
1302- return a: url
1335+ let a: into .url = url
1336+ endif
1337+ if len (a: cb )
1338+ call call (a: cb [0 ], [a: into ] + a: cb [1 :-1 ])
13031339 endif
13041340endfunction
13051341
1306- function ! s: ConfigLengthSort (i1, i2) abort
1307- return len (a: i2 [0 ]) - len (a: i1 [0 ])
1342+ function ! s: Remote (dir , remote, flags, cb ) abort
1343+ let into = {' remote_name' : a: remote , ' git_dir' : s: GitDir (a: dir )}
1344+ let config = fugitive#Config (a: dir , function (' s:RemoteCallback' ), into, a: flags , a: cb )
1345+ if len (a: cb )
1346+ return config
1347+ else
1348+ call fugitive#Wait (config)
1349+ return into
1350+ endif
13081351endfunction
13091352
13101353function ! s: RemoteParseArgs (args ) abort
@@ -1344,34 +1387,22 @@ function! s:RemoteParseArgs(args) abort
13441387 return [dir_or_config, remote, flags, cb ]
13451388endfunction
13461389
1390+ function ! fugitive#Remote (... ) abort
1391+ let [dir_or_config, remote, flags, cb ] = s: RemoteParseArgs (a: 000 )
1392+ return s: Remote (dir_or_config, remote, flags, cb )
1393+ endfunction
1394+
1395+ function ! s: RemoteUrlCallback (remote, callback) abort
1396+ return call (a: callback [0 ], [a: remote .url] + a: callback [1 :-1 ])
1397+ endfunction
1398+
13471399function ! fugitive#RemoteUrl (... ) abort
1348- let [dir_or_config, url, flags, cb ] = s: RemoteParseArgs (a: 000 )
1349- let config = fugitive#Config (dir_or_config)
1350- if url = ~# ' ^\.\=$'
1351- let url = s: RemoteDefault (config)
1352- endif
1353- if url == # ' .git'
1354- let url = s: GitDir (config)
1355- elseif url !~# ' :\|^/\|^\.\.\=/'
1356- let url = FugitiveConfigGet (' remote.' . url . ' .url' , config)
1400+ let [dir_or_config, remote, flags, cb ] = s: RemoteParseArgs (a: 000 )
1401+ if len (cb )
1402+ let cb = [function (' s:RemoteUrlCallback' ), cb ]
13571403 endif
1358- let instead_of = []
1359- for [k , vs ] in items (fugitive#ConfigGetRegexp (' ^url\.\zs.\{-\}\ze\.insteadof$' , config))
1360- for v in vs
1361- call add (instead_of, [v , k ])
1362- endfor
1363- endfor
1364- call sort (instead_of, ' s:ConfigLengthSort' )
1365- for [orig, replacement] in instead_of
1366- if strpart (url, 0 , len (orig)) == # orig
1367- let url = replacement . strpart (url, len (orig))
1368- break
1369- endif
1370- endfor
1371- if index (flags, 1 ) < 0 && index (flags, get (v: , ' true' , 1 )) < 0 && index (flags, ' :noresolve' ) < 0
1372- let url = fugitive#ResolveRemote (url)
1373- endif
1374- return url
1404+ let remote = s: Remote (dir_or_config, remote, flags, cb )
1405+ return get (remote, ' url' , remote)
13751406endfunction
13761407
13771408" Section: Quickfix
0 commit comments