Skip to content
Snippets Groups Projects

evolve: add pre-checking for content-divergence

Closed Sushil Khanchi requested to merge topic/default/PreChecking into branch/default
Files
17
@@ -22,7 +22,6 @@ from mercurial import (
node,
obsolete,
obsutil,
phases,
revset,
util,
)
@@ -77,6 +76,15 @@ def precheck(repo, revs, action=b'rewrite'):
msg %= (action, len(newunstable))
hint = _(b"see 'hg help evolution.instability'")
raise error.Abort(msg, hint=hint)
divrisk = revs_hascontentdivrisk(repo, revs)
allowdivergence = repo.ui.configbool(b'experimental',
b'evolution.allowdivergence')
if divrisk and not allowdivergence:
msg = _(b"revision being rewritten or one of its precursor was "
b"rewritten as %s, performing '%s' will create "
b"content-divergence") % (repo[divrisk[0]], action)
hint = _(b"For more, see 'hg help evolution.instability'")
raise error.Abort(msg, hint=hint)
def bookmarksupdater(repo, oldid, tr):
"""Return a callable update(newid) updating the current bookmark
@@ -89,6 +97,14 @@ def bookmarksupdater(repo, oldid, tr):
repo._bookmarks.applychanges(repo, tr, bmchanges)
return updatebookmarks
def revs_hascontentdivrisk(repo, revs):
obsrevs = repo.revs(b'%ld and obsolete()', revs)
for r in obsrevs:
div = contentdivrisk(repo, repo[r])
if div:
return div
return []
def disallowednewunstable(repo, revs):
"""Check that editing <revs> will not create disallowed unstable
@@ -106,9 +122,6 @@ def foldcheck(repo, revs):
if len(roots) > 1:
raise error.Abort(_(b"cannot fold non-linear revisions "
b"(multiple roots given)"))
root = repo[roots.first()]
if root.phase() <= phases.public:
raise error.Abort(_(b"cannot fold public revisions"))
heads = repo.revs(b'heads(%ld)', revs)
if len(heads) > 1:
raise error.Abort(_(b"cannot fold non-linear revisions "
@@ -125,6 +138,7 @@ def foldcheck(repo, revs):
hint = _(b'set experimental.evolution.allowdivergence=yes'
b' to allow folding them')
raise error.Abort(msg, hint=hint)
root = repo[roots.first()]
# root's p1 is already used as the target ctx p1
baseparents -= {root.p1().rev()}
p2 = repo[baseparents.first()]
@@ -257,10 +271,12 @@ def rewrite(repo, old, updates, head, newbases, commitopts):
lockmod.release(tr, lock, wlock)
def contentdivrisk(repo, ctx):
"""logic to check if rewriting an obsolete cset will create divergence"""
"""return divergent revision if rewriting an obsolete cset (ctx) will
create divergence"""
# We need to check two cases that can cause divergence:
# case 1: the rev being rewritten has a non-obsolete successor (easily
# detected by successorssets)
divergent = []
sset = obsutil.successorssets(repo, ctx.node())
nodivergencerisk = (len(sset) == 0
or (len(sset) == 1
@@ -271,6 +287,10 @@ def contentdivrisk(repo, ctx):
# case 2: one of the precursors of the rev being revived has a
# non-obsolete successor (we need divergentsets for this)
from . import evolvecmd
if evolvecmd.divergentsets(repo, ctx):
nodivergencerisk = False
return not nodivergencerisk
divsets = evolvecmd.divergentsets(repo, ctx)
if divsets:
nsuccset = divsets[0][b'divergentnodes']
divergent.append(nsuccset[0][0])
else:
divergent.append(sset[0][0])
return divergent
Loading