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]