##// END OF EJS Templates
phases: avoid N² behavior in `advanceboundary`...
phases: avoid N² behavior in `advanceboundary` We allowed duplicated entries in the deque, which each entry could potentially insert all its ancestors. So advancing boundary for the full repository would mean each revision would walk all its ancestors, resulting in O(N²) iteration. For repository of any decent size, N² is quickly insane. We introduce a simple set to avoid this and get back to reasonable performance.

File last commit:

r49730:6000f5b2 default
r52398:c9ceb4f6 6.7 stable
Show More
reject_new_heads.py
40 lines | 1.2 KiB | text/x-python | PythonLexer
/ hgext / hooklib / reject_new_heads.py
Joerg Sonnenberger
hgext: start building a library for simple hooks...
r44897 # Copyright 2020 Joerg Sonnenberger <joerg@bec.de>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
"""reject_new_heads is a hook to check that branches touched by new changesets
have at most one open head. It can be used to enforce policies for
merge-before-push or rebase-before-push. It does not handle pre-existing
hydras.
Usage:
[hooks]
pretxnclose.reject_new_heads = \
python:hgext.hooklib.reject_new_heads.hook
"""
from mercurial.i18n import _
from mercurial import (
error,
pycompat,
)
def hook(ui, repo, hooktype, node=None, **kwargs):
if hooktype != b"pretxnclose":
raise error.Abort(
_(b'Unsupported hook type %r') % pycompat.bytestr(hooktype)
)
ctx = repo.unfiltered()[node]
branches = set()
for rev in repo.changelog.revs(start=ctx.rev()):
rev = repo[rev]
branches.add(rev.branch())
for branch in branches:
if len(repo.revs("head() and not closed() and branch(%s)", branch)) > 1:
raise error.Abort(
_(b'Changes on branch %r resulted in multiple heads')
% pycompat.bytestr(branch)
)