当前位置: 首页 > news >正文

能连上 GitHub(SSH 验证成功),却 push 失败?常见原因与逐步解决方案 - 详解

能连上 GitHub(SSH 验证成功),却 push 失败?常见原因与逐步解决方案 - 详解

能连上 GitHub(SSH 验证成功),却 push 失败?常见原因与逐步解决方案

在无法通过 HTTPS 或普通 Git 方式推送代码到远程仓库时,很多人会尝试改用 SSH 密钥的方式来连接与推送。本文先说明为什么网络策略或端口限制会导致无法 push、以及在什么场景下使用 SSH(尤其是将连接改为 ssh.github.com:443)可以绕过这些限制;随后分析为何有时即便 SSH 验证成功,git push 仍然失败,并给出可直接执行的解决方案与诊断命令,便于快速恢复推送能力。

一、为什么会出现“能连上但无法 push”的矛盾?

在继续分析具体原因之前,先简要说明“为什么有时改用 SSH 密钥可以绕过网络限制”:

  1. 网络端口与代理策略差异
    • 许多公司封锁外部 22 端口,允许 443(HTTPS)。通过把 ssh 目标指向 ssh.github.com:443 可以通过防火墙,但这需要 SSH 客户端实际使用该端口。
  2. SSH 验证成功只是说明公钥在 GitHub 上被接受,但 git push 失败可能是因为:
    • Git 在执行 push 时没有使用你测试时用的同一把私钥(例如你用 ssh -i 测试成功,但 git 调用的 ssh 没有读取该 key)。
    • Git 调用了不同的 ssh 可执行文件(系统自带的、Git for Windows 自带的或 Putty/plink),而这些客户端对 ~/.ssh/config 或端口声明的支持不同。
    • remote URL 使用了 ssh://...:443 这类带端口的写法时,有的 Git 的 ssh 变体(“simple”)不支持在 URL 中带端口,会报 “ssh variant ‘simple’ does not support setting port”。
    • ssh-agent 未加载或私钥权限不当,导致 push 时没有合适的私钥被提供给远端(即使单次 ssh -i 可用)。
  3. 本地路径/配置格式不兼容(Windows 路径在 Git Bash 下需用 POSIX 形式),导致 Git 调用 ssh 时失败或不读取 config

结论:ssh 验证成功说明“密钥对 + GitHub”是正确的;失败通常出在“git 调用 ssh 的方式”或“remote URL 与客户端组合”的不匹配上。


二、优先的检查与调试命令(先执行这些,便于定位)

在能访问命令行的机器上按顺序执行(把输出保存/粘贴用于进一步分析):

  • 验证 SSH 单次连接(指定私钥和端口)

    • Git Bash:
      ssh -i /c/Users/youruser/.ssh/id_ed25519_project -T -p 443 git@ssh.github.com
    • PowerShell:
      ssh -i C:\Users\youruser\.ssh\id_ed25519_project -T -p 443 git@ssh.github.com
  • 查看尝试密钥的详细信息(verbose)

    ssh -vvv -i /c/Users/youruser/.ssh/id_ed25519_project -T -p 443 git@ssh.github.com
  • 检查 Git 用哪个 ssh(可能为空)

    git config --get core.sshCommand
    git config --global --get core.sshCommand
    git var GIT_SSH
    where.exe ssh
  • 查看远程 URL 与当前 remote

    git remote -v
  • 在 push 时用 verbose 查看 ssh 行为(临时,不持久)

    # Git Bash 临时
    export GIT_SSH_COMMAND="ssh -vvv -F /c/Users/youruser/.ssh/config"
    git push origin master
    unset GIT_SSH_COMMAND
    # PowerShell 临时
    $env:GIT_SSH_COMMAND = "ssh -vvv -F C:\Users\youruser\.ssh\config"
    git push origin master
    Remove-Item Env:\GIT_SSH_COMMAND

三、逐条可执行方案(按便利性/长期性排序)

方案 1 — 推荐:在 ~/.ssh/config 映射 host(一次配置,透明生效)

  • C:\Users\<user>\.ssh\config 写:
    Host github.comHostName ssh.github.comPort 443User gitIdentityFile C:/Users/youruser/.ssh/id_ed25519_projectIdentitiesOnly yes
  • 优点:你可以继续使用 git@github.com:OWNER/REPO.git 形式的 remote,SSH 会透明走 443 并用指定 key,适合大量仓库。

方案 2 — 推荐备选:在当前会话临时指定 ssh(立刻生效,适合不想改配置时)

  • Git Bash:
    export GIT_SSH_COMMAND="/c/Windows/System32/OpenSSH/ssh.exe -F /c/Users/youruser/.ssh/config"
    git push origin master
    unset GIT_SSH_COMMAND
  • PowerShell:
    $env:GIT_SSH_COMMAND='C:\Windows\System32\OpenSSH\ssh.exe -F C:\Users\youruser\.ssh\config'
    git push origin master
    Remove-Item Env:\GIT_SSH_COMMAND
  • 优点:无需改全局设置或每个仓库,适合临时使用或测试。

