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