Commits

Brodie Rao committed fd6c044

Refreshing queue and updating url patches

Comments (0)

Files changed (15)

darcs-non-utf-8

-# HG changeset patch
-# Parent 10dcfba4f16d42f2fd80faf91818a0d6607591da
-convert/darcs: support changelogs with bytes 0x7F-0xFF (issue2411)
-
-This is a followup to 4481f8a93c7a, which only fixed the conversion of
-patches with UTF-8 metadata.
-
-This patch allows a changelog to have any bytes with values
-0x7F-0xFF. It parses the XML changelog as Latin-1 and uses
-converter_source.recode() to decode the data as UTF-8/Latin-1.
-
-Caveats:
-
-- Since the convert extension doesn't provide any way to specify the
-  source encoding, users are still limited to UTF-8 and Latin-1.
-
-- etree will still complain if the changelog has bytes with values
-  0x00-0x19. XML only allows printable characters.
-
-diff --git a/hgext/convert/darcs.py b/hgext/convert/darcs.py
---- a/hgext/convert/darcs.py
-+++ b/hgext/convert/darcs.py
-@@ -7,22 +7,22 @@
- 
- from common import NoRepo, checktool, commandline, commit, converter_source
- from mercurial.i18n import _
--from mercurial import util
-+from mercurial import encoding, util
- import os, shutil, tempfile, re
- 
- # The naming drift of ElementTree is fun!
- 
- try:
--    from xml.etree.cElementTree import ElementTree
-+    from xml.etree.cElementTree import ElementTree, XMLParser
- except ImportError:
-     try:
--        from xml.etree.ElementTree import ElementTree
-+        from xml.etree.ElementTree import ElementTree, XMLParser
-     except ImportError:
-         try:
--            from elementtree.cElementTree import ElementTree
-+            from elementtree.cElementTree import ElementTree, XMLParser
-         except ImportError:
-             try:
--                from elementtree.ElementTree import ElementTree
-+                from elementtree.ElementTree import ElementTree, XMLParser
-             except ImportError:
-                 ElementTree = None
- 
-@@ -88,12 +88,24 @@ class darcs_source(converter_source, com
-         self.ui.debug('cleaning up %s\n' % self.tmppath)
-         shutil.rmtree(self.tmppath, ignore_errors=True)
- 
-+    def recode(self, s, encoding=None):
-+        if isinstance(s, unicode):
-+            # XMLParser returns unicode objects for anything it can't
-+            # encode into ASCII. We convert them back to str to get
-+            # recode's normal conversion behavior.
-+            s = s.encode('latin-1')
-+        return super(darcs_source, self).recode(s, encoding)
-+
-     def xml(self, cmd, **kwargs):
-         # NOTE: darcs is currently encoding agnostic and will print
-         # patch metadata byte-for-byte, even in the XML changelog.
-         etree = ElementTree()
-+        # While we are decoding the XML as latin-1 to be as liberal as
-+        # possible, etree will still raise an exception if any
-+        # non-printable characters are in the XML changelog.
-+        parser = XMLParser(encoding='latin-1')
-         fp = self._run(cmd, **kwargs)
--        etree.parse(fp)
-+        etree.parse(fp, parser=parser)
-         self.checkexit(fp.close())
-         return etree.getroot()
- 
-diff --git a/tests/test-convert-darcs b/tests/test-convert-darcs
---- a/tests/test-convert-darcs
-+++ b/tests/test-convert-darcs
-@@ -65,9 +65,15 @@ echo g > g
- # darcs is encoding agnostic, so it takes whatever bytes it's given
- darcs record -a -l -m 'p4: desc ñ' -A 'author ñ'
- 
-+echo % test latin-1 commit message
-+echo h > h
-+printf "p5: desc " > ../p5
-+python -c 'print "".join([chr(i) for i in range(128, 256)])' >> ../p5
-+darcs record -a -l --logfile ../p5
-+
- glog()
- {
--    HGENCODING=utf-8 hg glog --template '{rev} "{desc|firstline}" ({author}) files: {files}\n' "$@"
-+    hg glog --template '{rev} "{desc|firstline}" ({author}) files: {files}\n' "$@"
- }
- 
- cd ..
-@@ -78,6 +84,7 @@ hg convert darcs-repo darcs-repo-hg
- # Unfortunately, non-conflicting changes, like the addition of the
- # "c" file in p1.1 patch are reverted too.
- # Just to say that manifest not listing "c" here is a bug.
--glog -R darcs-repo-hg
-+HGENCODING=latin-1 glog -R darcs-repo-hg -r 6 | "$TESTDIR"/printrepr.py
-+HGENCODING=utf-8 glog -R darcs-repo-hg -r 0:5 | "$TESTDIR"/printrepr.py
- hg up -q -R darcs-repo-hg
- hg -R darcs-repo-hg manifest --debug
-diff --git a/tests/test-convert-darcs.out b/tests/test-convert-darcs.out
---- a/tests/test-convert-darcs.out
-+++ b/tests/test-convert-darcs.out
-@@ -16,17 +16,22 @@ Finished recording patch 'p2'
- Finished recording patch 'p3'
- % test utf-8 commit message and author
- Finished recording patch 'p4: desc ñ'
-+% test latin-1 commit message
-+Finished recording patch 'p5: desc ��������������������������������������������������������������������������������������������������������������������������������'
- initializing destination darcs-repo-hg repository
- scanning source...
- sorting...
- converting...
--5 p0
--4 p1.2
--3 p1.1
--2 p2
--1 p3
--0 p4: desc ?
--o  5 "p4: desc ñ" (author ñ) files: g
-+6 p0
-+5 p1.2
-+4 p1.1
-+3 p2
-+2 p3
-+1 p4: desc ?
-+0 p5: desc ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
-+o  6 "p5: desc \x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" (test@example.org) files: h
-+|
-+o  5 "p4: desc \xc3\xb1" (author \xc3\xb1) files: g
- |
- o  4 "p3" (test@example.org) files: dir/d dir/d2 dir2/d f ff
- |
-@@ -43,3 +48,4 @@ 1e88685f5ddec574a34c70af492f95b6debc8741
- 37406831adc447ec2385014019599dfec953c806 644   dir2/d
- b783a337463792a5c7d548ad85a7d3253c16ba8c 644   ff
- 0973eb1b2ecc4de7fafe7447ce1b7462108b4848 644   g
-+fe6f8b4f507fe3eb524c527192a84920a4288dac 644   h

post-pushkey

-# HG changeset patch
-# Parent 158ca54a79cce2439c9f66a95d174d993f9ebc4b
-wireproto: fix pushkey not being sent via POST over HTTP
-
-diff --git a/mercurial/httprepo.py b/mercurial/httprepo.py
---- a/mercurial/httprepo.py
-+++ b/mercurial/httprepo.py
-@@ -157,8 +157,11 @@ class httprepository(wireproto.wirerepos
-                     type = x
-                     break
- 
--        tempname = changegroup.writebundle(cg, None, type)
--        fp = url.httpsendfile(tempname, "rb")
-+        if cg is not None:
-+            tempname = changegroup.writebundle(cg, None, type)
-+            fp = url.httpsendfile(tempname, "rb")
-+        else:
-+            fp = ''
-         headers = {'Content-Type': 'application/mercurial-0.1'}
- 
-         try:
-@@ -170,8 +173,9 @@ class httprepository(wireproto.wirerepos
-                     raise util.Abort(_('push failed: %s') % err.args[1])
-                 raise util.Abort(err.args[1])
-         finally:
--            fp.close()
--            os.unlink(tempname)
-+            if cg is not None:
-+                fp.close()
-+                os.unlink(tempname)
- 
-     def _abort(self, exception):
-         raise exception
-diff --git a/mercurial/sshrepo.py b/mercurial/sshrepo.py
---- a/mercurial/sshrepo.py
-+++ b/mercurial/sshrepo.py
-@@ -129,8 +129,8 @@ class sshrepository(wireproto.wirereposi
- 
-     def _callpush(self, cmd, fp, **args):
-         r = self._call(cmd, **args)
--        if r:
--            return '', r
-+        if r or fp is None:
-+            return r.split('\n')
-         while 1:
-             d = fp.read(4096)
-             if not d:
-@@ -139,7 +139,7 @@ class sshrepository(wireproto.wirereposi
-         self._send("", flush=True)
-         r = self._recv()
-         if r:
--            return '', r
-+            return r.split('\n')
-         return self._recv(), ''
- 
-     def _decompress(self, stream):
-diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
---- a/mercurial/wireproto.py
-+++ b/mercurial/wireproto.py
-@@ -82,9 +82,9 @@ class wirerepository(repo.repository):
-     def pushkey(self, namespace, key, old, new):
-         if not self.capable('pushkey'):
-             return False
--        d = self._call("pushkey",
--                      namespace=namespace, key=key, old=old, new=new)
--        return bool(int(d))
-+        d = self._callpush("pushkey", None, # force a POST
-+                           namespace=namespace, key=key, old=old, new=new)
-+        return bool(int(d[0]))
- 
-     def listkeys(self, namespace):
-         if not self.capable('pushkey'):
-post-pushkey
 hgplain-i18n
 mq-opt-fuckery #+mq-opt-fuckery
 localdate-config #+localdate-config
-darcs-non-utf-8 #+convert
 gnuarch-encoding #+convert
 url-class #+urlsplit
 url-subrepo #+urlsplit
 url-hg-parseurl #+urlsplit
 url-ui #+urlsplit
 url-drop-scheme #+urlsplit
-url-schemes-ext #+urlsplit
 fetch-ret #+fetch-ret
 popen-and-wait #+popen-wait
 pager-popen-wait #+popen-wait
 # HG changeset patch
-# Parent 05077896ffe233bbaf9e1c180f18dd85fd45a8e4
+# Parent dc5ff71579877c60e22c98e2b7e246204494db3c
 url: provide URL object
 
 This patch adds a URL object that re-implements urlsplit() and
 diff --git a/tests/test-url.py b/tests/test-url.py
 --- a/tests/test-url.py
 +++ b/tests/test-url.py
-@@ -46,3 +46,149 @@ check(_verifycert({'notAfter': 'Sep 29 1
+@@ -36,3 +36,149 @@ check(_verifycert({'subject': ()},
        'no commonName found in certificate')
  check(_verifycert(None, 'example.com'),
        'no certificate received')
 # HG changeset patch
-# Parent 77388198fa24a2bd2c03076ee17992c1d1827624
+# Parent 1395e9c19eb01a49ad224fc2ee33ce1391eef2d8
 url: use url.URL in util.drop_scheme() and remove hg.localpath()
 
 This updates drop_scheme() to use url.URL for parsing instead of doing
 @@ -15,7 +15,7 @@ from node import nullid
  from i18n import _
  import os, struct, tempfile, shutil
- import changegroup, util, mdiff
+ import changegroup, util, mdiff, discovery
 -import localrepo, changelog, manifest, filelog, revlog, error
 +import localrepo, changelog, manifest, filelog, revlog, error, url
  
  class bundlerevlog(revlog.revlog):
      def __init__(self, opener, indexfile, bundle,
-@@ -277,9 +277,9 @@ def instance(ui, path, create):
+@@ -279,9 +279,9 @@ def instance(ui, path, create):
              cwd = os.path.join(cwd,'')
              if parentpath.startswith(cwd):
                  parentpath = parentpath[len(cwd):]
  
  def _local(path):
 -    path = util.expandpath(util.drop_scheme('file', path))
-+    path = util.expandpath(url.drop_scheme('file', path))
++    path = util.expandpath(url.localpath(path))
      return (os.path.isfile(path) and bundlerepo or localrepo)
  
  def addbranchrevs(lrepo, repo, branches, revs):
  
 -    dest = localpath(dest)
 -    source = localpath(source)
-+    dest = url.drop_scheme('file', dest)
-+    source = url.drop_scheme('file', source)
++    dest = url.localpath(dest)
++    source = url.localpath(source)
  
      if os.path.exists(dest):
          if not os.path.isdir(dest):
          copy = False
          if src_repo.cancopy() and islocal(dest):
 -            abspath = os.path.abspath(util.drop_scheme('file', origsource))
-+            abspath = os.path.abspath(url.drop_scheme('file', origsource))
++            abspath = os.path.abspath(url.localpath(origsource))
              copy = not pull and not rev
  
          if copy:
 diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
 --- a/mercurial/localrepo.py
 +++ b/mercurial/localrepo.py
-@@ -1887,7 +1887,7 @@ def aftertrans(files):
+@@ -1898,7 +1898,7 @@ def aftertrans(files):
      return a
  
  def instance(ui, path, create):
 diff --git a/mercurial/util.py b/mercurial/util.py
 --- a/mercurial/util.py
 +++ b/mercurial/util.py
-@@ -1257,26 +1257,6 @@ def bytecount(nbytes):
+@@ -1301,26 +1301,6 @@ def bytecount(nbytes):
              return format % (nbytes / float(divisor))
      return units[-1][2] % nbytes
  
    requesting all changes
    adding changesets
    adding manifests
-@@ -250,7 +256,7 @@ Create partial clones
+@@ -249,7 +255,7 @@ Create partial clones
  
  Log -R full.hg in partial
  
    changeset:   8:aa35859c02ea
    tag:         tip
    parent:      3:eebf5a27f8ca
-@@ -302,8 +308,8 @@ Log -R full.hg in partial
+@@ -301,8 +307,8 @@ Log -R full.hg in partial
  
  Incoming full.hg in partial
  
    searching for changes
    changeset:   4:095197eb4973
    parent:      0:f9ee2f85a263
-@@ -336,7 +342,7 @@ Incoming full.hg in partial
+@@ -335,7 +341,7 @@ Incoming full.hg in partial
  
  Outgoing -R full.hg vs partial2 in partial
  
    comparing with ../partial2
    searching for changes
    changeset:   4:095197eb4973
-@@ -370,7 +376,7 @@ Outgoing -R full.hg vs partial2 in parti
+@@ -369,7 +375,7 @@ Outgoing -R full.hg vs partial2 in parti
  
  Outgoing -R does-not-exist.hg vs partial2 in partial
  
    abort: No such file or directory: ../does-not-exist.hg
    [255]
    $ cd ..
-@@ -456,6 +462,22 @@ test for 540d1059c802
+@@ -455,6 +461,22 @@ test for 540d1059c802
    
    $ cd ..
  
 # HG changeset patch
-# Parent 4c61af084e5fac1b56f6076544000c914d9fe9cb
+# Parent 471a23d441bfe161c72519c0cc1ba3c750e08b42
 hg: look up schemes using url.URL
 
 diff --git a/mercurial/hg.py b/mercurial/hg.py
 # HG changeset patch
-# Parent ea4bf94365ab88221f02b5c8a7eea764451a81fc
+# Parent a21c5ad302530fe33d51af6f4d653c0646182b9f
 hg: use url.URL to parse branch names in parseurl()
 
 diff --git a/mercurial/hg.py b/mercurial/hg.py
 # HG changeset patch
-# Parent 43e103fa04ecf23fe5df483ac04496671416df46
+# Parent 0a232f8e72689e81587fa88b27d6041bb4bb4421
 hgweb: use url.URL when setting CGI environment variables
 
 diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
 # HG changeset patch
-# Parent d836f0e09afbfb74bf11ba9af4e62fa4dbaff942
+# Parent 3977079fd7e4a2cf7ae988ca481232923fc933f1
 url: use url.URL in hidepassword() and removeauth()
 
 diff --git a/mercurial/url.py b/mercurial/url.py
 # HG changeset patch
-# Parent 60b52b29a89c26075a93944cf79dec7252fae3f1
+# Parent 84c92bd94ee98a84a2b524d56edb75d4a81e6b99
 url: use url.URL in url.open()
 
 diff --git a/mercurial/url.py b/mercurial/url.py
  # This software may be used and distributed according to the terms of the
  # GNU General Public License version 2 or any later version.
  
--import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO, time
-+import urllib, urllib2, urlparse, httplib, os, socket, cStringIO, time
+-import urllib, urllib2, urlparse, httplib, os, re, socket, cStringIO
++import urllib, urllib2, urlparse, httplib, os, socket, cStringIO
  import __builtin__
  from i18n import _
  import keepalive, util
-@@ -844,17 +844,14 @@ def opener(ui, authinfo=None):
+@@ -841,17 +841,14 @@ def opener(ui, authinfo=None):
      opener.addheaders.append(('Accept', 'application/mercurial-0.1'))
      return opener
  
 # HG changeset patch
-# Parent 95f7ce017fe0dfc4f59c04dcdfb5929a24988ef7
+# Parent 4f45b616d4edf996e8f50e988b3ba5c053e54e1d
 url: use url.URL in proxyhandler
 
 diff --git a/mercurial/url.py b/mercurial/url.py
 --- a/mercurial/url.py
 +++ b/mercurial/url.py
-@@ -346,14 +346,10 @@ class proxyhandler(urllib2.ProxyHandler)
+@@ -349,14 +349,10 @@ class proxyhandler(urllib2.ProxyHandler)
              if not (proxyurl.startswith('http:') or
                      proxyurl.startswith('https:')):
                  proxyurl = 'http://' + proxyurl + '/'
  
              # see if we should use a proxy for this url
              no_list = ["localhost", "127.0.0.1"]
-@@ -368,13 +364,10 @@ class proxyhandler(urllib2.ProxyHandler)
+@@ -371,13 +367,10 @@ class proxyhandler(urllib2.ProxyHandler)
              else:
                  self.no_list = no_list
  
          else:
              proxies = {}
  
-@@ -523,13 +516,9 @@ def _generic_start_transaction(handler, 
+@@ -526,13 +519,9 @@ def _generic_start_transaction(handler, 
          new_tunnel = False
  
      if new_tunnel or tunnel_host == req.get_full_url(): # has proxy
 # HG changeset patch
-# Parent 42207aba31083ec7b2931aaa48fd5f10b37cc7ce
+# Parent 9ca153ab3c4b3c3c0a4d8e1f11f4f616326fe996
 httprepo/sshrepo: use url.URL
 
 Like the previous patch to getauthinfo(), this also makes

url-schemes-ext

-# HG changeset patch
-# Parent 11ccf7a3aec839a9751a096080b195b92b20250c
-clone: don't mangle schemes that point to local paths (issue2316)
-
-When a custom scheme is defined using file://, hg.clone() would apply
-os.path.abspath() to the source URL when writing the default path to
-the destination's .hg/hgrc. This would result in appending the current
-working directory to the URL, making it invalid.
-
-This patch moves the abspath behavior into url.drop_scheme(). Calling
-drop_scheme('file', path, abspath=True) will only apply abspath() for
-local URLs.
-
-diff --git a/mercurial/hg.py b/mercurial/hg.py
---- a/mercurial/hg.py
-+++ b/mercurial/hg.py
-@@ -250,7 +250,7 @@ def clone(ui, source, dest=None, pull=Fa
-         abspath = origsource
-         copy = False
-         if src_repo.cancopy() and islocal(dest):
--            abspath = os.path.abspath(url.drop_scheme('file', origsource))
-+            abspath = url.drop_scheme('file', origsource, abspath=True)
-             copy = not pull and not rev
- 
-         if copy:
-diff --git a/mercurial/url.py b/mercurial/url.py
---- a/mercurial/url.py
-+++ b/mercurial/url.py
-@@ -168,7 +168,7 @@ class URL(object):
-             s += '#' + self.fragment
-         return s
- 
--def drop_scheme(scheme, path):
-+def drop_scheme(scheme, path, abspath=False):
-     u = URL(path, parse_query=False, parse_fragment=False)
-     if u.scheme == scheme:
-         if scheme == 'file' or scheme == 'bundle':
-@@ -184,7 +184,11 @@ def drop_scheme(scheme, path):
-                     # the file system root.
-                     droot = os.path.splitdrive(os.getcwd())[0] + '/'
-                     u.path = os.path.join(droot, u.path)
-+            if abspath:
-+                u.path = os.path.abspath(u.path)
-         return u.path or ''
-+    elif abspath and not u.scheme:
-+        path = os.path.abspath(path)
-     return path
- 
- def hidepassword(url):
-diff --git a/tests/test-schemes.t b/tests/test-schemes.t
---- a/tests/test-schemes.t
-+++ b/tests/test-schemes.t
-@@ -7,6 +7,7 @@
-   > l = http://localhost:$HGPORT/
-   > parts = http://{1}:$HGPORT/
-   > z = file:\$PWD/
-+  > f = file:./
-   > EOF
-   $ hg init test
-   $ cd test
-@@ -40,6 +41,21 @@ check that paths are expanded
-   no changes found
-   [1]
- 
-+check that file:// aliases are handled correctly (issue2316)
-+
-+  $ cd ..
-+  $ hg clone f://test test2
-+  updating to branch default
-+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-+  $ hg -R test2 showconfig paths.default
-+  f://test
-+  $ hg -R test2 incoming
-+  comparing with f://test
-+  searching for changes
-+  no changes found
-+  [1]
-+  $ cd test
-+
- errors
- 
-   $ cat errors.log
 # HG changeset patch
-# Parent 70ad1653c028d1e45994c0539a8679f525d9bd09
+# Parent d02eda3d3809eae76653e2cc2d3694dfc19e78b6
 subrepos: use url.URL when normalizing repo paths
 
 This works around an issue in older versions of Python that would
 diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
 --- a/mercurial/subrepo.py
 +++ b/mercurial/subrepo.py
-@@ -5,9 +5,9 @@
+@@ -5,10 +5,10 @@
  # This software may be used and distributed according to the terms of the
  # GNU General Public License version 2 or any later version.
  
 -import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
 +import errno, os, re, xml.dom.minidom, shutil, posixpath
+ import stat, subprocess
  from i18n import _
 -import config, util, node, error, cmdutil
 +import config, util, node, error, cmdutil, url
  hg = None
  
  nullstate = ('', '', 'empty')
-@@ -167,19 +167,14 @@ def _abssource(repo, push=False):
-     """return pull/push path of repo - either based on parent repo
-     .hgsub info or on the subrepos own config"""
+@@ -180,21 +180,16 @@ def _abssource(repo, push=False, abort=T
+     """return pull/push path of repo - either based on parent repo .hgsub info
+     or on the top repo config. Abort or return None if no source found."""
      if hasattr(repo, '_subparent'):
 -        source = repo._subsource
 -        if source.startswith('/') or '://' in source:
 -            return source
--        parent = _abssource(repo._subparent, push)
--        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
--        return posixpath.normpath(os.path.join(parent, repo._subsource))
 +        source = url.url(repo._subsource)
 +        source.path = posixpath.normpath(source.path)
 +        if posixpath.isabs(source.path) or source.scheme:
 +            return str(source)
-+        parent = url.url(_abssource(repo._subparent, push))
-+        parent.path = posixpath.join(parent.path, source.path)
-+        parent.path = posixpath.normpath(parent.path)
-+        return str(parent)
-     if push and repo.ui.config('paths', 'default-push'):
-         return repo.ui.config('paths', 'default-push', repo.root)
-     return repo.ui.config('paths', 'default', repo.root)
+         parent = _abssource(repo._subparent, push, abort=False)
+         if parent:
+-            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
+-            else: # plain file system path
+-                return posixpath.normpath(os.path.join(parent, repo._subsource))
++            parent = url.url(parent)
++            parent.path = posixpath.join(parent.path, source.path)
++            parent.path = posixpath.normpath(parent.path)
++            return str(parent)
+     else: # recursion reached top repo
+         if hasattr(repo, '_subtoppath'):
+             return repo._subtoppath
 # HG changeset patch
-# Parent 33b34263d155cd4401fce50725101c04da57ae5b
+# Parent dd9b781cbfcfe115b61260fdc6941907f1746bbd
 url: use url.URL in ui.expandpath()
 
 diff --git a/mercurial/ui.py b/mercurial/ui.py
  
  class ui(object):
      def __init__(self, src=None):
-@@ -110,7 +110,7 @@ class ui(object):
-                               % (n, p, self.configsource('paths', n)))
-                     p = p.replace('%%', '%')
-                 p = util.expandpath(p)
--                if '://' not in p and not os.path.isabs(p):
-+                if not url.has_scheme(p) and not os.path.isabs(p):
-                     p = os.path.normpath(os.path.join(root, p))
-                 c.set("paths", n, p)
+@@ -111,7 +111,7 @@ class ui(object):
+                                   % (n, p, self.configsource('paths', n)))
+                         p = p.replace('%%', '%')
+                     p = util.expandpath(p)
+-                    if '://' not in p and not os.path.isabs(p):
++                    if not url.has_scheme(p) and not os.path.isabs(p):
+                         p = os.path.normpath(os.path.join(root, p))
+                     c.set("paths", n, p)
  
-@@ -311,7 +311,7 @@ class ui(object):
+@@ -322,7 +322,7 @@ class ui(object):
  
      def expandpath(self, loc, default=None):
          """Return repository location relative to cwd or from [paths]"""