changeset 18132:db25bf1dc828

branchmap: move validity logic in the object itself In several place, We check if a branchcache is still valid regarding the current state of the repository. This changeset puts this logic in a method of the object that can be reused when necessary. A branch map is considered valid whenever it is up to date or a strict subset of the repository state. The change will help making branchcache aware of filtered revision. The change in keyword is expected. the branch cache is actually invalid after the amend. The previous check did not detected it.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Mon, 24 Dec 2012 02:49:59 +0100
parents f0eeb9b3444a
children 7f5a0eba3768
files mercurial/branchmap.py tests/test-keyword.t
diffstat 2 files changed, 17 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/branchmap.py	Sat Dec 22 17:08:15 2012 +0100
+++ b/mercurial/branchmap.py	Mon Dec 24 02:49:59 2012 +0100
@@ -9,7 +9,6 @@
 import encoding
 
 def read(repo):
-    partial = branchcache()
     try:
         f = repo.opener("cache/branchheads")
         lines = f.read().split('\n')
@@ -20,7 +19,8 @@
     try:
         last, lrev = lines.pop(0).split(" ", 1)
         last, lrev = bin(last), int(lrev)
-        if lrev >= len(repo) or repo[lrev].node() != last:
+        partial = branchcache(tipnode=last, tiprev=lrev)
+        if not partial.validfor(repo):
             # invalidate the cache
             raise ValueError('invalidating branch cache (tip differs)')
         for l in lines:
@@ -32,8 +32,6 @@
                 raise ValueError('invalidating branch cache because node '+
                                  '%s does not exist' % node)
             partial.setdefault(label, []).append(bin(node))
-        partial.tipnode = last
-        partial.tiprev = lrev
     except KeyboardInterrupt:
         raise
     except Exception, inst:
@@ -47,12 +45,9 @@
 def updatecache(repo):
     repo = repo.unfiltered()  # Until we get a smarter cache management
     cl = repo.changelog
-    tip = cl.tip()
     partial = repo._branchcache
-    if partial is not None and partial.tipnode == tip:
-        return
 
-    if partial is None or partial.tipnode not in cl.nodemap:
+    if partial is None or not partial.validfor(repo):
         partial = read(repo)
 
     catip = repo._cacheabletip()
@@ -80,6 +75,17 @@
         self.tipnode = tipnode
         self.tiprev = tiprev
 
+    def validfor(self, repo):
+        """Is the cache content valide regarding a repo
+
+        - False when cached tipnode are unknown or if we detect a strip.
+        - True when cache is up to date or a subset of current repo."""
+        try:
+            return self.tipnode == repo.changelog.node(self.tiprev)
+        except IndexError:
+            return False
+
+
     def write(self, repo):
         try:
             f = repo.opener("cache/branchheads", "w", atomictemp=True)
@@ -157,12 +163,8 @@
             if not nodes:
                 droppednodes.extend(nodes)
                 del self[branch]
-        try:
-            node = cl.node(self.tiprev)
-        except IndexError:
-            node = None
-        if ((self.tipnode != node)
-            or (self.tipnode in droppednodes)):
+        if ((not self.validfor(repo)) or (self.tipnode in droppednodes)):
+
             # cache key are not valid anymore
             self.tipnode = nullid
             self.tiprev = nullrev
--- a/tests/test-keyword.t	Sat Dec 22 17:08:15 2012 +0100
+++ b/tests/test-keyword.t	Mon Dec 24 02:49:59 2012 +0100
@@ -507,6 +507,7 @@
   $ hg -q commit -d '14 1' -m 'prepare amend'
 
   $ hg --debug commit --amend -d '15 1' -m 'amend without changes' | grep keywords
+  invalidating branch cache (tip differs)
   overwriting a expanding keywords
   $ hg -q id
   67d8c481a6be