Mercurial > hg-stable
changeset 50226:f18e4608bb61
narrow: delegate the dirstate's narrow spec writing to the transaction
This make it more transactional and will help us to simplify their backup.
The implementation is not great, but it keep the patch simple as this is not the
time for a larger refactoring yet.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 23 Feb 2023 03:25:44 +0100 |
parents | 8bc14ac53a41 |
children | 39256bee2ed9 |
files | mercurial/localrepo.py mercurial/narrowspec.py |
diffstat | 2 files changed, 38 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Thu Feb 23 04:15:16 2023 +0100 +++ b/mercurial/localrepo.py Thu Feb 23 03:25:44 2023 +0100 @@ -1470,6 +1470,7 @@ self._postdsstatus = [] self._pending_narrow_pats = None + self._pending_narrow_pats_dirstate = None # generic mapping between names and nodes self.names = namespaces.namespaces()
--- a/mercurial/narrowspec.py Thu Feb 23 04:15:16 2023 +0100 +++ b/mercurial/narrowspec.py Thu Feb 23 03:25:44 2023 +0100 @@ -212,8 +212,34 @@ def copytoworkingcopy(repo): + repo = repo.unfiltered() + tr = repo.currenttransaction() spec = format(*repo.narrowpats) - repo.vfs.write(DIRSTATE_FILENAME, spec) + if tr is None: + repo.vfs.write(DIRSTATE_FILENAME, spec) + else: + + reporef = weakref.ref(repo) + + def clean_pending(tr): + r = reporef() + if r is not None: + r._pending_narrow_pats_dirstate = None + + tr.addpostclose(b'narrow-spec-dirstate', clean_pending) + tr.addabort(b'narrow-spec-dirstate', clean_pending) + repo._pending_narrow_pats_dirstate = repo.narrowpats + + def write_spec(f): + f.write(spec) + + tr.addfilegenerator( + # XXX think about order at some point + b"narrow-spec-dirstate", + (DIRSTATE_FILENAME,), + write_spec, + location=b'plain', + ) def savebackup(repo, backupname): @@ -328,8 +354,10 @@ if getattr(repo, '_updatingnarrowspec', False): return storespec = repo.narrowpats - wcspec = repo.vfs.tryread(DIRSTATE_FILENAME) - wcspec = parseconfig(repo.ui, wcspec) + wcspec = repo._pending_narrow_pats_dirstate + if wcspec is None: + oldspec = repo.vfs.tryread(DIRSTATE_FILENAME) + wcspec = parseconfig(repo.ui, oldspec) if wcspec != storespec: raise error.StateError( _(b"working copy's narrowspec is stale"), @@ -343,11 +371,15 @@ When assumeclean=True, files that are not known to be clean will also be deleted. It is then up to the caller to make sure they are clean. """ - oldspec = repo.vfs.tryread(DIRSTATE_FILENAME) + old = repo._pending_narrow_pats_dirstate + if old is None: + oldspec = repo.vfs.tryread(DIRSTATE_FILENAME) + oldincludes, oldexcludes = parseconfig(repo.ui, oldspec) + else: + oldincludes, oldexcludes = old newincludes, newexcludes = repo.narrowpats repo._updatingnarrowspec = True - oldincludes, oldexcludes = parseconfig(repo.ui, oldspec) oldmatch = match(repo.root, include=oldincludes, exclude=oldexcludes) newmatch = match(repo.root, include=newincludes, exclude=newexcludes) addedmatch = matchmod.differencematcher(newmatch, oldmatch)