我知道我的 ssh 配置可以正常工作,因为我只需键入ssh myAlias.ssh
和连接就可以了。
我正在尝试使用该命令hg clone ssh://myAlias.ssh//path/to/repo
并获得remote: ssh: Could not resolve hostname myAlias.ssh: No such file or directory
是否可以在这里使用 SSH 别名?
Mercurial 确实适用于创建的别名~/.ssh/config
——我在 Linux 和 OS X 上一直使用此功能。这是因为 Mercurial 不会尝试解析主机名本身,而是依赖 SSH 来执行此操作(并将错误向上传递,当它遇到一个)。这就是为什么错误具有ssh:
作为其前缀的一部分。Bitbucket 甚至可以通过.ssh/config
. (在链接的示例中,他们使用它来管理两个单独的身份。)如果您通过另一种机制创建别名,例如 BASH alias
,那么这将不起作用,因为它依赖于 Mercurial 不使用的 BASH。
我还浏览了 Mercurial 的源代码,clone
包括检查SSH 相关部分,Mercurial 确实将主机名/别名传递给 SSH 以进行正确的解析/解释。sshpeer.py
util.py
Mercurial (2.6.3) 源代码的class url
in文档字符串 :util.py
Reliable URL parser.
This parses URLs and provides attributes for the following
components:
<scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment>
Missing components are set to None. The only exception is
fragment, which is set to '' if present but empty.
If parsefragment is False, fragment is included in query. If
parsequery is False, query is included in path. If both are
False, both fragment and query are included in path.
See http://www.ietf.org/rfc/rfc2396.txt for more information.
Note that for backward compatibility reasons, bundle URLs do not
take host names. That means 'bundle://../' has a path of '../'.
Examples:
>>> url('http://www.ietf.org/rfc/rfc2396.txt')
<url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
>>> url('ssh://[::1]:2200//home/joe/repo')
<url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
>>> url('file:///home/joe/repo')
<url scheme: 'file', path: '/home/joe/repo'>
>>> url('file:///c:/temp/foo/')
<url scheme: 'file', path: 'c:/temp/foo/'>
>>> url('bundle:foo')
<url scheme: 'bundle', path: 'foo'>
>>> url('bundle://../foo')
<url scheme: 'bundle', path: '../foo'>
>>> url(r'c:\foo\bar')
<url path: 'c:\\foo\\bar'>
>>> url(r'\\blah\blah\blah')
<url path: '\\\\blah\\blah\\blah'>
>>> url(r'\\blah\blah\blah#baz')
<url path: '\\\\blah\\blah\\blah', fragment: 'baz'>
Authentication credentials:
>>> url('ssh://joe:xyz@x/repo')
<url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
>>> url('ssh://joe@x/repo')
<url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
Query strings and fragments:
>>> url('http://host/a?b#c')
<url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
>>> url('http://host/a?b#c', parsequery=False, parsefragment=False)
<url scheme: 'http', host: 'host', path: 'a?b#c'>
但是,in__init__
方法(用于通过 SSH 克隆)引入了 URL 中不允许密码的附加限制:class sshpeer
sshpeer.py
u = util.url(path, parsequery=False, parsefragment=False)
if u.scheme != 'ssh' or not u.host or u.path is None:
self._abort(error.RepoError(_("couldn't parse location %s") % path))
self.user = u.user
if u.passwd is not None:
self._abort(error.RepoError(_("password in URL not supported")))
(其他协议允许使用 URL 中的密码,但我会将查找相关代码块作为练习留给读者,或查看有关URL的文档)
我们可以使用该-v
选项准确查看 Mercurial 在克隆期间如何与 SSH 交互。但首先,我的配置文件中的一些相关摘录。
从我的.ssh/config
文件:
Host bitbucket.ssh
Hostname bitbucket.org
User hg
从我的.hgrc
文件:
[ui]
# Irrelevant settings omitted
# enable compression in SSH
ssh = ssh -C
现在,我们来看看在克隆期间会发生什么:
livius@localhost ~ $ hg clone -v ssh://bitbucket.ssh/palday/splitauthor
running ssh -C bitbucket.ssh 'hg -R palday/splitauthor serve --stdio'
destination directory: splitauthor
requesting all changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 9 changes to 6 files
updating to branch default
resolving manifests
getting .hgignore
getting COPYING
getting README.rst
getting filter-revisions.awk
getting splitauthor.sh
getting testregex.sh
6 files updated, 0 files merged, 0 files removed, 0 files unresolved
第一个输出行确实说明了一切:Mercurial 将它从 URL 中解析出来的主机名(在本例中为您的别名)传递给 SSH,后者处理解析主机名/别名的实际问题。
在您的示例hg clone ssh://myAlias.ssh//path/to/repo
中,主机名后的斜杠太多,但我假设这仅在示例中。如果不是,这可能会导致您的路径是绝对的,而不是相对于用户名(如 中配置.ssh/config
)。另请参阅文档中的示例hg clone
我还发现确切的错误消息有点奇怪。当我使用未定义的主机名尝试此操作时,例如我尚未在我.ssh/config
的
remote: ssh: Could not resolve hostname server.ssh: nodename nor servname provided, or not known
. 在 Linux 上,我得到remote: ssh: Could not resolve hostname server.ssh: Name or service not known
.
所以,我怀疑你是在 Windows 上这样做的。我不知道 PuTTY 之类的如何处理 Windows 上的配置文件,这可能意味着语法不同,这就是您的问题所在。运行hg clone -v
还可以让您看到 Mercurial 正在发出的确切调用,这对于追踪出错的地方也非常有用。
在 Unix-y 系统上,您可以尝试ssh -T myAlias.ssh
测试连接和您的别名通过/失败,或者ssh -v myAlias.ssh
获得关于连接期间发生的事情的异常详细的输出。如果ssh -T
失败了,那肯定是比 Mercurial 级别低的问题。
您还可以将 set SSH 本身设置为详细:您可以设置为从 SSH 获取详细的调试输出,而不是ssh = ssh -C
像我上面的代码段中那样。这为我生成了大约 70 行调试输出。.hgrc
ssh = ssh -Cv
hg help urls
[paths]
可以(必须)在存储库 .hgrc 文件的部分中创建在 Mercurial 中使用的可能别名