mercurial - How to clone remote repo when using SSH alias -
i know ssh configuration works because can type ssh myalias.ssh
, connect fine.
i'm trying use command hg clone ssh://myalias.ssh//path/to/repo
, getting remote: ssh: not resolve hostname myalias.ssh: no such file or directory
is possible use ssh alias here?
theory
general principles
mercurial work aliases created in ~/.ssh/config
-- use feature time on linux , os x. works because mercurial doesn't try resolve hostname itself, rather depends on ssh (and passes error up, when encounters one). why error has ssh:
part of prefix. bitbucket has help on setting aliases via .ssh/config
. (in linked example, use manage 2 separate identities.) if created alias via mechanism, bash alias
, not work because dependent on bash, mercurial not use.
from mercurial source code
i have gone through mercurial source code clone
, including examining sshpeer.py
, util.py
ssh related parts, , mercurial indeed pass along hostname/alias ssh correct parsing / interpretation.
the docstring class url
in util.py
of mercurial (2.6.3) source code:
reliable url parser. parses urls , provides attributes following components: <scheme>://<user>:<passwd>@<host>:<port>/<path>?<query>#<fragment> missing components set none. exception fragment, set '' if present empty. if parsefragment false, fragment included in query. if parsequery false, query included in path. if both false, both fragment , query included in path. see http://www.ietf.org/rfc/rfc2396.txt more information. note backward compatibility reasons, bundle urls not take host names. means 'bundle://../' has 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 , 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'>
however, __init__
method of class sshpeer
in sshpeer.py
(which used cloning on ssh) introduces additional restriction passwords not allowed in url:
u = util.url(path, parsequery=false, parsefragment=false) if u.scheme != 'ssh' or not u.host or u.path none: self._abort(error.repoerror(_("couldn't parse location %s") % path)) self.user = u.user if u.passwd not none: self._abort(error.repoerror(_("password in url not supported")))
(password in url allowed other protocols, i'll leave finding relevant blocks of code exercise reader, or see documentation on urls)
demonstrating live -- potential in debugging
we can use -v
option see how mercurial interacts ssh during clone. first, relevant excerpts configuration files.
from .ssh/config
file:
host bitbucket.ssh hostname bitbucket.org user hg
from .hgrc
file:
[ui] # irrelevant settings omitted # enable compression in ssh ssh = ssh -c
now, take @ happens during clone:
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 changes adding changesets adding manifests adding file changes added 3 changesets 9 changes 6 files updating 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
the first output line says all: mercurial passes hostname parses out of url -- in case, alias -- ssh, handles actual issue of resolving hostname/alias.
other comments , tips
in example
hg clone ssh://myalias.ssh//path/to/repo
, have slash many after hostname, i'm assuming in example. if not, causing path absolute, instead of relative user name (as configured in.ssh/config
). see examples in documentation onhg clone
i find exact error message bit odd. when try undefined hostname, e.g. alias haven't defined in
.ssh/config
, following error on os x:remote: ssh: not resolve hostname server.ssh: nodename nor servname provided, or not known
. on linux,remote: ssh: not resolve hostname server.ssh: name or service not known
.so, suspicion you're doing on windows. don't know how putty , handle configuration file on windows, might mean there's different syntax , that's problem is. running
hg clone -v
let see exact call mercurial making, quite useful in tracking down things going wrong.on unix-y systems, can try
ssh -t myalias.ssh
test connection , alias pass/fail, orssh -v myalias.ssh
exceptionally verbose output on what's happening during connection. ifssh -t
fails, it's issue @ level lower mercurial.you can set set ssh verbose: instead of
ssh = ssh -c
in.hgrc
snippet above, can setssh = ssh -cv
verbose debugging output ssh. generated 70 lines of debugging output me.
Comments
Post a Comment