Mercurial > public > mercurial-scm > hg
comparison mercurial/hbisect.py @ 15146:b39d85be78a8
hbisect.get: use simpler code with repo.set(), fix 'pruned' set
Use repo.set() wherever possible, instead of locally trying to
reproduce complex graph computations.
'pruned' now means 'all csets that will no longer be visited by the
bisection'. The change is done is this very patch instead of its own
dedicated one becasue the code changes all over the place, and the
previous 'pruned' code was totally rewritten by the cleanup, so it
was easier to just change the behavior at the same time.
The previous series went in too fast for this cleanup pass to be
included, so here it is. ;-)
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
author | "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr> |
---|---|
date | Tue, 20 Sep 2011 20:19:48 +0200 |
parents | 883d28233a4d |
children | 395ca8cd2669 |
comparison
equal
deleted
inserted
replaced
15145:ff26712a0c50 | 15146:b39d85be78a8 |
---|---|
158 """ | 158 """ |
159 Return a list of revision(s) that match the given status: | 159 Return a list of revision(s) that match the given status: |
160 | 160 |
161 - ``good``, ``bad``, ``skip``: as the names imply | 161 - ``good``, ``bad``, ``skip``: as the names imply |
162 - ``range`` : all csets taking part in the bisection | 162 - ``range`` : all csets taking part in the bisection |
163 - ``pruned`` : good|bad|skip, excluding out-of-range csets | 163 - ``pruned`` : csets that are good, bad or skipped |
164 - ``untested`` : csets whose fate is yet unknown | 164 - ``untested`` : csets whose fate is yet unknown |
165 """ | 165 """ |
166 state = load_state(repo) | 166 state = load_state(repo) |
167 if status in ('good', 'bad', 'skip'): | 167 if status in ('good', 'bad', 'skip'): |
168 return [repo.changelog.rev(n) for n in state[status]] | 168 return [repo.changelog.rev(n) for n in state[status]] |
169 else: | 169 else: |
170 # Build sets of good, bad, and skipped csets | 170 # In the floowing sets, we do *not* call 'bisect()' with more |
171 goods = set(repo.changelog.rev(n) for n in state['good']) | 171 # than one level of recusrsion, because that can be very, very |
172 bads = set(repo.changelog.rev(n) for n in state['bad']) | 172 # time consuming. Instead, we always develop the expression as |
173 skips = set(repo.changelog.rev(n) for n in state['skip']) | 173 # much as possible. |
174 | 174 |
175 # Build kinship of good csets | 175 # 'range' is all csets that make the bisection: |
176 ga = goods.copy() # Goods' Ancestors | 176 # - have a good ancestor and a bad descendant, or conversely |
177 gd = goods.copy() # Goods' Descendants | 177 # that's because the bisection can go either way |
178 for g in goods: | 178 range = '( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )' |
179 ga |= set(repo.changelog.ancestors(g)) | 179 |
180 gd |= set(repo.changelog.descendants(g)) | 180 # 'pruned' is all csets whose fate is already known: |
181 | 181 # - a good ancestor and a good ascendant, or |
182 # Build kinship of bad csets | 182 # - a bad ancestor and a bad descendant, or |
183 ba = bads.copy() # Bads' Ancestors | 183 # - skipped |
184 bd = bads.copy() # Bads' Descendants | 184 # But in case of irrelevant goods/bads, we also need to |
185 for b in bads: | 185 # include them. |
186 ba |= set(repo.changelog.ancestors(b)) | 186 pg = 'bisect(good)::bisect(good)' # Pruned goods |
187 bd |= set(repo.changelog.descendants(b)) | 187 pb = 'bisect(bad)::bisect(bad)' # Pruned bads |
188 | 188 ps = 'bisect(skip)' # Pruned skipped |
189 # Build the range of the bisection | 189 pruned = '( (%s) | (%s) | (%s) )' % (pg, pb, ps) |
190 range = set(c for c in ba if c in gd) | 190 |
191 range |= set(c for c in ga if c in bd) | 191 # 'untested' is all cset that are- in 'range', but not in 'pruned' |
192 untested = '( (%s) - (%s) )' % (range, pruned) | |
192 | 193 |
193 if status == 'range': | 194 if status == 'range': |
194 return [c for c in range] | 195 return [c.rev() for c in repo.set(range)] |
195 elif status == 'pruned': | 196 elif status == 'pruned': |
196 # We do not want skipped csets that are out-of-range | 197 return [c.rev() for c in repo.set(pruned)] |
197 return [c for c in range if c in (goods | bads | skips)] | |
198 elif status == 'untested': | 198 elif status == 'untested': |
199 # Return the csets in range that are not pruned | 199 return [c.rev() for c in repo.set(untested)] |
200 return [c for c in range if not c in (goods | bads | skips)] | |
201 | 200 |
202 else: | 201 else: |
203 raise error.ParseError(_('invalid bisect state')) | 202 raise error.ParseError(_('invalid bisect state')) |