comparison hgext/inhibit.py @ 1232:37c00aeb4762

inhibit: enable direct access from parsing the revset tree To enable direct access we: - detect explicit hexadical reference to node in the revset tree - add these hashes to the static blockers to make them and their parent visible for the command to run
author Laurent Charignon <lcharignon@fb.com>
date Fri, 27 Mar 2015 10:58:04 -0700
parents 577f5340be6f
children 63ee05dd557a
comparison
equal deleted inserted replaced
1227:3d9c5f5df6d8 1232:37c00aeb4762
11 11
12 The first feature provided by this extension is the ability to "inhibit" 12 The first feature provided by this extension is the ability to "inhibit"
13 obsolescence markers. Obsolete revision can be cheaply brought back to life 13 obsolescence markers. Obsolete revision can be cheaply brought back to life
14 that way. However as the inhibitor are not fitting in an append only model, 14 that way. However as the inhibitor are not fitting in an append only model,
15 this is incompatible with sharing mutable history. 15 this is incompatible with sharing mutable history.
16
17 The second feature is called direct access. It is the ability to refer and
18 access hidden sha in commands provided that you know their value.
19 For example hg log -r XXX where XXX is a commit has should work whether XXX is
20 hidden or not as we assume that the user knows what he is doing when referring
21 to XXX.
16 """ 22 """
17 from mercurial import localrepo 23 from mercurial import localrepo
18 from mercurial import obsolete 24 from mercurial import obsolete
19 from mercurial import extensions 25 from mercurial import extensions
20 from mercurial import cmdutil 26 from mercurial import cmdutil
21 from mercurial import scmutil 27 from mercurial import scmutil
28 from mercurial import repoview
29 from mercurial import revset
30 from mercurial import error
22 31
23 cmdtable = {} 32 cmdtable = {}
24 command = cmdutil.command(cmdtable) 33 command = cmdutil.command(cmdtable)
25 34
26 def reposetup(ui, repo): 35 def reposetup(ui, repo):
35 for i in xrange(0, len(raw), 20): 44 for i in xrange(0, len(raw), 20):
36 obsinhibit.add(raw[i:i+20]) 45 obsinhibit.add(raw[i:i+20])
37 return obsinhibit 46 return obsinhibit
38 47
39 repo.__class__ = obsinhibitedrepo 48 repo.__class__ = obsinhibitedrepo
49 repo._explicitaccess = set()
40 50
41 # obsolescence inhibitor 51 # obsolescence inhibitor
42 ######################## 52 ########################
43 53
44 def _schedulewrite(tr, obsinhibit): 54 def _schedulewrite(tr, obsinhibit):
123 obsolete.cachefuncs['divergent'] = lambda repo: set() 133 obsolete.cachefuncs['divergent'] = lambda repo: set()
124 # drop bumped computation since it is incompatible with "light revive" 134 # drop bumped computation since it is incompatible with "light revive"
125 obsolete.cachefuncs['bumped'] = lambda repo: set() 135 obsolete.cachefuncs['bumped'] = lambda repo: set()
126 # wrap create marker to make it able to lift the inhibition 136 # wrap create marker to make it able to lift the inhibition
127 extensions.wrapfunction(obsolete, 'createmarkers', _createmarkers) 137 extensions.wrapfunction(obsolete, 'createmarkers', _createmarkers)
138 extensions.wrapfunction(repoview, '_getdynamicblockers', _accessvisible)
139 extensions.wrapfunction(revset, 'posttreebuilthook', _posttreebuilthook)
140
141 def gethashsymbols(tree):
142 # Returns the list of symbols of the tree that look like hashes
143 # for example for the revset 3::abe3ff it will return ('abe3ff')
144 if not tree:
145 return []
146
147 if len(tree) == 2 and tree[0] == "symbol":
148 try:
149 int(tree[1])
150 return []
151 except ValueError as e:
152 return [tree[1]]
153 elif len(tree) == 3:
154 return gethashsymbols(tree[1]) + gethashsymbols(tree[2])
155 else:
156 return []
157
158 def _posttreebuilthook(orig, tree, repo):
159 # This is use to enabled direct hash access
160 # We extract the symbols that look like hashes and add them to the
161 # explicitaccess set
162 orig(tree, repo)
163 if repo and repo.filtername == 'visible':
164 prelength = len(repo._explicitaccess)
165 repo.symbols = gethashsymbols(tree)
166 cl = repo.unfiltered().changelog
167 for node in repo.symbols:
168 try:
169 node = cl._partialmatch(node)
170 except error.LookupError:
171 node = None
172 if node is not None:
173 rev = cl.rev(node)
174 if rev not in repo.changelog:
175 repo._explicitaccess.add(rev)
176 if prelength != len(repo._explicitaccess):
177 repo.invalidatevolatilesets()
128 178
129 @command('debugobsinhibit', [], '') 179 @command('debugobsinhibit', [], '')
130 def cmddebugobsinhibit(ui, repo, *revs): 180 def cmddebugobsinhibit(ui, repo, *revs):
131 """inhibit obsolescence markers effect on a set of revs""" 181 """inhibit obsolescence markers effect on a set of revs"""
132 nodes = (repo[r].node() for r in scmutil.revrange(repo, revs)) 182 nodes = (repo[r].node() for r in scmutil.revrange(repo, revs))
133 _inhibitmarkers(repo, nodes) 183 _inhibitmarkers(repo, nodes)
184
185 # ensure revision accessed by hash are visible
186 ###############################################
187
188 def _accessvisible(orig, repo):
189 """ensure accessed revs stay visible"""
190 blockers = orig(repo)
191 blockers.update(getattr(repo, '_explicitaccess', ()))
192 return blockers