comparison mercurial/repoview.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents d345627d104b
children 687b865b95ad
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
17 phases, 17 phases,
18 pycompat, 18 pycompat,
19 tags as tagsmod, 19 tags as tagsmod,
20 util, 20 util,
21 ) 21 )
22 from .utils import ( 22 from .utils import repoviewutil
23 repoviewutil, 23
24 )
25 24
26 def hideablerevs(repo): 25 def hideablerevs(repo):
27 """Revision candidates to be hidden 26 """Revision candidates to be hidden
28 27
29 This is a standalone function to allow extensions to wrap it. 28 This is a standalone function to allow extensions to wrap it.
34 assertions and lead to crashes.""" 33 assertions and lead to crashes."""
35 obsoletes = obsolete.getrevs(repo, 'obsolete') 34 obsoletes = obsolete.getrevs(repo, 'obsolete')
36 internals = repo._phasecache.getrevset(repo, phases.localhiddenphases) 35 internals = repo._phasecache.getrevset(repo, phases.localhiddenphases)
37 internals = frozenset(internals) 36 internals = frozenset(internals)
38 return obsoletes | internals 37 return obsoletes | internals
38
39 39
40 def pinnedrevs(repo): 40 def pinnedrevs(repo):
41 """revisions blocking hidden changesets from being filtered 41 """revisions blocking hidden changesets from being filtered
42 """ 42 """
43 43
70 for p in pfunc(stack.pop()): 70 for p in pfunc(stack.pop()):
71 if p != nullrev and p in hidden: 71 if p != nullrev and p in hidden:
72 hidden.remove(p) 72 hidden.remove(p)
73 stack.append(p) 73 stack.append(p)
74 74
75
75 def computehidden(repo, visibilityexceptions=None): 76 def computehidden(repo, visibilityexceptions=None):
76 """compute the set of hidden revision to filter 77 """compute the set of hidden revision to filter
77 78
78 During most operation hidden should be filtered.""" 79 During most operation hidden should be filtered."""
79 assert not repo.changelog.filteredrevs 80 assert not repo.changelog.filteredrevs
88 89
89 visible = mutable - hidden 90 visible = mutable - hidden
90 _revealancestors(pfunc, hidden, visible) 91 _revealancestors(pfunc, hidden, visible)
91 return frozenset(hidden) 92 return frozenset(hidden)
92 93
94
93 def computesecret(repo, visibilityexceptions=None): 95 def computesecret(repo, visibilityexceptions=None):
94 """compute the set of revision that can never be exposed through hgweb 96 """compute the set of revision that can never be exposed through hgweb
95 97
96 Changeset in the secret phase (or above) should stay unaccessible.""" 98 Changeset in the secret phase (or above) should stay unaccessible."""
97 assert not repo.changelog.filteredrevs 99 assert not repo.changelog.filteredrevs
98 secrets = repo._phasecache.getrevset(repo, phases.remotehiddenphases) 100 secrets = repo._phasecache.getrevset(repo, phases.remotehiddenphases)
99 return frozenset(secrets) 101 return frozenset(secrets)
102
100 103
101 def computeunserved(repo, visibilityexceptions=None): 104 def computeunserved(repo, visibilityexceptions=None):
102 """compute the set of revision that should be filtered when used a server 105 """compute the set of revision that should be filtered when used a server
103 106
104 Secret and hidden changeset should not pretend to be here.""" 107 Secret and hidden changeset should not pretend to be here."""
109 if secrets: 112 if secrets:
110 return frozenset(hiddens | secrets) 113 return frozenset(hiddens | secrets)
111 else: 114 else:
112 return hiddens 115 return hiddens
113 116
117
114 def computemutable(repo, visibilityexceptions=None): 118 def computemutable(repo, visibilityexceptions=None):
115 assert not repo.changelog.filteredrevs 119 assert not repo.changelog.filteredrevs
116 # fast check to avoid revset call on huge repo 120 # fast check to avoid revset call on huge repo
117 if any(repo._phasecache.phaseroots[1:]): 121 if any(repo._phasecache.phaseroots[1:]):
118 getphase = repo._phasecache.phase 122 getphase = repo._phasecache.phase
119 maymutable = filterrevs(repo, 'base') 123 maymutable = filterrevs(repo, 'base')
120 return frozenset(r for r in maymutable if getphase(repo, r)) 124 return frozenset(r for r in maymutable if getphase(repo, r))
121 return frozenset() 125 return frozenset()
126
122 127
123 def computeimpactable(repo, visibilityexceptions=None): 128 def computeimpactable(repo, visibilityexceptions=None):
124 """Everything impactable by mutable revision 129 """Everything impactable by mutable revision
125 130
126 The immutable filter still have some chance to get invalidated. This will 131 The immutable filter still have some chance to get invalidated. This will
143 firstmutable = min(firstmutable, min(cl.rev(r) for r in roots)) 148 firstmutable = min(firstmutable, min(cl.rev(r) for r in roots))
144 # protect from nullrev root 149 # protect from nullrev root
145 firstmutable = max(0, firstmutable) 150 firstmutable = max(0, firstmutable)
146 return frozenset(pycompat.xrange(firstmutable, len(cl))) 151 return frozenset(pycompat.xrange(firstmutable, len(cl)))
147 152
153
148 # function to compute filtered set 154 # function to compute filtered set
149 # 155 #
150 # When adding a new filter you MUST update the table at: 156 # When adding a new filter you MUST update the table at:
151 # mercurial.utils.repoviewutil.subsettable 157 # mercurial.utils.repoviewutil.subsettable
152 # Otherwise your filter will have to recompute all its branches cache 158 # Otherwise your filter will have to recompute all its branches cache
153 # from scratch (very slow). 159 # from scratch (very slow).
154 filtertable = {'visible': computehidden, 160 filtertable = {
155 'visible-hidden': computehidden, 161 'visible': computehidden,
156 'served.hidden': computesecret, 162 'visible-hidden': computehidden,
157 'served': computeunserved, 163 'served.hidden': computesecret,
158 'immutable': computemutable, 164 'served': computeunserved,
159 'base': computeimpactable} 165 'immutable': computemutable,
166 'base': computeimpactable,
167 }
160 168
161 _basefiltername = list(filtertable) 169 _basefiltername = list(filtertable)
170
162 171
163 def extrafilter(ui): 172 def extrafilter(ui):
164 """initialize extra filter and return its id 173 """initialize extra filter and return its id
165 174
166 If extra filtering is configured, we make sure the associated filtered view 175 If extra filtering is configured, we make sure the associated filtered view
176 185
177 subsettable = repoviewutil.subsettable 186 subsettable = repoviewutil.subsettable
178 187
179 if combine('base') not in filtertable: 188 if combine('base') not in filtertable:
180 for name in _basefiltername: 189 for name in _basefiltername:
190
181 def extrafilteredrevs(repo, *args, **kwargs): 191 def extrafilteredrevs(repo, *args, **kwargs):
182 baserevs = filtertable[name](repo, *args, **kwargs) 192 baserevs = filtertable[name](repo, *args, **kwargs)
183 extrarevs = frozenset(repo.revs(frevs)) 193 extrarevs = frozenset(repo.revs(frevs))
184 return baserevs | extrarevs 194 return baserevs | extrarevs
195
185 filtertable[combine(name)] = extrafilteredrevs 196 filtertable[combine(name)] = extrafilteredrevs
186 if name in subsettable: 197 if name in subsettable:
187 subsettable[combine(name)] = combine(subsettable[name]) 198 subsettable[combine(name)] = combine(subsettable[name])
188 return fid 199 return fid
200
189 201
190 def filterrevs(repo, filtername, visibilityexceptions=None): 202 def filterrevs(repo, filtername, visibilityexceptions=None):
191 """returns set of filtered revision for this filter name 203 """returns set of filtered revision for this filter name
192 204
193 visibilityexceptions is a set of revs which must are exceptions for 205 visibilityexceptions is a set of revs which must are exceptions for
198 if visibilityexceptions: 210 if visibilityexceptions:
199 return func(repo.unfiltered, visibilityexceptions) 211 return func(repo.unfiltered, visibilityexceptions)
200 repo.filteredrevcache[filtername] = func(repo.unfiltered()) 212 repo.filteredrevcache[filtername] = func(repo.unfiltered())
201 return repo.filteredrevcache[filtername] 213 return repo.filteredrevcache[filtername]
202 214
215
203 class repoview(object): 216 class repoview(object):
204 """Provide a read/write view of a repo through a filtered changelog 217 """Provide a read/write view of a repo through a filtered changelog
205 218
206 This object is used to access a filtered version of a repository without 219 This object is used to access a filtered version of a repository without
207 altering the original repository object itself. We can not alter the 220 altering the original repository object itself. We can not alter the
239 object.__setattr__(self, r'_unfilteredrepo', repo) 252 object.__setattr__(self, r'_unfilteredrepo', repo)
240 object.__setattr__(self, r'filtername', filtername) 253 object.__setattr__(self, r'filtername', filtername)
241 object.__setattr__(self, r'_clcachekey', None) 254 object.__setattr__(self, r'_clcachekey', None)
242 object.__setattr__(self, r'_clcache', None) 255 object.__setattr__(self, r'_clcache', None)
243 # revs which are exceptions and must not be hidden 256 # revs which are exceptions and must not be hidden
244 object.__setattr__(self, r'_visibilityexceptions', 257 object.__setattr__(self, r'_visibilityexceptions', visibilityexceptions)
245 visibilityexceptions)
246 258
247 # not a propertycache on purpose we shall implement a proper cache later 259 # not a propertycache on purpose we shall implement a proper cache later
248 @property 260 @property
249 def changelog(self): 261 def changelog(self):
250 """return a filtered version of the changeset 262 """return a filtered version of the changeset
261 revs = filterrevs(unfi, self.filtername, self._visibilityexceptions) 273 revs = filterrevs(unfi, self.filtername, self._visibilityexceptions)
262 cl = self._clcache 274 cl = self._clcache
263 newkey = (unfilen, unfinode, hash(revs), unfichangelog._delayed) 275 newkey = (unfilen, unfinode, hash(revs), unfichangelog._delayed)
264 # if cl.index is not unfiindex, unfi.changelog would be 276 # if cl.index is not unfiindex, unfi.changelog would be
265 # recreated, and our clcache refers to garbage object 277 # recreated, and our clcache refers to garbage object
266 if (cl is not None and 278 if cl is not None and (
267 (cl.index is not unfiindex or newkey != self._clcachekey)): 279 cl.index is not unfiindex or newkey != self._clcachekey
280 ):
268 cl = None 281 cl = None
269 # could have been made None by the previous if 282 # could have been made None by the previous if
270 if cl is None: 283 if cl is None:
271 cl = copy.copy(unfichangelog) 284 cl = copy.copy(unfichangelog)
272 cl.filteredrevs = revs 285 cl.filteredrevs = revs
283 if name == self.filtername and not visibilityexceptions: 296 if name == self.filtername and not visibilityexceptions:
284 return self 297 return self
285 return self.unfiltered().filtered(name, visibilityexceptions) 298 return self.unfiltered().filtered(name, visibilityexceptions)
286 299
287 def __repr__(self): 300 def __repr__(self):
288 return r'<%s:%s %r>' % (self.__class__.__name__, 301 return r'<%s:%s %r>' % (
289 pycompat.sysstr(self.filtername), 302 self.__class__.__name__,
290 self.unfiltered()) 303 pycompat.sysstr(self.filtername),
304 self.unfiltered(),
305 )
291 306
292 # everything access are forwarded to the proxied repo 307 # everything access are forwarded to the proxied repo
293 def __getattr__(self, attr): 308 def __getattr__(self, attr):
294 return getattr(self._unfilteredrepo, attr) 309 return getattr(self._unfilteredrepo, attr)
295 310
296 def __setattr__(self, attr, value): 311 def __setattr__(self, attr, value):
297 return setattr(self._unfilteredrepo, attr, value) 312 return setattr(self._unfilteredrepo, attr, value)
298 313
299 def __delattr__(self, attr): 314 def __delattr__(self, attr):
300 return delattr(self._unfilteredrepo, attr) 315 return delattr(self._unfilteredrepo, attr)
316
301 317
302 # Python <3.4 easily leaks types via __mro__. See 318 # Python <3.4 easily leaks types via __mro__. See
303 # https://bugs.python.org/issue17950. We cache dynamically created types 319 # https://bugs.python.org/issue17950. We cache dynamically created types
304 # so they won't be leaked on every invocation of repo.filtered(). 320 # so they won't be leaked on every invocation of repo.filtered().
305 _filteredrepotypes = weakref.WeakKeyDictionary() 321 _filteredrepotypes = weakref.WeakKeyDictionary()
306 322
323
307 def newtype(base): 324 def newtype(base):
308 """Create a new type with the repoview mixin and the given base class""" 325 """Create a new type with the repoview mixin and the given base class"""
309 if base not in _filteredrepotypes: 326 if base not in _filteredrepotypes:
327
310 class filteredrepo(repoview, base): 328 class filteredrepo(repoview, base):
311 pass 329 pass
330
312 _filteredrepotypes[base] = filteredrepo 331 _filteredrepotypes[base] = filteredrepo
313 return _filteredrepotypes[base] 332 return _filteredrepotypes[base]