Mercurial > evolve
comparison hgext3rd/topic/stack.py @ 2919:5b514ab2ab4e
stack: properly order stack when gaps existing inside it
We transitively search for the next "stack" ancestors, of changeset in the stack
not based on other revision of the stack. This should help having a consistent
display when topic are interleaved.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Sat, 09 Sep 2017 22:32:50 +0530 |
parents | 0437158e0ed6 |
children | 3a9303b7b648 |
comparison
equal
deleted
inserted
replaced
2918:0437158e0ed6 | 2919:5b514ab2ab4e |
---|---|
6 from mercurial import ( | 6 from mercurial import ( |
7 destutil, | 7 destutil, |
8 context, | 8 context, |
9 error, | 9 error, |
10 node, | 10 node, |
11 phases, | |
11 util, | 12 util, |
12 ) | 13 ) |
13 from .evolvebits import builddependencies, _orderrevs, _singlesuccessor | 14 from .evolvebits import builddependencies, _singlesuccessor |
14 | 15 |
15 short = node.short | 16 short = node.short |
16 | 17 |
17 # TODO: compat | 18 # TODO: compat |
18 | 19 |
48 def index(self, item): | 49 def index(self, item): |
49 return self.revs.index(item) | 50 return self.revs.index(item) |
50 | 51 |
51 @util.propertycache | 52 @util.propertycache |
52 def _dependencies(self): | 53 def _dependencies(self): |
53 return builddependencies(self._repo, self.revs[1:]) | 54 deps, rdeps = builddependencies(self._repo, self._revs) |
55 | |
56 repo = self._repo | |
57 srcpfunc = repo.changelog.parentrevs | |
58 | |
59 ### post process to skip over possible gaps in the stack | |
60 # | |
61 # For example in the following situation, we need to detect that "t3" | |
62 # indirectly depends on t2. | |
63 # | |
64 # o t3 | |
65 # | | |
66 # o other | |
67 # | | |
68 # o t2 | |
69 # | | |
70 # o t1 | |
71 | |
72 pmap = {} | |
73 | |
74 def pfuncrev(repo, rev): | |
75 """a special "parent func" that also consider successors""" | |
76 parents = pmap.get(rev) | |
77 if parents is None: | |
78 parents = [repo[_singlesuccessor(repo, repo[p])].rev() | |
79 for p in srcpfunc(rev) if 0 <= p] | |
80 pmap[rev] = parents | |
81 return parents | |
82 | |
83 revs = self._revs | |
84 stackrevs = set(self._revs) | |
85 for root in [r for r in revs if not deps[r]]: | |
86 seen = set() | |
87 stack = [root] | |
88 while stack: | |
89 current = stack.pop() | |
90 for p in pfuncrev(repo, current): | |
91 if p in seen: | |
92 continue | |
93 seen.add(p) | |
94 if p in stackrevs: | |
95 rdeps[p].add(root) | |
96 deps[root].add(p) | |
97 elif phases.public < repo[p].phase(): | |
98 # traverse only if we did not found a proper candidate | |
99 stack.append(p) | |
100 | |
101 return deps, rdeps | |
54 | 102 |
55 @util.propertycache | 103 @util.propertycache |
56 def revs(self): | 104 def revs(self): |
57 revs = _orderrevs(self._repo, self._revs) | 105 # some duplication/change from _orderrevs because we use a post |
106 # processed dependency graph. | |
107 | |
108 # Step 1: compute relation of revision with each other | |
109 dependencies, rdependencies = self._dependencies | |
110 dependencies = dependencies.copy() | |
111 rdependencies = rdependencies.copy() | |
112 # Step 2: Build the ordering | |
113 # Remove the revisions with no dependency(A) and add them to the ordering. | |
114 # Removing these revisions leads to new revisions with no dependency (the | |
115 # one depending on A) that we can remove from the dependency graph and add | |
116 # to the ordering. We progress in a similar fashion until the ordering is | |
117 # built | |
118 solvablerevs = [r for r in sorted(dependencies.keys()) | |
119 if not dependencies[r]] | |
120 revs = [] | |
121 while solvablerevs: | |
122 rev = solvablerevs.pop() | |
123 for dependent in rdependencies[rev]: | |
124 dependencies[dependent].remove(rev) | |
125 if not dependencies[dependent]: | |
126 solvablerevs.append(dependent) | |
127 del dependencies[rev] | |
128 revs.append(rev) | |
129 | |
130 revs.extend(sorted(dependencies)) | |
131 # step 3: add t0 | |
58 if revs: | 132 if revs: |
59 pt1 = self._repo[revs[0]].p1() | 133 pt1 = self._repo[revs[0]].p1() |
60 if pt1.obsolete(): | 134 if pt1.obsolete(): |
61 pt1 = self._repo[_singlesuccessor(self._repo, pt1)] | 135 pt1 = self._repo[_singlesuccessor(self._repo, pt1)] |
62 revs.insert(0, pt1.rev()) | 136 revs.insert(0, pt1.rev()) |