[PATCH 1 of 6 V2] peer: introduce peer methods to prepare for peer classes

Sune Foldager cryo at cyanite.org
Fri Jul 13 15:12:43 CDT 2012


# HG changeset patch
# User Sune Foldager <cryo at cyanite.org>
# Date 1342208813 -7200
# Node ID 93dab38d13c19badf4dbaf332743f109144877a2
# Parent  3ac9592b7ab432e1470ec97d19c9b7c58c3fda86
peer: introduce peer methods to prepare for peer classes

This introduces a peer method into all repository classes, which currently
simply returns self. It also changes hg.repository so it now raises an
exception if the supplied paths does not resolve to a localrepo or descendant.

Finally, all call sites are changed to use the peer and local methods as
appropriate, where peer is used whenever the code is dealing with a remote
repository (even if it's on local disk).

diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -412,7 +412,7 @@
         ui.status(_('comparing with %s\n') % util.hidepassword(dest))
 
         revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
-        other = hg.repository(hg.remoteui(repo, opts), dest)
+        other = hg.peer(repo, opts, dest)
 
         if revs:
             revs = [repo.lookup(rev) for rev in revs]
diff --git a/hgext/largefiles/localstore.py b/hgext/largefiles/localstore.py
--- a/hgext/largefiles/localstore.py
+++ b/hgext/largefiles/localstore.py
@@ -22,9 +22,9 @@
     the user cache.'''
 
     def __init__(self, ui, repo, remote):
-        url = os.path.join(remote.path, '.hg', lfutil.longname)
+        url = os.path.join(remote.local().path, '.hg', lfutil.longname)
         super(localstore, self).__init__(ui, repo, util.expandpath(url))
-        self.remote = remote
+        self.remote = remote.local()
 
     def put(self, source, hash):
         util.makedirs(os.path.dirname(lfutil.storepath(self.remote, hash)))
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -722,7 +722,7 @@
         return True
     if opts.get('all_largefiles'):
         sourcerepo, destrepo = result
-        success, missing = lfcommands.downloadlfiles(ui, destrepo, None)
+        success, missing = lfcommands.downloadlfiles(ui, destrepo.local(), None)
         return missing != 0
     return result is None
 
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -2228,7 +2228,7 @@
     # main repo (destination and sources)
     if dest is None:
         dest = hg.defaultdest(source)
-    sr = hg.repository(hg.remoteui(ui, opts), ui.expandpath(source))
+    sr = hg.peer(ui, opts, ui.expandpath(source))
 
     # patches repo (source only)
     if opts.get('patches'):
@@ -2236,18 +2236,19 @@
     else:
         patchespath = patchdir(sr)
     try:
-        hg.repository(ui, patchespath)
+        hg.peer(ui, opts, patchespath)
     except error.RepoError:
         raise util.Abort(_('versioned patch repository not found'
                            ' (see init --mq)'))
     qbase, destrev = None, None
     if sr.local():
-        if sr.mq.applied and sr[qbase].phase() != phases.secret:
-            qbase = sr.mq.applied[0].node
+        repo = sr.local()
+        if repo.mq.applied and repo[qbase].phase() != phases.secret:
+            qbase = repo.mq.applied[0].node
             if not hg.islocal(dest):
-                heads = set(sr.heads())
-                destrev = list(heads.difference(sr.heads(qbase)))
-                destrev.append(sr.changelog.parents(qbase)[0])
+                heads = set(repo.heads())
+                destrev = list(heads.difference(repo.heads(qbase)))
+                destrev.append(repo.changelog.parents(qbase)[0])
     elif sr.capable('lookup'):
         try:
             qbase = sr.lookup('qbase')
@@ -2267,13 +2268,14 @@
              stream=opts.get('uncompressed'))
 
     if dr.local():
+        repo = dr.local()
         if qbase:
             ui.note(_('stripping applied patches from destination '
                       'repository\n'))
-            dr.mq.strip(dr, [qbase], update=False, backup=None)
+            repo.mq.strip(repo, [qbase], update=False, backup=None)
         if not opts.get('noupdate'):
             ui.note(_('updating destination repository\n'))
-            hg.update(dr, dr.changelog.tip())
+            hg.update(repo, repo.changelog.tip())
 
 @command("qcommit|qci",
          commands.table["^commit|ci"][1],
diff --git a/hgext/relink.py b/hgext/relink.py
--- a/hgext/relink.py
+++ b/hgext/relink.py
@@ -43,8 +43,6 @@
         raise util.Abort(_('hardlinks are not supported on this system'))
     src = hg.repository(ui, ui.expandpath(origin or 'default-relink',
                                           origin or 'default'))
-    if not src.local():
-        raise util.Abort(_('must specify local origin repository'))
     ui.status(_('relinking %s to %s\n') % (src.store.path, repo.store.path))
     if repo.root == src.root:
         ui.status(_('there is nothing to relink\n'))
diff --git a/hgext/transplant.py b/hgext/transplant.py
--- a/hgext/transplant.py
+++ b/hgext/transplant.py
@@ -139,7 +139,7 @@
                         continue
                     if pulls:
                         if source != repo:
-                            repo.pull(source, heads=pulls)
+                            repo.pull(source.peer(), heads=pulls)
                         merge.update(repo, pulls[-1], False, False, None)
                         p1, p2 = repo.dirstate.parents()
                         pulls = []
@@ -203,7 +203,7 @@
                             os.unlink(patchfile)
             tr.close()
             if pulls:
-                repo.pull(source, heads=pulls)
+                repo.pull(source.peer(), heads=pulls)
                 merge.update(repo, pulls[-1], False, False, None)
         finally:
             self.saveseries(revmap, merges)
@@ -614,9 +614,9 @@
 
     sourcerepo = opts.get('source')
     if sourcerepo:
-        source = hg.peer(ui, opts, ui.expandpath(sourcerepo))
-        branches = map(source.lookup, opts.get('branch', ()))
-        source, csets, cleanupfn = bundlerepo.getremotechanges(ui, repo, source,
+        peer = hg.peer(ui, opts, ui.expandpath(sourcerepo))
+        branches = map(peer.lookup, opts.get('branch', ()))
+        source, csets, cleanupfn = bundlerepo.getremotechanges(ui, repo, peer,
                                     onlyheads=branches, force=True)
     else:
         source = repo
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -344,8 +344,8 @@
 
     bundle = None
     bundlerepo = None
-    localrepo = other
-    if bundlename or not other.local():
+    localrepo = other.local()
+    if bundlename or not localrepo:
         # create a bundle (uncompressed if other repo is not local)
 
         if other.capable('getbundle'):
@@ -356,12 +356,12 @@
             rheads = None
         else:
             cg = other.changegroupsubset(incoming, rheads, 'incoming')
-        bundletype = other.local() and "HG10BZ" or "HG10UN"
+        bundletype = localrepo and "HG10BZ" or "HG10UN"
         fname = bundle = changegroup.writebundle(cg, bundlename, bundletype)
         # keep written bundle?
         if bundlename:
             bundle = None
-        if not other.local():
+        if not localrepo:
             # use the created uncompressed bundlerepo
             localrepo = bundlerepo = bundlerepository(ui, repo.root, fname)
             # this repo contains local and other now, so filter out local again
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1783,7 +1783,7 @@
     # make sure tests are repeatable
     random.seed(12323)
 
-    def doit(localheads, remoteheads):
+    def doit(localheads, remoteheads, remote=remote):
         if opts.get('old'):
             if localheads:
                 raise util.Abort('cannot use localheads with old style '
@@ -3456,10 +3456,11 @@
 
     if source:
         source, branches = hg.parseurl(ui.expandpath(source))
-        repo = hg.peer(ui, opts, source)
-        revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
-
-    if not repo.local():
+        peer = hg.peer(ui, opts, source)
+        repo = peer.local()
+        revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
+
+    if not repo:
         if num or branch or tags:
             raise util.Abort(
                 _("can't query remote revision number, branch, or tags"))
@@ -3468,16 +3469,16 @@
         if not rev:
             rev = "tip"
 
-        remoterev = repo.lookup(rev)
+        remoterev = peer.lookup(rev)
         if default or id:
             output = [hexfunc(remoterev)]
 
         def getbms():
             bms = []
 
-            if 'bookmarks' in repo.listkeys('namespaces'):
+            if 'bookmarks' in peer.listkeys('namespaces'):
                 hexremoterev = hex(remoterev)
-                bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
+                bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
                        if bmr == hexremoterev]
 
             return bms
diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -169,7 +169,7 @@
 
         # 2. Check for new branches on the remote.
         if remote.local():
-            remotemap = phases.visiblebranchmap(remote)
+            remotemap = phases.visiblebranchmap(remote.local())
         else:
             remotemap = remote.branchmap()
         newbranches = branches - set(remotemap)
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -20,21 +20,22 @@
     path = util.expandpath(util.urllocalpath(path))
     return (os.path.isfile(path) and bundlerepo or localrepo)
 
-def addbranchrevs(lrepo, repo, branches, revs):
+def addbranchrevs(lrepo, other, branches, revs):
+    peer = other.peer() # a courtesy to callers using a localrepo for other
     hashbranch, branches = branches
     if not hashbranch and not branches:
         return revs or None, revs and revs[0] or None
     revs = revs and list(revs) or []
-    if not repo.capable('branchmap'):
+    if not peer.capable('branchmap'):
         if branches:
             raise util.Abort(_("remote branch lookup not supported"))
         revs.append(hashbranch)
         return revs, revs[0]
-    branchmap = repo.branchmap()
+    branchmap = peer.branchmap()
 
     def primary(branch):
         if branch == '.':
-            if not lrepo or not lrepo.local():
+            if not lrepo:
                 raise util.Abort(_("dirstate branch not accessible"))
             branch = lrepo.dirstate.branch()
         if branch in branchmap:
@@ -88,20 +89,29 @@
             return False
     return repo.local()
 
-def repository(ui, path='', create=False):
+def _peerorrepo(ui, path, create=False):
     """return a repository object for the specified path"""
-    repo = _peerlookup(path).instance(ui, path, create)
-    ui = getattr(repo, "ui", ui)
+    obj = _peerlookup(path).instance(ui, path, create)
+    ui = getattr(obj, "ui", ui)
     for name, module in extensions.extensions():
         hook = getattr(module, 'reposetup', None)
         if hook:
-            hook(ui, repo)
+            hook(ui, obj)
+    return obj
+
+def repository(ui, path='', create=False):
+    """return a repository object for the specified path"""
+    peer = _peerorrepo(ui, path, create)
+    repo = peer.local()
+    if not repo:
+        raise util.Abort(_("repository '%s' is not local") %
+                         (path or peer.url()))
     return repo
 
 def peer(uiorrepo, opts, path, create=False):
     '''return a repository peer for the specified path'''
     rui = remoteui(uiorrepo, opts)
-    return repository(rui, path, create)
+    return _peerorrepo(rui, path, create).peer()
 
 def defaultdest(source):
     '''return default destination of clone if none is given'''
@@ -124,7 +134,7 @@
         srcrepo = repository(ui, source)
         rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
     else:
-        srcrepo = source
+        srcrepo = source.local()
         origsource = source = srcrepo.url()
         checkout = None
 
@@ -213,7 +223,7 @@
 
     Create a copy of an existing repository in a new directory.  The
     source and destination are URLs, as passed to the repository
-    function.  Returns a pair of repository objects, the source and
+    function.  Returns a pair of repository peers, the source and
     newly created destination.
 
     The location of the source is added to the new repository's
@@ -247,12 +257,12 @@
     if isinstance(source, str):
         origsource = ui.expandpath(source)
         source, branch = parseurl(origsource, branch)
-        srcrepo = repository(remoteui(ui, peeropts), source)
+        srcpeer = peer(ui, peeropts, source)
     else:
-        srcrepo = source
+        srcpeer = source.peer() # in case we were called with a localrepo
         branch = (None, branch or [])
-        origsource = source = srcrepo.url()
-    rev, checkout = addbranchrevs(srcrepo, srcrepo, branch, rev)
+        origsource = source = srcpeer.url()
+    rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
 
     if dest is None:
         dest = defaultdest(source)
@@ -280,6 +290,7 @@
                 self.rmtree(self.dir_, True)
 
     srclock = destlock = dircleanup = None
+    srcrepo = srcpeer.local()
     try:
         abspath = origsource
         if islocal(origsource):
@@ -289,7 +300,7 @@
             dircleanup = DirCleanup(dest)
 
         copy = False
-        if srcrepo.cancopy() and islocal(dest) and not srcrepo.revs("secret()"):
+        if srcpeer.cancopy() and islocal(dest) and not srcrepo.revs("secret()"):
             copy = not pull and not rev
 
         if copy:
@@ -324,13 +335,12 @@
 
             # we need to re-init the repo after manually copying the data
             # into it
-            destrepo = repository(remoteui(ui, peeropts), dest)
+            destpeer = peer(ui, peeropts, dest)
             srcrepo.hook('outgoing', source='clone',
                           node=node.hex(node.nullid))
         else:
             try:
-                destrepo = repository(remoteui(ui, peeropts), dest,
-                                      create=True)
+                destpeer = peer(ui, peeropts, dest, create=True)
             except OSError, inst:
                 if inst.errno == errno.EEXIST:
                     dircleanup.close()
@@ -340,16 +350,16 @@
 
             revs = None
             if rev:
-                if not srcrepo.capable('lookup'):
+                if not srcpeer.capable('lookup'):
                     raise util.Abort(_("src repository does not support "
                                        "revision lookup and so doesn't "
                                        "support clone by revision"))
-                revs = [srcrepo.lookup(r) for r in rev]
+                revs = [srcpeer.lookup(r) for r in rev]
                 checkout = revs[0]
-            if destrepo.local():
-                destrepo.clone(srcrepo, heads=revs, stream=stream)
-            elif srcrepo.local():
-                srcrepo.push(destrepo, revs=revs)
+            if destpeer.local():
+                destpeer.local().clone(srcpeer, heads=revs, stream=stream)
+            elif srcrepo:
+                srcrepo.push(destpeer, revs=revs)
             else:
                 raise util.Abort(_("clone from remote to remote not supported"))
 
@@ -357,8 +367,9 @@
             dircleanup.close()
 
         # clone all bookmarks except divergent ones
-        if destrepo.local() and srcrepo.capable("pushkey"):
-            rb = srcrepo.listkeys('bookmarks')
+        destrepo = destpeer.local()
+        if destrepo and srcpeer.capable("pushkey"):
+            rb = srcpeer.listkeys('bookmarks')
             for k, n in rb.iteritems():
                 try:
                     m = destrepo.lookup(n)
@@ -367,11 +378,11 @@
                     pass
             if rb:
                 bookmarks.write(destrepo)
-        elif srcrepo.local() and destrepo.capable("pushkey"):
+        elif srcrepo and destpeer.capable("pushkey"):
             for k, n in srcrepo._bookmarks.iteritems():
-                destrepo.pushkey('bookmarks', k, '', hex(n))
+                destpeer.pushkey('bookmarks', k, '', hex(n))
 
-        if destrepo.local():
+        if destrepo:
             fp = destrepo.opener("hgrc", "w", text=True)
             fp.write("[paths]\n")
             u = util.url(abspath)
@@ -384,9 +395,7 @@
 
             if update:
                 if update is not True:
-                    checkout = update
-                    if srcrepo.local():
-                        checkout = srcrepo.lookup(update)
+                    checkout = srcrepo.lookup(update)
                 for test in (checkout, 'default', 'tip'):
                     if test is None:
                         continue
@@ -399,13 +408,13 @@
                 destrepo.ui.status(_("updating to branch %s\n") % bn)
                 _update(destrepo, uprev)
 
-        return srcrepo, destrepo
+        return srcpeer, destpeer
     finally:
         release(srclock, destlock)
         if dircleanup is not None:
             dircleanup.cleanup()
-        if srcrepo is not None:
-            srcrepo.close()
+        if srcpeer is not None:
+            srcpeer.close()
 
 def _showstats(repo, stats):
     repo.ui.status(_("%d files updated, %d files merged, "
diff --git a/mercurial/repo.py b/mercurial/repo.py
--- a/mercurial/repo.py
+++ b/mercurial/repo.py
@@ -33,6 +33,9 @@
     def local(self):
         return False
 
+    def peer(self):
+        return self
+
     def cancopy(self):
         return self.local()
 
diff --git a/mercurial/setdiscovery.py b/mercurial/setdiscovery.py
--- a/mercurial/setdiscovery.py
+++ b/mercurial/setdiscovery.py
@@ -100,7 +100,7 @@
     sample = ownheads
     if remote.local():
         # stopgap until we have a proper localpeer that supports batch()
-        srvheadhashes = phases.visibleheads(remote)
+        srvheadhashes = phases.visibleheads(remote.local())
         yesno = remote.known(dag.externalizeall(sample))
     elif remote.capable('batch'):
         batch = remote.batch()
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -503,9 +503,10 @@
                                      % (subrelpath(self), srcurl))
                 parentrepo = self._repo._subparent
                 shutil.rmtree(self._repo.path)
-                other, self._repo = hg.clone(self._repo._subparent.ui, {},
-                                             other, self._repo.root,
-                                             update=False)
+                other, cloned = hg.clone(self._repo._subparent.ui, {},
+                                         other, self._repo.root,
+                                         update=False)
+                self._repo = cloned.local()
                 self._initrepo(parentrepo, source, create=True)
             else:
                 self._repo.ui.status(_('pulling subrepo %s from %s\n')


More information about the Mercurial-devel mailing list