如何在使用SSH别名时克隆远程仓库

时间:2013-06-29 12:33:56

标签: ssh mercurial

我知道我的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别名吗?

2 个答案:

答案 0 :(得分:6)

理论

一般原则

Mercurial可以使用~/.ssh/config中创建的别名 - 我在Linux和OS X上一直使用此功能。这是因为Mercurial不会尝试解析主机名本身,而是依赖于SSH这样做(并在遇到错误时传递错误)。这就是错误是ssh:作为其前缀的一部分的原因。 Bitbucket甚至通过.ssh/config设置了别名help。 (在链接的示例中,他们使用它来管理两个单独的身份。)如果您通过另一种机制创建别名,比如BASH alias,那么这将无法工作,因为它依赖于BASH,Mercurial不使用

来自Mercurial源代码

我还浏览了clone的Mercurial源代码,包括检查SSH相关部分的sshpeer.pyutil.py,Mercurial确实将主机名/别名传递给了SSH用于正确的解析/解释。

Mercurial(2.6.3)源代码class urlutil.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'> 

但是,__init__class sshpeer的{​​{1}}方法(用于通过SSH克隆)会引入额外的限制,即网址中不允许使用密码:

sshpeer.py

(其他协议允许使用URL中的密码,但我会留下相关的代码块作为读者练习,或查看URLs上的文档)

在调试

中展示这种直播帮助

我们可以使用 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"))) 选项查看Mercurial在克隆过程中如何与SSH进行交互。但首先,我的配置文件中有一些相关的摘录。

来自我的-v文件:

.ssh/config

来自我的Host bitbucket.ssh Hostname bitbucket.org User hg 文件:

.hgrc

现在,我们来看看克隆期间会发生什么:

[ui]
# Irrelevant settings omitted
# enable compression in SSH
ssh = ssh -C

第一个输出行确实说明了一切:Mercurial将它解析出的主机名 - 在这种情况下,你的别名 - 传递给SSH,它处理解析主机名/别名的实际问题。

其他评论和提示

  • 在您的示例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 中,主机名后面有一个斜杠,但我假设这只是在示例中。如果没有,这可能导致您的路径是绝对的,而不是相对于用户名(在hg clone ssh://myAlias.ssh//path/to/repo中配置)。另请参阅hg clone

  • 文档中的示例
  • 我也发现确切的错误消息有点奇怪。当我尝试使用未定义的主机名时,例如我没有在.ssh/config中定义的别名,我在OS X上收到以下错误: .ssh/config。在Linux上,我得到remote: ssh: Could not resolve hostname server.ssh: nodename nor servname provided, or not known

    所以,我怀疑你是在Windows上这样做的。我不知道PuTTY等在Windows上如何处理配置文件,这可能意味着语法不同,这就是你的问题所在。运行remote: ssh: Could not resolve hostname server.ssh: Name or service not known还可以让您看到Mercurial正在进行的确切调用,这对于追踪出错的地方也非常有用。

  • 在Unix-y系统上,您可以尝试hg clone -v测试连接和别名通过/失败,或ssh -T myAlias.ssh以获得关于连接期间发生的异常详细输出。如果ssh -v myAlias.ssh失败,那么它肯定是一个低于Mercurial的问题。

  • 您还可以将设置SSH本身设置为详细:您可以设置ssh -T以获取来自SSH的详细调试输出,而不是ssh = ssh -C上面的.hgrc代码。这为我生成了大约70行调试输出。

答案 1 :(得分:0)

  1. Mercurial一无所知,不使用ssh-aliases
  2. 所有可用的网址类型都在hg help urls
  3. 中枚举
  4. 在Mercurial别名中使用可以(必须)在存储库.hgrc文件的[paths]部分中创建