annotate hgext/hbisect.py @ 5773:2f6105ab4c54

bisect: merge ancestor lists when pushing to children - eliminate some redundant tests and assignments - move ancestor list merging to child update
author Matt Mackall <mpm@selenic.com>
date Mon, 31 Dec 2007 18:20:34 -0600
parents 4c46636eafe5
children c850a8640981
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1855
0ba9dee8cfbd Fixed spacing/indentation, removed #! script header, added short description.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1854
diff changeset
1 # bisect extension for mercurial
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
2 #
1861
65949d1c9bf7 Added copyright information to hbisect.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1856
diff changeset
3 # Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
65949d1c9bf7 Added copyright information to hbisect.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1856
diff changeset
4 # Inspired by git bisect, extension skeleton taken from mq.py.
65949d1c9bf7 Added copyright information to hbisect.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1856
diff changeset
5 #
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
6 # This software may be used and distributed according to the terms
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
7 # of the GNU General Public License, incorporated herein by reference.
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
8
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
9 from mercurial.i18n import _
5731
19691160d7f5 bisect: remove unused imports
Matt Mackall <mpm@selenic.com>
parents: 5730
diff changeset
10 from mercurial import hg, util, cmdutil
5767
dd5f8ed31057 bisect: propagate ancestor lists directly to children
Matt Mackall <mpm@selenic.com>
parents: 5766
diff changeset
11 import os
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
12
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
13 def _bisect(changelog, state):
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
14 clparents = changelog.parentrevs
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
15 # only the earliest bad revision matters
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
16 badrev = min([changelog.rev(n) for n in state['bad']])
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
17 bad = changelog.node(badrev)
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
18 skip = dict.fromkeys([changelog.rev(n) for n in state['skip']])
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
19
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
20 # build ancestors array
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
21 ancestors = [[]] * (changelog.count() + 1) # an extra for [-1]
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
22
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
23 # clear good revs from array
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
24 for node in state['good']:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
25 ancestors[changelog.rev(node)] = None
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
26 for rev in xrange(changelog.count(), -1, -1):
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
27 if ancestors[rev] is None:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
28 for prev in clparents(rev):
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
29 ancestors[prev] = None
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
30
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
31 if ancestors[badrev] is None:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
32 raise util.Abort(_("Inconsistent state, %s:%s is good and bad")
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
33 % (badrev, hg.short(bad)))
5723
e3b09819496b bisect: switch to rev-based calculation
Matt Mackall <mpm@selenic.com>
parents: 5722
diff changeset
34
5768
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
35 # build children dict
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
36 children = {}
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
37 visit = [badrev]
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
38 candidates = []
5768
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
39 while visit:
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
40 rev = visit.pop(0)
5767
dd5f8ed31057 bisect: propagate ancestor lists directly to children
Matt Mackall <mpm@selenic.com>
parents: 5766
diff changeset
41 if ancestors[rev] == []:
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
42 candidates.append(rev)
5767
dd5f8ed31057 bisect: propagate ancestor lists directly to children
Matt Mackall <mpm@selenic.com>
parents: 5766
diff changeset
43 for prev in clparents(rev):
5768
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
44 if prev != -1:
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
45 if prev in children:
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
46 children[prev].append(rev)
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
47 else:
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
48 children[prev] = [rev]
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
49 visit.append(prev)
5767
dd5f8ed31057 bisect: propagate ancestor lists directly to children
Matt Mackall <mpm@selenic.com>
parents: 5766
diff changeset
50
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
51 candidates.sort()
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
52 # have we narrowed it down to one entry?
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
53 tot = len(candidates)
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
54 if tot == 1:
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
55 return (bad, 0)
5771
9d3f49f52a4a bisect: stop early if we find a perfect candidate
Matt Mackall <mpm@selenic.com>
parents: 5770
diff changeset
56 perfect = tot / 2
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
57
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
58 # find the best node to test
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
59 best_rev = None
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
60 best_len = -1
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
61 poison = {}
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
62 for rev in candidates:
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
63 if rev in poison:
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
64 for c in children.get(rev, []):
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
65 poison[c] = True # poison children
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
66 continue
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
67
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
68 a = ancestors[rev] or [rev]
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
69 ancestors[rev] = None
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
70
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
71 x = len(a) # number of ancestors
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
72 y = tot - x # number of non-ancestors
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
73 value = min(x, y) # how good is this test?
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
74 if value > best_len and rev not in skip:
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
75 best_len = value
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
76 best_rev = rev
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
77 if value == perfect: # found a perfect candidate? quit early
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
78 break
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
79
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
80 if y < perfect: # all downhill from here?
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
81 for c in children.get(rev, []):
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
82 poison[c] = True # poison children
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
83 continue
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
84
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
85 for c in children.get(rev, []):
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
86 if ancestors[c]:
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
87 s = dict.fromkeys(ancestors[c])
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
88 s.update(dict.fromkeys(a))
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
89 ancestors[c] = s.keys()
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
90 else:
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
91 ancestors[c] = a + [c]
5734
944b231fa0e7 bisect: move reporting out of core bisect function
Matt Mackall <mpm@selenic.com>
parents: 5733
diff changeset
92
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
93 assert best_rev is not None
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
94 best_node = changelog.node(best_rev)
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
95
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
96 return (best_node, tot)
5733
47ec288456bb bisect: add skip command
Matt Mackall <mpm@selenic.com>
parents: 5732
diff changeset
97
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
98 def bisect(ui, repo, rev=None, extra=None,
5766
23caedc5a28f bisect: add noupdate option
Matt Mackall <mpm@selenic.com>
parents: 5738
diff changeset
99 reset=None, good=None, bad=None, skip=None, noupdate=None):
5729
73646515c435 bisect: slightly improve the help message
Matt Mackall <mpm@selenic.com>
parents: 5728
diff changeset
100 """Subdivision search of changesets
4390
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
101
5729
73646515c435 bisect: slightly improve the help message
Matt Mackall <mpm@selenic.com>
parents: 5728
diff changeset
102 This extension helps to find changesets which introduce problems.
73646515c435 bisect: slightly improve the help message
Matt Mackall <mpm@selenic.com>
parents: 5728
diff changeset
103 To use, mark the earliest changeset you know exhibits the problem
4390
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
104 as bad, then mark the latest changeset which is free from the problem
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
105 as good. Bisect will update your working directory to a revision for
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
106 testing. Once you have performed tests, mark the working directory
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
107 as bad or good and bisect will either update to another candidate
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
108 changeset or announce that it has found the bad revision.
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
109
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
110 Note: bisect expects bad revisions to be descendants of good revisions.
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
111 If you are looking for the point at which a problem was fixed, then make
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
112 the problem-free state "bad" and the problematic state "good."
052062b98f26 Flesh out bisect help text
Brendan Cully <brendan@kublai.com>
parents: 3891
diff changeset
113
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
114 """
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
115 # backward compatibility
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
116 if rev in "good bad reset init".split():
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
117 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
118 cmd, rev, extra = rev, extra, None
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
119 if cmd == "good":
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
120 good = True
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
121 elif cmd == "bad":
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
122 bad = True
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
123 else:
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
124 reset = True
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
125 elif extra or good + bad + skip + reset > 1:
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
126 raise util.Abort("Incompatible arguments")
1855
0ba9dee8cfbd Fixed spacing/indentation, removed #! script header, added short description.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1854
diff changeset
127
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
128 if reset:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
129 p = repo.join("bisect.state")
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
130 if os.path.exists(p):
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
131 os.unlink(p)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
132 return
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
133
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
134 # load state
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
135 state = {'good': [], 'bad': [], 'skip': []}
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
136 if os.path.exists(repo.join("bisect.state")):
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
137 for l in repo.opener("bisect.state"):
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
138 kind, node = l[:-1].split()
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
139 node = repo.lookup(node)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
140 if kind not in state:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
141 raise util.Abort(_("unknown bisect kind %s") % kind)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
142 state[kind].append(node)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
143
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
144 # update state
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
145 node = repo.lookup(rev or '.')
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
146 if good:
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
147 state['good'].append(node)
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
148 elif bad:
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
149 state['bad'].append(node)
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
150 elif skip:
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
151 state['skip'].append(node)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
152
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
153 # save state
5738
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
154 f = repo.opener("bisect.state", "w", atomictemp=True)
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
155 wlock = repo.wlock()
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
156 try:
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
157 for kind in state:
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
158 for node in state[kind]:
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
159 f.write("%s %s\n" % (kind, hg.hex(node)))
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
160 f.rename()
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
161 finally:
2a54e2b177b6 bisect: use proper locking when updating bisect.state
Matt Mackall <mpm@selenic.com>
parents: 5737
diff changeset
162 del wlock
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
163
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
164 if not state['good'] or not state['bad']:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
165 return
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
166
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
167 # actually bisect
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
168 node, changesets = _bisect(repo.changelog, state)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
169 if changesets == 0:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
170 ui.write(_("The first bad revision is:\n"))
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
171 displayer = cmdutil.show_changeset(ui, repo, {})
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
172 displayer.show(changenode=node)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
173 elif node is not None:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
174 # compute the approximate number of remaining tests
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
175 tests, size = 0, 2
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
176 while size <= changesets:
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
177 tests, size = tests + 1, size * 2
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
178 rev = repo.changelog.rev(node)
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
179 ui.write(_("Testing changeset %s:%s "
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
180 "(%s changesets remaining, ~%s tests)\n")
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
181 % (rev, hg.short(node), changesets, tests))
5766
23caedc5a28f bisect: add noupdate option
Matt Mackall <mpm@selenic.com>
parents: 5738
diff changeset
182 if not noupdate:
23caedc5a28f bisect: add noupdate option
Matt Mackall <mpm@selenic.com>
parents: 5738
diff changeset
183 cmdutil.bail_if_changed(repo)
23caedc5a28f bisect: add noupdate option
Matt Mackall <mpm@selenic.com>
parents: 5738
diff changeset
184 return hg.clean(repo, node)
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
185
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
186 cmdtable = {
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
187 "bisect": (bisect,
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
188 [('r', 'reset', False, _('reset bisect state')),
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
189 ('g', 'good', False, _('mark changeset good')),
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
190 ('b', 'bad', False, _('mark changeset bad')),
5766
23caedc5a28f bisect: add noupdate option
Matt Mackall <mpm@selenic.com>
parents: 5738
diff changeset
191 ('s', 'skip', False, _('skip testing changeset')),
23caedc5a28f bisect: add noupdate option
Matt Mackall <mpm@selenic.com>
parents: 5738
diff changeset
192 ('U', 'noupdate', False, _('do not update to target'))],
5735
9079081b8982 bisect: use more standard command syntax and help
Matt Mackall <mpm@selenic.com>
parents: 5734
diff changeset
193 _("hg bisect [-gbsr] [REV]"))
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
194 }