[PATCH] rebase: turn rebase revs into set before filtering obsolete
Jun Wu
quark at fb.com
Tue Jul 19 08:24:37 EDT 2016
LGTM. Thanks for the detailed explanation.
Excerpts from Simon Farnsworth's message of 2016-07-19 03:39:43 -0700:
> # HG changeset patch
> # User Simon Farnsworth <simonfar at fb.com>
> # Date 1468924193 25200
> # Tue Jul 19 03:29:53 2016 -0700
> # Branch stable
> # Node ID 39ca6ff7183e4a42fea832e0fedfe65de9b70ffa
> # Parent 02a8fea4289b51992b2495a06d4b12cbda876cf1
> rebase: turn rebase revs into set before filtering obsolete
>
> When the inhibit extension from mutable-history is enabled, it attempts to
> iterate over the rebaseset to prevent the nodes being rebased from being
> marked obsolete. This happens at the same time as rebase's
> _filterobsoleterevs function trying to iterate over the rebaseset to figure
> out which ones are obsolete. The two of these iterating over the same
> revset generatorset cause a 'generator already executing' exception. This is
> probably a flaw in the revset implementation, since iterating over the same
> set twice should be supported.
>
> This regression was introduced in 5d16ebe7b14, since it changed
> _filterobsoleterevs to be called before the rebaseset was turned into a
> set(). For now let’s just make the rebaseset an actual set again before
> calling that function. This was caught by the inhibit tests.
>
> The relevant call stack from test-inhibit.t:
>
> File "/tmp/hgtests.jgjrN5/install/lib/python/hgext/rebase.py", line 285, in _preparenewrebase
> obsrevs = _filterobsoleterevs(self.repo, rebaseset)
> File "/data/hgbuild/facebook-hg-rpms/mutable-history/hgext/inhibit.py", line 197, in _filterobsoleterevswrap
> r = orig(repo, rebasesetrevs, *args, **kwargs)
> File "/tmp/hgtests.jgjrN5/install/lib/python/hgext/rebase.py", line 1380, in _filterobsoleterevs
> return set(r for r in revs if repo[r].obsolete())
> File "/tmp/hgtests.jgjrN5/install/lib/python/hgext/rebase.py", line 1380, in <genexpr>
> return set(r for r in revs if repo[r].obsolete())
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/revset.py", line 3079, in _iterordered
> val2 = next(iter2)
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/revset.py", line 3417, in gen
> yield nextrev()
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/revset.py", line 3424, in _consumegen
> for item in self._gen:
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/revset.py", line 71, in iterate
> cl = repo.changelog
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/repoview.py", line 319, in changelog
> revs = filterrevs(unfi, self.filtername)
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/repoview.py", line 261, in filterrevs
> repo.filteredrevcache[filtername] = func(repo.unfiltered())
> File "/data/hgbuild/facebook-hg-rpms/mutable-history/hgext/directaccess.py", line 65, in _computehidden
> hidden = repoview.filterrevs(repo, 'visible')
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/repoview.py", line 261, in filterrevs
> repo.filteredrevcache[filtername] = func(repo.unfiltered())
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/repoview.py", line 175, in computehidden
> hideable = hideablerevs(repo)
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/repoview.py", line 33, in hideablerevs
> return obsolete.getrevs(repo, 'obsolete')
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/obsolete.py", line 1097, in getrevs
> repo.obsstore.caches[name] = cachefuncs[name](repo)
> File "/data/hgbuild/facebook-hg-rpms/mutable-history/hgext/inhibit.py", line 255, in _computeobsoleteset
> if getrev(n) not in blacklist:
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/revset.py", line 3264, in __contains__
> return x in self._r1 or x in self._r2
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/revset.py", line 3348, in __contains__
> for l in self._consumegen():
> File "/tmp/hgtests.jgjrN5/install/lib/python/mercurial/revset.py", line 3424, in _consumegen
> for item in self._gen:
> ValueError: generator already executing
>
> diff --git a/hgext/rebase.py b/hgext/rebase.py
> --- a/hgext/rebase.py
> +++ b/hgext/rebase.py
> @@ -281,7 +281,7 @@
> " unrebased descendants"),
> hint=_('use --keep to keep original changesets'))
>
> - obsrevs = _filterobsoleterevs(self.repo, rebaseset)
> + obsrevs = _filterobsoleterevs(self.repo, set(rebaseset))
> self._handleskippingobsolete(rebaseset, obsrevs, dest)
>
> result = buildstate(self.repo, dest, rebaseset, self.collapsef,
More information about the Mercurial-devel
mailing list