##// 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 1 # Mercurial phases support code
2 2 #
3 3 # Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
4 4 # Logilab SA <contact@logilab.fr>
5 5 # Augie Fackler <durin42@gmail.com>
6 6 #
7 7 # This software may be used and distributed according to the terms of the
8 8 # GNU General Public License version 2 or any later version.
9 9
10 10 import errno
11 11 from node import nullid, bin, hex, short
12 12 from i18n import _
13 13
14 14 allphases = range(2)
15 15 trackedphases = allphases[1:]
16 16
17 17 def readroots(repo):
18 18 """Read phase roots from disk"""
19 19 roots = [set() for i in allphases]
20 20 roots[0].add(nullid)
21 21 try:
22 22 f = repo.sopener('phaseroots')
23 23 try:
24 24 for line in f:
25 25 phase, nh = line.strip().split()
26 26 roots[int(phase)].add(bin(nh))
27 27 finally:
28 28 f.close()
29 29 except IOError, inst:
30 30 if inst.errno != errno.ENOENT:
31 31 raise
32 32 return roots
33 33
34 34 def writeroots(repo):
35 35 """Write phase roots from disk"""
36 36 f = repo.sopener('phaseroots', 'w', atomictemp=True)
37 37 try:
38 38 for phase, roots in enumerate(repo._phaseroots):
39 39 for h in roots:
40 40 f.write('%i %s\n' % (phase, hex(h)))
41 41 repo._dirtyphases = False
42 42 finally:
43 43 f.close()
44 44
45 45 def filterunknown(repo, phaseroots=None):
46 46 """remove unknown nodes from the phase boundary
47 47
48 48 no data is lost as unknown node only old data for their descentants
49 49 """
50 50 if phaseroots is None:
51 51 phaseroots = repo._phaseroots
52 52 for phase, nodes in enumerate(phaseroots):
53 53 missing = [node for node in nodes if node not in repo]
54 54 if missing:
55 55 for mnode in missing:
56 56 msg = _('Removing unknown node %(n)s from %(p)i-phase boundary')
57 57 repo.ui.debug(msg, {'n': short(mnode), 'p': phase})
58 58 nodes.symmetric_difference_update(missing)
59 59 repo._dirtyphases = True
60 60
61 61 def advanceboundary(repo, targetphase, nodes):
62 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 68 for phase in xrange(targetphase + 1, len(allphases)):
68 69 # filter nodes that are not in a compatible phase already
69 70 # XXX rev phase cache might have been invalidated by a previous loop
70 71 # XXX we need to be smarter here
71 72 nodes = [n for n in nodes if repo[n].phase() >= phase]
72 73 if not nodes:
73 74 break # no roots to move anymore
74 75 roots = repo._phaseroots[phase]
75 76 olds = roots.copy()
76 77 ctxs = list(repo.set('roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
77 78 roots.clear()
78 79 roots.update(ctx.node() for ctx in ctxs)
79 80 if olds != roots:
80 81 # invalidate cache (we probably could be smarter here
81 82 if '_phaserev' in vars(repo):
82 83 del repo._phaserev
83 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