Skip to content
Snippets Groups Projects
  • Simon Farnsworth's avatar
    754f63671229
    rebase: turn rebase revs into set before filtering obsolete · 754f63671229
    Simon Farnsworth authored
    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 5d16ebe7b14f, 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
    754f63671229
    History
    rebase: turn rebase revs into set before filtering obsolete
    Simon Farnsworth authored
    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 5d16ebe7b14f, 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
rebase.py 56.88 KiB