Mercurial > evolve
comparison hgext3rd/evolve/obshistory.py @ 2411:bd937b7ce7d2
debugobshistory: handle multiple cycles
We previously handled up to one cycle only. This is now fixed.
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Thu, 18 May 2017 14:58:22 +0200 |
parents | 783a74c60a5e |
children | 89a5dabbb43d |
comparison
equal
deleted
inserted
replaced
2410:0756d36696bc | 2411:bd937b7ce7d2 |
---|---|
82 o = object() | 82 o = object() |
83 path = [o] | 83 path = [o] |
84 path_set = set(path) | 84 path_set = set(path) |
85 stack = [iter(graph)] | 85 stack = [iter(graph)] |
86 while stack: | 86 while stack: |
87 for v in stack[-1]: | 87 for v in sorted(stack[-1]): |
88 if v in path_set: | 88 if v in path_set: |
89 path_set.remove(o) | 89 path_set.remove(o) |
90 return path_set | 90 return path_set |
91 elif v not in visited: | 91 elif v not in visited: |
92 visited.add(v) | 92 visited.add(v) |
106 """ | 106 """ |
107 | 107 |
108 # Get the list of nodes and links between them | 108 # Get the list of nodes and links between them |
109 candidates, nodesucc, nodeprec = _obshistorywalker_links(repo, revs) | 109 candidates, nodesucc, nodeprec = _obshistorywalker_links(repo, revs) |
110 | 110 |
111 # If we have a cycle | |
112 cycle = cyclic(nodesucc) | |
113 # XXX We might have multiple cycles | |
114 if cycle: | |
115 # Break the cycle | |
116 breaknode = sorted(cycle)[0] | |
117 # By removing one of the node in the cycle successors | |
118 del nodesucc[breaknode] | |
119 repo.ui.debug('obs-cycle detected, breaking at %s\n' | |
120 % nodemod.short(breaknode)) | |
121 | |
122 # Shown, set of nodes presents in items | 111 # Shown, set of nodes presents in items |
123 shown = set() | 112 shown = set() |
124 | 113 |
125 def isvalidcandidate(candidate): | 114 def isvalidcandidate(candidate): |
126 """ Function to filter candidates, check the candidate succ are | 115 """ Function to filter candidates, check the candidate succ are |
133 | 122 |
134 # Filter out candidates, returns only nodes with all their successors | 123 # Filter out candidates, returns only nodes with all their successors |
135 # already shown | 124 # already shown |
136 validcandidates = filter(isvalidcandidate, candidates) | 125 validcandidates = filter(isvalidcandidate, candidates) |
137 | 126 |
138 # Check for cycles | 127 # If we likely have a cycle |
139 assert validcandidates | 128 if not validcandidates: |
140 | 129 cycle = cyclic(nodesucc) |
130 assert cycle | |
131 | |
132 # Then choose a random node from the cycle | |
133 breaknode = sorted(cycle)[0] | |
134 # And display it by force | |
135 repo.ui.debug('obs-cycle detected, forcing display of %s\n' | |
136 % nodemod.short(breaknode)) | |
137 validcandidates = [breaknode] | |
138 | |
139 # Display all valid candidates | |
141 for cand in sorted(validcandidates): | 140 for cand in sorted(validcandidates): |
142 # Remove candidate from candidates set | 141 # Remove candidate from candidates set |
143 candidates.remove(cand) | 142 candidates.remove(cand) |
143 # And remove it from nodesucc in case of future cycle detected | |
144 try: | |
145 del nodesucc[cand] | |
146 except KeyError: | |
147 pass | |
148 | |
144 shown.add(cand) | 149 shown.add(cand) |
145 | 150 |
146 # Add the right changectx class | 151 # Add the right changectx class |
147 if cand in repo: | 152 if cand in repo: |
148 changectx = repo[cand] | 153 changectx = repo[cand] |