# HG changeset patch # User Pierre-Yves David # Date 1342012822 -7200 # Node ID 43f79983f6388061338ba8c1866399662f2380eb # Parent 8feb73f733cb8eefb007b822b92ff2682ede818e# Parent 56d4c6207ef9dc80963979fc47038fb2c007dbf8 merge with conflicting detection diff -r 8feb73f733cb -r 43f79983f638 hgext/evolve.py --- a/hgext/evolve.py Tue Jul 10 16:14:29 2012 +0200 +++ b/hgext/evolve.py Wed Jul 11 15:20:22 2012 +0200 @@ -33,24 +33,6 @@ return map(repo.changelog.node, scmutil.revrange(repo, revsets)) -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()')) - #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 - #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) - ### changeset rewriting logic ############################# @@ -677,6 +659,10 @@ rebase = None raise error.Abort(_('evolution extension require rebase extension.')) + for cmd in ['amend', 'kill', 'uncommit']: + entry = extensions.wrapcommand(cmdtable, cmd, + obsolete.warnobserrors) + entry = extensions.wrapcommand(commands.table, 'commit', commitwrapper) entry[1].append(('o', 'obsolete', [], _("make commit obsolete this revision"))) @@ -686,11 +672,3 @@ entry[1].append(('O', 'old-obsolete', False, _("make graft obsoletes its source"))) - # warning about more obsolete - for cmd in ['commit', 'push', 'pull', 'graft', 'phase', 'unbundle']: - entry = extensions.wrapcommand(commands.table, cmd, warnobserrors) - for cmd in ['amend', 'kill', 'uncommit']: - entry = extensions.wrapcommand(cmdtable, cmd, warnobserrors) - - if rebase is not None: - entry = extensions.wrapcommand(rebase.cmdtable, 'rebase', warnobserrors) diff -r 8feb73f733cb -r 43f79983f638 hgext/obsolete.py --- 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 is a new version of """ diff -r 8feb73f733cb -r 43f79983f638 tests/test-obsolete.t --- a/tests/test-obsolete.t Tue Jul 10 16:14:29 2012 +0200 +++ b/tests/test-obsolete.t Wed Jul 11 15:20:22 2012 +0200 @@ -118,6 +118,7 @@ $ hg up 3 -q Working directory parent is obsolete $ mkcommit d # 5 (on 3) + 1 new unstables changesets $ qlog -r 'obsolete()' 3 - 0d3f46688ccc @@ -190,6 +191,7 @@ Working directory parent is obsolete $ mkcommit obsol_d # 6 created new head + 1 new unstables changesets $ hg debugobsolete `getid 5` `getid 6` $ qlog 6 @@ -245,6 +247,7 @@ Working directory parent is obsolete $ mkcommit "obsol_d'" # 7 created new head + 1 new unstables changesets $ hg debugobsolete `getid 6` `getid 7` $ hg pull -R ../other-new . pulling from . @@ -328,6 +331,7 @@ Working directory parent is obsolete $ mkcommit "obsol_d''" created new head + 1 new unstables changesets $ hg debugobsolete `getid 7` `getid 8` $ cd ../other-new $ hg up -q 3 @@ -500,6 +504,7 @@ $ cd local $ hg phase --public 11 + 1 new latecomers changesets $ hg --config extensions.graphlog=glog glog --template='{rev} - ({phase}) {node|short} {desc}\n' @ 12 - (draft) 6db5e282cb91 add obsol_d''' | @@ -590,3 +595,24 @@ 9468a5f5d8b2 6db5e282cb91 95de7fc6918d 909a0fb57e5d a7a6f2b5d8a5 95de7fc6918d + +Check conflict detection + + $ hg up 9468a5f5d8b2 # add obsol_d'' + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit "obsolet_conflicting_d" + $ hg summary + parent: 14:50f11e5e3a63 tip + add obsolet_conflicting_d + branch: default + commit: (clean) + update: 9 new changesets, 9 branch heads (merge) + $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63` + $ hg log -r 'conflicting()' + changeset: 14:50f11e5e3a63 + tag: tip + parent: 11:9468a5f5d8b2 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: add obsolet_conflicting_d + diff -r 8feb73f733cb -r 43f79983f638 tests/test-uncommit.t --- a/tests/test-uncommit.t Tue Jul 10 16:14:29 2012 +0200 +++ b/tests/test-uncommit.t Wed Jul 11 15:20:22 2012 +0200 @@ -242,6 +242,7 @@ Working directory parent is obsolete $ hg --config extensions.purge= purge $ hg uncommit -I 'set:added() and e' + 2 new conflictings changesets $ hg st --copies A e $ hg st --copies --change . @@ -285,6 +286,7 @@ Working directory parent is obsolete $ hg --config extensions.purge= purge $ hg uncommit --all -X e + 1 new conflictings changesets $ hg st --copies M b M d