##// END OF EJS Templates
bisect: handle search for bad to good transitions...
Matt Mackall -
r5776:35ec669c default
parent child Browse files
Show More
@@ -258,11 +258,6 b' def bisect(ui, repo, rev=None, extra=Non'
258 working directory as bad or good and bisect will either update to
258 working directory as bad or good and bisect will either update to
259 another candidate changeset or announce that it has found the bad
259 another candidate changeset or announce that it has found the bad
260 revision.
260 revision.
261
262 Note: bisect expects bad revisions to be descendants of good
263 revisions. If you are looking for the point at which a problem was
264 fixed, then make the problem-free state \"bad\" and the
265 problematic state \"good.\"
266 """
261 """
267 # backward compatibility
262 # backward compatibility
268 if rev in "good bad reset init".split():
263 if rev in "good bad reset init".split():
@@ -317,9 +312,9 b' def bisect(ui, repo, rev=None, extra=Non'
317 return
312 return
318
313
319 # actually bisect
314 # actually bisect
320 node, changesets = hbisect.bisect(repo.changelog, state)
315 node, changesets, good = hbisect.bisect(repo.changelog, state)
321 if changesets == 0:
316 if changesets == 0:
322 ui.write(_("The first bad revision is:\n"))
317 ui.write(_("The first %s revision is:\n") % (good and "good" or "bad"))
323 displayer = cmdutil.show_changeset(ui, repo, {})
318 displayer = cmdutil.show_changeset(ui, repo, {})
324 displayer.show(changenode=node)
319 displayer.show(changenode=node)
325 elif node is not None:
320 elif node is not None:
@@ -12,25 +12,36 b' import hg, util'
12
12
13 def bisect(changelog, state):
13 def bisect(changelog, state):
14 clparents = changelog.parentrevs
14 clparents = changelog.parentrevs
15 # only the earliest bad revision matters
16 badrev = min([changelog.rev(n) for n in state['bad']])
17 bad = changelog.node(badrev)
18 skip = dict.fromkeys([changelog.rev(n) for n in state['skip']])
15 skip = dict.fromkeys([changelog.rev(n) for n in state['skip']])
19
16
17 def buildancestors(bad, good):
18 # only the earliest bad revision matters
19 badrev = min([changelog.rev(n) for n in bad])
20 goodrevs = [changelog.rev(n) for n in good]
20 # build ancestors array
21 # build ancestors array
21 ancestors = [[]] * (changelog.count() + 1) # an extra for [-1]
22 ancestors = [[]] * (changelog.count() + 1) # an extra for [-1]
22
23
23 # clear good revs from array
24 # clear good revs from array
24 for node in state['good']:
25 for node in goodrevs:
25 ancestors[changelog.rev(node)] = None
26 ancestors[node] = None
26 for rev in xrange(changelog.count(), -1, -1):
27 for rev in xrange(changelog.count(), -1, -1):
27 if ancestors[rev] is None:
28 if ancestors[rev] is None:
28 for prev in clparents(rev):
29 for prev in clparents(rev):
29 ancestors[prev] = None
30 ancestors[prev] = None
30
31
31 if ancestors[badrev] is None:
32 if ancestors[badrev] is None:
33 return None, None
34 return badrev, ancestors
35
36 good = 0
37 badrev, ancestors = buildancestors(state['bad'], state['good'])
38 if not ancestors: # looking for bad to good transition?
39 good = 1
40 badrev, ancestors = buildancestors(state['good'], state['bad'])
41 if not ancestors: # now we're confused
32 raise util.Abort(_("Inconsistent state, %s:%s is good and bad")
42 raise util.Abort(_("Inconsistent state, %s:%s is good and bad")
33 % (badrev, hg.short(bad)))
43 % (badrev, hg.short(bad)))
44 bad = changelog.node(badrev)
34
45
35 # build children dict
46 # build children dict
36 children = {}
47 children = {}
@@ -52,7 +63,7 b' def bisect(changelog, state):'
52 # have we narrowed it down to one entry?
63 # have we narrowed it down to one entry?
53 tot = len(candidates)
64 tot = len(candidates)
54 if tot == 1:
65 if tot == 1:
55 return (bad, 0)
66 return (bad, 0, good)
56 perfect = tot / 2
67 perfect = tot / 2
57
68
58 # find the best node to test
69 # find the best node to test
@@ -91,4 +102,4 b' def bisect(changelog, state):'
91 assert best_rev is not None
102 assert best_rev is not None
92 best_node = changelog.node(best_rev)
103 best_node = changelog.node(best_rev)
93
104
94 return (best_node, tot)
105 return (best_node, tot, good)
@@ -31,3 +31,13 b' hg bisect -g'
31 hg bisect -g
31 hg bisect -g
32 hg bisect -b
32 hg bisect -b
33 hg bisect -g
33 hg bisect -g
34
35 echo % bisect reverse test
36 hg bisect -r
37 hg bisect -b null
38 hg bisect -g tip
39 hg bisect -g
40 hg bisect -g
41 hg bisect -g
42 hg bisect -b
43 hg bisect -g
@@ -214,3 +214,20 b' user: test'
214 date: Thu Jan 01 00:00:29 1970 +0000
214 date: Thu Jan 01 00:00:29 1970 +0000
215 summary: msg 29
215 summary: msg 29
216
216
217 % bisect reverse test
218 Testing changeset 15:e7fa0811edb0 (32 changesets remaining, ~5 tests)
219 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 Testing changeset 7:03750880c6b5 (16 changesets remaining, ~4 tests)
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 Testing changeset 3:b53bea5e2fcb (8 changesets remaining, ~3 tests)
223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 Testing changeset 1:5cd978ea5149 (4 changesets remaining, ~2 tests)
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
226 Testing changeset 2:db07c04beaca (2 changesets remaining, ~1 tests)
227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 The first good revision is:
229 changeset: 2:db07c04beaca
230 user: test
231 date: Thu Jan 01 00:00:02 1970 +0000
232 summary: msg 2
233
General Comments 0
You need to be logged in to leave comments. Login now