mercurial/hbisect.py
author Martin von Zweigbergk <martinvonz@google.com>
Thu, 04 Mar 2021 16:06:55 -0800
changeset 46634 ad30b29bc23d
parent 45875 e641bb2a6159
child 46819 d4ba4d51f85f
permissions -rw-r--r--
copies: choose target directory based on longest match If one side of a merge renames `dir1/` to `dir2/` and the subdirectory `dir1/subdir1/` to `dir2/subdir2/`, and the other side of the merge adds a file in `dir1/subdir1/`, we should clearly move that into `dir2/subdir2/`. We already detect the directories correctly before this patch, but we iterate over them in arbitrary order. That results in the new file sometimes ending up in `dir2/subdir1/` instead. This patch fixes it by iterating over the source directories by visiting subdirectories first. That's achieved by simply iterating over them in reverse lexicographical order. Without the fix, the test case still passes on Python 2 but fails on Python 3. It depends on the iteration order of the dict. I did not look into how it's built up and why it behaved differently before the fix. I could probably have gotten it to fail on Python 2 as well by choosing different directory names. Differential Revision: https://phab.mercurial-scm.org/D10115
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
#
5775
2dd202a6e15b bisect: make bisect a built-in command
Matt Mackall <mpm@selenic.com>
parents: 5774
diff changeset
     3
# Copyright 2007 Matt 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
25952
f0ad094db832 hbisect: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25113
diff changeset
    11
