我知道我的 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 甚至有 help关于通过 .ssh/config
设置别名. (在链接的示例中,他们使用它来管理两个单独的身份。)如果您通过另一种机制创建别名,例如 BASH alias
, 那么这将不起作用,因为它依赖于 Mercurial 不使用的 BASH。
来自 Mercurial 源代码
我还浏览了 clone
的 Mercurial 源代码。 ,包括检查 sshpeer.py
和 util.py
对于 SSH 相关部分,Mercurial 确实将主机名/别名传递给 SSH 以进行正确的解析/解释。class url
的文档字符串在 util.py
Mercurial (2.6.3) 源代码:
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'>
但是,__init__
class sshpeer
的方法在 sshpeer.py
(用于通过 SSH 克隆)引入了 URL 中不允许密码的附加限制: 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")))
(其他协议(protocol)允许使用 URL 中的密码,但我会将查找相关代码块留给读者作为练习,或者参见 URLs 上的文档)现场演示——调试的潜在帮助
我们可以使用
-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
中定义的别名,我在 OS X 上收到以下错误: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 正在调用的确切电话,这对于追踪哪里出了问题也非常有用。ssh -T myAlias.ssh
测试连接和您的别名通过/失败,或 ssh -v myAlias.ssh
获得关于连接期间发生的事情的异常详细的输出。如果 ssh -T
失败了,那肯定是比 Mercurial 级别低的问题。ssh = ssh -C
就像我的 .hgrc
上面的片段,你可以设置ssh = ssh -Cv
从 SSH 获取详细的调试输出。这为我生成了大约 70 行调试输出。关于ssh - 使用 SSH 别名时如何克隆远程仓库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17380216/