Git URI 与 SSH URI 规范不匹配

Posted

技术标签:

【中文标题】Git URI 与 SSH URI 规范不匹配【英文标题】:Git URIs does not match SSH URI specification 【发布时间】:2022-01-14 14:09:42 【问题描述】:

我正在研究SSH URI specification,以便更多地了解用于通过 SSH 访问 Github 或 Bitbucket 等服务中的存储库的 URL。

一个典型的 SSH Github URL 是这样的:git@github.com:myuser/myrepo.git,我认为可以分解成以下几个部分:

   scheme           authority
     |                 |
    /‾‾\/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\
    ssh://git@github.com:myuser/myrepo.git
          \_/ \________/ \_______________/
           |      |              |
          user   host           port

我不明白的是端口部分。 official general URI specification 声明端口应该只包含数值。 SSH URI scheme specification 坚持通用 URI 规范。 OpenSSH config manual 也是如此。

为什么他们在端口部分使用类似路径的文本?这是否偏离了事实上已确立的标准?还是我理解错了整件事?

如果有人能澄清这一点,我将不胜感激。

【问题讨论】:

正常的Git语法要么是ssh://git@github.com/user/repo.git(注意这里ssh:后面没有冒号),要么 git@github.com:user/repo.git(注意没有@987654330 @ 这里)。你不应该将两者结合起来。使用第二种形式时,您根本没有使用标准 URL/URI。 【参考方案1】:

TL:DR 问题中描述的语法继承自一个名为 rcp 的旧程序,不符合 URI 规范。

说明

感谢@jthill 和@torek 为我指明了正确的方向。这是我经过几天研究后的猜测。

OpenSSH 中的所有三个远程操作程序(sshscpsftp)都接受符合 SSH URI 方案的参数,在其自己的IETF specification 中进行了描述。

从广义上讲,任何 URI 都由五个组件组成:方案、权限、路径、查询和片段。此外,权限可以由用户信息、主机和端口组成。对于 SSH URI 方案,只允许使用方案、权限和路径。

   scheme     authority           path
     |           |                 |
    /‾‾\/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\
    ssh://git@github.com:22/myuser/myrepo.git
          \_/\_________/\_/
           |      |      |
          user   host   port

但是,还有一种替代语法与标准 SSH URI 方案非常相似,但并不完全符合它。这种语法是 1981 年创建的旧 rcp(远程复制)程序的遗产,比创建 URI 协议早了将近 15 年。当Berkeley r-commands 发布时,要在rsh(远程shell)或rlogin(远程登录)中指定操作的目的地,只需要指定要执行操作的远程机器,可能还有那台机器上的用户。当时的共识是语法username@hostname。然而,rcp 程序还有一个附加条件,即为了从一个远程位置复制文件或将文件复制到某个远程位置,除了用户之外,开发人员还需要指定该远程计算机中文件的路径和主机,就像cp 程序一样。他们遇到的语法是将路径附加到用户/主机声明的末尾,用冒号分隔:username@hostname:path/to/file(如其自己的manpage 中所述)。

    git@github.com:myuser/myrepo.git
    \_/ \________/ \_______________/
     |      |              |
    user   host           path

当 OpenSSH 团队实施 scp 程序时,他们希望为已经使用 rcp 的开发人员提供熟悉的 API,因此他们决定在新的标准化 SSH 之外继续支持这种旧的自定义语法URI 方案。然后,在 2005 年,Git 进入了对 SSH 的本机支持的场景,可能在底层使用了 OpenSSH,当 SSH 用于像clone 这样的远程操作时,最终使用了 类似rcp 的语法fetchpushpull。 Git 文档将此语法称为 scp-like syntax,并在 scp manpage、git-clone docs 和 Git protocols docs 中进行了简要描述。最后,尽管它缺乏标准化,但它似乎是所有云 Git 服务(如 Github 或 Bitbucket)在提供​​克隆 repos 的 URL 时使用的语法。

【讨论】:

【参考方案2】:

Git 存储库不仅仅可以使用 URI 来引用。例如,您可以使用路径,并且您可以使用ssh command 所需要的大多数(也许是全部,尚未检查)的东西。 ssh 命令也不需要 ssh URI:它已经知道它是解释资源标识符的那个,所以对 uniform 资源标识符施加的限制在这里没有任何价值,这里有跟随他们没有任何收获。

可以在 git clone 文档的 GIT URLS 下找到 Git 接受的存储库标识符的完整语法。

【讨论】:

感谢@jthill 的回答。所以看看 Git Urls 链接,是否可以肯定地说 Github 提供的用于克隆 repo 的常用 URL 采用类似 scp 的语法,可以与 SSH 一起使用,这就是它与标准 SSH URI 不同的原因?

以上是关于Git URI 与 SSH URI 规范不匹配的主要内容,如果未能解决你的问题,请参考以下文章

Oauth2 Instagram API“重定向 URI 与注册的重定向 URI 不匹配”

摘要 URI 与代理不匹配

寻呼机号码与 drupal 7 中的 URI 字符串不匹配?

IOS 应用程序中的 instagram 集成中的“重定向 URI 与注册的重定向 URI 不匹配”

出现错误:redirect_uri_mismatch 请求中的重定向 URI:http://localhost:8080/oauth2callback 与注册的重定向 URI 不匹配

Google OAUTH:请求中的重定向URI与注册的重定向URI不匹配