from __future__ import absolute_import
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)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    43
        for rev in repo.revs(b"descendants(%ln) - ancestors(%ln)", good, 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
5773
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
   119
        for c in children.get(rev, []):
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
   120
            if ancestors[c]:
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8109
diff changeset
   121
                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
   122
            else:
2f6105ab4c54 bisect: merge ancestor lists when pushing to children
Matt Mackall <mpm@selenic.com>
parents: 5772
diff changeset
   123
                ancestors[c] = a + [c]
5734
944b231fa0e7 bisect: move reporting out of core bisect function
Matt Mackall <mpm@selenic.com>
parents: 5733
diff changeset
   124
5737
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
   125
    assert best_rev is not None
6c8df073c3ee bisect: remove class
Matt Mackall <mpm@selenic.com>
parents: 5736
diff changeset
   126
    best_node = changelog.node(best_rev)
1367
a7678cbd7c28 bisect extension for mercurial
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
diff changeset
   127
6858
8f256bf98219 Add support for multiple possible bisect results (issue1228, issue1182)
Bernhard Leiner <bleiner@gmail.com>
parents: 6217
diff changeset
   128
    return ([best_node], tot, good)
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   129
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   130
30066
5f93737d0ba8 bisect: move the 'extendrange' to the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30065
diff changeset
   131
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
   132
    # 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
   133
    # 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
   134
    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
   135
    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
   136
        if good:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   137
            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
   138
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   139
            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
   140
        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
   141
        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
   142
            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
   143
    return None
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   144
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   145
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   146
def load_state(repo):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   147
    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
   148
    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
   149
        kind, node = l[:-1].split()
42310
21eda240be07 bisect: do not crash with rewritten commits
timeless <timeless@mozdev.org>
parents: 42057
diff changeset
   150
        node = repo.unfiltered().lookup(node)
27525
cba62f996780 hbisect: use tryreadlines to load state
Bryan O'Sullivan <bos@serpentine.com>
parents: 26587
diff changeset
   151
        if kind not in state:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   152
            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
   153
        state[kind].append(node)
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   154
    return state
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   155
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   156
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   157
def save_state(repo, state):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   158
    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
   159
    with repo.wlock():
18358
93293813d753 bisect: store state sorted
Mads Kiilerich <mads@kiilerich.com>
parents: 17537
diff changeset
   160
        for kind in sorted(state):
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   161
            for node in state[kind]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   162
                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
   163
        f.close()
7227
e1afb50ec2aa bisect: ability to check revision with command
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6861
diff changeset
   164
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   165
30065
ee21ed7fc7a2 bisect: extract the 'reset' logic into its own function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 27853
diff changeset
   166
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
   167
    """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
   168
    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
   169
        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
   170
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   171
30126
755730fc1e48 bisect: move check_state into the bisect module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30067
diff changeset
   172
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
   173
    """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
   174
45875
e641bb2a6159 errors: raise StateError in `hg bisect`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44452
diff changeset
   175
    Raise StateError exception otherwise."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   176
    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
   177
        return True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   178
    if not state[b'good']:
45875
e641bb2a6159 errors: raise StateError in `hg bisect`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44452
diff changeset
   179
        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
   180
    else:
45875
e641bb2a6159 errors: raise StateError in `hg bisect`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44452
diff changeset
   181
        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
   182
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   183
43665
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
   184
@contextlib.contextmanager
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
   185
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
   186
    try:
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
   187
        yield
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
   188
    finally:
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
   189
        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
   190
        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
   191
f37da59a36d9 bisect: replace try:/finally: by a "restore_state" context manager
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 43077
diff changeset
   192
15135
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
   193
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
   194
    """
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
   195
    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
   196
15153
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   197
    - ``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
   198
    - ``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
   199
    - ``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
   200
    - ``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
   201
    - ``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
   202
    - ``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
   203
    - ``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
   204
    """
f19de58af225 revset.bisect: move bisect() code to hbisect.py
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15057
diff changeset
   205
    state = load_state(repo)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   206
    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
   207
        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
   208
    else:
17493
d057e92dadfc spelling: following
timeless@mozdev.org
parents: 16834
diff changeset
   209
        # In the following sets, we do *not* call 'bisect()' with more
17509
f7767f52e9eb spelling: recursion
timeless@mozdev.org
parents: 17493
diff changeset
   210
        # 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
   211
        # 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
   212
        # 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
   213
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
   214
        # '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
   215
        #   - 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
   216
        # 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
   217
        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
   218
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   219
        _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
   220
        # 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
   221
        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
   222
            # Goods are topologically after bads
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   223
            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
   224
            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
   225
        else:
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   226
            # Goods are topologically before bads
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   227
            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
   228
            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
   229
fa0a464e4ca5 hbisect: add two new revset descriptions: 'goods' and 'bads'
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15147
diff changeset
   230
        # '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
   231
        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
   232
        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
   233
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
   234
        # '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
   235
        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
   236
15147
395ca8cd2669 revset.bisect: add 'ignored' set to the bisect keyword
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15146
diff changeset
   237
        # '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
   238
        # 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
   239
        # 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
   240
        # 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
   241
        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
   242
        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
   243
        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
   244
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   245
        if status == b'range':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
   246
            return repo.revs(range)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   247
        elif status == b'pruned':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
   248
            return repo.revs(pruned)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   249
        elif status == b'untested':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
   250
            return repo.revs(untested)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   251
        elif status == b'ignored':
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
   252
            return repo.revs(ignored)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   253
        elif status == b"goods":
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
   254
            return repo.revs(goods)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   255
        elif status == b"bads":
15404
c1eb8398fe82 localrepo: convert various repo.set() users to repo.revs()
Matt Mackall <mpm@selenic.com>
parents: 15308
diff changeset
   256
            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
   257
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   258
            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
   259
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   260
15406
1f677c7e494d bisect: remove superfluous parameter in label()
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 15404
diff changeset
   261
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
   262
    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
   263
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
   264
    # Try explicit sets
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   265
    if rev in get(repo, b'good'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
   266
        # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   267
        return _(b'good')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   268
    if rev in get(repo, b'bad'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
   269
        # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   270
        return _(b'bad')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   271
    if rev in get(repo, b'skip'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
   272
        # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   273
        return _(b'skipped')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   274
    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
   275
        # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   276
        return _(b'untested')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   277
    if rev in get(repo, b'ignored'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
   278
        # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   279
        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
   280
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
   281
    # Try implicit sets
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   282
    if rev in get(repo, b'goods'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
   283
        # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   284
        return _(b'good (implicit)')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   285
    if rev in get(repo, b'bads'):
15308
ab341fbb05b1 bisect: add i18n contexts
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15154
diff changeset
   286
        # i18n: bisect changeset status
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   287
        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
   288
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
   289
    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
   290
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   291
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
   292
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
   293
    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
   294
    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
   295
        # 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
   296
        if good:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   297
            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
   298
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   299
            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
   300
        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
   301
        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
   302
        if extendnode is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   303
            ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   304
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   305
                    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
   306
                    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
   307
                    b'bisection from\nthe common ancestor, %s.\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   308
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   309
                % extendnode
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   310
            )
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
   311
    else:
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
   312
        # multiple possible revisions
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
   313
        if good:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   314
            ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   315
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   316
                    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
   317
                    b"good revision could be any of:\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
            )
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
   320
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   321
            ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   322
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   323
                    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
   324
                    b"bad revision could be any of:\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   325
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42310
diff changeset
   326
            )
30067
6e88cd060ba2 bisect: move 'printresult' in the 'hbisect' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30066
diff changeset
   327
        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
   328
            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
   329
    displayer.close()