comparison hgext/sparse.py @ 33321:d09e948dc303

sparse: move pruning of temporary includes into core This was our last method on the custom repo type, meaning we could remove that custom type and inline the 2 lines of code into reposetup(). As part of the move, instead of wrapping merge.update() from the sparse extension, we inline the function call. The ported function now no-ops if sparse isn't enabled, making it safe to always call. The call site in update() may not be the most appropriate. But it matches the previous behavior, which is the safest thing to do. It can be improved later.
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 06 Jul 2017 14:33:18 -0700
parents 153456f02426
children fa6c2c3064fd
comparison
equal deleted inserted replaced
33320:153456f02426 33321:d09e948dc303
117 117
118 def reposetup(ui, repo): 118 def reposetup(ui, repo):
119 if not util.safehasattr(repo, 'dirstate'): 119 if not util.safehasattr(repo, 'dirstate'):
120 return 120 return
121 121
122 _wraprepo(ui, repo) 122 if 'dirstate' in repo._filecache:
123 repo.dirstate.repo = repo
123 124
124 def replacefilecache(cls, propname, replacement): 125 def replacefilecache(cls, propname, replacement):
125 """Replace a filecache property with a new class. This allows changing the 126 """Replace a filecache property with a new class. This allows changing the
126 cache invalidation condition.""" 127 cache invalidation condition."""
127 origcls = cls 128 origcls = cls
222 223
223 return prunedactions, diverge, renamedelete 224 return prunedactions, diverge, renamedelete
224 225
225 extensions.wrapfunction(mergemod, 'calculateupdates', _calculateupdates) 226 extensions.wrapfunction(mergemod, 'calculateupdates', _calculateupdates)
226 227
227 def _update(orig, repo, node, branchmerge, *args, **kwargs):
228 results = orig(repo, node, branchmerge, *args, **kwargs)
229
230 # If we're updating to a location, clean up any stale temporary includes
231 # (ex: this happens during hg rebase --abort).
232 if not branchmerge and util.safehasattr(repo, 'prunetemporaryincludes'):
233 repo.prunetemporaryincludes()
234 return results
235
236 extensions.wrapfunction(mergemod, 'update', _update)
237
238 def _setupcommit(ui): 228 def _setupcommit(ui):
239 def _refreshoncommit(orig, self, node): 229 def _refreshoncommit(orig, self, node):
240 """Refresh the checkout when commits touch .hgsparse 230 """Refresh the checkout when commits touch .hgsparse
241 """ 231 """
242 orig(self, node) 232 orig(self, node)
249 if set(profiles) & set(ctx.files()): 239 if set(profiles) & set(ctx.files()):
250 origstatus = repo.status() 240 origstatus = repo.status()
251 origsparsematch = sparse.matcher(repo) 241 origsparsematch = sparse.matcher(repo)
252 _refresh(repo.ui, repo, origstatus, origsparsematch, True) 242 _refresh(repo.ui, repo, origstatus, origsparsematch, True)
253 243
254 if util.safehasattr(repo, 'prunetemporaryincludes'): 244 sparse.prunetemporaryincludes(repo)
255 repo.prunetemporaryincludes()
256 245
257 extensions.wrapfunction(context.committablectx, 'markcommitted', 246 extensions.wrapfunction(context.committablectx, 'markcommitted',
258 _refreshoncommit) 247 _refreshoncommit)
259 248
260 def _setuplog(ui): 249 def _setuplog(ui):
401 "the sparse checkout") % f, 390 "the sparse checkout") % f,
402 hint=hint) 391 hint=hint)
403 return orig(self, *args) 392 return orig(self, *args)
404 extensions.wrapfunction(dirstate.dirstate, func, _wrapper) 393 extensions.wrapfunction(dirstate.dirstate, func, _wrapper)
405 394
406 def _wraprepo(ui, repo):
407 class SparseRepo(repo.__class__):
408 def prunetemporaryincludes(self):
409 if repo.vfs.exists('tempsparse'):
410 origstatus = self.status()
411 modified, added, removed, deleted, a, b, c = origstatus
412 if modified or added or removed or deleted:
413 # Still have pending changes. Don't bother trying to prune.
414 return
415
416 sparsematch = sparse.matcher(self, includetemp=False)
417 dirstate = self.dirstate
418 actions = []
419 dropped = []
420 tempincludes = sparse.readtemporaryincludes(self)
421 for file in tempincludes:
422 if file in dirstate and not sparsematch(file):
423 message = 'dropping temporarily included sparse files'
424 actions.append((file, None, message))
425 dropped.append(file)
426
427 typeactions = collections.defaultdict(list)
428 typeactions['r'] = actions
429 mergemod.applyupdates(self, typeactions, self[None], self['.'],
430 False)
431
432 # Fix dirstate
433 for file in dropped:
434 dirstate.drop(file)
435
436 self.vfs.unlink('tempsparse')
437 sparse.invalidatesignaturecache(self)
438 msg = _("cleaned up %d temporarily added file(s) from the "
439 "sparse checkout\n")
440 ui.status(msg % len(tempincludes))
441
442 if 'dirstate' in repo._filecache:
443 repo.dirstate.repo = repo
444
445 repo.__class__ = SparseRepo
446
447 @command('^debugsparse', [ 395 @command('^debugsparse', [
448 ('I', 'include', False, _('include files in the sparse checkout')), 396 ('I', 'include', False, _('include files in the sparse checkout')),
449 ('X', 'exclude', False, _('exclude files in the sparse checkout')), 397 ('X', 'exclude', False, _('exclude files in the sparse checkout')),
450 ('d', 'delete', False, _('delete an include/exclude rule')), 398 ('d', 'delete', False, _('delete an include/exclude rule')),
451 ('f', 'force', False, _('allow changing rules even with pending changes')), 399 ('f', 'force', False, _('allow changing rules even with pending changes')),