diff hgext/obsolete.py @ 54:ad1a4fb0fc49

Make states more resilient to missing head In particuliar pushkey is now more robust (with a very naif approach)
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Thu, 08 Sep 2011 18:20:01 +0200
parents 0bcbf690dfca
children 27f9c0d0a996
line wrap: on
line diff
--- a/hgext/obsolete.py	Thu Sep 08 17:46:54 2011 +0200
+++ b/hgext/obsolete.py	Thu Sep 08 18:20:01 2011 +0200
@@ -6,6 +6,11 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 import os
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
 
 from mercurial import util
 from mercurial import context
@@ -84,10 +89,14 @@
 # Pushkey mechanism for mutable
 #########################################
 
-def pushobsolete(repo, key, old, relations):
+def pushobsolete(repo, key, old, raw):
     assert key == "relations"
     w = repo.wlock()
     try:
+        tmp = StringIO()
+        tmp.write(raw)
+        tmp.seek(0)
+        relations = repo._obsdeserialise(tmp)
         for sub, objs in relations.iteritems():
             for obj in objs:
                 repo.addobsolete(sub, obj)
@@ -95,7 +104,9 @@
         w.release()
 
 def listobsolete(repo):
-    return {'relations': repo._obssubrels}
+    tmp = StringIO()
+    repo._obsserialise(tmp)
+    return {'relations': tmp.getvalue()}
 
 pushkey.register('obsolete', pushobsolete, listobsolete)
 
@@ -170,32 +181,42 @@
             """{<new-node> -> set(<old-node>)}"""
             return self._readobsrels()
 
+        ### serialisation
+        # XXX get this out the repo
+
+        def _obsserialise(self, flike):
+            for sub, objs in self._obssubrels.iteritems():
+                for obj in objs:
+                    flike.write('%s %s\n' % (hex(sub), hex(obj)))
+
+        def _obsdeserialise(self,flike):
+            rels = {}
+            for line in flike:
+                subhex, objhex = line.split()
+                rels.setdefault(bin(subhex), set()).add(bin(objhex))
+            return rels
+
+
 
         ### Disk IO
         def _readobsrels(self):
             """Write obsolete relation on disk"""
             # XXX handle lock
-            rels = {}
             try:
                 f = self.opener('obsolete-relations')
                 try:
-                    for line in f:
-                        subhex, objhex = line.split()
-                        rels.setdefault(bin(subhex), set()).add(bin(objhex))
+                    return self._obsdeserialise(f)
                 finally:
                     f.close()
             except IOError:
-                pass
-            return rels
+                return {}
 
         def _writeobsrels(self):
             """Write obsolete relation on disk"""
             # XXX handle lock
             f = self.opener('obsolete-relations', 'w', atomictemp=True)
             try:
-                for sub, objs in self._obssubrels.iteritems():
-                    for obj in objs:
-                        f.write('%s %s\n' % (hex(sub), hex(obj)))
+                self._obsserialise(f)
                 f.rename()
             finally:
                 f.close()
@@ -221,7 +242,10 @@
             obssupport = 'relations' in obskey
             result = opush(remote, *args, **opts)
             if obssupport:
-                remote.pushkey('obsolete', 'relations', {}, self._obssubrels)
+                tmp = StringIO()
+                repo._obsserialise(tmp)
+                remote.pushkey('obsolete', 'relations', {}, tmp.getvalue())
+
             return result