4 # Logilab SA <contact@logilab.fr> |
4 # Logilab SA <contact@logilab.fr> |
5 # |
5 # |
6 # This software may be used and distributed according to the terms of the |
6 # This software may be used and distributed according to the terms of the |
7 # GNU General Public License version 2 or any later version. |
7 # GNU General Public License version 2 or any later version. |
8 |
8 |
|
9 import collections |
9 import copy |
10 import copy |
10 import error |
11 import error |
11 import phases |
12 import phases |
12 import util |
13 import util |
13 import obsolete |
14 import obsolete |
14 import struct |
15 import struct |
15 import tags as tagsmod |
16 import tags as tagsmod |
|
17 from node import nullrev |
16 |
18 |
17 def hideablerevs(repo): |
19 def hideablerevs(repo): |
18 """Revisions candidates to be hidden |
20 """Revisions candidates to be hidden |
19 |
21 |
20 This is a standalone function to help extensions to wrap it.""" |
22 This is a standalone function to help extensions to wrap it.""" |
21 return obsolete.getrevs(repo, 'obsolete') |
23 return obsolete.getrevs(repo, 'obsolete') |
22 |
24 |
23 def _getstaticblockers(repo): |
25 def _getstatichidden(repo): |
24 """Cacheable revisions blocking hidden changesets from being filtered. |
26 """Cacheable revisions blocking hidden changesets from being filtered. |
25 |
27 |
26 Additional non-cached hidden blockers are computed in _getdynamicblockers. |
28 Additional non-cached hidden blockers are computed in _getdynamicblockers. |
27 This is a standalone function to help extensions to wrap it.""" |
29 This is a standalone function to help extensions to wrap it.""" |
28 assert not repo.changelog.filteredrevs |
30 assert not repo.changelog.filteredrevs |
29 hideable = hideablerevs(repo) |
31 hideable = hideablerevs(repo) |
30 blockers = set() |
|
31 if hideable: |
32 if hideable: |
32 # We use cl to avoid recursive lookup from repo[xxx] |
33 actuallyhidden = {} |
33 cl = repo.changelog |
34 getphase = repo._phasecache.phase |
34 firsthideable = min(hideable) |
35 getparentrevs = repo.changelog.parentrevs |
35 revs = cl.revs(start=firsthideable) |
36 queue = collections.deque((r, False) for r in repo.changelog.headrevs()) |
36 tofilter = repo.revs( |
37 while queue: |
37 '(%ld) and children(%ld)', list(revs), list(hideable)) |
38 rev, blocked = queue.popleft() |
38 blockers.update([r for r in tofilter if r not in hideable]) |
39 phase = getphase(repo, rev) |
39 return blockers |
40 # Skip nodes which are public (guaranteed to not be hidden) and |
|
41 # nodes which have already been processed and won't be blocked by |
|
42 # the previous node. |
|
43 if phase == 0 or (not blocked and rev in actuallyhidden): |
|
44 continue |
|
45 if rev in hideable: |
|
46 if blocked: |
|
47 actuallyhidden[rev] = False |
|
48 else: |
|
49 actuallyhidden.setdefault(rev, True) |
|
50 else: |
|
51 blocked = True |
|
52 |
|
53 for parent in (p for p in getparentrevs(rev) if p != nullrev): |
|
54 queue.append((parent, blocked)) |
|
55 return set(rev for rev, hidden in actuallyhidden.iteritems() if hidden) |
40 |
56 |
41 def _getdynamicblockers(repo): |
57 def _getdynamicblockers(repo): |
42 """Non-cacheable revisions blocking hidden changesets from being filtered. |
58 """Non-cacheable revisions blocking hidden changesets from being filtered. |
43 |
59 |
44 Get revisions that will block hidden changesets and are likely to change, |
60 Get revisions that will block hidden changesets and are likely to change, |
135 hideable = hideablerevs(repo) |
151 hideable = hideablerevs(repo) |
136 if hideable: |
152 if hideable: |
137 cl = repo.changelog |
153 cl = repo.changelog |
138 hidden = tryreadcache(repo, hideable) |
154 hidden = tryreadcache(repo, hideable) |
139 if hidden is None: |
155 if hidden is None: |
140 blocked = cl.ancestors(_getstaticblockers(repo), inclusive=True) |
156 hidden = frozenset(_getstatichidden(repo)) |
141 hidden = frozenset(r for r in hideable if r not in blocked) |
|
142 trywritehiddencache(repo, hideable, hidden) |
157 trywritehiddencache(repo, hideable, hidden) |
143 |
158 |
144 # check if we have wd parents, bookmarks or tags pointing to hidden |
159 # check if we have wd parents, bookmarks or tags pointing to hidden |
145 # changesets and remove those. |
160 # changesets and remove those. |
146 dynamic = hidden & _getdynamicblockers(repo) |
161 dynamic = hidden & _getdynamicblockers(repo) |