annotate mercurial/hbisect.py @ 52075:ff4562ed9ed7

localrepo: drop the CamelCase name for `localrepo.localcommandexecutor` See 61557734c0ae for the reasoning.
author Matt Harbison <matt_harbison@yahoo.com>
date Wed, 23 Oct 2024 16:51:18 -0400
parents f4733654f144
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5775
2dd202a6e15b bisect: make bisect a built-in command
Matt Mackall <mpm@selenic.com>
parents: 5774
diff changeset
1 # changelog bisection for mercurial
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 45875
diff changeset
3 # Copyright 2007 Olivia Mackall
1861
65949d1c9bf7 Added copyright information to hbisect.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1856
diff changeset
4 # Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
8228
eee2319c5895 add blank line after copyright notices and after header
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
5 #
1861
65949d1c9bf7 Added copyright information to hbisect.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1856
diff changeset
6 # Inspired by git bisect, extension skeleton taken from mq.py.
65949d1c9bf7 Added copyright information to hbisect.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1856
diff changeset
7 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
8 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9583
diff changeset
9 # GNU General Public License version 2 or any later version.
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
10
51863
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 49491
diff changeset
11 from __future__ import annotations
25952
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
12
25113
0ca8410ea345 util: drop alias for collections.deque
Martin von Zweigbergk <martinvonz@google.com>
parents: 23877
diff changeset
13 import collections
43665
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
14 import contextlib
25952
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
15
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
16 from .i18n import _
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
17 from .node import (
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
18 hex,
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
19 short,
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
20 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
21 from . import error
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
22
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
23
35128
fd8b6b183073 hbisect: pass repo into hbisect.bisect
David Soria Parra <davidsp@fb.com>
parents: 30389
diff changeset
24 def bisect(repo, state):
6858
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
25 """find the next node (if any) for testing during a bisect search.
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
26 returns a (nodes, number, good) tuple.
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
27
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
28 'nodes' is the final result of the bisect if 'number' is 0.
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
29 Otherwise 'number' indicates the remaining possible candidates for
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
30 the search and 'nodes' contains the next bisect target.
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
31 'good' is True if bisect is searching for a first good changeset, False
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
32 if searching for a first bad one.
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
33 """
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
34
42310
21eda240be07 bisect: do not crash with rewritten commits
timeless <timeless@mozdev.org>
parents: 42057
diff changeset
35 repo = repo.unfiltered()
35128
fd8b6b183073 hbisect: pass repo into hbisect.bisect
David Soria Parra <davidsp@fb.com>
parents: 30389
diff changeset
36 changelog = repo.changelog
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
37 clparents = changelog.parentrevs
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
38 skip = {changelog.rev(n) for n in state[b'skip']}
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
39
5776
35ec669cdd43 bisect: handle search for bad to good transitions
Matt Mackall <mpm@selenic.com>
parents: 5775
diff changeset
40 def buildancestors(bad, good):
35ec669cdd43 bisect: handle search for bad to good transitions
Matt Mackall <mpm@selenic.com>
parents: 5775
diff changeset
41 badrev = min([changelog.rev(n) for n in bad])
35130
8287df8b7be5 hbisect: use a defaultdict to avoid large allocations for a large changelogs
David Soria Parra <davidsp@fb.com>
parents: 35129
diff changeset
42 ancestors = collections.defaultdict(lambda: None)
49441
3ef153aa1eed bisect: limit ancestors to revs topologically between good and bad revs
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 48875
diff changeset
43 for rev in repo.revs(b"(%ln::%d) - (::%ln)", good, badrev, good):
14895
a35d6f822e3e hbisect: do not assume that min(good) is an ancestor of min(bad)
Alexander Krauss <krauss@in.tum.de>
parents: 14894
diff changeset
44 ancestors[rev] = []
5776
35ec669cdd43 bisect: handle search for bad to good transitions
Matt Mackall <mpm@selenic.com>
parents: 5775
diff changeset
45 if ancestors[badrev] is None:
5777
51776e50bc8c bisect: improve tests
Matt Mackall <mpm@selenic.com>
parents: 5776
diff changeset
46 return badrev, None
5776
35ec669cdd43 bisect: handle search for bad to good transitions
Matt Mackall <mpm@selenic.com>
parents: 5775
diff changeset
47 return badrev, ancestors
35ec669cdd43 bisect: handle search for bad to good transitions
Matt Mackall <mpm@selenic.com>
parents: 5775
diff changeset
48
14215
e5a59d31bb04 hbisect: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents: 12067
diff changeset
49 good = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
50 badrev, ancestors = buildancestors(state[b'bad'], state[b'good'])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
51 if not ancestors: # looking for bad to good transition?
14215
e5a59d31bb04 hbisect: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents: 12067
diff changeset
52 good = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
53 badrev, ancestors = buildancestors(state[b'good'], state[b'bad'])
5777
51776e50bc8c bisect: improve tests
Matt Mackall <mpm@selenic.com>
parents: 5776
diff changeset
54 bad = changelog.node(badrev)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
55 if not ancestors: # now we're confused
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
56 if (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
57 len(state[b'bad']) == 1
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
58 and len(state[b'good']) == 1
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
59 and state[b'bad'] != state[b'good']
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
60 ):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
61 raise error.Abort(_(b"starting revisions are not directly related"))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
62 raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
63 _(b"inconsistent state, %d:%s is good and bad")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
64 % (badrev, short(bad))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
65 )
5723
e3b09819496b bisect: switch to rev-based calculation
Matt Mackall <mpm@selenic.com>
parents: 5722
diff changeset
66
5768
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
67 # build children dict
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
68 children = {}
25113
0ca8410ea345 util: drop alias for collections.deque
Martin von Zweigbergk <martinvonz@google.com>
parents: 23877
diff changeset
69 visit = collections.deque([badrev])
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
70 candidates = []
5768
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
71 while visit:
16803
107a3270a24a cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16647
diff changeset
72 rev = visit.popleft()
5767
dd5f8ed31057 bisect: propagate ancestor lists directly to children
Matt Mackall <mpm@selenic.com>
parents: 5766
diff changeset
73 if ancestors[rev] == []:
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
74 candidates.append(rev)
5767
dd5f8ed31057 bisect: propagate ancestor lists directly to children
Matt Mackall <mpm@selenic.com>
parents: 5766
diff changeset
75 for prev in clparents(rev):
5768
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
76 if prev != -1:
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
77 if prev in children:
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
78 children[prev].append(rev)
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
79 else:
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
80 children[prev] = [rev]
78d14403bdc7 bisect: use a dict for children
Matt Mackall <mpm@selenic.com>
parents: 5767
diff changeset
81 visit.append(prev)
5767
dd5f8ed31057 bisect: propagate ancestor lists directly to children
Matt Mackall <mpm@selenic.com>
parents: 5766
diff changeset
82
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
83 candidates.sort()
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
84 # have we narrowed it down to one entry?
6858
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
85 # or have all other possible candidates besides 'bad' have been skipped?
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
86 tot = len(candidates)
6858
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
87 unskipped = [c for c in candidates if (c not in skip) and (c != badrev)]
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
88 if tot == 1 or not unskipped:
30389
e124e83fd159 hbisect: avoid shadowing a variable in a list comprehension
Augie Fackler <augie@google.com>
parents: 30126
diff changeset
89 return ([changelog.node(c) for c in candidates], 0, good)
7902
afddc32b2b3f bisect: use integer division
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7557
diff changeset
90 perfect = tot // 2
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
91
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
92 # find the best node to test
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
93 best_rev = None
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
94 best_len = -1
8463
43186df4bb8e bisect: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8228
diff changeset
95 poison = set()
5769
49809f4a38d8 bisect: calculate candidate set while finding children
Matt Mackall <mpm@selenic.com>
parents: 5768
diff changeset
96 for rev in candidates:
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
97 if rev in poison:
8482
fc27c91fff2c hbisect: use set.update for bulk updates
Martin Geisler <mg@lazybytes.net>
parents: 8463
diff changeset
98 # poison children
fc27c91fff2c hbisect: use set.update for bulk updates
Martin Geisler <mg@lazybytes.net>
parents: 8463
diff changeset
99 poison.update(children.get(rev, []))
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
100 continue
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
101
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
102 a = ancestors[rev] or [rev]
5770
f5b858fc8067 bisect: find best node in ancestor collection pass
Matt Mackall <mpm@selenic.com>
parents: 5769
diff changeset
103 ancestors[rev] = None
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
104
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
105 x = len(a) # number of ancestors
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
106 y = tot - x # number of non-ancestors
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
107 value = min(x, y) # how good is this test?
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
108 if value > best_len and rev not in skip:
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
109 best_len = value
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
110 best_rev = rev
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
111 if value == perfect: # found a perfect candidate? quit early
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
112 break
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
113
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
114 if y < perfect and rev not in skip: # all downhill from here?
8482
fc27c91fff2c hbisect: use set.update for bulk updates
Martin Geisler <mg@lazybytes.net>
parents: 8463
diff changeset
115 # poison children
fc27c91fff2c hbisect: use set.update for bulk updates
Martin Geisler <mg@lazybytes.net>
parents: 8463
diff changeset
116 poison.update(children.get(rev, []))
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
117 continue
5772
4c46636eafe5 bisect: skip calculations on candidates with too many ancestors
Matt Mackall <mpm@selenic.com>
parents: 5771
diff changeset
118
49491
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
119 unvisited = []
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
120 for c in children.get(rev, []):
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
121 if ancestors[c]:
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8109
diff changeset
122 ancestors[c] = list(set(ancestors[c] + a))
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
123 else:
49491
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
124 unvisited.append(c)
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
125
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
126 # Reuse existing ancestor list for the first unvisited child to avoid
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
127 # excessive copying for linear portions of history.
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
128 if unvisited:
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
129 first = unvisited.pop(0)
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
130 for c in unvisited:
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
131 ancestors[c] = a + [c]
49491
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
132 a.append(first)
c6a1beba27e9 bisect: avoid copying ancestor list for non-merge commits
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents: 49441
diff changeset
133 ancestors[first] = a
5734
944b231fa0e7 bisect: move reporting out of core bisect function
Matt Mackall <mpm@selenic.com>
parents: 5733
diff changeset
134
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
135 assert best_rev is not None
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
136 best_node = changelog.node(best_rev)
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
137
6858
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
138 return ([best_node], tot, good)
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
139
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
140
30066
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
141 def extendrange(repo, state, nodes, good):
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
142 # bisect is incomplete when it ends on a merge node and
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
143 # one of the parent was not checked.
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
144 parents = repo[nodes[0]].parents()
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
145 if len(parents) > 1:
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
146 if good:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
147 side = state[b'bad']
30066
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
148 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
149 side = state[b'good']
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43665
diff changeset
150 num = len({i.node() for i in parents} & set(side))
30066
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
151 if num == 1:
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
152 return parents[0].ancestor(parents[1])
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
153 return None
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
154
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
155
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
156 def load_state(repo):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
157 state = {b'current': [], b'good': [], b'bad': [], b'skip': []}
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
158 for l in repo.vfs.tryreadlines(b"bisect.state"):
27525
cba62f996780 hbisect: use tryreadlines to load state
Bryan O'Sullivan <bos@serpentine.com>
parents: 26587
diff changeset
159 kind, node = l[:-1].split()
42310
21eda240be07 bisect: do not crash with rewritten commits
timeless <timeless@mozdev.org>
parents: 42057
diff changeset
160 node = repo.unfiltered().lookup(node)
27525
cba62f996780 hbisect: use tryreadlines to load state
Bryan O'Sullivan <bos@serpentine.com>
parents: 26587
diff changeset
161 if kind not in state:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
162 raise error.Abort(_(b"unknown bisect kind %s") % kind)
27525
cba62f996780 hbisect: use tryreadlines to load state
Bryan O'Sullivan <bos@serpentine.com>
parents: 26587
diff changeset
163 state[kind].append(node)
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
164 return state
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
165
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
166
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
167 def save_state(repo, state):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
168 f = repo.vfs(b"bisect.state", b"w", atomictemp=True)
27853
9b8a5c6ac176 with: use context manager in bisect save_state
Bryan O'Sullivan <bryano@fb.com>
parents: 27525
diff changeset
169 with repo.wlock():
18358
93293813d753 bisect: store state sorted
Mads Kiilerich <mads@kiilerich.com>
parents: 17537
diff changeset
170 for kind in sorted(state):
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
171 for node in state[kind]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
172 f.write(b"%s %s\n" % (kind, hex(node)))
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14895
diff changeset
173 f.close()
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
174
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
175
30065
ee21ed7fc7a2 bisect: extract the 'reset' logic into its own function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 27853
diff changeset
176 def resetstate(repo):
ee21ed7fc7a2 bisect: extract the 'reset' logic into its own function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 27853
diff changeset
177 """remove any bisect state from the repository"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
178 if repo.vfs.exists(b"bisect.state"):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
179 repo.vfs.unlink(b"bisect.state")
30065
ee21ed7fc7a2 bisect: extract the 'reset' logic into its own function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 27853
diff changeset
180
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
181
30126
755730fc1e48 bisect: move check_state into the bisect module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30067
diff changeset
182 def checkstate(state):
755730fc1e48 bisect: move check_state into the bisect module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30067
diff changeset
183 """check we have both 'good' and 'bad' to define a range
755730fc1e48 bisect: move check_state into the bisect module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30067
diff changeset
184
45875
e641bb2a6159 errors: raise StateError in `hg bisect`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44452
diff changeset
185 Raise StateError exception otherwise."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
186 if state[b'good'] and state[b'bad']:
30126
755730fc1e48 bisect: move check_state into the bisect module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30067
diff changeset
187 return True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
188 if not state[b'good']:
45875
e641bb2a6159 errors: raise StateError in `hg bisect`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44452
diff changeset
189 raise error.StateError(_(b'cannot bisect (no known good revisions)'))
30126
755730fc1e48 bisect: move check_state into the bisect module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30067
diff changeset
190 else:
45875
e641bb2a6159 errors: raise StateError in `hg bisect`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44452
diff changeset
191 raise error.StateError(_(b'cannot bisect (no known bad revisions)'))
30126
755730fc1e48 bisect: move check_state into the bisect module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30067
diff changeset
192
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
193
43665
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
194 @contextlib.contextmanager
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
195 def restore_state(repo, state, node):
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
196 try:
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
197 yield
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
198 finally:
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
199 state[b'current'] = [node]
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
200 save_state(repo, state)
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
201
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
202
15135
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
203 def get(repo, status):
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
204 """
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
205 Return a list of revision(s) that match the given status:
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
206
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
207 - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 16834
diff changeset
208 - ``goods``, ``bads`` : csets topologically good/bad
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
209 - ``range`` : csets taking part in the bisection
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
210 - ``pruned`` : csets that are goods, bads or skipped
15138
883d28233a4d revset.bisect: add new 'untested' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15137
diff changeset
211 - ``untested`` : csets whose fate is yet unknown
15147
395ca8cd2669 revset.bisect: add 'ignored' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15146
diff changeset
212 - ``ignored`` : csets ignored due to DAG topology
16647
14913fcb30c6 bisect: track the current changeset (issue3382)
Bryan O'Sullivan <bryano@fb.com>
parents: 15406
diff changeset
213 - ``current`` : the cset currently being bisected
15135
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
214 """
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
215 state = load_state(repo)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
216 if status in (b'good', b'bad', b'skip', b'current'):
42310
21eda240be07 bisect: do not crash with rewritten commits
timeless <timeless@mozdev.org>
parents: 42057
diff changeset
217 return map(repo.unfiltered().changelog.rev, state[status])
15135
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
218 else:
17493
d057e92dadfc spelling: following
timeless@mozdev.org
parents: 16834
diff changeset
219 # In the following sets, we do *not* call 'bisect()' with more
17509
f7767f52e9eb spelling: recursion
timeless@mozdev.org
parents: 17493
diff changeset
220 # than one level of recursion, because that can be very, very
15146
b39d85be78a8 hbisect.get: use simpler code with repo.set(), fix 'pruned' set
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15138
diff changeset
221 # time consuming. Instead, we always develop the expression as
b39d85be78a8 hbisect.get: use simpler code with repo.set(), fix 'pruned' set
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15138
diff changeset
222 # much as possible.
b39d85be78a8 hbisect.get: use simpler code with repo.set(), fix 'pruned' set
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15138
diff changeset
223
b39d85be78a8 hbisect.get: use simpler code with repo.set(), fix 'pruned' set
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15138
diff changeset
224 # 'range' is all csets that make the bisection:
b39d85be78a8 hbisect.get: use simpler code with repo.set(), fix 'pruned' set
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15138
diff changeset
225 # - have a good ancestor and a bad descendant, or conversely
b39d85be78a8 hbisect.get: use simpler code with repo.set(), fix 'pruned' set
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15138
diff changeset
226 # that's because the bisection can go either way
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
227 range = b'( bisect(bad)::bisect(good) | bisect(good)::bisect(bad) )'
15136
18219c0789ae revset.bisect: add new 'range' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15135
diff changeset
228
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
229 _t = repo.revs(b'bisect(good)::bisect(bad)')
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
230 # The sets of topologically good or bad csets
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
231 if len(_t) == 0:
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
232 # Goods are topologically after bads
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
233 goods = b'bisect(good)::' # Pruned good csets
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
234 bads = b'::bisect(bad)' # Pruned bad csets
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
235 else:
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
236 # Goods are topologically before bads
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
237 goods = b'::bisect(good)' # Pruned good csets
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
238 bads = b'bisect(bad)::' # Pruned bad csets
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
239
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
240 # 'pruned' is all csets whose fate is already known: good, bad, skip
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
241 skips = b'bisect(skip)' # Pruned skipped csets
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
242 pruned = b'( (%s) | (%s) | (%s) )' % (goods, bads, skips)
15136
18219c0789ae revset.bisect: add new 'range' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15135
diff changeset
243
15146
b39d85be78a8 hbisect.get: use simpler code with repo.set(), fix 'pruned' set
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15138
diff changeset
244 # 'untested' is all cset that are- in 'range', but not in 'pruned'
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
245 untested = b'( (%s) - (%s) )' % (range, pruned)
15136
18219c0789ae revset.bisect: add new 'range' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15135
diff changeset
246
15147
395ca8cd2669 revset.bisect: add 'ignored' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15146
diff changeset
247 # 'ignored' is all csets that were not used during the bisection
395ca8cd2669 revset.bisect: add 'ignored' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15146
diff changeset
248 # due to DAG topology, but may however have had an impact.
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 16834
diff changeset
249 # E.g., a branch merged between bads and goods, but whose branch-
15147
395ca8cd2669 revset.bisect: add 'ignored' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15146
diff changeset
250 # point is out-side of the range.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
251 iba = b'::bisect(bad) - ::bisect(good)' # Ignored bads' ancestors
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
252 iga = b'::bisect(good) - ::bisect(bad)' # Ignored goods' ancestors
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
253 ignored = b'( ( (%s) | (%s) ) - (%s) )' % (iba, iga, range)
15147
395ca8cd2669 revset.bisect: add 'ignored' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15146
diff changeset
254
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
255 if status == b'range':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
256 return repo.revs(range)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
257 elif status == b'pruned':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
258 return repo.revs(pruned)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
259 elif status == b'untested':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
260 return repo.revs(untested)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
261 elif status == b'ignored':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
262 return repo.revs(ignored)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
263 elif status == b"goods":
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
264 return repo.revs(goods)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
265 elif status == b"bads":
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
266 return repo.revs(bads)
15136
18219c0789ae revset.bisect: add new 'range' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15135
diff changeset
267 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
268 raise error.ParseError(_(b'invalid bisect state'))
15154
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
269
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
270
15406
1f677c7e494d bisect: remove superfluous parameter in label()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15404
diff changeset
271 def label(repo, node):
15154
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
272 rev = repo.changelog.rev(node)
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
273
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
274 # Try explicit sets
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
275 if rev in get(repo, b'good'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
276 # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
277 return _(b'good')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
278 if rev in get(repo, b'bad'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
279 # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
280 return _(b'bad')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
281 if rev in get(repo, b'skip'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
282 # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
283 return _(b'skipped')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
284 if rev in get(repo, b'untested') or rev in get(repo, b'current'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
285 # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
286 return _(b'untested')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
287 if rev in get(repo, b'ignored'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
288 # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
289 return _(b'ignored')
15154
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
290
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
291 # Try implicit sets
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
292 if rev in get(repo, b'goods'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
293 # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
294 return _(b'good (implicit)')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
295 if rev in get(repo, b'bads'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
296 # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
297 return _(b'bad (implicit)')
15154
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
298
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
299 return None
aa2e908c521e hbisect: add functions to return a label for a cset bisection status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15153
diff changeset
300
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
301
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
302 def printresult(ui, repo, state, displayer, nodes, good):
42310
21eda240be07 bisect: do not crash with rewritten commits
timeless <timeless@mozdev.org>
parents: 42057
diff changeset
303 repo = repo.unfiltered()
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
304 if len(nodes) == 1:
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
305 # narrowed it down to a single revision
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
306 if good:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
307 ui.write(_(b"The first good revision is:\n"))
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
308 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
309 ui.write(_(b"The first bad revision is:\n"))
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
310 displayer.show(repo[nodes[0]])
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
311 extendnode = extendrange(repo, state, nodes, good)
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
312 if extendnode is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
313 ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
314 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
315 b'Not all ancestors of this changeset have been'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
316 b' checked.\nUse bisect --extend to continue the '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
317 b'bisection from\nthe common ancestor, %s.\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
318 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
319 % extendnode
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
320 )
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
321 else:
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
322 # multiple possible revisions
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
323 if good:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
324 ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
325 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
326 b"Due to skipped revisions, the first "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
327 b"good revision could be any of:\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
328 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
329 )
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
330 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
331 ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
332 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
333 b"Due to skipped revisions, the first "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
334 b"bad revision could be any of:\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
335 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
336 )
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
337 for n in nodes:
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
338 displayer.show(repo[n])
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
339 displayer.close()