subrepos with ssh urls with absolute paths

Previous Topic Next Topic
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

subrepos with ssh urls with absolute paths

Mads Kiilerich
  [mk@D610 hg]$ cd /tmp
[mk@D610 tmp]$ hg init repo
[mk@D610 tmp]$ hg init repo/s
[mk@D610 tmp]$ echo a > repo/s/a
[mk@D610 tmp]$ hg -R repo/s ci -Am0
adding a
[mk@D610 tmp]$ echo s = s > repo/.hgsub
[mk@D610 tmp]$ hg -R repo ci -Am1
adding .hgsub
committing subrepository s
[mk@D610 tmp]$ hg clone ssh://localhost//tmp/repo repo2
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 2 changes to 2 files
updating to branch default
pulling subrepo s from ssh://localhost/tmp/repo/s
remote: abort: There is no Mercurial repository here (.hg not found)!
abort: no suitable response from remote hg!
[mk@D610 tmp]$ grep default repo2/.hg/hgrc
default = ssh://localhost//tmp/repo
[mk@D610 tmp]$ grep default repo2/s/.hg/hgrc
default = ssh://localhost/tmp/repo/s

For some reason the double slash isn't used for the subrepo. That is the
issue reported in .

This is caused by mercurial/ _abssource which now uses
urlparse and normpath.

A: introduced normpath on the
path part in order to handle ..-relative paths in http URLs. Normpath
might be fine on http URLs in all cases, but it isn't fine on ssh URL
paths where leading double slash has special semantics. That could
perhaps be solved by normalizing path[1:] if it wasn't for

As issue discussed in Python urlparse
tries to be smart and handle known protocols differently, and thus
doesn't find a netloc (host) part in an ssh URL:
 >>> urlparse.urlparse('http://foo//bar')
ParseResult(scheme='http', netloc='foo', path='//bar', params='',
query='', fragment='')
 >>> urlparse.urlparse('ssh://foo//bar')
ParseResult(scheme='ssh', netloc='', path='//foo//bar', params='',
query='', fragment='')

 >>> urlparse.urlunparse(urlparse.urlparse('ssh://foo//bar'))

We should thus (probably) only use urlparse when we know it is a
http/https URL - never with ssh URLs.

How should we resolve this issue?

One possible answer might be: There are quite well-defined use-cases for
defining subrepos both with simple relative (s = s) and remote absolute
(s = scheme://x/y) .hgsub mappings. All other mappings are so strange or
problematic that we can't support them without getting into huge
problems, and we should avoid the complexity of trying. The use-cases
that were (badly) solved with these "other" mappings are probably better
solved with the new subpaths remapping. So perhaps we should back
a2bc2f2d77a9 out?

Or should we implement our own urlparse, for general use or only in this

Perhaps just something like

--- a/mercurial/
+++ b/mercurial/
@@ -156,11 +156,9 @@
          if '://' in parent:
              if parent[-1] == '/':
                  parent = parent[:-1]
-            r = urlparse.urlparse(parent + '/' + source)
-            r = urlparse.urlunparse((r[0], r[1],
-                                     posixpath.normpath(r[2]),
-                                     r[3], r[4], r[5]))
-            return r
+            url = parent + '/' + source
+            i = url.find('/', url.find(':') + 3) + 1
+            return url[:i] + posixpath.normpath(url[i:])
          return posixpath.normpath(os.path.join(parent, repo._subsource))
      if push and repo.ui.config('paths', 'default-push'):
          return repo.ui.config('paths', 'default-push', repo.root)

Mercurial-devel mailing list
[hidden email]