Git仓库不同分支能否用不同传输协议?分支连接异常排查
服务器封禁了22端口的出站SSH连接,执行以下命令关联GitHub私有仓库:
git init . git remote add git@github.com:<github_username>/repo_name.git
出现异常:切换到main分支时,因SSH走22端口无法连通GitHub;但切换到2nd分支时通信正常,连接的是ssh.github.com:443,且从未给分支单独设置过HTTPS连接。
执行git config --list输出如下:
push.default=simple core.autocrlf=false grep.linenumber=true core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true core.sshcommand=ssh -vvv remote.origin.url=git@github.com:<github_username>/repo_name.git remote.origin.fetch=+refs/heads/*:refs/remotes/origin/* branch.main.remote=origin branch.main.merge=refs/heads/main branch.2nd.remote=origin branch.2nd.merge=refs/heads/2nd
2nd分支调试信息
debug2: resolving "ssh.github.com" port 443 debug2: ssh_connect_direct: needpriv 0 debug1: Connecting to ssh.github.com [20.248.137.50] port 443. debug1: Connection established.
main分支调试信息
debug2: resolving "github.com" port 22 debug2: ssh_connect_direct: needpriv 0 debug1: Connecting to github.com [20.248.137.48] port 22. # Hangs here (firewall) but why the different address / protocol?
补充调试结果:2nd分支执行ssh -vv git@github.com会读取/root/.ssh/config,连接ssh.github.com:443;main分支仅读取/etc/ssh/ssh_config,连接github.com:22。
原因分析
这不是Git分支本身设置了不同传输协议,问题出在SSH配置的读取上下文差异:
切换到2nd分支时,执行Git命令的用户上下文是root,SSH会读取
/root/.ssh/config,该配置里应该包含针对GitHub的跳转规则,示例如下:Host github.com Hostname ssh.github.com Port 443这条规则会让SSH自动将
git@github.com的请求转发到ssh.github.com:443,避开22端口的封禁。切换到main分支时,执行Git命令的用户上下文不是root(或Shell未加载root的环境变量),SSH默认读取系统级的
/etc/ssh/ssh_config,而该配置没有针对GitHub的特殊端口跳转规则,因此依然走默认的22端口连接github.com,最终被防火墙拦截。
Git本身不会为单个分支设置不同的远程连接方式,所有分支共享同一个remote.origin.url。差异的根源是执行Git命令时的用户上下文不同,导致SSH读取的配置文件不一致,进而出现不同的连接行为。
内容的提问来源于stack exchange,提问作者pd_au

