--- a/hgext/inhibit.py Tue May 12 12:26:46 2015 -0700
+++ b/hgext/inhibit.py Tue May 12 13:52:29 2015 -0700
@@ -26,6 +26,7 @@
from mercurial import cmdutil
from mercurial import scmutil
from mercurial import repoview
+from mercurial import branchmap
from mercurial import revset
from mercurial import error
from mercurial import commands
@@ -37,6 +38,15 @@
cmdtable = {}
command = cmdutil.command(cmdtable)
+# List of commands where no warning is shown for direct access
+directaccesslevel = [
+ # warning or not, extension (None if core), command name
+ (False, None, 'update'),
+ (False, None, 'export'),
+ (True, 'rebase', 'rebase'),
+ (False, 'evolve', 'prune'),
+]
+
def reposetup(ui, repo):
class obsinhibitedrepo(repo.__class__):
@@ -62,7 +72,30 @@
extensions.wrapfunction(localrepo.localrepository,
'transaction', transactioncallback)
+def _computehidden(repo):
+ hidden = repoview.computehidden(repo)
+ cl = repo.changelog
+ dynamic = hidden & repo._explicitaccess
+ if dynamic:
+ blocked = cl.ancestors(dynamic, inclusive=True)
+ hidden = frozenset(r for r in hidden if r not in blocked)
+ return hidden
+def setupdirectaccess():
+ """ Add two new filtername that behave like visible to provide direct access
+ and direct access with warning. Wraps the commands to setup direct access """
+ repoview.filtertable.update({'visible-directaccess-nowarn': _computehidden})
+ repoview.filtertable.update({'visible-directaccess-warn': _computehidden})
+ branchmap.subsettable['visible-directaccess-nowarn'] = 'visible'
+ branchmap.subsettable['visible-directaccess-warn'] = 'visible'
+
+ for warn, ext, cmd in directaccesslevel:
+ cmdtable = extensions.find(ext).cmdtable if ext else commands.table
+ wrapper = wrapwithwarning if warn else wrapwithoutwarning
+ try:
+ extensions.wrapcommand(cmdtable, cmd, wrapper)
+ except error.UnknownCommand:
+ pass
def _update(orig, ui, repo, *args, **kwargs):
"""
When moving to a commit we want to inhibit any obsolete commit affecting
@@ -192,6 +225,16 @@
transaction.addpostclose('inhibitposttransaction', inhibitposttransaction)
return transaction
+def wrapwithoutwarning(orig, ui, repo, *args, **kwargs):
+ if repo and repo.filtername == 'visible':
+ repo = repo.filtered("visible-directaccess-nowarn")
+ return orig(ui, repo, *args, **kwargs)
+
+def wrapwithwarning(orig, ui, repo, *args, **kwargs):
+ if repo and repo.filtername == 'visible':
+ repo = repo.filtered("visible-directaccess-warn")
+ return orig(ui, repo, *args, **kwargs)
+
def extsetup(ui):
# lets wrap the computation of the obsolete set
# We apply inhibition there
@@ -208,8 +251,8 @@
obsolete.cachefuncs['obsolete'] = _computeobsoleteset
# wrap create marker to make it able to lift the inhibition
extensions.wrapfunction(obsolete, 'createmarkers', _createmarkers)
- extensions.wrapfunction(repoview, '_getdynamicblockers', _accessvisible)
extensions.wrapfunction(revset, 'posttreebuilthook', _posttreebuilthook)
+ setupdirectaccess()
if not ui.configbool('inhibit', 'onlydirectaccess', False):
# drop divergence computation since it is incompatible with "light revive"
obsolete.cachefuncs['divergent'] = lambda repo: set()
@@ -251,8 +294,12 @@
# We extract the symbols that look like hashes and add them to the
# explicitaccess set
orig(tree, repo)
- if repo is not None and repo.filtername == 'visible':
+ filternm = ""
+ if repo is not None:
+ filternm = repo.filtername
+ if filternm is not None and filternm.startswith('visible-directaccess'):
prelength = len(repo._explicitaccess)
+ accessbefore = set(repo._explicitaccess)
repo.symbols = gethashsymbols(tree)
cl = repo.unfiltered().changelog
for node in repo.symbols:
@@ -265,6 +312,12 @@
if rev not in repo.changelog:
repo._explicitaccess.add(rev)
if prelength != len(repo._explicitaccess):
+ if repo.filtername != 'visible-directaccess-nowarn':
+ unhiddencommits = repo._explicitaccess - accessbefore
+ repo.ui.warn( _("Warning: accessing hidden changesets %s "
+ "for write operation\n") %
+ (",".join([str(repo.unfiltered()[l])
+ for l in unhiddencommits])))
repo.invalidatevolatilesets()
@command('debugobsinhibit', [], '')
@@ -272,12 +325,3 @@
"""inhibit obsolescence markers effect on a set of revs"""
nodes = (repo[r].node() for r in scmutil.revrange(repo, revs))
_inhibitmarkers(repo, nodes)
-
-# ensure revision accessed by hash are visible
-###############################################
-
-def _accessvisible(orig, repo):
- """ensure accessed revs stay visible"""
- blockers = orig(repo)
- blockers.update(getattr(repo, '_explicitaccess', ()))
- return blockers