phases: add a moveboundary function to move phases boundaries
authorPierre-Yves David <pierre-yves.david@ens-lyon.org>
Mon, 07 Nov 2011 14:11:01 +0100
changeset 15454 5a7dde5adec8
parent 15453 cff509500a24
child 15455 c6f87bdab2a1
phases: add a moveboundary function to move phases boundaries Also include logic to detect when to write phases data.
mercurial/localrepo.py
mercurial/phases.py
--- a/mercurial/localrepo.py	Mon Nov 07 18:37:58 2011 +0100
+++ b/mercurial/localrepo.py	Mon Nov 07 14:11:01 2011 +0100
@@ -36,6 +36,7 @@
         self.wopener = scmutil.opener(self.root)
         self.baseui = baseui
         self.ui = baseui.copy()
+        self._dirtyphases = False
 
         try:
             self.ui.readconfig(self.join("hgrc"), self.root)
@@ -172,6 +173,7 @@
 
     @filecache('phaseroots')
     def _phaseroots(self):
+        self._dirtyphases = False
         return phases.readroots(self)
 
     @propertycache
@@ -910,6 +912,8 @@
 
         def unlock():
             self.store.write()
+            if self._dirtyphases:
+                phases.writeroots(self)
             for k, ce in self._filecache.items():
                 if k == 'dirstate':
                     continue
--- a/mercurial/phases.py	Mon Nov 07 18:37:58 2011 +0100
+++ b/mercurial/phases.py	Mon Nov 07 14:11:01 2011 +0100
@@ -37,5 +37,30 @@
         for phase, roots in enumerate(repo._phaseroots):
             for h in roots:
                 f.write('%i %s\n' % (phase, hex(h)))
+        repo._dirtyphases = False
     finally:
         f.close()
+
+def moveboundary(repo, target_phase, nodes):
+    """Add nodes to a phase changing other nodes phases if necessary.
+
+    Simplify boundary to contains phase roots only."""
+
+    # move roots of lower states
+    for phase in xrange(target_phase + 1, len(allphases)):
+        # filter nodes that are not in a compatible phase already
+        # XXX rev phase cache might have been invalidated by a previous loop
+        # XXX we need to be smarter here
+        nodes = [n for n in nodes if repo[n].phase() >= phase]
+        if not nodes:
+            break # no roots to move anymore
+        roots = repo._phaseroots[phase]
+        olds = roots.copy()
+        ctxs = list(repo.set('roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
+        roots.clear()
+        roots.update(ctx.node() for ctx in ctxs)
+        if olds != roots:
+            # invalidate cache (we probably could be smarter here
+            if '_phaserev' in vars(repo):
+                del repo._phaserev
+            repo._dirtyphases = True