protocol: use changegroupsubset() if possible (issue1389)
authorBenoit Boissinot <benoit.boissinot@ens-lyon.org>
Tue, 25 Nov 2008 23:26:33 +0100
changeset 7415 6163ef936a00
parent 7414 040484030491
child 7416 196b05a548d0
child 7417 d3f1d316b72b
protocol: use changegroupsubset() if possible (issue1389) Due to the fix to the pull race, to avoid sending unnecessary changesets, use changegroupsubset if possible. This will increase the load on the server.
hgext/transplant.py
mercurial/commands.py
mercurial/localrepo.py
tests/test-fetch.out
tests/test-http-proxy.out
--- a/hgext/transplant.py	Tue Nov 25 16:24:22 2008 -0600
+++ b/hgext/transplant.py	Tue Nov 25 23:26:33 2008 +0100
@@ -461,13 +461,16 @@
     def getremotechanges(repo, url):
         sourcerepo = ui.expandpath(url)
         source = hg.repository(ui, sourcerepo)
-        incoming = repo.findincoming(source, force=True)
+        common, incoming, rheads = repo.findcommonincoming(source, force=True)
         if not incoming:
             return (source, None, None)
 
         bundle = None
         if not source.local():
-            cg = source.changegroup(incoming, 'incoming')
+            if source.capable('changegroupsubset'):
+                cg = source.changegroupsubset(incoming, rheads, 'incoming')
+            else:
+                cg = source.changegroup(incoming, 'incoming')
             bundle = changegroup.writebundle(cg, None, 'HG10UN')
             source = bundlerepo.bundlerepository(ui, repo.root, bundle)
 
--- a/mercurial/commands.py	Tue Nov 25 16:24:22 2008 -0600
+++ b/mercurial/commands.py	Tue Nov 25 23:26:33 2008 +0100
@@ -1700,7 +1700,8 @@
     ui.status(_('comparing with %s\n') % url.hidepassword(source))
     if revs:
         revs = [other.lookup(rev) for rev in revs]
-    incoming = repo.findincoming(other, heads=revs, force=opts["force"])
+    common, incoming, rheads = repo.findcommonincoming(other, heads=revs,
+                                                       force=opts["force"])
     if not incoming:
         try:
             os.unlink(opts["bundle"])
@@ -1714,6 +1715,10 @@
         fname = opts["bundle"]
         if fname or not other.local():
             # create a bundle (uncompressed if other repo is not local)
+
+            if revs is None and other.capable('changegroupsubset'):
+                revs = rheads
+
             if revs is None:
                 cg = other.changegroup(incoming, "incoming")
             else:
--- a/mercurial/localrepo.py	Tue Nov 25 16:24:22 2008 -0600
+++ b/mercurial/localrepo.py	Tue Nov 25 23:26:33 2008 +0100
@@ -1266,6 +1266,22 @@
         (and so we know that the rest of the nodes are missing in remote, see
         outgoing)
         """
+        return self.findcommonincoming(remote, base, heads, force)[1]
+
+    def findcommonincoming(self, remote, base=None, heads=None, force=False):
+        """Return a tuple (common, missing roots, heads) used to identify
+        missing nodes from remote.
+
+        If base dict is specified, assume that these nodes and their parents
+        exist on the remote side and that no child of a node of base exists
+        in both remote and self.
+        Furthermore base will be updated to include the nodes that exists
+        in self and remote but no children exists in self and remote.
+        If a list of heads is specified, return only nodes which are heads
+        or ancestors of these heads.
+
+        All the ancestors of base are in self and in remote.
+        """
         m = self.changelog.nodemap
         search = []
         fetch = {}
@@ -1280,8 +1296,8 @@
         if self.changelog.tip() == nullid:
             base[nullid] = 1
             if heads != [nullid]:
-                return [nullid]
-            return []
+                return [nullid], [nullid], list(heads)
+            return [nullid], [], []
 
         # assume we're closer to the tip than the root
         # and start by examining the heads
@@ -1294,8 +1310,9 @@
             else:
                 base[h] = 1
 
+        heads = unknown
         if not unknown:
-            return []
+            return base.keys(), [], []
 
         req = dict.fromkeys(unknown)
         reqcnt = 0
@@ -1390,7 +1407,7 @@
 
         self.ui.debug(_("%d total queries\n") % reqcnt)
 
-        return fetch.keys()
+        return base.keys(), fetch.keys(), heads
 
     def findoutgoing(self, remote, base=None, heads=None, force=False):
         """Return list of nodes that are roots of subsets not in remote
