From ddea2ecb0ff221f1f4cdba4d3b5ff121c3ff0338 Mon Sep 17 00:00:00 2001 From: Tim Pope Date: Sat, 20 Mar 2021 05:43:04 -0400 Subject: [PATCH] Expand ssh host aliases in remote urls A common practice for using multiple accounts with a hosting service such as GitHub is to alias the host in ~/.ssh/config and use an alternate ssh key to authenticate as the alternate user: Host github.com-work HostName github.com IdentityFile ~/.ssh/id_rsa_work By swapping in the original host name for the alias in FugitiveRemoteUrl(), we can enable :GBrowse plugins to correctly recognize the hosting service's domain name. If for some reason you need the original URL without modification, pass a true value as the third parameter: let url = FugitiveRemoteUrl('', bufnr(''), 1) References https://github.com/tpope/vim-rhubarb/issues/60 --- autoload/fugitive.vim | 39 +++++++++++++++++++++++++++++++++++++-- plugin/fugitive.vim | 2 +- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 221a601..533354b 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -609,13 +609,48 @@ function! s:Remote(dir) abort return remote =~# '^\.\=$' ? 'origin' : remote endfunction +unlet! s:ssh_aliases +function! fugitive#SshHostAlias(...) abort + if !exists('s:ssh_aliases') + let s:ssh_aliases = {} + if filereadable(expand('~/.ssh/config')) + let hosts = [] + for line in readfile(expand('~/.ssh/config')) + let key = matchstr(line, '^\s*\zs\w\+\ze\s') + let value = matchstr(line, '^\s*\w\+\s\+\zs.*\S') + if key ==? 'host' + let hosts = split(value, '\s\+') + elseif key ==? 'hostname' + for host in hosts + if !has_key(s:ssh_aliases, host) + let s:ssh_aliases[host] = tolower(value) + endif + endfor + endif + endfor + endif + endif + if a:0 + return get(s:ssh_aliases, a:1, a:1) + else + return s:ssh_aliases + endif +endfunction + function! fugitive#RemoteUrl(...) abort let dir = a:0 > 1 ? a:2 : s:Dir() let remote = !a:0 || a:1 =~# '^\.\=$' ? s:Remote(dir) : a:1 if !fugitive#GitVersion(2, 7) - return fugitive#Config('remote.' . remote . '.url') + let url = FugitiveConfigGet('remote.' . remote . '.url') + else + let url = s:ChompDefault('', [dir, 'remote', 'get-url', remote, '--']) endif - return s:ChompDefault('', [dir, 'remote', 'get-url', remote, '--']) + if !get(a:, 3, 0) + let url = substitute(url, + \ '^ssh://\%([^@:/]\+@\)\=\zs[^/:]\+\|^\%([^@:/]\+@\)\=\zs[^/:]\+\ze:/\@!', + \ '\=fugitive#SshHostAlias(submatch(0))', '') + endif + return url endfunction " Section: Quickfix diff --git a/plugin/fugitive.vim b/plugin/fugitive.vim index 5d1fa9f..83e5f44 100644 --- a/plugin/fugitive.vim +++ b/plugin/fugitive.vim @@ -122,7 +122,7 @@ function! FugitiveConfigGetAll(name, ...) abort endfunction function! FugitiveRemoteUrl(...) abort - return fugitive#RemoteUrl(a:0 ? a:1 : '', FugitiveGitDir(a:0 > 1 ? a:2 : -1)) + return fugitive#RemoteUrl(a:0 ? a:1 : '', FugitiveGitDir(a:0 > 1 ? a:2 : -1), a:0 > 2 ? a:3 : 0) endfunction function! FugitiveHead(...) abort