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.
--- 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" - -