[PATCH 1 of 4 STABLE] changegroup: don't support versions 01 and 02 with treemanifests

Martin von Zweigbergk martinvonz at google.com
Thu Jan 21 04:42:43 UTC 2016


# HG changeset patch
# User Martin von Zweigbergk <martinvonz at google.com>
# Date 1453242438 28800
#      Tue Jan 19 14:27:18 2016 -0800
# Branch stable
# Node ID 22ca2d9f75057441e0b33aa25731f6fb876dc0fe
# Parent  158bdc8965720ca4061f8f8d806563cfc7cdb62e
changegroup: don't support versions 01 and 02 with treemanifests

Since it would be terribly expensive to convert between flat manifests
and treemanifests, we have decided to simply not support changegroup
version 01 and 02 with treemanifests. Therefore, let's stop announcing
that we support these versions on treemanifest repos.

Note that this means that older clients that try to clone from a
treemanifest repo will fail. What happens is that the server, after
this patch, finds that there are no common versions and raises
"ValueError: no common changegroup version". This results in "abort:
HTTP Error 500: Internal Server Error" on the client.

Before this patch, it was no better: The server would instead find
that there were directory manifest nodes to put in the changegroup 01
or 02 and raise an AssertionError on changegroup.py#668 (assert not
tmfnodes), which would also appear as a 500 to the client.

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -947,12 +947,18 @@
 }
 
 def supportedversions(repo):
-    versions = _packermap.keys()
-    cg3 = ('treemanifest' in repo.requirements or
-           repo.ui.configbool('experimental', 'changegroup3') or
-           repo.ui.configbool('experimental', 'treemanifest'))
-    if not cg3:
-        versions.remove('03')
+    versions = set(_packermap.keys())
+    if ('treemanifest' in repo.requirements or
+        repo.ui.configbool('experimental', 'treemanifest')):
+        # Versions 01 and 02 support only flat manifests and it's just too
+        # expensive to convert between the flat manifest and tree manifest on
+        # the fly. Since tree manifests are hashed differently, all of history
+        # would have to be converted. Instead, we simply don't even pretend to
+        # support versions 01 and 02.
+        versions.discard('01')
+        versions.discard('02')
+    elif not repo.ui.configbool('experimental', 'changegroup3'):
+        versions.discard('03')
     return versions
 
 def getbundler(version, repo, bundlecaps=None):


More information about the Mercurial-devel mailing list