# HG changeset patch # User FUJIWARA Katsunori # Date 2017-06-09 04:07:48 # Node ID b698921ee1378b039a0f8bef5a3aace16d658b9d # Parent b5524fd9a4e33ca100326ef7754756929e215371 dirstate: add identity information to detect simultaneous changing in storage This identity is used to examine whether dirstate is simultaneously changed in storage after previous caching (see issue5584 for detail). util.cachestat can't be used for this purpose, because it has no valuable information on Windows. On the other hand, util.filestat can detect changing dirstate in storage certainly, regardless of platforms. https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan Strictly speaking, if underlying filesystem doesn't support ctime/mtime, util.filestat can't detect simultaneous changing in storage as expected. But simultaneous changing on such (very rare) platform can't be detected regardless of this patch series. Therefore, util.filestat should be reasonable identity for almost all usecases. diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -159,6 +159,11 @@ class dirstate(object): return self._copymap @propertycache + def _identity(self): + self._read() + return self._identity + + @propertycache def _nonnormalset(self): nonnorm, otherparents = nonnormalentries(self._map) self._otherparentset = otherparents @@ -426,6 +431,8 @@ class dirstate(object): def _read(self): self._map = {} self._copymap = {} + # ignore HG_PENDING because identity is used only for writing + self._identity = util.filestat(self._opener.join(self._filename)) try: fp = self._opendirstatefile() try: @@ -476,7 +483,8 @@ class dirstate(object): rereads the dirstate. Use localrepo.invalidatedirstate() if you want to check whether the dirstate has changed before rereading it.''' - for a in ("_map", "_copymap", "_filefoldmap", "_dirfoldmap", "_branch", + for a in ("_map", "_copymap", "_identity", + "_filefoldmap", "_dirfoldmap", "_branch", "_pl", "_dirs", "_ignore", "_nonnormalset", "_otherparentset"): if a in self.__dict__: @@ -741,6 +749,14 @@ class dirstate(object): self._dirty = True + def identity(self): + '''Return identity of dirstate itself to detect changing in storage + + If identity of previous dirstate is equal to this, writing + changes based on the former dirstate out can keep consistency. + ''' + return self._identity + def write(self, tr): if not self._dirty: return