Patchwork [08,of,16] localrepo: filter unknown nodes from the phasecache on destroyed

mail settings
Submitter Pierre-Yves David
Date Jan. 2, 2013, 1:09 a.m.
Message ID <3739f9b4dfcef8eea702.1357088970@yamac.lan>
Download mbox | patch
Permalink /patch/353/
State Superseded, archived
Commit 082d6929fd4dcaf0c6ae97e0589e5dcb083d1a4c
Headers show


Pierre-Yves David - Jan. 2, 2013, 1:09 a.m.
# HG changeset patch
# User Idan Kamara <idankk86 at>
# Date 1356106792 -3600
# Node ID 3739f9b4dfcef8eea702baafed1c9506c3694548
# Parent  223cb873a170ee0d9c6a9d3ec93aeb8057ca4ffe
localrepo: filter unknown nodes from the phasecache on destroyed

When commit is followed by strip (qrefresh), phasecache contains nodes that were
removed from the changelog. Since phasecache is filecached with .hg/store/phaseroots
which doesn't change as a result of stripping, we have to filter it manually.

If we don't write it immediately, the next time it is read from disk the nodes
will be filtered again. That's what happened before, but there's no reason not
to write it immediately.

The change in test-keyword.t is caused by the above.


diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -1423,10 +1423,22 @@  class localrepository(object):
                       if self.changelog.hasnode(node))
             cache = self._branchcaches[None]
             cache.update(self, ctxgen)
+        # When one tries to:
+        # 1) destroy nodes thus calling this method (e.g. strip)
+        # 2) use phasecache somewhere (e.g. commit)
+        #
+        # then 2) will fail because the phasecache contains nodes that were
+        # removed. We can either remove phasecache from the filecache,
+        # causing it to reload next time it is accessed, or simply filter
+        # the removed nodes now and write the updated cache.
+        if '_phasecache' in self._filecache:
+            self._phasecache.filterunknown(self)
+            self._phasecache.write()
         # Ensure the persistent tag cache is updated.  Doing it now
         # means that the tag cache only has to worry about destroyed
         # heads immediately after a strip/rollback.  That in turn
         # guarantees that "cachetip == currenttip" (comparing both rev
         # and node) always means no nodes have been added or destroyed.
diff --git a/tests/test-keyword.t b/tests/test-keyword.t
--- a/tests/test-keyword.t
+++ b/tests/test-keyword.t
@@ -576,11 +576,10 @@  Copy and show added kwfiles
 Commit and show expansion in original and copy
   $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user at>'
    c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
-  removing unknown node 40a904bbbe4c from 1-phase boundary
   overwriting c expanding keywords
   committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
   $ cat a c
   expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
   do not process $Id:
@@ -747,11 +746,10 @@  Interrupted commit should not change sta
 Commit with multi-line message and custom expansion
   $ hg --debug commit -l log -d '2 0' -u 'User Name <user at>'
-  removing unknown node 40a904bbbe4c from 1-phase boundary
   overwriting a expanding keywords
   committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
   $ rm log
 Stat, verify and show custom expansion (firstline)