diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -167,26 +167,33 @@ def subrelpath(sub): 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 @@ class hgsubrepo(abstractsubrepo): 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) diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -585,3 +585,64 @@ Issue1977: multirepo push should fail if $ 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]