@@ -1443,7 +1460,8 @@
     def pull(self, remote, heads=None, force=False):
         lock = self.lock()
         try:
-            fetch = self.findincoming(remote, heads=heads, force=force)
+            common, fetch, rheads = self.findcommonincoming(remote, heads=heads,
+                                                            force=force)
             if fetch == [nullid]:
                 self.ui.status(_("requesting all changes\n"))
 
@@ -1451,10 +1469,13 @@
                 self.ui.status(_("no changes found\n"))
                 return 0
 
+            if heads is None and remote.capable('changegroupsubset'):
+                heads = rheads
+
             if heads is None:
                 cg = remote.changegroup(fetch, 'pull')
             else:
-                if 'changegroupsubset' not in remote.capabilities:
+                if not remote.capable('changegroupsubset'):
                     raise util.Abort(_("Partial pull cannot be done because other repository doesn't support changegroupsubset."))
                 cg = remote.changegroupsubset(fetch, heads, 'pull')
             return self.addchangegroup(cg, 'pull', remote.url())
--- a/tests/test-fetch.out	Tue Nov 25 16:24:22 2008 -0600
+++ b/tests/test-fetch.out	Tue Nov 25 23:26:33 2008 +0100
@@ -100,7 +100,7 @@
 adding changesets
 adding manifests
 adding file changes
-added 1 changesets with 1 changes to 2 files
+added 1 changesets with 1 changes to 1 files
 % parent should be 2 (no automatic update)
 2
 
--- a/tests/test-http-proxy.out	Tue Nov 25 16:24:22 2008 -0600
+++ b/tests/test-http-proxy.out	Tue Nov 25 23:26:33 2008 +0100
@@ -62,13 +62,17 @@
 XXX "GET http://localhost:/?cmd=stream_out HTTP/1.1" - -
 XXX "GET http://localhost:/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - -
 XXX "GET http://localhost:/?cmd=heads HTTP/1.1" - -
-XXX "GET http://localhost:/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - -
+XXX "GET http://localhost:/?cmd=capabilities HTTP/1.1" - -
+XXX "GET http://localhost:/?bases=0000000000000000000000000000000000000000&cmd=changegroupsubset&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - -
 XXX "GET http://localhost:/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - -
 XXX "GET http://localhost:/?cmd=heads HTTP/1.1" - -
-XXX "GET http://localhost:/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - -
+XXX "GET http://localhost:/?cmd=capabilities HTTP/1.1" - -
+XXX "GET http://localhost:/?bases=0000000000000000000000000000000000000000&cmd=changegroupsubset&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - -
 XXX "GET http://localhost:/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - -
 XXX "GET http://localhost:/?cmd=heads HTTP/1.1" - -
-XXX "GET http://localhost:/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - -
+XXX "GET http://localhost:/?cmd=capabilities HTTP/1.1" - -
+XXX "GET http://localhost:/?bases=0000000000000000000000000000000000000000&cmd=changegroupsubset&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - -
 XXX "GET http://localhost:/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - -
 XXX "GET http://localhost:/?cmd=heads HTTP/1.1" - -
-XXX "GET http://localhost:/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - -
+XXX "GET http://localhost:/?cmd=capabilities HTTP/1.1" - -
+XXX "GET http://localhost:/?bases=0000000000000000000000000000000000000000&cmd=changegroupsubset&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - -