[PATCH STABLE] changegroup: fix pulling to treemanifest repo from flat repo (issue5066)

Martin von Zweigbergk martinvonz at google.com
Thu Jan 28 14:00:54 CST 2016


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

On Thu, Jan 28, 2016, 10:51 Martin von Zweigbergk <martinvonz at google.com>
wrote:

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


More information about the Mercurial-devel mailing list