##// END OF EJS Templates
bisect: use changelog for iteration...
Pierre-Yves David -
r18463:07771e23 stable
parent child Browse files
Show More
@@ -1,258 +1,258
1 1 # changelog bisection for mercurial
2 2 #
3 3 # Copyright 2007 Matt Mackall
4 4 # Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
5 5 #
6 6 # Inspired by git bisect, extension skeleton taken from mq.py.
7 7 #
8 8 # This software may be used and distributed according to the terms of the
9 9 # GNU General Public License version 2 or any later version.
10 10
11 11 import os, error
12 12 from i18n import _
13 13 from node import short, hex
14 14 import util
15 15
16 16 def bisect(changelog, state):
17 17 """find the next node (if any) for testing during a bisect search.
18 18 returns a (nodes, number, good) tuple.
19 19
20 20 'nodes' is the final result of the bisect if 'number' is 0.
21 21 Otherwise 'number' indicates the remaining possible candidates for
22 22 the search and 'nodes' contains the next bisect target.
23 23 'good' is True if bisect is searching for a first good changeset, False
24 24 if searching for a first bad one.
25 25 """
26 26
27 27 clparents = changelog.parentrevs
28 28 skip = set([changelog.rev(n) for n in state['skip']])
29 29
30 30 def buildancestors(bad, good):
31 31 # only the earliest bad revision matters
32 32 badrev = min([changelog.rev(n) for n in bad])
33 33 goodrevs = [changelog.rev(n) for n in good]
34 34 goodrev = min(goodrevs)
35 35 # build visit array
36 36 ancestors = [None] * (len(changelog) + 1) # an extra for [-1]
37 37
38 38 # set nodes descended from goodrevs
39 39 for rev in goodrevs:
40 40 ancestors[rev] = []
41 for rev in xrange(goodrev + 1, len(changelog)):
41 for rev in changelog.revs(goodrev + 1):
42 42 for prev in clparents(rev):
43 43 if ancestors[prev] == []:
44 44 ancestors[rev] = []
45 45
46 46 # clear good revs from array
47 47 for rev in goodrevs:
48 48 ancestors[rev] = None
49 for rev in xrange(len(changelog), goodrev, -1):
49 for rev in changelog.revs(len(changelog), goodrev):
50 50 if ancestors[rev] is None:
51 51 for prev in clparents(rev):
52 52 ancestors[prev] = None
53 53
54 54 if ancestors[badrev] is None:
55 55 return badrev, None
56 56 return badrev, ancestors
57 57
58 58 good = False
59 59 badrev, ancestors = buildancestors(state['bad'], state['good'])
60 60 if not ancestors: # looking for bad to good transition?
61 61 good = True
62 62 badrev, ancestors = buildancestors(state['good'], state['bad'])
63 63 bad = changelog.node(badrev)
64 64 if not ancestors: # now we're confused
65 65 if len(state['bad']) == 1 and len(state['good']) == 1:
66 66 raise util.Abort(_("starting revisions are not directly related"))
67 67 raise util.Abort(_("inconsistent state, %s:%s is good and bad")
68 68 % (badrev, short(bad)))
69 69
70 70 # build children dict
71 71 children = {}
72 72 visit = util.deque([badrev])
73 73 candidates = []
74 74 while visit:
75 75 rev = visit.popleft()
76 76 if ancestors[rev] == []:
77 77 candidates.append(rev)
78 78 for prev in clparents(rev):
79 79 if prev != -1:
80 80 if prev in children:
81 81 children[prev].append(rev)
82 82 else:
83 83 children[prev] = [rev]
84 84 visit.append(prev)
85 85
86 86 candidates.sort()
87 87 # have we narrowed it down to one entry?
88 88 # or have all other possible candidates besides 'bad' have been skipped?
89 89 tot = len(candidates)
90 90 unskipped = [c for c in candidates if (c not in skip) and (c != badrev)]
91 91 if tot == 1 or not unskipped:
92 92 return ([changelog.node(rev) for rev in candidates], 0, good)
93 93 perfect = tot // 2
94 94
95 95 # find the best node to test
96 96 best_rev = None
97 97 best_len = -1
98 98 poison = set()
99 99 for rev in candidates:
100 100 if rev in poison:
101 101 # poison children
102 102 poison.update(children.get(rev, []))
103 103 continue
104 104
105 105 a = ancestors[rev] or [rev]
106 106 ancestors[rev] = None
107 107
108 108 x = len(a) # number of ancestors
109 109 y = tot - x # number of non-ancestors
110 110 value = min(x, y) # how good is this test?
111 111 if value > best_len and rev not in skip:
112 112 best_len = value
113 113 best_rev = rev
114 114 if value == perfect: # found a perfect candidate? quit early
115 115 break
116 116
117 117 if y < perfect and rev not in skip: # all downhill from here?
118 118 # poison children
119 119 poison.update(children.get(rev, []))
120 120 continue
121 121
122 122 for c in children.get(rev, []):
123 123 if ancestors[c]:
124 124 ancestors[c] = list(set(ancestors[c] + a))
125 125 else:
126 126 ancestors[c] = a + [c]
127 127
128 128 assert best_rev is not None
129 129 best_node = changelog.node(best_rev)
130 130
131 131 return ([best_node], tot, good)
132 132
133 133
134 134 def load_state(repo):
135 135 state = {'current': [], 'good': [], 'bad': [], 'skip': []}
136 136 if os.path.exists(repo.join("bisect.state")):
137 137 for l in repo.opener("bisect.state"):
138 138 kind, node = l[:-1].split()
139 139 node = repo.lookup(node)
140 140 if kind not in state:
141 141 raise util.Abort(_("unknown bisect kind %s") % kind)
142 142 state[kind].append(node)
143 143 return state
144 144
145 145
146 146 def save_state(repo, state):
147 147 f = repo.opener("bisect.state", "w", atomictemp=True)
148 148 wlock = repo.wlock()
149 149 try:
150 150 for kind in sorted(state):
151 151 for node in state[kind]:
152 152 f.write("%s %s\n" % (kind, hex(node)))
153 153 f.close()
154 154 finally:
155 155 wlock.release()
156 156
157 157 def get(repo, status):
158 158 """
159 159 Return a list of revision(s) that match the given status:
160 160
161 161 - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
162 162 - ``goods``, ``bads`` : csets topologically good/bad
163 163 - ``range`` : csets taking part in the bisection
164 164 - ``pruned`` : csets that are goods, bads or skipped
165 165 - ``untested`` : csets whose fate is yet unknown
166 166 - ``ignored`` : csets ignored due to DAG topology
167 167 - ``current`` : the cset currently being bisected
168 168 """
169 169 state = load_state(repo)
170 170 if status in ('good', 'bad', 'skip', 'current'):
171 171 return map(repo.changelog.rev, state[status])
172 172 else:
173 173 # In the following sets, we do *not* call 'bisect()' with more
174 174 # than one level of recursion, because that can be very, very
175 175 # time consuming. Instead, we always develop the expression as
176 176 # much as possible.
177 177
178 178 # 'range' is all csets that make the bisection:
179 179 # - have a good ancestor and a bad descendant, or conversely
180 180 # that's because the bisection can go either way
181 181 range = '( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )'
182 182
183 183 _t = repo.revs('bisect(good)::bisect(bad)')
184 184 # The sets of topologically good or bad csets
185 185 if len(_t) == 0:
186 186 # Goods are topologically after bads
187 187 goods = 'bisect(good)::' # Pruned good csets
188 188 bads = '::bisect(bad)' # Pruned bad csets
189 189 else:
190 190 # Goods are topologically before bads
191 191 goods = '::bisect(good)' # Pruned good csets
192 192 bads = 'bisect(bad)::' # Pruned bad csets
193 193
194 194 # 'pruned' is all csets whose fate is already known: good, bad, skip
195 195 skips = 'bisect(skip)' # Pruned skipped csets
196 196 pruned = '( (%s) | (%s) | (%s) )' % (goods, bads, skips)
197 197
198 198 # 'untested' is all cset that are- in 'range', but not in 'pruned'
199 199 untested = '( (%s) - (%s) )' % (range, pruned)
200 200
201 201 # 'ignored' is all csets that were not used during the bisection
202 202 # due to DAG topology, but may however have had an impact.
203 203 # E.g., a branch merged between bads and goods, but whose branch-
204 204 # point is out-side of the range.
205 205 iba = '::bisect(bad) - ::bisect(good)' # Ignored bads' ancestors
206 206 iga = '::bisect(good) - ::bisect(bad)' # Ignored goods' ancestors
207 207 ignored = '( ( (%s) | (%s) ) - (%s) )' % (iba, iga, range)
208 208
209 209 if status == 'range':
210 210 return repo.revs(range)
211 211 elif status == 'pruned':
212 212 return repo.revs(pruned)
213 213 elif status == 'untested':
214 214 return repo.revs(untested)
215 215 elif status == 'ignored':
216 216 return repo.revs(ignored)
217 217 elif status == "goods":
218 218 return repo.revs(goods)
219 219 elif status == "bads":
220 220 return repo.revs(bads)
221 221 else:
222 222 raise error.ParseError(_('invalid bisect state'))
223 223
224 224 def label(repo, node):
225 225 rev = repo.changelog.rev(node)
226 226
227 227 # Try explicit sets
228 228 if rev in get(repo, 'good'):
229 229 # i18n: bisect changeset status
230 230 return _('good')
231 231 if rev in get(repo, 'bad'):
232 232 # i18n: bisect changeset status
233 233 return _('bad')
234 234 if rev in get(repo, 'skip'):
235 235 # i18n: bisect changeset status
236 236 return _('skipped')
237 237 if rev in get(repo, 'untested') or rev in get(repo, 'current'):
238 238 # i18n: bisect changeset status
239 239 return _('untested')
240 240 if rev in get(repo, 'ignored'):
241 241 # i18n: bisect changeset status
242 242 return _('ignored')
243 243
244 244 # Try implicit sets
245 245 if rev in get(repo, 'goods'):
246 246 # i18n: bisect changeset status
247 247 return _('good (implicit)')
248 248 if rev in get(repo, 'bads'):
249 249 # i18n: bisect changeset status
250 250 return _('bad (implicit)')
251 251
252 252 return None
253 253
254 254 def shortlabel(label):
255 255 if label:
256 256 return label[0].upper()
257 257
258 258 return None
@@ -1,510 +1,565
1 1 $ hg init
2 2
3 3
4 4 committing changes
5 5
6 6 $ count=0
7 7 $ echo > a
8 8 $ while test $count -lt 32 ; do
9 9 > echo 'a' >> a
10 10 > test $count -eq 0 && hg add
11 11 > hg ci -m "msg $count" -d "$count 0"
12 12 > count=`expr $count + 1`
13 13 > done
14 14 adding a
15 15
16 16
17 17 $ hg log
18 18 changeset: 31:58c80a7c8a40
19 19 tag: tip
20 20 user: test
21 21 date: Thu Jan 01 00:00:31 1970 +0000
22 22 summary: msg 31
23 23
24 24 changeset: 30:ed2d2f24b11c
25 25 user: test
26 26 date: Thu Jan 01 00:00:30 1970 +0000
27 27 summary: msg 30
28 28
29 29 changeset: 29:b5bd63375ab9
30 30 user: test
31 31 date: Thu Jan 01 00:00:29 1970 +0000
32 32 summary: msg 29
33 33
34 34 changeset: 28:8e0c2264c8af
35 35 user: test
36 36 date: Thu Jan 01 00:00:28 1970 +0000
37 37 summary: msg 28
38 38
39 39 changeset: 27:288867a866e9
40 40 user: test
41 41 date: Thu Jan 01 00:00:27 1970 +0000
42 42 summary: msg 27
43 43
44 44 changeset: 26:3efc6fd51aeb
45 45 user: test
46 46 date: Thu Jan 01 00:00:26 1970 +0000
47 47 summary: msg 26
48 48
49 49 changeset: 25:02a84173a97a
50 50 user: test
51 51 date: Thu Jan 01 00:00:25 1970 +0000
52 52 summary: msg 25
53 53
54 54 changeset: 24:10e0acd3809e
55 55 user: test
56 56 date: Thu Jan 01 00:00:24 1970 +0000
57 57 summary: msg 24
58 58
59 59 changeset: 23:5ec79163bff4
60 60 user: test
61 61 date: Thu Jan 01 00:00:23 1970 +0000
62 62 summary: msg 23
63 63
64 64 changeset: 22:06c7993750ce
65 65 user: test
66 66 date: Thu Jan 01 00:00:22 1970 +0000
67 67 summary: msg 22
68 68
69 69 changeset: 21:e5db6aa3fe2a
70 70 user: test
71 71 date: Thu Jan 01 00:00:21 1970 +0000
72 72 summary: msg 21
73 73
74 74 changeset: 20:7128fb4fdbc9
75 75 user: test
76 76 date: Thu Jan 01 00:00:20 1970 +0000
77 77 summary: msg 20
78 78
79 79 changeset: 19:52798545b482
80 80 user: test
81 81 date: Thu Jan 01 00:00:19 1970 +0000
82 82 summary: msg 19
83 83
84 84 changeset: 18:86977a90077e
85 85 user: test
86 86 date: Thu Jan 01 00:00:18 1970 +0000
87 87 summary: msg 18
88 88
89 89 changeset: 17:03515f4a9080
90 90 user: test
91 91 date: Thu Jan 01 00:00:17 1970 +0000
92 92 summary: msg 17
93 93
94 94 changeset: 16:a2e6ea4973e9
95 95 user: test
96 96 date: Thu Jan 01 00:00:16 1970 +0000
97 97 summary: msg 16
98 98
99 99 changeset: 15:e7fa0811edb0
100 100 user: test
101 101 date: Thu Jan 01 00:00:15 1970 +0000
102 102 summary: msg 15
103 103
104 104 changeset: 14:ce8f0998e922
105 105 user: test
106 106 date: Thu Jan 01 00:00:14 1970 +0000
107 107 summary: msg 14
108 108
109 109 changeset: 13:9d7d07bc967c
110 110 user: test
111 111 date: Thu Jan 01 00:00:13 1970 +0000
112 112 summary: msg 13
113 113
114 114 changeset: 12:1941b52820a5
115 115 user: test
116 116 date: Thu Jan 01 00:00:12 1970 +0000
117 117 summary: msg 12
118 118
119 119 changeset: 11:7b4cd9578619
120 120 user: test
121 121 date: Thu Jan 01 00:00:11 1970 +0000
122 122 summary: msg 11
123 123
124 124 changeset: 10:7c5eff49a6b6
125 125 user: test
126 126 date: Thu Jan 01 00:00:10 1970 +0000
127 127 summary: msg 10
128 128
129 129 changeset: 9:eb44510ef29a
130 130 user: test
131 131 date: Thu Jan 01 00:00:09 1970 +0000
132 132 summary: msg 9
133 133
134 134 changeset: 8:453eb4dba229
135 135 user: test
136 136 date: Thu Jan 01 00:00:08 1970 +0000
137 137 summary: msg 8
138 138
139 139 changeset: 7:03750880c6b5
140 140 user: test
141 141 date: Thu Jan 01 00:00:07 1970 +0000
142 142 summary: msg 7
143 143
144 144 changeset: 6:a3d5c6fdf0d3
145 145 user: test
146 146 date: Thu Jan 01 00:00:06 1970 +0000
147 147 summary: msg 6
148 148
149 149 changeset: 5:7874a09ea728
150 150 user: test
151 151 date: Thu Jan 01 00:00:05 1970 +0000
152 152 summary: msg 5
153 153
154 154 changeset: 4:9b2ba8336a65
155 155 user: test
156 156 date: Thu Jan 01 00:00:04 1970 +0000
157 157 summary: msg 4
158 158
159 159 changeset: 3:b53bea5e2fcb
160 160 user: test
161 161 date: Thu Jan 01 00:00:03 1970 +0000
162 162 summary: msg 3
163 163
164 164 changeset: 2:db07c04beaca
165 165 user: test
166 166 date: Thu Jan 01 00:00:02 1970 +0000
167 167 summary: msg 2
168 168
169 169 changeset: 1:5cd978ea5149
170 170 user: test
171 171 date: Thu Jan 01 00:00:01 1970 +0000
172 172 summary: msg 1
173 173
174 174 changeset: 0:b99c7b9c8e11
175 175 user: test
176 176 date: Thu Jan 01 00:00:00 1970 +0000
177 177 summary: msg 0
178 178
179 179
180 180 $ hg up -C
181 181 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 182
183 183 bisect test
184 184
185 185 $ hg bisect -r
186 186 $ hg bisect -b
187 187 $ hg bisect -g 1
188 188 Testing changeset 16:a2e6ea4973e9 (30 changesets remaining, ~4 tests)
189 189 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 190 $ hg bisect -g
191 191 Testing changeset 23:5ec79163bff4 (15 changesets remaining, ~3 tests)
192 192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193
194 194 skip
195 195
196 196 $ hg bisect -s
197 197 Testing changeset 24:10e0acd3809e (15 changesets remaining, ~3 tests)
198 198 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 199 $ hg bisect -g
200 200 Testing changeset 27:288867a866e9 (7 changesets remaining, ~2 tests)
201 201 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
202 202 $ hg bisect -g
203 203 Testing changeset 29:b5bd63375ab9 (4 changesets remaining, ~2 tests)
204 204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
205 205 $ hg bisect -b
206 206 Testing changeset 28:8e0c2264c8af (2 changesets remaining, ~1 tests)
207 207 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 208 $ hg bisect -g
209 209 The first bad revision is:
210 210 changeset: 29:b5bd63375ab9
211 211 user: test
212 212 date: Thu Jan 01 00:00:29 1970 +0000
213 213 summary: msg 29
214 214
215 215
216 216 mark revsets instead of single revs
217 217
218 218 $ hg bisect -r
219 219 $ hg bisect -b "0::3"
220 220 $ hg bisect -s "13::16"
221 221 $ hg bisect -g "26::tip"
222 222 Testing changeset 12:1941b52820a5 (23 changesets remaining, ~4 tests)
223 223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 224 $ cat .hg/bisect.state
225 225 bad b99c7b9c8e11558adef3fad9af211c58d46f325b
226 226 bad 5cd978ea51499179507ee7b6f340d2dbaa401185
227 227 bad db07c04beaca44cf24832541e7f4a2346a95275b
228 228 bad b53bea5e2fcb30d3e00bd3409507a5659ce0fd8b
229 229 current 1941b52820a544549596820a8ae006842b0e2c64
230 230 good 3efc6fd51aeb8594398044c6c846ca59ae021203
231 231 good 288867a866e9adb7a29880b66936c874b80f4651
232 232 good 8e0c2264c8af790daf3585ada0669d93dee09c83
233 233 good b5bd63375ab9a290419f2024b7f4ee9ea7ce90a8
234 234 good ed2d2f24b11c368fa8aa0da9f4e1db580abade59
235 235 good 58c80a7c8a4025a94cedaf7b4a4e3124e8909a96
236 236 skip 9d7d07bc967ca98ad0600c24953fd289ad5fa991
237 237 skip ce8f0998e922c179e80819d5066fbe46e2998784
238 238 skip e7fa0811edb063f6319531f0d0a865882138e180
239 239 skip a2e6ea4973e9196ddd3386493b0c214b41fd97d3
240 240
241 241 bisect reverse test
242 242
243 243 $ hg bisect -r
244 244 $ hg bisect -b null
245 245 $ hg bisect -g tip
246 246 Testing changeset 15:e7fa0811edb0 (32 changesets remaining, ~5 tests)
247 247 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
248 248 $ hg bisect -g
249 249 Testing changeset 7:03750880c6b5 (16 changesets remaining, ~4 tests)
250 250 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
251 251
252 252 skip
253 253
254 254 $ hg bisect -s
255 255 Testing changeset 6:a3d5c6fdf0d3 (16 changesets remaining, ~4 tests)
256 256 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 257 $ hg bisect -g
258 258 Testing changeset 2:db07c04beaca (7 changesets remaining, ~2 tests)
259 259 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 260 $ hg bisect -g
261 261 Testing changeset 0:b99c7b9c8e11 (3 changesets remaining, ~1 tests)
262 262 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 263 $ hg bisect -b
264 264 Testing changeset 1:5cd978ea5149 (2 changesets remaining, ~1 tests)
265 265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 266 $ hg bisect -g
267 267 The first good revision is:
268 268 changeset: 1:5cd978ea5149
269 269 user: test
270 270 date: Thu Jan 01 00:00:01 1970 +0000
271 271 summary: msg 1
272 272
273 273
274 274 $ hg bisect -r
275 275 $ hg bisect -g tip
276 276 $ hg bisect -b tip
277 277 abort: starting revisions are not directly related
278 278 [255]
279 279
280 280 $ hg bisect -r
281 281 $ hg bisect -g null
282 282 $ hg bisect -bU tip
283 283 Testing changeset 15:e7fa0811edb0 (32 changesets remaining, ~5 tests)
284 284 $ hg id
285 285 5cd978ea5149
286 286
287 287
288 288 Issue1228: hg bisect crashes when you skip the last rev in bisection
289 289 Issue1182: hg bisect exception
290 290
291 291 $ hg bisect -r
292 292 $ hg bisect -b 4
293 293 $ hg bisect -g 0
294 294 Testing changeset 2:db07c04beaca (4 changesets remaining, ~2 tests)
295 295 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 296 $ hg bisect -s
297 297 Testing changeset 1:5cd978ea5149 (4 changesets remaining, ~2 tests)
298 298 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
299 299 $ hg bisect -s
300 300 Testing changeset 3:b53bea5e2fcb (4 changesets remaining, ~2 tests)
301 301 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 302 $ hg bisect -s
303 303 Due to skipped revisions, the first bad revision could be any of:
304 304 changeset: 1:5cd978ea5149
305 305 user: test
306 306 date: Thu Jan 01 00:00:01 1970 +0000
307 307 summary: msg 1
308 308
309 309 changeset: 2:db07c04beaca
310 310 user: test
311 311 date: Thu Jan 01 00:00:02 1970 +0000
312 312 summary: msg 2
313 313
314 314 changeset: 3:b53bea5e2fcb
315 315 user: test
316 316 date: Thu Jan 01 00:00:03 1970 +0000
317 317 summary: msg 3
318 318
319 319 changeset: 4:9b2ba8336a65
320 320 user: test
321 321 date: Thu Jan 01 00:00:04 1970 +0000
322 322 summary: msg 4
323 323
324 324
325 325
326 326 reproduce non converging bisect, issue1182
327 327
328 328 $ hg bisect -r
329 329 $ hg bisect -g 0
330 330 $ hg bisect -b 2
331 331 Testing changeset 1:5cd978ea5149 (2 changesets remaining, ~1 tests)
332 332 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 333 $ hg bisect -s
334 334 Due to skipped revisions, the first bad revision could be any of:
335 335 changeset: 1:5cd978ea5149
336 336 user: test
337 337 date: Thu Jan 01 00:00:01 1970 +0000
338 338 summary: msg 1
339 339
340 340 changeset: 2:db07c04beaca
341 341 user: test
342 342 date: Thu Jan 01 00:00:02 1970 +0000
343 343 summary: msg 2
344 344
345 345
346 346
347 347 test no action
348 348
349 349 $ hg bisect -r
350 350 $ hg bisect
351 351 abort: cannot bisect (no known good revisions)
352 352 [255]
353 353
354 354
355 355 reproduce AssertionError, issue1445
356 356
357 357 $ hg bisect -r
358 358 $ hg bisect -b 6
359 359 $ hg bisect -g 0
360 360 Testing changeset 3:b53bea5e2fcb (6 changesets remaining, ~2 tests)
361 361 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
362 362 $ hg bisect -s
363 363 Testing changeset 2:db07c04beaca (6 changesets remaining, ~2 tests)
364 364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 365 $ hg bisect -s
366 366 Testing changeset 4:9b2ba8336a65 (6 changesets remaining, ~2 tests)
367 367 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
368 368 $ hg bisect -s
369 369 Testing changeset 1:5cd978ea5149 (6 changesets remaining, ~2 tests)
370 370 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
371 371 $ hg bisect -s
372 372 Testing changeset 5:7874a09ea728 (6 changesets remaining, ~2 tests)
373 373 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 374 $ hg bisect -g
375 375 The first bad revision is:
376 376 changeset: 6:a3d5c6fdf0d3
377 377 user: test
378 378 date: Thu Jan 01 00:00:06 1970 +0000
379 379 summary: msg 6
380 380
381 381 $ hg log -r "bisect(good)"
382 382 changeset: 0:b99c7b9c8e11
383 383 user: test
384 384 date: Thu Jan 01 00:00:00 1970 +0000
385 385 summary: msg 0
386 386
387 387 changeset: 5:7874a09ea728
388 388 user: test
389 389 date: Thu Jan 01 00:00:05 1970 +0000
390 390 summary: msg 5
391 391
392 392 $ hg log -r "bisect(bad)"
393 393 changeset: 6:a3d5c6fdf0d3
394 394 user: test
395 395 date: Thu Jan 01 00:00:06 1970 +0000
396 396 summary: msg 6
397 397
398 398 $ hg log -r "bisect(current)"
399 399 changeset: 5:7874a09ea728
400 400 user: test
401 401 date: Thu Jan 01 00:00:05 1970 +0000
402 402 summary: msg 5
403 403
404 404 $ hg log -r "bisect(skip)"
405 405 changeset: 1:5cd978ea5149
406 406 user: test
407 407 date: Thu Jan 01 00:00:01 1970 +0000
408 408 summary: msg 1
409 409
410 410 changeset: 2:db07c04beaca
411 411 user: test
412 412 date: Thu Jan 01 00:00:02 1970 +0000
413 413 summary: msg 2
414 414
415 415 changeset: 3:b53bea5e2fcb
416 416 user: test
417 417 date: Thu Jan 01 00:00:03 1970 +0000
418 418 summary: msg 3
419 419
420 420 changeset: 4:9b2ba8336a65
421 421 user: test
422 422 date: Thu Jan 01 00:00:04 1970 +0000
423 423 summary: msg 4
424 424
425 425
426 426 test legacy bisected() keyword
427 427
428 428 $ hg log -r "bisected(bad)"
429 429 changeset: 6:a3d5c6fdf0d3
430 430 user: test
431 431 date: Thu Jan 01 00:00:06 1970 +0000
432 432 summary: msg 6
433 433
434 434
435 435 $ set +e
436 436
437 437 test invalid command
438 438 assuming that the shell returns 127 if command not found ...
439 439
440 440 $ hg bisect -r
441 441 $ hg bisect --command 'exit 127'
442 442 abort: failed to execute exit 127
443 443 [255]
444 444
445 445
446 446 test bisecting command
447 447
448 448 $ cat > script.py <<EOF
449 449 > #!/usr/bin/env python
450 450 > import sys
451 451 > from mercurial import ui, hg
452 452 > repo = hg.repository(ui.ui(), '.')
453 453 > if repo['.'].rev() < 6:
454 454 > sys.exit(1)
455 455 > EOF
456 456 $ chmod +x script.py
457 457 $ hg bisect -r
458 458 $ hg bisect --good tip
459 459 $ hg bisect --bad 0
460 460 Testing changeset 15:e7fa0811edb0 (31 changesets remaining, ~4 tests)
461 461 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
462 462 $ hg bisect --command "python \"$TESTTMP/script.py\" and some parameters"
463 463 changeset 15:e7fa0811edb0: good
464 464 changeset 7:03750880c6b5: good
465 465 changeset 3:b53bea5e2fcb: bad
466 466 changeset 5:7874a09ea728: bad
467 467 changeset 6:a3d5c6fdf0d3: good
468 468 The first good revision is:
469 469 changeset: 6:a3d5c6fdf0d3
470 470 user: test
471 471 date: Thu Jan 01 00:00:06 1970 +0000
472 472 summary: msg 6
473 473
474 474
475 475
476 476 test bisecting via a command without updating the working dir, and
477 477 ensure that the bisect state file is updated before running a test
478 478 command
479 479
480 480 $ hg update null
481 481 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
482 482 $ cat > script.sh <<'EOF'
483 483 > #!/bin/sh
484 484 > test -n "$HG_NODE" || (echo HG_NODE missing; exit 127)
485 485 > current="`hg log -r \"bisect(current)\" --template {node}`"
486 486 > test "$current" = "$HG_NODE" || (echo current is bad: $current; exit 127)
487 487 > rev="`hg log -r $HG_NODE --template {rev}`"
488 488 > test "$rev" -ge 6
489 489 > EOF
490 490 $ chmod +x script.sh
491 491 $ hg bisect -r
492 492 $ hg bisect --good tip --noupdate
493 493 $ hg bisect --bad 0 --noupdate
494 494 Testing changeset 15:e7fa0811edb0 (31 changesets remaining, ~4 tests)
495 495 $ hg bisect --command "sh \"$TESTTMP/script.sh\" and some params" --noupdate
496 496 changeset 15:e7fa0811edb0: good
497 497 changeset 7:03750880c6b5: good
498 498 changeset 3:b53bea5e2fcb: bad
499 499 changeset 5:7874a09ea728: bad
500 500 changeset 6:a3d5c6fdf0d3: good
501 501 The first good revision is:
502 502 changeset: 6:a3d5c6fdf0d3
503 503 user: test
504 504 date: Thu Jan 01 00:00:06 1970 +0000
505 505 summary: msg 6
506 506
507 507
508 508 ensure that we still don't have a working dir
509 509
510 510 $ hg parents
511
512
513 Check that bisect does not break on obsolete changesets
514 =========================================================
515
516 $ cat > ${TESTTMP}/obs.py << EOF
517 > import mercurial.obsolete
518 > mercurial.obsolete._enabled = True
519 > EOF
520 $ echo '[extensions]' >> $HGRCPATH
521 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
522
523 tip is obsolete
524 ---------------------
525
526 $ hg debugobsolete `hg id --debug -i -r tip`
527 $ hg bisect --reset
528 $ hg bisect --good 15
529 $ hg bisect --bad 30
530 Testing changeset 22:06c7993750ce (15 changesets remaining, ~3 tests)
531 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
532 $ hg bisect --command true
533 changeset 22:06c7993750ce: good
534 changeset 26:3efc6fd51aeb: good
535 changeset 28:8e0c2264c8af: good
536 changeset 29:b5bd63375ab9: good
537 The first bad revision is:
538 changeset: 30:ed2d2f24b11c
539 tag: tip
540 user: test
541 date: Thu Jan 01 00:00:30 1970 +0000
542 summary: msg 30
543
544
545 Changeset in the bad:good range is obsolete
546 ---------------------------------------------
547
548 $ hg up 30
549 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
550 $ echo 'a' >> a
551 $ hg ci -m "msg 32" -d "32 0"
552 $ hg bisect --reset
553 $ hg bisect --good .
554 $ hg bisect --bad 25
555 Testing changeset 28:8e0c2264c8af (6 changesets remaining, ~2 tests)
556 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
557 $ hg bisect --command true
558 changeset 28:8e0c2264c8af: good
559 changeset 26:3efc6fd51aeb: good
560 The first good revision is:
561 changeset: 26:3efc6fd51aeb
562 user: test
563 date: Thu Jan 01 00:00:26 1970 +0000
564 summary: msg 26
565
General Comments 0
You need to be logged in to leave comments. Login now