<p dir="ltr">I realized I should also make sure that pushing from flat to tree works. Will add tests (and fixes if necessary) and resend after lunch</p>
<br><div class="gmail_quote"><div dir="ltr">On Thu, Jan 28, 2016, 10:51 Martin von Zweigbergk <<a href="mailto:martinvonz@google.com">martinvonz@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Martin von Zweigbergk <<a href="mailto:martinvonz@google.com" target="_blank">martinvonz@google.com</a>><br>
# Date 1453914448 28800<br>
# Wed Jan 27 09:07:28 2016 -0800<br>
# Branch stable<br>
# Node ID 798557f9b388175637a61a35503e3bc528ccf894<br>
# Parent 4511e8dac4c798e5fed91e629aa9802b01c2b6c3<br>
changegroup: fix pulling to treemanifest repo from flat repo (issue5066)<br>
<br>
In c0f11347b107 (changegroup: don't support versions 01 and 02 with<br>
treemanifests, 2016-01-19), I stopped supporting use of cg1 and cg2<br>
with treemanifest repos. What I had not considered was that it's<br>
perfectly safe to pull *to* a treemanifest repo using any changegroup<br>
version. As reported in issue5066, I therefore broke pull from old<br>
repos into a treemanifest repo. It was not covered by the test case,<br>
because that pulled from a local repo while enabling treemanifests,<br>
which enabled treemanifests on the source repo as well. After<br>
switching to pulling via HTTP, it breaks.<br>
<br>
Fix by splitting up changegroup.supportedversions() into<br>
supportedincomingversions() and supportedoutgoingversions().<br>
<br>
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py<br>
--- a/mercurial/bundle2.py<br>
+++ b/mercurial/bundle2.py<br>
@@ -1242,7 +1242,8 @@<br>
Exists to allow extensions (like evolution) to mutate the capabilities.<br>
"""<br>
caps = capabilities.copy()<br>
- caps['changegroup'] = tuple(sorted(changegroup.supportedversions(repo)))<br>
+ caps['changegroup'] = tuple(sorted(<br>
+ changegroup.supportedincomingversions(repo)))<br>
if obsolete.isenabled(repo, obsolete.exchangeopt):<br>
supportedformat = tuple('V%i' % v for v in obsolete.formats)<br>
caps['obsmarkers'] = supportedformat<br>
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py<br>
--- a/mercurial/bundlerepo.py<br>
+++ b/mercurial/bundlerepo.py<br>
@@ -282,7 +282,7 @@<br>
"multiple changegroups")<br>
cgstream = part<br>
version = part.params.get('version', '01')<br>
- if version not in changegroup.supportedversions(self):<br>
+ if version not in changegroup.allsupportedversions(ui):<br>
msg = _('Unsupported changegroup version: %s')<br>
raise error.Abort(msg % version)<br>
if self.bundle.compressed():<br>
diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py<br>
--- a/mercurial/changegroup.py<br>
+++ b/mercurial/changegroup.py<br>
@@ -946,10 +946,25 @@<br>
'03': (cg3packer, cg3unpacker),<br>
}<br>
<br>
-def supportedversions(repo):<br>
+def allsupportedversions(ui):<br>
versions = set(_packermap.keys())<br>
- if ('treemanifest' in repo.requirements or<br>
- repo.ui.configbool('experimental', 'treemanifest')):<br>
+ versions.discard('03')<br>
+ if (ui.configbool('experimental', 'changegroup3') or<br>
+ ui.configbool('experimental', 'treemanifest')):<br>
+ versions.add('03')<br>
+ return versions<br>
+<br>
+# Changegroup versions that can be applied to the repo<br>
+def supportedincomingversions(repo):<br>
+ versions = allsupportedversions(repo.ui)<br>
+ if 'treemanifest' in repo.requirements:<br>
+ versions.add('03')<br>
+ return versions<br>
+<br>
+# Changegroup versions that can be created from the repo<br>
+def supportedoutgoingversions(repo):<br>
+ versions = allsupportedversions(repo.ui)<br>
+ if 'treemanifest' in repo.requirements:<br>
# Versions 01 and 02 support only flat manifests and it's just too<br>
# expensive to convert between the flat manifest and tree manifest on<br>
# the fly. Since tree manifests are hashed differently, all of history<br>
@@ -957,22 +972,21 @@<br>
# support versions 01 and 02.<br>
versions.discard('01')<br>
versions.discard('02')<br>
- elif not repo.ui.configbool('experimental', 'changegroup3'):<br>
- versions.discard('03')<br>
+ versions.add('03')<br>
return versions<br>
<br>
def safeversion(repo):<br>
# Finds the smallest version that it's safe to assume clients of the repo<br>
# will support. For example, all hg versions that support generaldelta also<br>
# support changegroup 02.<br>
- versions = supportedversions(repo)<br>
+ versions = supportedoutgoingversions(repo)<br>
if 'generaldelta' in repo.requirements:<br>
versions.discard('01')<br>
assert versions<br>
return min(versions)<br>
<br>
def getbundler(version, repo, bundlecaps=None):<br>
- assert version in supportedversions(repo)<br>
+ assert version in supportedoutgoingversions(repo)<br>
return _packermap[version][0](repo, bundlecaps)<br>
<br>
def getunbundler(version, fh, alg):<br>
diff --git a/mercurial/exchange.py b/mercurial/exchange.py<br>
--- a/mercurial/exchange.py<br>
+++ b/mercurial/exchange.py<br>
@@ -707,7 +707,8 @@<br>
pushop.outgoing)<br>
else:<br>
cgversions = [v for v in cgversions<br>
- if v in changegroup.supportedversions(pushop.repo)]<br>
+ if v in changegroup.supportedoutgoingversions(<br>
+ pushop.repo)]<br>
if not cgversions:<br>
raise ValueError(_('no common changegroup version'))<br>
version = max(cgversions)<br>
@@ -1562,7 +1563,7 @@<br>
getcgkwargs = {}<br>
if cgversions: # 3.1 and 3.2 ship with an empty value<br>
cgversions = [v for v in cgversions<br>
- if v in changegroup.supportedversions(repo)]<br>
+ if v in changegroup.supportedoutgoingversions(repo)]<br>
if not cgversions:<br>
raise ValueError(_('no common changegroup version'))<br>
version = getcgkwargs['version'] = max(cgversions)<br>
diff --git a/tests/test-treemanifest.t b/tests/test-treemanifest.t<br>
--- a/tests/test-treemanifest.t<br>
+++ b/tests/test-treemanifest.t<br>
@@ -202,11 +202,14 @@<br>
3 files updated, 0 files merged, 0 files removed, 0 files unresolved<br>
(branch merge, don't forget to commit)<br>
$ hg ci -m 'merge of flat manifests to new flat manifest'<br>
+ $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log<br>
+ $ cat hg.pid >> $DAEMON_PIDS<br>
<br>
Create clone with tree manifests enabled<br>
<br>
$ cd ..<br>
- $ hg clone --pull --config experimental.treemanifest=1 repo-flat repo-mixed<br>
+ $ hg clone --config experimental.treemanifest=1 \<br>
+ > http://localhost:$HGPORT repo-mixed<br>
requesting all changes<br>
adding changesets<br>
adding manifests<br>
@@ -441,13 +444,13 @@<br>
$ hg ci -m troz<br>
<br>
Test cloning a treemanifest repo over http.<br>
- $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log<br>
+ $ hg serve -p $HGPORT2 -d --pid-file=hg.pid --errorlog=errors.log<br>
$ cat hg.pid >> $DAEMON_PIDS<br>
$ cd ..<br>
We can clone even with the knob turned off and we'll get a treemanifest repo.<br>
$ hg clone --config experimental.treemanifest=False \<br>
> --config experimental.changegroup3=True \<br>
- > http://localhost:$HGPORT deepclone<br>
+ > http://localhost:$HGPORT2 deepclone<br>
requesting all changes<br>
adding changesets<br>
adding manifests<br>
_______________________________________________<br>
Mercurial-devel mailing list<br>
<a href="mailto:Mercurial-devel@selenic.com" target="_blank">Mercurial-devel@selenic.com</a><br>
<a href="https://selenic.com/mailman/listinfo/mercurial-devel" rel="noreferrer" target="_blank">https://selenic.com/mailman/listinfo/mercurial-devel</a><br>
</blockquote></div>