##// END OF EJS Templates
phases: add retractboundary function to move boundary backward...
Pierre-Yves David -
r15482:a667c89e default
parent child Browse files
Show More
@@ -1,83 +1,102 b''
1 # Mercurial phases support code
1 # Mercurial phases support code
2 #
2 #
3 # Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
3 # Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
4 # Logilab SA <contact@logilab.fr>
4 # Logilab SA <contact@logilab.fr>
5 # Augie Fackler <durin42@gmail.com>
5 # Augie Fackler <durin42@gmail.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 import errno
10 import errno
11 from node import nullid, bin, hex, short
11 from node import nullid, bin, hex, short
12 from i18n import _
12 from i18n import _
13
13
14 allphases = range(2)
14 allphases = range(2)
15 trackedphases = allphases[1:]
15 trackedphases = allphases[1:]
16
16
17 def readroots(repo):
17 def readroots(repo):
18 """Read phase roots from disk"""
18 """Read phase roots from disk"""
19 roots = [set() for i in allphases]
19 roots = [set() for i in allphases]
20 roots[0].add(nullid)
20 roots[0].add(nullid)
21 try:
21 try:
22 f = repo.sopener('phaseroots')
22 f = repo.sopener('phaseroots')
23 try:
23 try:
24 for line in f:
24 for line in f:
25 phase, nh = line.strip().split()
25 phase, nh = line.strip().split()
26 roots[int(phase)].add(bin(nh))
26 roots[int(phase)].add(bin(nh))
27 finally:
27 finally:
28 f.close()
28 f.close()
29 except IOError, inst:
29 except IOError, inst:
30 if inst.errno != errno.ENOENT:
30 if inst.errno != errno.ENOENT:
31 raise
31 raise
32 return roots
32 return roots
33
33
34 def writeroots(repo):
34 def writeroots(repo):
35 """Write phase roots from disk"""
35 """Write phase roots from disk"""
36 f = repo.sopener('phaseroots', 'w', atomictemp=True)
36 f = repo.sopener('phaseroots', 'w', atomictemp=True)
37 try:
37 try:
38 for phase, roots in enumerate(repo._phaseroots):
38 for phase, roots in enumerate(repo._phaseroots):
39 for h in roots:
39 for h in roots:
40 f.write('%i %s\n' % (phase, hex(h)))
40 f.write('%i %s\n' % (phase, hex(h)))
41 repo._dirtyphases = False
41 repo._dirtyphases = False
42 finally:
42 finally:
43 f.close()
43 f.close()
44
44
45 def filterunknown(repo, phaseroots=None):
45 def filterunknown(repo, phaseroots=None):
46 """remove unknown nodes from the phase boundary
46 """remove unknown nodes from the phase boundary
47
47
48 no data is lost as unknown node only old data for their descentants
48 no data is lost as unknown node only old data for their descentants
49 """
49 """
50 if phaseroots is None:
50 if phaseroots is None:
51 phaseroots = repo._phaseroots
51 phaseroots = repo._phaseroots
52 for phase, nodes in enumerate(phaseroots):
52 for phase, nodes in enumerate(phaseroots):
53 missing = [node for node in nodes if node not in repo]
53 missing = [node for node in nodes if node not in repo]
54 if missing:
54 if missing:
55 for mnode in missing:
55 for mnode in missing:
56 msg = _('Removing unknown node %(n)s from %(p)i-phase boundary')
56 msg = _('Removing unknown node %(n)s from %(p)i-phase boundary')
57 repo.ui.debug(msg, {'n': short(mnode), 'p': phase})
57 repo.ui.debug(msg, {'n': short(mnode), 'p': phase})
58 nodes.symmetric_difference_update(missing)
58 nodes.symmetric_difference_update(missing)
59 repo._dirtyphases = True
59 repo._dirtyphases = True
60
60
61 def advanceboundary(repo, targetphase, nodes):
61 def advanceboundary(repo, targetphase, nodes):
62 """Add nodes to a phase changing other nodes phases if necessary.
62 """Add nodes to a phase changing other nodes phases if necessary.
63
63
64 Simplify boundary to contains phase roots only."""
64 This function move boundary *forward* this means that all nodes are set
65 in the target phase or kept in a *lower* phase.
65
66
66 # move roots of lower states
67 Simplify boundary to contains phase roots only."""
67 for phase in xrange(targetphase + 1, len(allphases)):
68 for phase in xrange(targetphase + 1, len(allphases)):
68 # filter nodes that are not in a compatible phase already
69 # filter nodes that are not in a compatible phase already
69 # XXX rev phase cache might have been invalidated by a previous loop
70 # XXX rev phase cache might have been invalidated by a previous loop
70 # XXX we need to be smarter here
71 # XXX we need to be smarter here
71 nodes = [n for n in nodes if repo[n].phase() >= phase]
72 nodes = [n for n in nodes if repo[n].phase() >= phase]
72 if not nodes:
73 if not nodes:
73 break # no roots to move anymore
74 break # no roots to move anymore
74 roots = repo._phaseroots[phase]
75 roots = repo._phaseroots[phase]
75 olds = roots.copy()
76 olds = roots.copy()
76 ctxs = list(repo.set('roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
77 ctxs = list(repo.set('roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
77 roots.clear()
78 roots.clear()
78 roots.update(ctx.node() for ctx in ctxs)
79 roots.update(ctx.node() for ctx in ctxs)
79 if olds != roots:
80 if olds != roots:
80 # invalidate cache (we probably could be smarter here
81 # invalidate cache (we probably could be smarter here
81 if '_phaserev' in vars(repo):
82 if '_phaserev' in vars(repo):
82 del repo._phaserev
83 del repo._phaserev
83 repo._dirtyphases = True
84 repo._dirtyphases = True
85
86 def retractboundary(repo, targetphase, nodes):
87 """Set nodes back to a phase changing other nodes phases if necessary.
88
89 This function move boundary *backward* this means that all nodes are set
90 in the target phase or kept in a *higher* phase.
91
92 Simplify boundary to contains phase roots only."""
93 currentroots = repo._phaseroots[targetphase]
94 newroots = [n for n in nodes if repo[n].phase() < targetphase]
95 if newroots:
96 currentroots.update(newroots)
97 ctxs = repo.set('roots(%ln::)', currentroots)
98 currentroots.intersection_update(ctx.node() for ctx in ctxs)
99 if '_phaserev' in vars(repo):
100 del repo._phaserev
101 repo._dirtyphases = True
102
General Comments 0
You need to be logged in to leave comments. Login now