# HG changeset patch # User FUJIWARA Katsunori # Date 1473617188 -32400 # Node ID d9c49138ab93a06371e613eb15dbb38f7684849d # Parent f32f8bf5dc4c23ef97ba56813ef9fb668ef543f7 localrepo: make invalidate avoid invalidating store inside transaction (API) Before this patch, invalidate() discards in-memory fncache changes, even inside transaction scope. Such changes should be written out at closing transaction. Otherwise, fncache might overlook newly added files. A file overlooked by fncache isn't accessible via store vfs, even if it actually exists in store. On the other hand, a non-existing file in fncache is less harmful, because fncachestore always examines whether a file actually exists or not before access. Therefore, discarding in-memory changes can be safely omitted. It is typical case that repo.invalidate() in streamclone is executed inside nested transaction. This patch makes invalidate() avoid invalidating store inside transaction. This patch focuses on describing only how invalidate() changes own behavior according to activity of transaction. Describing other detail of invalidate() in docstr will be done in another series, which refactors invalidate*() functions. diff -r f32f8bf5dc4c -r d9c49138ab93 mercurial/localrepo.py --- a/mercurial/localrepo.py Mon Sep 12 03:06:28 2016 +0900 +++ b/mercurial/localrepo.py Mon Sep 12 03:06:28 2016 +0900 @@ -1246,6 +1246,13 @@ delattr(self.unfiltered(), 'dirstate') def invalidate(self, clearfilecache=False): + '''Invalidates both store and non-store parts other than dirstate + + If a transaction is running, invalidation of store is omitted, + because discarding in-memory changes might cause inconsistency + (e.g. incomplete fncache causes unintentional failure, but + redundant one doesn't). + ''' unfiltered = self.unfiltered() # all file caches are stored unfiltered for k in self._filecache.keys(): # dirstate is invalidated separately in invalidatedirstate() @@ -1259,7 +1266,11 @@ except AttributeError: pass self.invalidatecaches() - self.store.invalidatecaches() + if not self.currenttransaction(): + # TODO: Changing contents of store outside transaction + # causes inconsistency. We should make in-memory store + # changes detectable, and abort if changed. + self.store.invalidatecaches() def invalidateall(self): '''Fully invalidates both store and non-store parts, causing the