方案 3 — 持久化:让 Git 永久使用指定 OpenSSH(写入 core.sshCommand)

  • 在 Git Bash(或 PowerShell)执行:
    git config --global core.sshCommand "/c/Windows/System32/OpenSSH/ssh.exe -F /c/Users/youruser/.ssh/config"
  • 优点:一次配置后所有仓库自动使用该 ssh 客户端,适合你最终希望长期生效的场景。

方案 4 — 把 remote 改成不带端口的 SSH(仅当前仓库)

  • 在仓库目录执行:
    git remote set-url origin git@github.com:OWNER/REPO.git
    git push origin master
  • 说明:如果方案 1 的 ~/.ssh/config 已正确设置,这种写法会通过 config 映射到 ssh.github.com:443。适合逐仓切换的做法。

方案 5 — 全局 URL 重写(大量仓库且 remote 多为 HTTPS)

  • https://github.com/... 自动走 ssh://git@ssh.github.com:443/...
    git config --global url."ssh://git@ssh.github.com:443/".insteadOf "https://github.com/"
  • 优点:不需改每个仓库的 remote,适合公司内大量已有 HTTPS remote 的情形。

方案 6 — 离线/替代推送(当所有外网被限制)

  • 使用 git bundle 在内网打包,然后在能上网的机器上 clone/bundle 并 push:
    # 内网机器
    git bundle create ../repo.bundle --all
    # 在能上网的机器上
    git clone repo.bundle repo-from-bundle
    cd repo-from-bundle
    git remote add origin https://github.com/OWNER/REPO.git
    git push origin --all
    git push origin --tags

四、常见错误与针对性修复

  • 错误 “ssh variant ‘simple’ does not support setting port”

    • 原因:remote 使用了 ssh://...:PORT 形式,但 Git 内置 ssh 变体不支持 URL 里显式端口。
    • 解决:去掉 URL 中的端口,改用 git@github.com:owner/repo.git 并依赖 ~/.ssh/config 做端口映射,或设置 core.sshCommand 强制使用系统 OpenSSH。
  • 报 “Permission denied (publickey).” 在 push 时,但 ssh -i ... 验证成功

    • 原因:git push 调用了不同的 ssh(或未加载该私钥),或者 ssh 在 push 时未读取你的 config
    • 解决:用 GIT_SSH_COMMAND 指定同一 ssh 可执行文件或在 ~/.ssh/config 中声明 IdentityFile;也可把私钥放到默认位置并用 ssh-agent 加载。
  • 在 Windows 下设置 core.sshCommand 出现 “command not found” 或路径问题

    • 原因:Git Bash 解释 Windows 路径不兼容(需要 POSIX 路径 /c/Windows/…)。
    • 解决:在 Git Bash 使用 /c/Windows/System32/OpenSSH/ssh.exe 形式;在 PowerShell 使用双反斜杠转义路径。

五、安全与运维建议


六、快速决策指南(选择一个最快恢复办法)

  • 想最快解决并不改任何仓库:在当前终端临时执行 GIT_SSH_COMMAND(方案 2)。
  • 想一次性对所有仓库透明生效:写 ~/.ssh/config 并把 remote 保持 git@github.com:...(方案 1)。
  • 仓库多且为 HTTPS:使用全局 insteadOf 自动重写(方案 5)。
  • 完全无外网访问:使用 git bundle 离线转发(方案 6)。
http://www.sczhlp.com/news/187743/

相关文章:

  • 如何在UE中创建动态枚举
  • 杭州品牌网站开发图片编辑在线使用
  • 网站页面打开速度慢wordpress sae 上传
  • 郑州高新区做网站的公司17网站一起做网店不发货
  • 张家港做网站收费标准医院网站建设的重要性
  • 网站优化建设扬州学做衣服的网站有哪些
  • 海西州建设局网站seo运营
  • 广西网站建设软件推广sydney wordpress
  • 汕头seo建站许昌seo推广
  • 营销型网站建设的概念建设网站 报告书
  • 开远市住房和城乡建设局网站app开发公司都有哪些部门
  • 免费看电视的网站有哪些餐馆餐饮装修设计
  • 集美区建设局网站哪个是网络营销导向网站建设的基础
  • 如何查网站的备案信息wordpress 很慢
  • 网站常见程序问题手机怎么登pc端智慧团建
  • 做任务挣钱的网站appwordpress高级自定义字段怎么显示
  • 百度手机网站建设wordpress采集附件
  • 查询建筑企业网站宜春做网站哪里好
  • 宿迁哪家做网站好加强二级部门网站建设
  • 莒县做网站和微信seo 推广
  • 手机可怎么样做网站网站建设服务标准化
  • 做剧情网站侵权吗济宁做网站的电话
  • 鲜花店网站建设的总结网站任务界面
  • 枣庄手机网站开发公司网站建设技术知乎
  • 珠海建设网站公司简介小程序制作
  • 深入解析:Telerik UI for ASP.NET MVC 2025 Q3
  • UE网络编程完全指南:UDP TCP WebSocket实现详解
  • 一键解决MetaHuman播放动画时头部穿模问题
  • 忽然很好奇为什么素未谋面的大家都知道我是学姐?
  • 中国建设基础设施公司网站有口碑的赣州网站建设