--- a/hgext/obsolete.py Tue Jul 10 16:14:29 2012 +0200
+++ b/hgext/obsolete.py Wed Jul 11 15:20:22 2012 +0200
@@ -151,6 +151,14 @@
context.changectx.latecomer = latecomer
+def conflicting(ctx):
+ """is the changeset conflicting (Try to succeed to public change)"""
+ if ctx.node() is None:
+ return False
+ return ctx.rev() in ctx._repo._conflictingset
+
+context.changectx.conflicting = conflicting
+
### revset
#############################
@@ -192,6 +200,11 @@
args = revset.getargs(x, 0, 0, 'latecomer takes no arguments')
return [r for r in subset if r in repo._latecomerset]
+def revsetconflicting(repo, subset, x):
+ """conflicting, Try to succeed to public change"""
+ args = revset.getargs(x, 0, 0, 'conflicting takes no arguments')
+ return [r for r in subset if r in repo._conflictingset]
+
def _precursors(repo, s):
"""Precursor of a changeset"""
cs = set()
@@ -390,6 +403,7 @@
revset.symbols["suspended"] = revsetsuspended
revset.symbols["extinct"] = revsetextinct
revset.symbols["latecomer"] = revsetlatecomer
+ revset.symbols["conflicting"] = revsetconflicting
revset.symbols["obsparents"] = revsetprecursors # DEPR
revset.symbols["precursors"] = revsetprecursors
revset.symbols["obsancestors"] = revsetallprecursors # DEPR
@@ -399,9 +413,13 @@
templatekw.keywords['obsolete'] = obsoletekw
+ # warning about more obsolete
+ for cmd in ['commit', 'push', 'pull', 'graft', 'phase', 'unbundle']:
+ entry = extensions.wrapcommand(commands.table, cmd, warnobserrors)
try:
rebase = extensions.find('rebase')
if rebase:
+ entry = extensions.wrapcommand(rebase.cmdtable, 'rebase', warnobserrors)
extensions.wrapfunction(rebase, 'buildstate', buildstate)
extensions.wrapfunction(rebase, 'defineparents', defineparents)
extensions.wrapfunction(rebase, 'concludenode', concludenode)
@@ -454,6 +472,9 @@
if ctx.latecomer():
raise util.Abort(_("Trying to push latecomer changeset: %s!") % ctx,
hint=hint)
+ if ctx.conflicting():
+ raise util.Abort(_("Trying to push conflicting changeset: %s!") % ctx,
+ hint=hint)
### patch remote branch map
# do not read it this burn eyes
try:
@@ -640,6 +661,28 @@
lock.release()
return res
+def warnobserrors(orig, ui, repo, *args, **kwargs):
+ """display warning is the command resulted in more instable changeset"""
+ priorunstables = len(repo.revs('unstable()'))
+ priorlatecomers = len(repo.revs('latecomer()'))
+ priorconflictings = len(repo.revs('conflicting()'))
+ #print orig, priorunstables
+ #print len(repo.revs('secret() - obsolete()'))
+ try:
+ return orig(ui, repo, *args, **kwargs)
+ finally:
+ newunstables = len(repo.revs('unstable()')) - priorunstables
+ newlatecomers = len(repo.revs('latecomer()')) - priorlatecomers
+ newconflictings = len(repo.revs('conflicting()')) - priorconflictings
+ #print orig, newunstables
+ #print len(repo.revs('secret() - obsolete()'))
+ if newunstables > 0:
+ ui.warn(_('%i new unstables changesets\n') % newunstables)
+ if newlatecomers > 0:
+ ui.warn(_('%i new latecomers changesets\n') % newlatecomers)
+ if newconflictings > 0:
+ ui.warn(_('%i new conflictings changesets\n') % newconflictings)
+
def noextinctsvisibleheads(orig, repo):
repo._turn_extinct_secret()
return orig(repo)
@@ -806,6 +849,26 @@
query = 'allsuccessors(public()) - obsolete() - public()'
return set(self.revs(query))
+ @util.propertycache
+ def _conflictingset(self):
+ """the set of rev trying to obsolete public revision"""
+ conflicting = set()
+ obsstore = self.obsstore
+ newermap = {}
+ for ctx in self.set('(not public()) - obsolete()'):
+ prec = obsstore.successors.get(ctx.node(), ())
+ toprocess = set(prec)
+ while toprocess:
+ prec = toprocess.pop()[0]
+ if prec not in newermap:
+ newermap[prec] = newerversion(self, prec)
+ newer = [n for n in newermap[prec] if n] # filter kill
+ if len(newer) > 1:
+ conflicting.add(ctx.rev())
+ break
+ toprocess.update(obsstore.successors.get(prec, ()))
+ return conflicting
+
def _clearobsoletecache(self):
if '_obsoleteset' in vars(self):
del self._obsoleteset
@@ -824,6 +887,8 @@
del self._extinctset
if '_latecomerset' in vars(self):
del self._latecomerset
+ if '_conflictingset' in vars(self):
+ del self._conflictingset
def addobsolete(self, sub, obj):
"""Add a relation marking that node <sub> is a new version of <obj>"""