##// END OF EJS Templates
bisect: do not crash with rewritten commits
timeless -
r42501:21eda240 default
parent child Browse files
Show More
@@ -1,294 +1,296 b''
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 from __future__ import absolute_import
11 from __future__ import absolute_import
12
12
13 import collections
13 import collections
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import (
16 from .node import (
17 hex,
17 hex,
18 short,
18 short,
19 )
19 )
20 from . import (
20 from . import (
21 error,
21 error,
22 )
22 )
23
23
24 def bisect(repo, state):
24 def bisect(repo, state):
25 """find the next node (if any) for testing during a bisect search.
25 """find the next node (if any) for testing during a bisect search.
26 returns a (nodes, number, good) tuple.
26 returns a (nodes, number, good) tuple.
27
27
28 'nodes' is the final result of the bisect if 'number' is 0.
28 'nodes' is the final result of the bisect if 'number' is 0.
29 Otherwise 'number' indicates the remaining possible candidates for
29 Otherwise 'number' indicates the remaining possible candidates for
30 the search and 'nodes' contains the next bisect target.
30 the search and 'nodes' contains the next bisect target.
31 'good' is True if bisect is searching for a first good changeset, False
31 'good' is True if bisect is searching for a first good changeset, False
32 if searching for a first bad one.
32 if searching for a first bad one.
33 """
33 """
34
34
35 repo = repo.unfiltered()
35 changelog = repo.changelog
36 changelog = repo.changelog
36 clparents = changelog.parentrevs
37 clparents = changelog.parentrevs
37 skip = {changelog.rev(n) for n in state['skip']}
38 skip = {changelog.rev(n) for n in state['skip']}
38
39
39 def buildancestors(bad, good):
40 def buildancestors(bad, good):
40 badrev = min([changelog.rev(n) for n in bad])
41 badrev = min([changelog.rev(n) for n in bad])
41 ancestors = collections.defaultdict(lambda: None)
42 ancestors = collections.defaultdict(lambda: None)
42 for rev in repo.revs("descendants(%ln) - ancestors(%ln)", good, good):
43 for rev in repo.revs("descendants(%ln) - ancestors(%ln)", good, good):
43 ancestors[rev] = []
44 ancestors[rev] = []
44 if ancestors[badrev] is None:
45 if ancestors[badrev] is None:
45 return badrev, None
46 return badrev, None
46 return badrev, ancestors
47 return badrev, ancestors
47
48
48 good = False
49 good = False
49 badrev, ancestors = buildancestors(state['bad'], state['good'])
50 badrev, ancestors = buildancestors(state['bad'], state['good'])
50 if not ancestors: # looking for bad to good transition?
51 if not ancestors: # looking for bad to good transition?
51 good = True
52 good = True
52 badrev, ancestors = buildancestors(state['good'], state['bad'])
53 badrev, ancestors = buildancestors(state['good'], state['bad'])
53 bad = changelog.node(badrev)
54 bad = changelog.node(badrev)
54 if not ancestors: # now we're confused
55 if not ancestors: # now we're confused
55 if (len(state['bad']) == 1 and len(state['good']) == 1 and
56 if (len(state['bad']) == 1 and len(state['good']) == 1 and
56 state['bad'] != state['good']):
57 state['bad'] != state['good']):
57 raise error.Abort(_("starting revisions are not directly related"))
58 raise error.Abort(_("starting revisions are not directly related"))
58 raise error.Abort(_("inconsistent state, %d:%s is good and bad")
59 raise error.Abort(_("inconsistent state, %d:%s is good and bad")
59 % (badrev, short(bad)))
60 % (badrev, short(bad)))
60
61
61 # build children dict
62 # build children dict
62 children = {}
63 children = {}
63 visit = collections.deque([badrev])
64 visit = collections.deque([badrev])
64 candidates = []
65 candidates = []
65 while visit:
66 while visit:
66 rev = visit.popleft()
67 rev = visit.popleft()
67 if ancestors[rev] == []:
68 if ancestors[rev] == []:
68 candidates.append(rev)
69 candidates.append(rev)
69 for prev in clparents(rev):
70 for prev in clparents(rev):
70 if prev != -1:
71 if prev != -1:
71 if prev in children:
72 if prev in children:
72 children[prev].append(rev)
73 children[prev].append(rev)
73 else:
74 else:
74 children[prev] = [rev]
75 children[prev] = [rev]
75 visit.append(prev)
76 visit.append(prev)
76
77
77 candidates.sort()
78 candidates.sort()
78 # have we narrowed it down to one entry?
79 # have we narrowed it down to one entry?
79 # or have all other possible candidates besides 'bad' have been skipped?
80 # or have all other possible candidates besides 'bad' have been skipped?
80 tot = len(candidates)
81 tot = len(candidates)
81 unskipped = [c for c in candidates if (c not in skip) and (c != badrev)]
82 unskipped = [c for c in candidates if (c not in skip) and (c != badrev)]
82 if tot == 1 or not unskipped:
83 if tot == 1 or not unskipped:
83 return ([changelog.node(c) for c in candidates], 0, good)
84 return ([changelog.node(c) for c in candidates], 0, good)
84 perfect = tot // 2
85 perfect = tot // 2
85
86
86 # find the best node to test
87 # find the best node to test
87 best_rev = None
88 best_rev = None
88 best_len = -1
89 best_len = -1
89 poison = set()
90 poison = set()
90 for rev in candidates:
91 for rev in candidates:
91 if rev in poison:
92 if rev in poison:
92 # poison children
93 # poison children
93 poison.update(children.get(rev, []))
94 poison.update(children.get(rev, []))
94 continue
95 continue
95
96
96 a = ancestors[rev] or [rev]
97 a = ancestors[rev] or [rev]
97 ancestors[rev] = None
98 ancestors[rev] = None
98
99
99 x = len(a) # number of ancestors
100 x = len(a) # number of ancestors
100 y = tot - x # number of non-ancestors
101 y = tot - x # number of non-ancestors
101 value = min(x, y) # how good is this test?
102 value = min(x, y) # how good is this test?
102 if value > best_len and rev not in skip:
103 if value > best_len and rev not in skip:
103 best_len = value
104 best_len = value
104 best_rev = rev
105 best_rev = rev
105 if value == perfect: # found a perfect candidate? quit early
106 if value == perfect: # found a perfect candidate? quit early
106 break
107 break
107
108
108 if y < perfect and rev not in skip: # all downhill from here?
109 if y < perfect and rev not in skip: # all downhill from here?
109 # poison children
110 # poison children
110 poison.update(children.get(rev, []))
111 poison.update(children.get(rev, []))
111 continue
112 continue
112
113
113 for c in children.get(rev, []):
114 for c in children.get(rev, []):
114 if ancestors[c]:
115 if ancestors[c]:
115 ancestors[c] = list(set(ancestors[c] + a))
116 ancestors[c] = list(set(ancestors[c] + a))
116 else:
117 else:
117 ancestors[c] = a + [c]
118 ancestors[c] = a + [c]
118
119
119 assert best_rev is not None
120 assert best_rev is not None
120 best_node = changelog.node(best_rev)
121 best_node = changelog.node(best_rev)
121
122
122 return ([best_node], tot, good)
123 return ([best_node], tot, good)
123
124
124 def extendrange(repo, state, nodes, good):
125 def extendrange(repo, state, nodes, good):
125 # bisect is incomplete when it ends on a merge node and
126 # bisect is incomplete when it ends on a merge node and
126 # one of the parent was not checked.
127 # one of the parent was not checked.
127 parents = repo[nodes[0]].parents()
128 parents = repo[nodes[0]].parents()
128 if len(parents) > 1:
129 if len(parents) > 1:
129 if good:
130 if good:
130 side = state['bad']
131 side = state['bad']
131 else:
132 else:
132 side = state['good']
133 side = state['good']
133 num = len(set(i.node() for i in parents) & set(side))
134 num = len(set(i.node() for i in parents) & set(side))
134 if num == 1:
135 if num == 1:
135 return parents[0].ancestor(parents[1])
136 return parents[0].ancestor(parents[1])
136 return None
137 return None
137
138
138 def load_state(repo):
139 def load_state(repo):
139 state = {'current': [], 'good': [], 'bad': [], 'skip': []}
140 state = {'current': [], 'good': [], 'bad': [], 'skip': []}
140 for l in repo.vfs.tryreadlines("bisect.state"):
141 for l in repo.vfs.tryreadlines("bisect.state"):
141 kind, node = l[:-1].split()
142 kind, node = l[:-1].split()
142 node = repo.lookup(node)
143 node = repo.unfiltered().lookup(node)
143 if kind not in state:
144 if kind not in state:
144 raise error.Abort(_("unknown bisect kind %s") % kind)
145 raise error.Abort(_("unknown bisect kind %s") % kind)
145 state[kind].append(node)
146 state[kind].append(node)
146 return state
147 return state
147
148
148
149
149 def save_state(repo, state):
150 def save_state(repo, state):
150 f = repo.vfs("bisect.state", "w", atomictemp=True)
151 f = repo.vfs("bisect.state", "w", atomictemp=True)
151 with repo.wlock():
152 with repo.wlock():
152 for kind in sorted(state):
153 for kind in sorted(state):
153 for node in state[kind]:
154 for node in state[kind]:
154 f.write("%s %s\n" % (kind, hex(node)))
155 f.write("%s %s\n" % (kind, hex(node)))
155 f.close()
156 f.close()
156
157
157 def resetstate(repo):
158 def resetstate(repo):
158 """remove any bisect state from the repository"""
159 """remove any bisect state from the repository"""
159 if repo.vfs.exists("bisect.state"):
160 if repo.vfs.exists("bisect.state"):
160 repo.vfs.unlink("bisect.state")
161 repo.vfs.unlink("bisect.state")
161
162
162 def checkstate(state):
163 def checkstate(state):
163 """check we have both 'good' and 'bad' to define a range
164 """check we have both 'good' and 'bad' to define a range
164
165
165 Raise Abort exception otherwise."""
166 Raise Abort exception otherwise."""
166 if state['good'] and state['bad']:
167 if state['good'] and state['bad']:
167 return True
168 return True
168 if not state['good']:
169 if not state['good']:
169 raise error.Abort(_('cannot bisect (no known good revisions)'))
170 raise error.Abort(_('cannot bisect (no known good revisions)'))
170 else:
171 else:
171 raise error.Abort(_('cannot bisect (no known bad revisions)'))
172 raise error.Abort(_('cannot bisect (no known bad revisions)'))
172
173
173 def get(repo, status):
174 def get(repo, status):
174 """
175 """
175 Return a list of revision(s) that match the given status:
176 Return a list of revision(s) that match the given status:
176
177
177 - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
178 - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
178 - ``goods``, ``bads`` : csets topologically good/bad
179 - ``goods``, ``bads`` : csets topologically good/bad
179 - ``range`` : csets taking part in the bisection
180 - ``range`` : csets taking part in the bisection
180 - ``pruned`` : csets that are goods, bads or skipped
181 - ``pruned`` : csets that are goods, bads or skipped
181 - ``untested`` : csets whose fate is yet unknown
182 - ``untested`` : csets whose fate is yet unknown
182 - ``ignored`` : csets ignored due to DAG topology
183 - ``ignored`` : csets ignored due to DAG topology
183 - ``current`` : the cset currently being bisected
184 - ``current`` : the cset currently being bisected
184 """
185 """
185 state = load_state(repo)
186 state = load_state(repo)
186 if status in ('good', 'bad', 'skip', 'current'):
187 if status in ('good', 'bad', 'skip', 'current'):
187 return map(repo.changelog.rev, state[status])
188 return map(repo.unfiltered().changelog.rev, state[status])
188 else:
189 else:
189 # In the following sets, we do *not* call 'bisect()' with more
190 # In the following sets, we do *not* call 'bisect()' with more
190 # than one level of recursion, because that can be very, very
191 # than one level of recursion, because that can be very, very
191 # time consuming. Instead, we always develop the expression as
192 # time consuming. Instead, we always develop the expression as
192 # much as possible.
193 # much as possible.
193
194
194 # 'range' is all csets that make the bisection:
195 # 'range' is all csets that make the bisection:
195 # - have a good ancestor and a bad descendant, or conversely
196 # - have a good ancestor and a bad descendant, or conversely
196 # that's because the bisection can go either way
197 # that's because the bisection can go either way
197 range = '( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )'
198 range = '( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )'
198
199
199 _t = repo.revs('bisect(good)::bisect(bad)')
200 _t = repo.revs('bisect(good)::bisect(bad)')
200 # The sets of topologically good or bad csets
201 # The sets of topologically good or bad csets
201 if len(_t) == 0:
202 if len(_t) == 0:
202 # Goods are topologically after bads
203 # Goods are topologically after bads
203 goods = 'bisect(good)::' # Pruned good csets
204 goods = 'bisect(good)::' # Pruned good csets
204 bads = '::bisect(bad)' # Pruned bad csets
205 bads = '::bisect(bad)' # Pruned bad csets
205 else:
206 else:
206 # Goods are topologically before bads
207 # Goods are topologically before bads
207 goods = '::bisect(good)' # Pruned good csets
208 goods = '::bisect(good)' # Pruned good csets
208 bads = 'bisect(bad)::' # Pruned bad csets
209 bads = 'bisect(bad)::' # Pruned bad csets
209
210
210 # 'pruned' is all csets whose fate is already known: good, bad, skip
211 # 'pruned' is all csets whose fate is already known: good, bad, skip
211 skips = 'bisect(skip)' # Pruned skipped csets
212 skips = 'bisect(skip)' # Pruned skipped csets
212 pruned = '( (%s) | (%s) | (%s) )' % (goods, bads, skips)
213 pruned = '( (%s) | (%s) | (%s) )' % (goods, bads, skips)
213
214
214 # 'untested' is all cset that are- in 'range', but not in 'pruned'
215 # 'untested' is all cset that are- in 'range', but not in 'pruned'
215 untested = '( (%s) - (%s) )' % (range, pruned)
216 untested = '( (%s) - (%s) )' % (range, pruned)
216
217
217 # 'ignored' is all csets that were not used during the bisection
218 # 'ignored' is all csets that were not used during the bisection
218 # due to DAG topology, but may however have had an impact.
219 # due to DAG topology, but may however have had an impact.
219 # E.g., a branch merged between bads and goods, but whose branch-
220 # E.g., a branch merged between bads and goods, but whose branch-
220 # point is out-side of the range.
221 # point is out-side of the range.
221 iba = '::bisect(bad) - ::bisect(good)' # Ignored bads' ancestors
222 iba = '::bisect(bad) - ::bisect(good)' # Ignored bads' ancestors
222 iga = '::bisect(good) - ::bisect(bad)' # Ignored goods' ancestors
223 iga = '::bisect(good) - ::bisect(bad)' # Ignored goods' ancestors
223 ignored = '( ( (%s) | (%s) ) - (%s) )' % (iba, iga, range)
224 ignored = '( ( (%s) | (%s) ) - (%s) )' % (iba, iga, range)
224
225
225 if status == 'range':
226 if status == 'range':
226 return repo.revs(range)
227 return repo.revs(range)
227 elif status == 'pruned':
228 elif status == 'pruned':
228 return repo.revs(pruned)
229 return repo.revs(pruned)
229 elif status == 'untested':
230 elif status == 'untested':
230 return repo.revs(untested)
231 return repo.revs(untested)
231 elif status == 'ignored':
232 elif status == 'ignored':
232 return repo.revs(ignored)
233 return repo.revs(ignored)
233 elif status == "goods":
234 elif status == "goods":
234 return repo.revs(goods)
235 return repo.revs(goods)
235 elif status == "bads":
236 elif status == "bads":
236 return repo.revs(bads)
237 return repo.revs(bads)
237 else:
238 else:
238 raise error.ParseError(_('invalid bisect state'))
239 raise error.ParseError(_('invalid bisect state'))
239
240
240 def label(repo, node):
241 def label(repo, node):
241 rev = repo.changelog.rev(node)
242 rev = repo.changelog.rev(node)
242
243
243 # Try explicit sets
244 # Try explicit sets
244 if rev in get(repo, 'good'):
245 if rev in get(repo, 'good'):
245 # i18n: bisect changeset status
246 # i18n: bisect changeset status
246 return _('good')
247 return _('good')
247 if rev in get(repo, 'bad'):
248 if rev in get(repo, 'bad'):
248 # i18n: bisect changeset status
249 # i18n: bisect changeset status
249 return _('bad')
250 return _('bad')
250 if rev in get(repo, 'skip'):
251 if rev in get(repo, 'skip'):
251 # i18n: bisect changeset status
252 # i18n: bisect changeset status
252 return _('skipped')
253 return _('skipped')
253 if rev in get(repo, 'untested') or rev in get(repo, 'current'):
254 if rev in get(repo, 'untested') or rev in get(repo, 'current'):
254 # i18n: bisect changeset status
255 # i18n: bisect changeset status
255 return _('untested')
256 return _('untested')
256 if rev in get(repo, 'ignored'):
257 if rev in get(repo, 'ignored'):
257 # i18n: bisect changeset status
258 # i18n: bisect changeset status
258 return _('ignored')
259 return _('ignored')
259
260
260 # Try implicit sets
261 # Try implicit sets
261 if rev in get(repo, 'goods'):
262 if rev in get(repo, 'goods'):
262 # i18n: bisect changeset status
263 # i18n: bisect changeset status
263 return _('good (implicit)')
264 return _('good (implicit)')
264 if rev in get(repo, 'bads'):
265 if rev in get(repo, 'bads'):
265 # i18n: bisect changeset status
266 # i18n: bisect changeset status
266 return _('bad (implicit)')
267 return _('bad (implicit)')
267
268
268 return None
269 return None
269
270
270 def printresult(ui, repo, state, displayer, nodes, good):
271 def printresult(ui, repo, state, displayer, nodes, good):
272 repo = repo.unfiltered()
271 if len(nodes) == 1:
273 if len(nodes) == 1:
272 # narrowed it down to a single revision
274 # narrowed it down to a single revision
273 if good:
275 if good:
274 ui.write(_("The first good revision is:\n"))
276 ui.write(_("The first good revision is:\n"))
275 else:
277 else:
276 ui.write(_("The first bad revision is:\n"))
278 ui.write(_("The first bad revision is:\n"))
277 displayer.show(repo[nodes[0]])
279 displayer.show(repo[nodes[0]])
278 extendnode = extendrange(repo, state, nodes, good)
280 extendnode = extendrange(repo, state, nodes, good)
279 if extendnode is not None:
281 if extendnode is not None:
280 ui.write(_('Not all ancestors of this changeset have been'
282 ui.write(_('Not all ancestors of this changeset have been'
281 ' checked.\nUse bisect --extend to continue the '
283 ' checked.\nUse bisect --extend to continue the '
282 'bisection from\nthe common ancestor, %s.\n')
284 'bisection from\nthe common ancestor, %s.\n')
283 % extendnode)
285 % extendnode)
284 else:
286 else:
285 # multiple possible revisions
287 # multiple possible revisions
286 if good:
288 if good:
287 ui.write(_("Due to skipped revisions, the first "
289 ui.write(_("Due to skipped revisions, the first "
288 "good revision could be any of:\n"))
290 "good revision could be any of:\n"))
289 else:
291 else:
290 ui.write(_("Due to skipped revisions, the first "
292 ui.write(_("Due to skipped revisions, the first "
291 "bad revision could be any of:\n"))
293 "bad revision could be any of:\n"))
292 for n in nodes:
294 for n in nodes:
293 displayer.show(repo[n])
295 displayer.show(repo[n])
294 displayer.close()
296 displayer.close()
@@ -1,671 +1,794 b''
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 status -v
187 $ hg status -v
188 # The repository is in an unfinished *bisect* state.
188 # The repository is in an unfinished *bisect* state.
189
189
190 # To mark the changeset good: hg bisect --good
190 # To mark the changeset good: hg bisect --good
191 # To mark the changeset bad: hg bisect --bad
191 # To mark the changeset bad: hg bisect --bad
192 # To abort: hg bisect --reset
192 # To abort: hg bisect --reset
193
193
194 $ hg status -v --config commands.status.skipstates=bisect
194 $ hg status -v --config commands.status.skipstates=bisect
195 $ hg summary
195 $ hg summary
196 parent: 31:58c80a7c8a40 tip
196 parent: 31:58c80a7c8a40 tip
197 msg 31
197 msg 31
198 branch: default
198 branch: default
199 commit: (clean)
199 commit: (clean)
200 update: (current)
200 update: (current)
201 phases: 32 draft
201 phases: 32 draft
202 $ hg bisect -g 1
202 $ hg bisect -g 1
203 Testing changeset 16:a2e6ea4973e9 (30 changesets remaining, ~4 tests)
203 Testing changeset 16:a2e6ea4973e9 (30 changesets remaining, ~4 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 -g
205 $ hg bisect -g
206 Testing changeset 23:5ec79163bff4 (15 changesets remaining, ~3 tests)
206 Testing changeset 23:5ec79163bff4 (15 changesets remaining, ~3 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
208
209 skip
209 skip
210
210
211 $ hg bisect -s
211 $ hg bisect -s
212 Testing changeset 24:10e0acd3809e (15 changesets remaining, ~3 tests)
212 Testing changeset 24:10e0acd3809e (15 changesets remaining, ~3 tests)
213 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
213 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
214 $ hg bisect -g
214 $ hg bisect -g
215 Testing changeset 27:288867a866e9 (7 changesets remaining, ~2 tests)
215 Testing changeset 27:288867a866e9 (7 changesets remaining, ~2 tests)
216 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
216 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
217 $ hg bisect -g
217 $ hg bisect -g
218 Testing changeset 29:b5bd63375ab9 (4 changesets remaining, ~2 tests)
218 Testing changeset 29:b5bd63375ab9 (4 changesets remaining, ~2 tests)
219 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 $ hg bisect -b
220 $ hg bisect -b
221 Testing changeset 28:8e0c2264c8af (2 changesets remaining, ~1 tests)
221 Testing changeset 28:8e0c2264c8af (2 changesets remaining, ~1 tests)
222 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 $ hg bisect -g
223 $ hg bisect -g
224 The first bad revision is:
224 The first bad revision is:
225 changeset: 29:b5bd63375ab9
225 changeset: 29:b5bd63375ab9
226 user: test
226 user: test
227 date: Thu Jan 01 00:00:29 1970 +0000
227 date: Thu Jan 01 00:00:29 1970 +0000
228 summary: msg 29
228 summary: msg 29
229
229
230
230
231 mark revsets instead of single revs
231 mark revsets instead of single revs
232
232
233 $ hg bisect -r
233 $ hg bisect -r
234 $ hg bisect -b "0::3"
234 $ hg bisect -b "0::3"
235 $ hg bisect -s "13::16"
235 $ hg bisect -s "13::16"
236 $ hg bisect -g "26::tip"
236 $ hg bisect -g "26::tip"
237 Testing changeset 12:1941b52820a5 (23 changesets remaining, ~4 tests)
237 Testing changeset 12:1941b52820a5 (23 changesets remaining, ~4 tests)
238 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
238 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
239 $ cat .hg/bisect.state
239 $ cat .hg/bisect.state
240 bad b99c7b9c8e11558adef3fad9af211c58d46f325b
240 bad b99c7b9c8e11558adef3fad9af211c58d46f325b
241 bad 5cd978ea51499179507ee7b6f340d2dbaa401185
241 bad 5cd978ea51499179507ee7b6f340d2dbaa401185
242 bad db07c04beaca44cf24832541e7f4a2346a95275b
242 bad db07c04beaca44cf24832541e7f4a2346a95275b
243 bad b53bea5e2fcb30d3e00bd3409507a5659ce0fd8b
243 bad b53bea5e2fcb30d3e00bd3409507a5659ce0fd8b
244 current 1941b52820a544549596820a8ae006842b0e2c64
244 current 1941b52820a544549596820a8ae006842b0e2c64
245 good 3efc6fd51aeb8594398044c6c846ca59ae021203
245 good 3efc6fd51aeb8594398044c6c846ca59ae021203
246 good 288867a866e9adb7a29880b66936c874b80f4651
246 good 288867a866e9adb7a29880b66936c874b80f4651
247 good 8e0c2264c8af790daf3585ada0669d93dee09c83
247 good 8e0c2264c8af790daf3585ada0669d93dee09c83
248 good b5bd63375ab9a290419f2024b7f4ee9ea7ce90a8
248 good b5bd63375ab9a290419f2024b7f4ee9ea7ce90a8
249 good ed2d2f24b11c368fa8aa0da9f4e1db580abade59
249 good ed2d2f24b11c368fa8aa0da9f4e1db580abade59
250 good 58c80a7c8a4025a94cedaf7b4a4e3124e8909a96
250 good 58c80a7c8a4025a94cedaf7b4a4e3124e8909a96
251 skip 9d7d07bc967ca98ad0600c24953fd289ad5fa991
251 skip 9d7d07bc967ca98ad0600c24953fd289ad5fa991
252 skip ce8f0998e922c179e80819d5066fbe46e2998784
252 skip ce8f0998e922c179e80819d5066fbe46e2998784
253 skip e7fa0811edb063f6319531f0d0a865882138e180
253 skip e7fa0811edb063f6319531f0d0a865882138e180
254 skip a2e6ea4973e9196ddd3386493b0c214b41fd97d3
254 skip a2e6ea4973e9196ddd3386493b0c214b41fd97d3
255
255
256 bisect reverse test
256 bisect reverse test
257
257
258 $ hg bisect -r
258 $ hg bisect -r
259 $ hg bisect -b null
259 $ hg bisect -b null
260 $ hg bisect -g tip
260 $ hg bisect -g tip
261 Testing changeset 15:e7fa0811edb0 (32 changesets remaining, ~5 tests)
261 Testing changeset 15:e7fa0811edb0 (32 changesets remaining, ~5 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 -g
263 $ hg bisect -g
264 Testing changeset 7:03750880c6b5 (16 changesets remaining, ~4 tests)
264 Testing changeset 7:03750880c6b5 (16 changesets remaining, ~4 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
266
267 skip
267 skip
268
268
269 $ hg bisect -s
269 $ hg bisect -s
270 Testing changeset 6:a3d5c6fdf0d3 (16 changesets remaining, ~4 tests)
270 Testing changeset 6:a3d5c6fdf0d3 (16 changesets remaining, ~4 tests)
271 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 $ hg bisect -g
272 $ hg bisect -g
273 Testing changeset 2:db07c04beaca (7 changesets remaining, ~2 tests)
273 Testing changeset 2:db07c04beaca (7 changesets remaining, ~2 tests)
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 $ hg bisect -g
275 $ hg bisect -g
276 Testing changeset 0:b99c7b9c8e11 (3 changesets remaining, ~1 tests)
276 Testing changeset 0:b99c7b9c8e11 (3 changesets remaining, ~1 tests)
277 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 $ hg bisect -b
278 $ hg bisect -b
279 Testing changeset 1:5cd978ea5149 (2 changesets remaining, ~1 tests)
279 Testing changeset 1:5cd978ea5149 (2 changesets remaining, ~1 tests)
280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
281 $ hg bisect -g
281 $ hg bisect -g
282 The first good revision is:
282 The first good revision is:
283 changeset: 1:5cd978ea5149
283 changeset: 1:5cd978ea5149
284 user: test
284 user: test
285 date: Thu Jan 01 00:00:01 1970 +0000
285 date: Thu Jan 01 00:00:01 1970 +0000
286 summary: msg 1
286 summary: msg 1
287
287
288
288
289 $ hg bisect -r
289 $ hg bisect -r
290 $ hg bisect -g tip
290 $ hg bisect -g tip
291 $ hg bisect -b tip
291 $ hg bisect -b tip
292 abort: inconsistent state, 31:58c80a7c8a40 is good and bad
292 abort: inconsistent state, 31:58c80a7c8a40 is good and bad
293 [255]
293 [255]
294
294
295 $ hg bisect -r
295 $ hg bisect -r
296 $ hg bisect -g null
296 $ hg bisect -g null
297 $ hg bisect -bU tip
297 $ hg bisect -bU tip
298 Testing changeset 15:e7fa0811edb0 (32 changesets remaining, ~5 tests)
298 Testing changeset 15:e7fa0811edb0 (32 changesets remaining, ~5 tests)
299 $ hg id
299 $ hg id
300 5cd978ea5149
300 5cd978ea5149
301
301
302
302
303 Issue1228: hg bisect crashes when you skip the last rev in bisection
303 Issue1228: hg bisect crashes when you skip the last rev in bisection
304 Issue1182: hg bisect exception
304 Issue1182: hg bisect exception
305
305
306 $ hg bisect -r
306 $ hg bisect -r
307 $ hg bisect -b 4
307 $ hg bisect -b 4
308 $ hg bisect -g 0
308 $ hg bisect -g 0
309 Testing changeset 2:db07c04beaca (4 changesets remaining, ~2 tests)
309 Testing changeset 2:db07c04beaca (4 changesets remaining, ~2 tests)
310 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 $ hg bisect -s
311 $ hg bisect -s
312 Testing changeset 1:5cd978ea5149 (4 changesets remaining, ~2 tests)
312 Testing changeset 1:5cd978ea5149 (4 changesets remaining, ~2 tests)
313 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
313 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 $ hg bisect -s
314 $ hg bisect -s
315 Testing changeset 3:b53bea5e2fcb (4 changesets remaining, ~2 tests)
315 Testing changeset 3:b53bea5e2fcb (4 changesets remaining, ~2 tests)
316 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
316 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
317 $ hg bisect -s
317 $ hg bisect -s
318 Due to skipped revisions, the first bad revision could be any of:
318 Due to skipped revisions, the first bad revision could be any of:
319 changeset: 1:5cd978ea5149
319 changeset: 1:5cd978ea5149
320 user: test
320 user: test
321 date: Thu Jan 01 00:00:01 1970 +0000
321 date: Thu Jan 01 00:00:01 1970 +0000
322 summary: msg 1
322 summary: msg 1
323
323
324 changeset: 2:db07c04beaca
324 changeset: 2:db07c04beaca
325 user: test
325 user: test
326 date: Thu Jan 01 00:00:02 1970 +0000
326 date: Thu Jan 01 00:00:02 1970 +0000
327 summary: msg 2
327 summary: msg 2
328
328
329 changeset: 3:b53bea5e2fcb
329 changeset: 3:b53bea5e2fcb
330 user: test
330 user: test
331 date: Thu Jan 01 00:00:03 1970 +0000
331 date: Thu Jan 01 00:00:03 1970 +0000
332 summary: msg 3
332 summary: msg 3
333
333
334 changeset: 4:9b2ba8336a65
334 changeset: 4:9b2ba8336a65
335 user: test
335 user: test
336 date: Thu Jan 01 00:00:04 1970 +0000
336 date: Thu Jan 01 00:00:04 1970 +0000
337 summary: msg 4
337 summary: msg 4
338
338
339
339
340
340
341 reproduce non converging bisect, issue1182
341 reproduce non converging bisect, issue1182
342
342
343 $ hg bisect -r
343 $ hg bisect -r
344 $ hg bisect -g 0
344 $ hg bisect -g 0
345 $ hg bisect -b 2
345 $ hg bisect -b 2
346 Testing changeset 1:5cd978ea5149 (2 changesets remaining, ~1 tests)
346 Testing changeset 1:5cd978ea5149 (2 changesets remaining, ~1 tests)
347 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
347 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
348 $ hg bisect -s
348 $ hg bisect -s
349 Due to skipped revisions, the first bad revision could be any of:
349 Due to skipped revisions, the first bad revision could be any of:
350 changeset: 1:5cd978ea5149
350 changeset: 1:5cd978ea5149
351 user: test
351 user: test
352 date: Thu Jan 01 00:00:01 1970 +0000
352 date: Thu Jan 01 00:00:01 1970 +0000
353 summary: msg 1
353 summary: msg 1
354
354
355 changeset: 2:db07c04beaca
355 changeset: 2:db07c04beaca
356 user: test
356 user: test
357 date: Thu Jan 01 00:00:02 1970 +0000
357 date: Thu Jan 01 00:00:02 1970 +0000
358 summary: msg 2
358 summary: msg 2
359
359
360
360
361
361
362 test no action
362 test no action
363
363
364 $ hg bisect -r
364 $ hg bisect -r
365 $ hg bisect
365 $ hg bisect
366 abort: cannot bisect (no known good revisions)
366 abort: cannot bisect (no known good revisions)
367 [255]
367 [255]
368
368
369
369
370 reproduce AssertionError, issue1445
370 reproduce AssertionError, issue1445
371
371
372 $ hg bisect -r
372 $ hg bisect -r
373 $ hg bisect -b 6
373 $ hg bisect -b 6
374 $ hg bisect -g 0
374 $ hg bisect -g 0
375 Testing changeset 3:b53bea5e2fcb (6 changesets remaining, ~2 tests)
375 Testing changeset 3:b53bea5e2fcb (6 changesets remaining, ~2 tests)
376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 $ hg bisect -s
377 $ hg bisect -s
378 Testing changeset 2:db07c04beaca (6 changesets remaining, ~2 tests)
378 Testing changeset 2:db07c04beaca (6 changesets remaining, ~2 tests)
379 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
379 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 $ hg bisect -s
380 $ hg bisect -s
381 Testing changeset 4:9b2ba8336a65 (6 changesets remaining, ~2 tests)
381 Testing changeset 4:9b2ba8336a65 (6 changesets remaining, ~2 tests)
382 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 $ hg bisect -s
383 $ hg bisect -s
384 Testing changeset 1:5cd978ea5149 (6 changesets remaining, ~2 tests)
384 Testing changeset 1:5cd978ea5149 (6 changesets remaining, ~2 tests)
385 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
385 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
386 $ hg bisect -s
386 $ hg bisect -s
387 Testing changeset 5:7874a09ea728 (6 changesets remaining, ~2 tests)
387 Testing changeset 5:7874a09ea728 (6 changesets remaining, ~2 tests)
388 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
389 $ hg bisect -g
389 $ hg bisect -g
390 The first bad revision is:
390 The first bad revision is:
391 changeset: 6:a3d5c6fdf0d3
391 changeset: 6:a3d5c6fdf0d3
392 user: test
392 user: test
393 date: Thu Jan 01 00:00:06 1970 +0000
393 date: Thu Jan 01 00:00:06 1970 +0000
394 summary: msg 6
394 summary: msg 6
395
395
396 $ hg log -r "bisect(good)"
396 $ hg log -r "bisect(good)"
397 changeset: 0:b99c7b9c8e11
397 changeset: 0:b99c7b9c8e11
398 user: test
398 user: test
399 date: Thu Jan 01 00:00:00 1970 +0000
399 date: Thu Jan 01 00:00:00 1970 +0000
400 summary: msg 0
400 summary: msg 0
401
401
402 changeset: 5:7874a09ea728
402 changeset: 5:7874a09ea728
403 user: test
403 user: test
404 date: Thu Jan 01 00:00:05 1970 +0000
404 date: Thu Jan 01 00:00:05 1970 +0000
405 summary: msg 5
405 summary: msg 5
406
406
407 $ hg log -r "bisect(bad)"
407 $ hg log -r "bisect(bad)"
408 changeset: 6:a3d5c6fdf0d3
408 changeset: 6:a3d5c6fdf0d3
409 user: test
409 user: test
410 date: Thu Jan 01 00:00:06 1970 +0000
410 date: Thu Jan 01 00:00:06 1970 +0000
411 summary: msg 6
411 summary: msg 6
412
412
413 $ hg log -r "bisect(current)"
413 $ hg log -r "bisect(current)"
414 changeset: 5:7874a09ea728
414 changeset: 5:7874a09ea728
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:05 1970 +0000
416 date: Thu Jan 01 00:00:05 1970 +0000
417 summary: msg 5
417 summary: msg 5
418
418
419 $ hg log -r "bisect(skip)"
419 $ hg log -r "bisect(skip)"
420 changeset: 1:5cd978ea5149
420 changeset: 1:5cd978ea5149
421 user: test
421 user: test
422 date: Thu Jan 01 00:00:01 1970 +0000
422 date: Thu Jan 01 00:00:01 1970 +0000
423 summary: msg 1
423 summary: msg 1
424
424
425 changeset: 2:db07c04beaca
425 changeset: 2:db07c04beaca
426 user: test
426 user: test
427 date: Thu Jan 01 00:00:02 1970 +0000
427 date: Thu Jan 01 00:00:02 1970 +0000
428 summary: msg 2
428 summary: msg 2
429
429
430 changeset: 3:b53bea5e2fcb
430 changeset: 3:b53bea5e2fcb
431 user: test
431 user: test
432 date: Thu Jan 01 00:00:03 1970 +0000
432 date: Thu Jan 01 00:00:03 1970 +0000
433 summary: msg 3
433 summary: msg 3
434
434
435 changeset: 4:9b2ba8336a65
435 changeset: 4:9b2ba8336a65
436 user: test
436 user: test
437 date: Thu Jan 01 00:00:04 1970 +0000
437 date: Thu Jan 01 00:00:04 1970 +0000
438 summary: msg 4
438 summary: msg 4
439
439
440
440
441 test legacy bisected() keyword
441 test legacy bisected() keyword
442
442
443 $ hg log -r "bisected(bad)"
443 $ hg log -r "bisected(bad)"
444 changeset: 6:a3d5c6fdf0d3
444 changeset: 6:a3d5c6fdf0d3
445 user: test
445 user: test
446 date: Thu Jan 01 00:00:06 1970 +0000
446 date: Thu Jan 01 00:00:06 1970 +0000
447 summary: msg 6
447 summary: msg 6
448
448
449
449
450 $ set +e
450 $ set +e
451
451
452 test invalid command
452 test invalid command
453 assuming that the shell returns 127 if command not found ...
453 assuming that the shell returns 127 if command not found ...
454
454
455 $ hg bisect -r
455 $ hg bisect -r
456 $ hg bisect --command 'exit 127'
456 $ hg bisect --command 'exit 127'
457 abort: failed to execute exit 127
457 abort: failed to execute exit 127
458 [255]
458 [255]
459
459
460
460
461 test bisecting command
461 test bisecting command
462
462
463 $ cat > script.py <<EOF
463 $ cat > script.py <<EOF
464 > #!$PYTHON
464 > #!$PYTHON
465 > from __future__ import absolute_import
465 > from __future__ import absolute_import
466 > import sys
466 > import sys
467 > from mercurial import hg, ui as uimod
467 > from mercurial import hg, ui as uimod
468 > repo = hg.repository(uimod.ui.load(), b'.')
468 > repo = hg.repository(uimod.ui.load(), b'.')
469 > if repo[b'.'].rev() < 6:
469 > if repo[b'.'].rev() < 6:
470 > sys.exit(1)
470 > sys.exit(1)
471 > EOF
471 > EOF
472 $ chmod +x script.py
472 $ chmod +x script.py
473 $ hg bisect -r
473 $ hg bisect -r
474 $ hg up -qr tip
474 $ hg up -qr tip
475 $ hg bisect --command "\"$PYTHON\" \"$TESTTMP/script.py\" and some parameters"
475 $ hg bisect --command "\"$PYTHON\" \"$TESTTMP/script.py\" and some parameters"
476 changeset 31:58c80a7c8a40: good
476 changeset 31:58c80a7c8a40: good
477 abort: cannot bisect (no known bad revisions)
477 abort: cannot bisect (no known bad revisions)
478 [255]
478 [255]
479 $ hg up -qr 0
479 $ hg up -qr 0
480 $ hg bisect --command "\"$PYTHON\" \"$TESTTMP/script.py\" and some parameters"
480 $ hg bisect --command "\"$PYTHON\" \"$TESTTMP/script.py\" and some parameters"
481 changeset 0:b99c7b9c8e11: bad
481 changeset 0:b99c7b9c8e11: bad
482 changeset 15:e7fa0811edb0: good
482 changeset 15:e7fa0811edb0: good
483 changeset 7:03750880c6b5: good
483 changeset 7:03750880c6b5: good
484 changeset 3:b53bea5e2fcb: bad
484 changeset 3:b53bea5e2fcb: bad
485 changeset 5:7874a09ea728: bad
485 changeset 5:7874a09ea728: bad
486 changeset 6:a3d5c6fdf0d3: good
486 changeset 6:a3d5c6fdf0d3: good
487 The first good revision is:
487 The first good revision is:
488 changeset: 6:a3d5c6fdf0d3
488 changeset: 6:a3d5c6fdf0d3
489 user: test
489 user: test
490 date: Thu Jan 01 00:00:06 1970 +0000
490 date: Thu Jan 01 00:00:06 1970 +0000
491 summary: msg 6
491 summary: msg 6
492
492
493
493
494
494
495 test bisecting via a command without updating the working dir, and
495 test bisecting via a command without updating the working dir, and
496 ensure that the bisect state file is updated before running a test
496 ensure that the bisect state file is updated before running a test
497 command
497 command
498
498
499 $ hg update null
499 $ hg update null
500 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
500 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
501 $ cat > script.sh <<'EOF'
501 $ cat > script.sh <<'EOF'
502 > #!/bin/sh
502 > #!/bin/sh
503 > test -n "$HG_NODE" || (echo HG_NODE missing; exit 127)
503 > test -n "$HG_NODE" || (echo HG_NODE missing; exit 127)
504 > current="`hg log -r \"bisect(current)\" --template {node}`"
504 > current="`hg log -r \"bisect(current)\" --template {node}`"
505 > test "$current" = "$HG_NODE" || (echo current is bad: $current; exit 127)
505 > test "$current" = "$HG_NODE" || (echo current is bad: $current; exit 127)
506 > rev="`hg log -r $HG_NODE --template {rev}`"
506 > rev="`hg log -r $HG_NODE --template {rev}`"
507 > test "$rev" -ge 6
507 > test "$rev" -ge 6
508 > EOF
508 > EOF
509 $ chmod +x script.sh
509 $ chmod +x script.sh
510 $ hg bisect -r
510 $ hg bisect -r
511 $ hg bisect --good tip --noupdate
511 $ hg bisect --good tip --noupdate
512 $ hg bisect --bad 0 --noupdate
512 $ hg bisect --bad 0 --noupdate
513 Testing changeset 15:e7fa0811edb0 (31 changesets remaining, ~4 tests)
513 Testing changeset 15:e7fa0811edb0 (31 changesets remaining, ~4 tests)
514 $ hg bisect --command "sh \"$TESTTMP/script.sh\" and some params" --noupdate
514 $ hg bisect --command "sh \"$TESTTMP/script.sh\" and some params" --noupdate
515 changeset 15:e7fa0811edb0: good
515 changeset 15:e7fa0811edb0: good
516 changeset 7:03750880c6b5: good
516 changeset 7:03750880c6b5: good
517 changeset 3:b53bea5e2fcb: bad
517 changeset 3:b53bea5e2fcb: bad
518 changeset 5:7874a09ea728: bad
518 changeset 5:7874a09ea728: bad
519 changeset 6:a3d5c6fdf0d3: good
519 changeset 6:a3d5c6fdf0d3: good
520 The first good revision is:
520 The first good revision is:
521 changeset: 6:a3d5c6fdf0d3
521 changeset: 6:a3d5c6fdf0d3
522 user: test
522 user: test
523 date: Thu Jan 01 00:00:06 1970 +0000
523 date: Thu Jan 01 00:00:06 1970 +0000
524 summary: msg 6
524 summary: msg 6
525
525
526
526
527 ensure that we still don't have a working dir
527 ensure that we still don't have a working dir
528
528
529 $ hg parents
529 $ hg parents
530
530
531
531
532 test the same case, this time with updating
532 test the same case, this time with updating
533
533
534 $ cat > script.sh <<'EOF'
534 $ cat > script.sh <<'EOF'
535 > #!/bin/sh
535 > #!/bin/sh
536 > test -n "$HG_NODE" || (echo HG_NODE missing; exit 127)
536 > test -n "$HG_NODE" || (echo HG_NODE missing; exit 127)
537 > current="`hg log -r \"bisect(current)\" --template {node}`"
537 > current="`hg log -r \"bisect(current)\" --template {node}`"
538 > test "$current" = "$HG_NODE" || (echo current is bad: $current; exit 127)
538 > test "$current" = "$HG_NODE" || (echo current is bad: $current; exit 127)
539 > rev="`hg log -r . --template {rev}`"
539 > rev="`hg log -r . --template {rev}`"
540 > test "$rev" -ge 6
540 > test "$rev" -ge 6
541 > EOF
541 > EOF
542 $ chmod +x script.sh
542 $ chmod +x script.sh
543 $ hg bisect -r
543 $ hg bisect -r
544 $ hg up -qr tip
544 $ hg up -qr tip
545 $ hg bisect --command "sh \"$TESTTMP/script.sh\" and some params"
545 $ hg bisect --command "sh \"$TESTTMP/script.sh\" and some params"
546 changeset 31:58c80a7c8a40: good
546 changeset 31:58c80a7c8a40: good
547 abort: cannot bisect (no known bad revisions)
547 abort: cannot bisect (no known bad revisions)
548 [255]
548 [255]
549 $ hg up -qr 0
549 $ hg up -qr 0
550 $ hg bisect --command "sh \"$TESTTMP/script.sh\" and some params"
550 $ hg bisect --command "sh \"$TESTTMP/script.sh\" and some params"
551 changeset 0:b99c7b9c8e11: bad
551 changeset 0:b99c7b9c8e11: bad
552 changeset 15:e7fa0811edb0: good
552 changeset 15:e7fa0811edb0: good
553 changeset 7:03750880c6b5: good
553 changeset 7:03750880c6b5: good
554 changeset 3:b53bea5e2fcb: bad
554 changeset 3:b53bea5e2fcb: bad
555 changeset 5:7874a09ea728: bad
555 changeset 5:7874a09ea728: bad
556 changeset 6:a3d5c6fdf0d3: good
556 changeset 6:a3d5c6fdf0d3: good
557 The first good revision is:
557 The first good revision is:
558 changeset: 6:a3d5c6fdf0d3
558 changeset: 6:a3d5c6fdf0d3
559 user: test
559 user: test
560 date: Thu Jan 01 00:00:06 1970 +0000
560 date: Thu Jan 01 00:00:06 1970 +0000
561 summary: msg 6
561 summary: msg 6
562
562
563 $ hg graft -q 15
563 $ hg graft -q 15
564 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
564 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
565 abort: unresolved conflicts, can't continue
565 abort: unresolved conflicts, can't continue
566 (use 'hg resolve' and 'hg graft --continue')
566 (use 'hg resolve' and 'hg graft --continue')
567 [255]
567 [255]
568 $ hg bisect --reset
568 $ hg bisect --reset
569 $ hg up -C .
569 $ hg up -C .
570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
571
571
572 Check that bisect does not break on obsolete changesets
572 Check that bisect does not break on obsolete changesets
573 =========================================================
573 =========================================================
574
574
575 $ cat >> $HGRCPATH << EOF
575 $ cat >> $HGRCPATH << EOF
576 > [experimental]
576 > [experimental]
577 > evolution.createmarkers=True
577 > evolution.createmarkers=True
578 > EOF
578 > EOF
579
579
580 tip is obsolete
580 tip is obsolete
581 ---------------------
581 ---------------------
582
582
583 $ hg debugobsolete `hg id --debug -i -r tip`
583 $ hg debugobsolete `hg id --debug -i -r tip`
584 obsoleted 1 changesets
584 obsoleted 1 changesets
585 $ hg bisect --reset
585 $ hg bisect --reset
586 $ hg bisect --good 15
586 $ hg bisect --good 15
587 $ hg bisect --bad 30
587 $ hg bisect --bad 30
588 Testing changeset 22:06c7993750ce (15 changesets remaining, ~3 tests)
588 Testing changeset 22:06c7993750ce (15 changesets remaining, ~3 tests)
589 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
589 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
590 $ hg bisect --command true
590 $ hg bisect --command true
591 changeset 22:06c7993750ce: good
591 changeset 22:06c7993750ce: good
592 changeset 26:3efc6fd51aeb: good
592 changeset 26:3efc6fd51aeb: good
593 changeset 28:8e0c2264c8af: good
593 changeset 28:8e0c2264c8af: good
594 changeset 29:b5bd63375ab9: good
594 changeset 29:b5bd63375ab9: good
595 The first bad revision is:
595 The first bad revision is:
596 changeset: 30:ed2d2f24b11c
596 changeset: 30:ed2d2f24b11c
597 tag: tip
597 tag: tip
598 user: test
598 user: test
599 date: Thu Jan 01 00:00:30 1970 +0000
599 date: Thu Jan 01 00:00:30 1970 +0000
600 summary: msg 30
600 summary: msg 30
601
601
602
602
603 Rewritten commits should not crash
604
605 $ hg co 29
606 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
607 $ hg revert --all -r 30
608 reverting a
609 $ hg commit -m 'msg 30 -- fixed'
610 created new head
611 $ hg debugobsolete `hg id --debug -i -r 30` `hg id --debug -i -r .`
612 obsoleted 1 changesets
613 $ hg bisect
614 The first bad revision is:
615 changeset: 30:ed2d2f24b11c
616 user: test
617 date: Thu Jan 01 00:00:30 1970 +0000
618 obsolete: rewritten as 32:8a638ebd1122
619 summary: msg 30
620
621
622 Log template does not crash
623
624 $ hg log -GTbisect -r 15::
625 @ changeset: 32:8a638ebd1122
626 | bisect: good (implicit)
627 | tag: tip
628 | parent: 29:b5bd63375ab9
629 | user: test
630 | date: Thu Jan 01 00:00:00 1970 +0000
631 | summary: msg 30 -- fixed
632 |
633 o changeset: 29:b5bd63375ab9
634 | bisect: good
635 | user: test
636 | date: Thu Jan 01 00:00:29 1970 +0000
637 | summary: msg 29
638 |
639 o changeset: 28:8e0c2264c8af
640 | bisect: good
641 | user: test
642 | date: Thu Jan 01 00:00:28 1970 +0000
643 | summary: msg 28
644 |
645 o changeset: 27:288867a866e9
646 | bisect: ignored
647 | user: test
648 | date: Thu Jan 01 00:00:27 1970 +0000
649 | summary: msg 27
650 |
651 o changeset: 26:3efc6fd51aeb
652 | bisect: good
653 | user: test
654 | date: Thu Jan 01 00:00:26 1970 +0000
655 | summary: msg 26
656 |
657 o changeset: 25:02a84173a97a
658 | bisect: ignored
659 | user: test
660 | date: Thu Jan 01 00:00:25 1970 +0000
661 | summary: msg 25
662 |
663 o changeset: 24:10e0acd3809e
664 | bisect: ignored
665 | user: test
666 | date: Thu Jan 01 00:00:24 1970 +0000
667 | summary: msg 24
668 |
669 o changeset: 23:5ec79163bff4
670 | bisect: ignored
671 | user: test
672 | date: Thu Jan 01 00:00:23 1970 +0000
673 | summary: msg 23
674 |
675 o changeset: 22:06c7993750ce
676 | bisect: good
677 | user: test
678 | date: Thu Jan 01 00:00:22 1970 +0000
679 | summary: msg 22
680 |
681 o changeset: 21:e5db6aa3fe2a
682 | bisect: ignored
683 | user: test
684 | date: Thu Jan 01 00:00:21 1970 +0000
685 | summary: msg 21
686 |
687 o changeset: 20:7128fb4fdbc9
688 | bisect: ignored
689 | user: test
690 | date: Thu Jan 01 00:00:20 1970 +0000
691 | summary: msg 20
692 |
693 o changeset: 19:52798545b482
694 | bisect: ignored
695 | user: test
696 | date: Thu Jan 01 00:00:19 1970 +0000
697 | summary: msg 19
698 |
699 o changeset: 18:86977a90077e
700 | bisect: ignored
701 | user: test
702 | date: Thu Jan 01 00:00:18 1970 +0000
703 | summary: msg 18
704 |
705 o changeset: 17:03515f4a9080
706 | bisect: ignored
707 | user: test
708 | date: Thu Jan 01 00:00:17 1970 +0000
709 | summary: msg 17
710 |
711 o changeset: 16:a2e6ea4973e9
712 | bisect: ignored
713 | user: test
714 | date: Thu Jan 01 00:00:16 1970 +0000
715 | summary: msg 16
716 |
717 o changeset: 15:e7fa0811edb0
718 | bisect: good
719 ~ user: test
720 date: Thu Jan 01 00:00:15 1970 +0000
721 summary: msg 15
722
723 $ hg debugobsolete --delete `hg debugobsolete --index -T'{index}\n' | tail -1`
724 deleted 1 obsolescence markers
725
603 Changeset in the bad:good range is obsolete
726 Changeset in the bad:good range is obsolete
604 ---------------------------------------------
727 ---------------------------------------------
605
728
606 $ hg up 30
729 $ hg up 30
607 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
730 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
608 $ echo 'a' >> a
731 $ echo 'a' >> a
609 $ hg ci -m "msg 32" -d "32 0"
732 $ hg ci -m "msg 32" -d "32 0"
610 $ hg bisect --reset
733 $ hg bisect --reset
611 $ hg bisect --good .
734 $ hg bisect --good .
612 $ hg bisect --bad 25
735 $ hg bisect --bad 25
613 Testing changeset 28:8e0c2264c8af (6 changesets remaining, ~2 tests)
736 Testing changeset 28:8e0c2264c8af (6 changesets remaining, ~2 tests)
614 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
737 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
615 $ hg bisect --command true
738 $ hg bisect --command true
616 changeset 28:8e0c2264c8af: good
739 changeset 28:8e0c2264c8af: good
617 changeset 26:3efc6fd51aeb: good
740 changeset 26:3efc6fd51aeb: good
618 The first good revision is:
741 The first good revision is:
619 changeset: 26:3efc6fd51aeb
742 changeset: 26:3efc6fd51aeb
620 user: test
743 user: test
621 date: Thu Jan 01 00:00:26 1970 +0000
744 date: Thu Jan 01 00:00:26 1970 +0000
622 summary: msg 26
745 summary: msg 26
623
746
624 Test the validation message when exclusive options are used:
747 Test the validation message when exclusive options are used:
625
748
626 $ hg bisect -r
749 $ hg bisect -r
627 $ hg bisect -b -c false
750 $ hg bisect -b -c false
628 abort: --bad and --command are incompatible
751 abort: --bad and --command are incompatible
629 [255]
752 [255]
630 $ hg bisect -b -e
753 $ hg bisect -b -e
631 abort: --bad and --extend are incompatible
754 abort: --bad and --extend are incompatible
632 [255]
755 [255]
633 $ hg bisect -b -g
756 $ hg bisect -b -g
634 abort: --bad and --good are incompatible
757 abort: --bad and --good are incompatible
635 [255]
758 [255]
636 $ hg bisect -b -r
759 $ hg bisect -b -r
637 abort: --bad and --reset are incompatible
760 abort: --bad and --reset are incompatible
638 [255]
761 [255]
639 $ hg bisect -b -s
762 $ hg bisect -b -s
640 abort: --bad and --skip are incompatible
763 abort: --bad and --skip are incompatible
641 [255]
764 [255]
642 $ hg bisect -c false -e
765 $ hg bisect -c false -e
643 abort: --command and --extend are incompatible
766 abort: --command and --extend are incompatible
644 [255]
767 [255]
645 $ hg bisect -c false -g
768 $ hg bisect -c false -g
646 abort: --command and --good are incompatible
769 abort: --command and --good are incompatible
647 [255]
770 [255]
648 $ hg bisect -c false -r
771 $ hg bisect -c false -r
649 abort: --command and --reset are incompatible
772 abort: --command and --reset are incompatible
650 [255]
773 [255]
651 $ hg bisect -c false -s
774 $ hg bisect -c false -s
652 abort: --command and --skip are incompatible
775 abort: --command and --skip are incompatible
653 [255]
776 [255]
654 $ hg bisect -e -g
777 $ hg bisect -e -g
655 abort: --extend and --good are incompatible
778 abort: --extend and --good are incompatible
656 [255]
779 [255]
657 $ hg bisect -e -r
780 $ hg bisect -e -r
658 abort: --extend and --reset are incompatible
781 abort: --extend and --reset are incompatible
659 [255]
782 [255]
660 $ hg bisect -e -s
783 $ hg bisect -e -s
661 abort: --extend and --skip are incompatible
784 abort: --extend and --skip are incompatible
662 [255]
785 [255]
663 $ hg bisect -g -r
786 $ hg bisect -g -r
664 abort: --good and --reset are incompatible
787 abort: --good and --reset are incompatible
665 [255]
788 [255]
666 $ hg bisect -g -s
789 $ hg bisect -g -s
667 abort: --good and --skip are incompatible
790 abort: --good and --skip are incompatible
668 [255]
791 [255]
669 $ hg bisect -r -s
792 $ hg bisect -r -s
670 abort: --reset and --skip are incompatible
793 abort: --reset and --skip are incompatible
671 [255]
794 [255]
General Comments 0
You need to be logged in to leave comments. Login now