# HG changeset patch # User Gregory Szorc <gregory.sz...@gmail.com> # Date 1499376798 25200 # Thu Jul 06 14:33:18 2017 -0700 # Node ID b80df45d3b5c8eb8f3f3183d4294c50ddf6eeaaf # Parent b56d19640ff132fe8e3c58944767b96b6b0c66a4 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. diff --git a/hgext/sparse.py b/hgext/sparse.py --- a/hgext/sparse.py +++ b/hgext/sparse.py @@ -126,7 +126,8 @@ def reposetup(ui, repo): if not util.safehasattr(repo, 'dirstate'): return - _wraprepo(ui, repo) + if 'dirstate' in repo._filecache: + repo.dirstate.repo = repo def replacefilecache(cls, propname, replacement): """Replace a filecache property with a new class. This allows changing the @@ -231,17 +232,6 @@ def _setupupdates(ui): extensions.wrapfunction(mergemod, 'calculateupdates', _calculateupdates) - def _update(orig, repo, node, branchmerge, *args, **kwargs): - results = orig(repo, node, branchmerge, *args, **kwargs) - - # If we're updating to a location, clean up any stale temporary includes - # (ex: this happens during hg rebase --abort). - if not branchmerge and util.safehasattr(repo, 'prunetemporaryincludes'): - repo.prunetemporaryincludes() - return results - - extensions.wrapfunction(mergemod, 'update', _update) - def _setupcommit(ui): def _refreshoncommit(orig, self, node): """Refresh the checkout when commits touch .hgsparse @@ -258,8 +248,7 @@ def _setupcommit(ui): origsparsematch = sparse.matcher(repo) _refresh(repo.ui, repo, origstatus, origsparsematch, True) - if util.safehasattr(repo, 'prunetemporaryincludes'): - repo.prunetemporaryincludes() + sparse.prunetemporaryincludes(repo) extensions.wrapfunction(context.committablectx, 'markcommitted', _refreshoncommit) @@ -410,47 +399,6 @@ def _setupdirstate(ui): return orig(self, *args) extensions.wrapfunction(dirstate.dirstate, func, _wrapper) -def _wraprepo(ui, repo): - class SparseRepo(repo.__class__): - def prunetemporaryincludes(self): - if repo.vfs.exists('tempsparse'): - origstatus = self.status() - modified, added, removed, deleted, a, b, c = origstatus - if modified or added or removed or deleted: - # Still have pending changes. Don't bother trying to prune. - return - - sparsematch = sparse.matcher(self, includetemp=False) - dirstate = self.dirstate - actions = [] - dropped = [] - tempincludes = sparse.readtemporaryincludes(self) - for file in tempincludes: - if file in dirstate and not sparsematch(file): - message = 'dropping temporarily included sparse files' - actions.append((file, None, message)) - dropped.append(file) - - typeactions = collections.defaultdict(list) - typeactions['r'] = actions - mergemod.applyupdates(self, typeactions, self[None], self['.'], - False) - - # Fix dirstate - for file in dropped: - dirstate.drop(file) - - self.vfs.unlink('tempsparse') - sparse.invalidatesignaturecache(self) - msg = _("cleaned up %d temporarily added file(s) from the " - "sparse checkout\n") - ui.status(msg % len(tempincludes)) - - if 'dirstate' in repo._filecache: - repo.dirstate.repo = repo - - repo.__class__ = SparseRepo - @command('^debugsparse', [ ('I', 'include', False, _('include files in the sparse checkout')), ('X', 'exclude', False, _('exclude files in the sparse checkout')), diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1515,6 +1515,8 @@ def update(repo, node, branchmerge, forc Return the same tuple as applyupdates(). """ + # Avoid cycle. + from . import sparse # This function used to find the default destination if node was None, but # that's now in destutil.py. @@ -1704,6 +1706,11 @@ def update(repo, node, branchmerge, forc if not branchmerge: repo.dirstate.setbranch(p2.branch()) + # If we're updating to a location, clean up any stale temporary includes + # (ex: this happens during hg rebase --abort). + if not branchmerge: + sparse.prunetemporaryincludes(repo) + if not partial: repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) return stats diff --git a/mercurial/sparse.py b/mercurial/sparse.py --- a/mercurial/sparse.py +++ b/mercurial/sparse.py @@ -7,6 +7,7 @@ from __future__ import absolute_import +import collections import hashlib import os @@ -15,6 +16,7 @@ from .node import nullid from . import ( error, match as matchmod, + merge as mergemod, pycompat, util, ) @@ -198,6 +200,41 @@ def addtemporaryincludes(repo, additiona includes.add(i) writetemporaryincludes(repo, includes) +def prunetemporaryincludes(repo): + if not enabled or not repo.vfs.exists('tempsparse'): + return + + origstatus = repo.status() + modified, added, removed, deleted, a, b, c = origstatus + if modified or added or removed or deleted: + # Still have pending changes. Don't bother trying to prune. + return + + sparsematch = matcher(repo, includetemp=False) + dirstate = repo.dirstate + actions = [] + dropped = [] + tempincludes = readtemporaryincludes(repo) + for file in tempincludes: + if file in dirstate and not sparsematch(file): + message = _('dropping temporarily included sparse files') + actions.append((file, None, message)) + dropped.append(file) + + typeactions = collections.defaultdict(list) + typeactions['r'] = actions + mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], False) + + # Fix dirstate + for file in dropped: + dirstate.drop(file) + + repo.vfs.unlink('tempsparse') + invalidatesignaturecache(repo) + msg = _('cleaned up %d temporarily added file(s) from the ' + 'sparse checkout\n') + repo.ui.status(msg % len(tempincludes)) + class forceincludematcher(matchmod.basematcher): """A matcher that returns true for any of the forced includes before testing against the actual matcher.""" _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel