changeset 12753:ef5eaf53f4f7

subrepo: abort instead of pushing/pulling to the repo itself _abssource will now abort (or return None) in the rare cases where no push/pull path can be found.
author Mads Kiilerich <mads@kiilerich.com>
date Tue, 19 Oct 2010 03:56:20 +0200
parents 18b5b6392fcf
children eaac5e8cb637
files mercurial/subrepo.py tests/test-subrepo.t
diffstat 2 files changed, 89 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/subrepo.py	Tue Oct 19 03:55:28 2010 +0200
+++ b/mercurial/subrepo.py	Tue Oct 19 03:56:20 2010 +0200
@@ -167,26 +167,33 @@
         return sub._path
     return reporelpath(sub._repo)
 
-def _abssource(repo, push=False):
-    """return pull/push path of repo - either based on parent repo
-    .hgsub info or on the subrepos own config"""
+def _abssource(repo, push=False, abort=True):
+    """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))
-    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))
+    else: # recursion reached top repo
+        if push and repo.ui.config('paths', 'default-push'):
+            return repo.ui.config('paths', 'default-push')
+        if repo.ui.config('paths', 'default'):
+            return repo.ui.config('paths', 'default')
+    if abort:
+        raise util.Abort(_("default path for subrepository %s not found") % 
+            reporelpath(repo))
 
 def itersubrepos(ctx1, ctx2):
     """find subrepos in ctx1 or ctx2"""
@@ -314,11 +321,12 @@
             fp.write('[paths]\n')
 
             def addpathconfig(key, value):
-                fp.write('%s = %s\n' % (key, value))
-                self._repo.ui.setconfig('paths', key, value)
+                if value:
+                    fp.write('%s = %s\n' % (key, value))
+                    self._repo.ui.setconfig('paths', key, value)
 
-            defpath = _abssource(self._repo)
-            defpushpath = _abssource(self._repo, True)
+            defpath = _abssource(self._repo, abort=False)
+            defpushpath = _abssource(self._repo, True, abort=False)
             addpathconfig('default', defpath)
             if defpath != defpushpath:
                 addpathconfig('default-push', defpushpath)
--- a/tests/test-subrepo.t	Tue Oct 19 03:55:28 2010 +0200
+++ b/tests/test-subrepo.t	Tue Oct 19 03:56:20 2010 +0200
@@ -585,3 +585,64 @@
   $ hg -R repo update
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ rm -rf repo2 repo
+
+
+Issue1852 subrepos with relative paths always push/pull relative to default
+
+Prepare a repo with subrepo
+
+  $ hg init issue1852a
+  $ cd issue1852a
+  $ hg init sub/repo
+  $ echo test > sub/repo/foo
+  $ hg -R sub/repo add sub/repo/foo
+  $ echo sub/repo = sub/repo > .hgsub
+  $ hg add .hgsub
+  $ hg ci -mtest
+  committing subrepository sub/repo
+  $ echo test >> sub/repo/foo
+  $ hg ci -mtest
+  committing subrepository sub/repo
+  $ cd ..
+
+Create repo without default path, pull top repo, and see what happens on update
+
+  $ hg init issue1852b
+  $ hg -R issue1852b pull issue1852a
+  pulling from issue1852a
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 3 changes to 2 files
+  (run 'hg update' to get a working copy)
+  $ hg -R issue1852b update
+  abort: default path for subrepository sub/repo not found
+  [255]
+
+Pull -u now doesn't help
+
+  $ hg -R issue1852b pull -u issue1852a
+  pulling from issue1852a
+  searching for changes
+  no changes found
+
+Try the same, but with pull -u
+
+  $ hg init issue1852c
+  $ hg -R issue1852c pull -r0 -u issue1852a
+  pulling from issue1852a
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 2 changes to 2 files
+  abort: default path for subrepository sub/repo not found
+  [255]
+
+Try to push from the other side
+
+  $ hg -R issue1852a push issue1852c
+  pushing to issue1852c
+  abort: default path for subrepository sub/repo not found
+  [255]