The argument is not used. This is a left-over of non-published
iterations, and it passed through.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Add two new functions that return a string containing the bisection status
of the node passed in parameter:
- .label(node): return a multi-char string representing the status of node
- .shortlabel(node): return a single-char string representing the status
of node, usually the initial of the label
bisection status .label() .shortlabel()
----------------------------------------------------------
good 'good' 'G'
good (implicit) 'good (implicit)' 'G'
bad 'bad' 'B'
bad (implicit) 'bad (implicit)' 'B'
skipped 'skip' 'S'
untested 'untested' 'U'
ignored 'ignored' 'I'
(others) None None
There is no point in returning 'range' or 'pruned', as these get covered
by another, more meaningful status in the table above.
In case the node is not being bisected, the functions return None to leave
it up to the caller to decide what to print (nothing, an empty space, or
whatever else suits).
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
This patch adds two new revset descriptions:
- 'goods': the list of topologicaly-good csets:
- if good csets are topologically before bad csets, yields '::good'
- else, yields 'good::'
- and conversely for 'bads'
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
The 'ignored' changesets are outside the bisection range, but are
changesets that may have an impact on the outcome of the bisection.
For example, in case there's a merge between the good and bad csets,
but the branch-point is out of the bisection range, and the issue
originates from this branch, the branch will not be visited by bisect
and bisect will find that the culprit cset is the merge.
So, the 'ignored' set is equivalent to:
( ( ::bisect(bad) - ::bisect(good) )
| ( ::bisect(good) - ::bisect(bad) ) )
- bisect(range)
- all ancestors of bad csets that are not ancestors of good csets, or
- all ancestors of good csets that are not ancestors of bad csets
- but that are not in the bisection range.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Use repo.set() wherever possible, instead of locally trying to
reproduce complex graph computations.
'pruned' now means 'all csets that will no longer be visited by the
bisection'. The change is done is this very patch instead of its own
dedicated one becasue the code changes all over the place, and the
previous 'pruned' code was totally rewritten by the cleanup, so it
was easier to just change the behavior at the same time.
The previous series went in too fast for this cleanup pass to be
included, so here it is. ;-)
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
The 'untested' set is made of changesets that are in the bisection range
but for which the status is still unknown, and that can later be used to
further decide on the bisection outcome.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
The 'pruned' set is made of changesets that did participate to
the bisection. They are made of
- all good changesets
- all bad changsets
- all skipped changesets, provided they are in the bisection range
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
The 'range' set is made of all changesets that make the bisection
range, that is
- csets that are ancestors of bad csets and descendants of good csets
or
- csets that are ancestors of good csets and descendants of bad csets
That is, roughly equivalent of:
bisect(good)::bisect(bad) | bisect(bad)::bisect(good)
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Computing the ranges of csets in the bisection belongs to the hbisect
code. This allows for reusing the status computation from many places,
not only the revset code, but also to later display the bisection status
of a cset...
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
The usual contract is that close() makes your writes permanent, so
atomictempfile's use of close() to *discard* writes (and rename() to
keep them) is rather unexpected. Thus, change it so close() makes
things permanent and add a new discard() method to throw them away.
discard() is only used internally, in __del__(), to ensure that writes
are discarded when an atomictempfile object goes out of scope.
I audited mercurial.*, hgext.*, and ~80 third-party extensions, and
found no one using the existing semantics of close() to discard
writes, so this should be safe.
The included test used to report "inconsistent state", which is
incorrect. While this situation cannot occur when the user sticks to
the suggested bisect sequence. However, adding more consistent
good/bad information to the bisect state should be tolerated as well.
As reported in issue 1445:
A valid candidate revision for a bisect test is not considered for testing
due to its skipped ancestor. If this revision is the only untested one left
an assertion error occurs.
The real reason for both issue is that bisect can not handle cases where there
are multiple possibilities for the result.
Example (from issue1228):
rev 0 -> good
rev 1 -> skipped
rev 2 -> skipped
rev 3 -> skipped
rev 4 -> bad
Note that this patch does not only fix the reported Assertion Error but also
the problem of a non converging bisect:
hg init
for i in `seq 3`; do echo $i > $i; hg add $i; hg ci -m$i; done
hg bisect -b 2
hg bisect -g 0
hg bisect -s
From this state on, you can:
a) mark as bad forever (non converging!)
b) mark as good to get an inconsistent state
c) skip for the Assertion Error
Minor description and code edits by pmezard.
Automatically detect whether we're looking for a bad to good
transition rather than the usual good to bad transition by detecting
when badrev is inside the good set and flipping good/bad.