# HG changeset patch # User Martin von Zweigbergk # Date 2018-08-03 18:09:41 # Node ID ad24b581e4d982221de2393b9fc7001e99e7fc46 # Parent 0db50770f388a570f76f5fb770da0e58d8023303 narrow: call narrowspec.{save,restore,clear}backup directly I want to move .hg/narrowspec to .hg/store/narrowspec and we need to decouple the narrowspec update from the dirstate update for that. This patch lets the callers call the narrowspec backup functions directly, in addition to the dirstate backup functions. The narrowspec methods are made to check if narrowing is enabled. For that, a repo instance was needed, which all the callers luckily already had available. Differential Revision: https://phab.mercurial-scm.org/D4096 diff --git a/hgext/narrow/narrowdirstate.py b/hgext/narrow/narrowdirstate.py --- a/hgext/narrow/narrowdirstate.py +++ b/hgext/narrow/narrowdirstate.py @@ -11,7 +11,6 @@ from mercurial.i18n import _ from mercurial import ( error, match as matchmod, - narrowspec, ) def wrapdirstate(repo, dirstate): @@ -28,10 +27,6 @@ def wrapdirstate(repo, dirstate): return fn(self, *args) return _wrapper - def _narrowbackupname(backupname): - assert 'dirstate' in backupname - return backupname.replace('dirstate', narrowspec.FILENAME) - class narrowdirstate(dirstate.__class__): def walk(self, match, subrepos, unknown, ignored, full=True, narrowonly=True): @@ -77,18 +72,5 @@ def wrapdirstate(repo, dirstate): allfiles = [f for f in allfiles if repo.narrowmatch()(f)] super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles) - def restorebackup(self, tr, backupname): - narrowspec.restorebackup(self._opener, - _narrowbackupname(backupname)) - super(narrowdirstate, self).restorebackup(tr, backupname) - - def savebackup(self, tr, backupname): - super(narrowdirstate, self).savebackup(tr, backupname) - narrowspec.savebackup(self._opener, _narrowbackupname(backupname)) - - def clearbackup(self, tr, backupname): - super(narrowdirstate, self).clearbackup(tr, backupname) - narrowspec.clearbackup(self._opener, _narrowbackupname(backupname)) - dirstate.__class__ = narrowdirstate return dirstate diff --git a/hgext/shelve.py b/hgext/shelve.py --- a/hgext/shelve.py +++ b/hgext/shelve.py @@ -41,6 +41,7 @@ from mercurial import ( lock as lockmod, mdiff, merge, + narrowspec, node as nodemod, patch, phases, @@ -314,10 +315,13 @@ def _aborttransaction(repo): '''Abort current transaction for shelve/unshelve, but keep dirstate ''' tr = repo.currenttransaction() - backupname = 'dirstate.shelve' - repo.dirstate.savebackup(tr, backupname) + dirstatebackupname = 'dirstate.shelve' + narrowspecbackupname = 'narrowspec.shelve' + repo.dirstate.savebackup(tr, dirstatebackupname) + narrowspec.savebackup(repo, narrowspecbackupname) tr.abort() - repo.dirstate.restorebackup(None, backupname) + narrowspec.restorebackup(repo, narrowspecbackupname) + repo.dirstate.restorebackup(None, dirstatebackupname) def createcmd(ui, repo, pats, opts): """subcommand that creates a new shelve""" diff --git a/mercurial/dirstateguard.py b/mercurial/dirstateguard.py --- a/mercurial/dirstateguard.py +++ b/mercurial/dirstateguard.py @@ -11,6 +11,7 @@ from .i18n import _ from . import ( error, + narrowspec, util, ) @@ -33,7 +34,10 @@ class dirstateguard(util.transactional): self._active = False self._closed = False self._backupname = 'dirstate.backup.%s.%d' % (name, id(self)) + self._narrowspecbackupname = ('narrowspec.backup.%s.%d' % + (name, id(self))) repo.dirstate.savebackup(repo.currenttransaction(), self._backupname) + narrowspec.savebackup(repo, self._narrowspecbackupname) self._active = True def __del__(self): @@ -52,10 +56,12 @@ class dirstateguard(util.transactional): self._repo.dirstate.clearbackup(self._repo.currenttransaction(), self._backupname) + narrowspec.clearbackup(self._repo, self._narrowspecbackupname) self._active = False self._closed = True def _abort(self): + narrowspec.restorebackup(self._repo, self._narrowspecbackupname) self._repo.dirstate.restorebackup(self._repo.currenttransaction(), self._backupname) self._active = False diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1373,6 +1373,7 @@ class localrepository(object): else: # discard all changes (including ones already written # out) in this transaction + narrowspec.restorebackup(self, 'journal.narrowspec') repo.dirstate.restorebackup(None, 'journal.dirstate') repo.invalidate(clearfilecache=True) @@ -1461,6 +1462,7 @@ class localrepository(object): @unfilteredmethod def _writejournal(self, desc): self.dirstate.savebackup(None, 'journal.dirstate') + narrowspec.savebackup(self, 'journal.narrowspec') self.vfs.write("journal.branch", encoding.fromlocal(self.dirstate.branch())) self.vfs.write("journal.desc", @@ -1548,6 +1550,7 @@ class localrepository(object): # prevent dirstateguard from overwriting already restored one dsguard.close() + narrowspec.restorebackup(self, 'undo.narrowspec') self.dirstate.restorebackup(None, 'undo.dirstate') try: branch = self.vfs.read('undo.branch') diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -13,6 +13,7 @@ from .i18n import _ from . import ( error, match as matchmod, + repository, sparse, util, ) @@ -129,15 +130,22 @@ def save(repo, includepats, excludepats) spec = format(includepats, excludepats) repo.vfs.write(FILENAME, spec) -def savebackup(vfs, backupname): +def savebackup(repo, backupname): + if repository.NARROW_REQUIREMENT not in repo.requirements: + return + vfs = repo.vfs vfs.tryunlink(backupname) util.copyfile(vfs.join(FILENAME), vfs.join(backupname), hardlink=True) -def restorebackup(vfs, backupname): - vfs.rename(backupname, FILENAME, checkambig=True) +def restorebackup(repo, backupname): + if repository.NARROW_REQUIREMENT not in repo.requirements: + return + repo.vfs.rename(backupname, FILENAME, checkambig=True) -def clearbackup(vfs, backupname): - vfs.unlink(backupname) +def clearbackup(repo, backupname): + if repository.NARROW_REQUIREMENT not in repo.requirements: + return + repo.vfs.unlink(backupname) def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes): r""" Restricts the patterns according to repo settings,