[PATCH 1 of 5 REVIEW] phases: add a moveboundary function to move phases boundaries

pierre-yves.david at logilab.fr pierre-yves.david at logilab.fr
Wed Oct 19 05:27:19 CDT 2011


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1319019427 -7200
# Node ID 585d4afe4752a33eb02ec3c03dd626e1d7e87317
# Parent  bf4b59cd0fdf09b139c8fbed1ef3495df5e55b40
phases: add a moveboundary function to move phases boundaries

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -34,10 +34,11 @@ class localrepository(repo.repository):
         self.auditor = scmutil.pathauditor(self.root, self._checknested)
         self.opener = scmutil.opener(self.path)
         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)
             extensions.loadall(self.ui)
         except IOError:
@@ -170,12 +171,14 @@ class localrepository(repo.repository):
     def _writebookmarks(self, marks):
       bookmarks.write(self)
 
     @filecache('phaseheads')
     def _phaseheads(self):
+        self._dirtyphases = False
         return phases.readheads(self)
 
+
     @propertycache
     def _phaserev(self):
         cache = [phases.allphases[-1]] * len(self)
         for phase in reversed(phases.trackedphases):
             heads = map(self.changelog.rev, self._phaseheads[phase])
@@ -908,10 +911,12 @@ class localrepository(repo.repository):
             l.lock()
             return l
 
         def unlock():
             self.store.write()
+            if self._dirtyphases:
+                phases.writeheads(self)
             for k, ce in self._filecache.items():
                 if k == 'dirstate':
                     continue
                 ce.refresh()
 
diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -34,7 +34,36 @@ def writeheads(repo):
     f = repo.sopener('phaseheads', 'w', atomictemp=True)
     try:
         for phase, heads in enumerate(repo._phaseheads):
             for h in heads:
                 f.write('%i %s\n' % (phase, hex(h)))
+        repo._dirtyphases = False
     finally:
         f.close()
+
+def moveboundary(repo, phase, nodes):
+    """Add nodes to a phase changing other nodes phases if necessary.
+
+    return True if phase boundary moved, False otherwise.
+
+    Simplify boundary to contains phase head only."""
+    if phase in trackedphases:
+        heads = repo._phaseheads[phase]
+        olds = heads.copy()
+        heads.update(set(nodes))
+        if olds != heads:
+            # remove nullid as it's rev is -1 and it confuse revset
+            if nullid in heads:
+                heads.remove(nullid)
+            # compute heads of the new set
+            revs = map(repo.changelog.rev, heads)
+            ctxs = repo.set('heads(::(%ld))', revs)
+            nodes = set([ctx.node() for ctx in ctxs])
+            heads.intersection_update(nodes)
+            # If heads really changed
+            if olds != heads:
+                # recursively move other phase boundary
+                moveboundary(repo, phase + 1, nodes) # cascading
+                # invalidate cache (we probably could be smarter here
+                if '_phaserev' in vars(repo):
+                    del repo._phaserev
+                repo._dirtyphases = True


More information about the Mercurial-devel mailing list