phases: add a moveboundary function to move phases boundaries
Also include logic to detect when to write phases data.
--- 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