[PATCH evolve-ext-V3] inhibit: direct access with and without warning on a per command basis
Laurent Charignon
lcharignon at fb.com
Tue May 12 21:11:03 UTC 2015
# HG changeset patch
# User Laurent Charignon <lcharignon at fb.com>
# Date 1431463949 25200
# Tue May 12 13:52:29 2015 -0700
# Node ID 5abc61cbb35e368185a535444d1d67f3651a7109
# Parent 5e82d78f5872c9503d7b6691c594a13794a9b4a4
inhibit: direct access with and without warning on a per command basis
We introduce a new filtername visibile-directaccess-nowarn to enable direct
access with no warning on a per command basis.
The motivation behing this change is to display warning when attempting direct
access in destructive commands.
diff --git a/hgext/inhibit.py b/hgext/inhibit.py
--- a/hgext/inhibit.py
+++ b/hgext/inhibit.py
@@ -37,6 +37,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,6 +71,20 @@
repo.__class__ = obsinhibitedrepo
repo._explicitaccess = set()
+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 """
+ visiblefilter = repoview.computehidden
+ repoview.filtertable.update({'visible-directaccess-nowarn': visiblefilter})
+ repoview.filtertable.update({'visible-directaccess-warn': visiblefilter})
+ for warn, ext, cmd in directaccesslevel:
+ try:
+ cmdtable = extensions.find(ext).cmdtable if ext else commands.table
+ wrapper = wrapwithwarning if warn else wrapwithoutwarning
+ extensions.wrapcommand(cmdtable, cmd, wrapper)
+ except error.UnknownCommand:
+ # Command not loaded, in that case we don't need to override it
+ pass
def _update(orig, ui, repo, *args, **kwargs):
"""
@@ -192,6 +215,22 @@
transaction.addpostclose('inhibitposttransaction', inhibitposttransaction)
return transaction
+def wrapwithoutwarning(orig, *args, **kwargs):
+ ui, repo, = args[0], args[1]
+ if repo and repo.filtername == 'visible':
+ object.__setattr__(repo, 'filtername',
+ 'visible-directaccess-nowarn')
+ k = orig(*args, **kwargs)
+ return k
+
+def wrapwithwarning(orig, *args, **kwargs):
+ ui, repo, = args[0], args[1]
+ if repo and repo.filtername == 'visible':
+ object.__setattr__(repo, 'filtername',
+ 'visible-directaccess-warn')
+ k = orig(*args, **kwargs)
+ return k
+
def extsetup(ui):
# lets wrap the computation of the obsolete set
# We apply inhibition there
@@ -214,6 +253,7 @@
extensions.wrapfunction(obsolete, 'createmarkers', _createmarkers)
extensions.wrapfunction(repoview, '_getdynamicblockers', _accessvisible)
extensions.wrapfunction(revset, 'posttreebuilthook', _posttreebuilthook)
+ setupdirectaccess()
# wrap update to make sure that no obsolete commit is visible after an
# update
extensions.wrapcommand(commands.table, 'update', _update)
@@ -250,21 +290,30 @@
# 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':
- prelength = len(repo._explicitaccess)
- repo.symbols = gethashsymbols(tree)
- cl = repo.unfiltered().changelog
- for node in repo.symbols:
- try:
- node = cl._partialmatch(node)
- except error.LookupError:
- node = None
- if node is not None:
- rev = cl.rev(node)
- if rev not in repo.changelog:
- repo._explicitaccess.add(rev)
- if prelength != len(repo._explicitaccess):
- repo.invalidatevolatilesets()
+ if repo is not None and repo.filtername:
+ hasdirectaccess = repo.filtername.startswith('visible-directaccess')
+ if hasdirectaccess:
+ prelength = len(repo._explicitaccess)
+ accessbefore = set(repo._explicitaccess)
+ repo.symbols = gethashsymbols(tree)
+ cl = repo.unfiltered().changelog
+ for node in repo.symbols:
+ try:
+ node = cl._partialmatch(node)
+ except error.LookupError:
+ node = None
+ if node is not None:
+ rev = cl.rev(node)
+ 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', [], '')
def cmddebugobsinhibit(ui, repo, *revs):
diff --git a/tests/test-inhibit.t b/tests/test-inhibit.t
--- a/tests/test-inhibit.t
+++ b/tests/test-inhibit.t
@@ -397,6 +397,9 @@
(use --hidden to access hidden revisions)
[255]
$ hg rebase -r ad78ff7d621f -r 53a94305e133 -d 2db36d8066ff
+ Warning: accessing hidden changesets 2db36d8066ff for write operation
+ Warning: accessing hidden changesets ad78ff7d621f for write operation
+ Warning: accessing hidden changesets 53a94305e133 for write operation
rebasing 10:ad78ff7d621f "add cK"
rebasing 11:53a94305e133 "add cL"
$ hg log -G
More information about the Mercurial-devel
mailing list