##// END OF EJS Templates
addchangegroup: remove the lock argument on the addchangegroup methods...
addchangegroup: remove the lock argument on the addchangegroup methods This argument is no longer require. post lock release code is now handled with dedicated post release callback code in lock itself.

File last commit:

r15482:a667c89e default
r15585:a348739d default
Show More
phases.py
102 lines | 3.6 KiB | text/x-python | PythonLexer
# Mercurial phases support code
#
# Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
# Logilab SA <contact@logilab.fr>
# Augie Fackler <durin42@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
import errno
from node import nullid, bin, hex, short
from i18n import _
allphases = range(2)
trackedphases = allphases[1:]
def readroots(repo):
"""Read phase roots from disk"""
roots = [set() for i in allphases]
roots[0].add(nullid)
try:
f = repo.sopener('phaseroots')
try:
for line in f:
phase, nh = line.strip().split()
roots[int(phase)].add(bin(nh))
finally:
f.close()
except IOError, inst:
if inst.errno != errno.ENOENT:
raise
return roots
def writeroots(repo):
"""Write phase roots from disk"""
f = repo.sopener('phaseroots', 'w', atomictemp=True)
try:
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 filterunknown(repo, phaseroots=None):
"""remove unknown nodes from the phase boundary
no data is lost as unknown node only old data for their descentants
"""
if phaseroots is None:
phaseroots = repo._phaseroots
for phase, nodes in enumerate(phaseroots):
missing = [node for node in nodes if node not in repo]
if missing:
for mnode in missing:
msg = _('Removing unknown node %(n)s from %(p)i-phase boundary')
repo.ui.debug(msg, {'n': short(mnode), 'p': phase})
nodes.symmetric_difference_update(missing)
repo._dirtyphases = True
def advanceboundary(repo, targetphase, nodes):
"""Add nodes to a phase changing other nodes phases if necessary.
This function move boundary *forward* this means that all nodes are set
in the target phase or kept in a *lower* phase.
Simplify boundary to contains phase roots only."""
for phase in xrange(targetphase + 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
def retractboundary(repo, targetphase, nodes):
"""Set nodes back to a phase changing other nodes phases if necessary.
This function move boundary *backward* this means that all nodes are set
in the target phase or kept in a *higher* phase.
Simplify boundary to contains phase roots only."""
currentroots = repo._phaseroots[targetphase]
newroots = [n for n in nodes if repo[n].phase() < targetphase]
if newroots:
currentroots.update(newroots)
ctxs = repo.set('roots(%ln::)', currentroots)
currentroots.intersection_update(ctx.node() for ctx in ctxs)
if '_phaserev' in vars(repo):
del repo._phaserev
repo._dirtyphases = True