Skip to content

Commit

Permalink
bisect: make "git bisect" use new "--next-all" bisect-helper function
Browse files Browse the repository at this point in the history
This patch replace the "--next-exit" option of "git bisect--helper"
with a "--next-all" option that does merge base checking using
the "check_good_are_ancestors_of_bad" function implemented in
"bisect.c" in a former patch.

The new "--next-all" option is then used in "git-bisect.sh" instead
of the "--next-exit" option, and all the shell functions in
"git-bisect.sh" that are now unused are removed.

Signed-off-by: Christian Couder <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
chriscool authored and gitster committed May 10, 2009
1 parent d937d4a commit 0871984
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 134 deletions.
4 changes: 3 additions & 1 deletion bisect.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix)
* the bisection process finished successfully.
* In this case the calling shell script should exit 0.
*/
int bisect_next_exit(const char *prefix)
int bisect_next_all(const char *prefix)
{
struct rev_info revs;
struct commit_list *tried;
Expand All @@ -841,6 +841,8 @@ int bisect_next_exit(const char *prefix)
if (read_bisect_refs())
die("reading bisect refs failed");

check_good_are_ancestors_of_bad(prefix);

bisect_rev_setup(&revs, prefix);

bisect_common(&revs, &reaches, &all);
Expand Down
2 changes: 1 addition & 1 deletion bisect.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct rev_list_info {

extern int show_bisect_vars(struct rev_list_info *info, int reaches, int all);

extern int bisect_next_exit(const char *prefix);
extern int bisect_next_all(const char *prefix);

extern int estimate_bisect_steps(int all);

Expand Down
14 changes: 7 additions & 7 deletions builtin-bisect--helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
#include "bisect.h"

static const char * const git_bisect_helper_usage[] = {
"git bisect--helper --next-exit",
"git bisect--helper --next-all",
NULL
};

int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
{
int next_exit = 0;
int next_all = 0;
struct option options[] = {
OPT_BOOLEAN(0, "next-exit", &next_exit,
"output bisect result and exit instuctions"),
OPT_BOOLEAN(0, "next-all", &next_all,
"perform 'git bisect next'"),
OPT_END()
};

argc = parse_options(argc, argv, options, git_bisect_helper_usage, 0);

if (!next_exit)
if (!next_all)
usage_with_options(git_bisect_helper_usage, options);

/* next-exit */
return bisect_next_exit(prefix);
/* next-all */
return bisect_next_all(prefix);
}
127 changes: 2 additions & 125 deletions git-bisect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,6 @@ is_expected_rev() {
test "$1" = $(cat "$GIT_DIR/BISECT_EXPECTED_REV")
}

mark_expected_rev() {
echo "$1" > "$GIT_DIR/BISECT_EXPECTED_REV"
}

check_expected_revs() {
for _rev in "$@"; do
if ! is_expected_rev "$_rev"; then
Expand Down Expand Up @@ -269,132 +265,13 @@ bisect_auto_next() {
bisect_next_check && bisect_next || :
}

bisect_checkout() {
_rev="$1"
_msg="$2"
echo "Bisecting: $_msg"
mark_expected_rev "$_rev"
git checkout -q "$_rev" -- || exit
git show-branch "$_rev"
}

is_among() {
_rev="$1"
_list="$2"
case "$_list" in *$_rev*) return 0 ;; esac
return 1
}

handle_bad_merge_base() {
_badmb="$1"
_good="$2"
if is_expected_rev "$_badmb"; then
cat >&2 <<EOF
The merge base $_badmb is bad.
This means the bug has been fixed between $_badmb and [$_good].
EOF
exit 3
else
cat >&2 <<EOF
Some good revs are not ancestor of the bad rev.
git bisect cannot work properly in this case.
Maybe you mistake good and bad revs?
EOF
exit 1
fi
}

handle_skipped_merge_base() {
_mb="$1"
_bad="$2"
_good="$3"
cat >&2 <<EOF
Warning: the merge base between $_bad and [$_good] must be skipped.
So we cannot be sure the first bad commit is between $_mb and $_bad.
We continue anyway.
EOF
}

#
# "check_merge_bases" checks that merge bases are not "bad".
#
# - If one is "good", that's good, we have nothing to do.
# - If one is "bad", it means the user assumed something wrong
# and we must exit.
# - If one is "skipped", we can't know but we should warn.
# - If we don't know, we should check it out and ask the user to test.
#
# In the last case we will return 1, and otherwise 0.
#
check_merge_bases() {
_bad="$1"
_good="$2"
_skip="$3"
for _mb in $(git merge-base --all $_bad $_good)
do
if is_among "$_mb" "$_good"; then
continue
elif test "$_mb" = "$_bad"; then
handle_bad_merge_base "$_bad" "$_good"
elif is_among "$_mb" "$_skip"; then
handle_skipped_merge_base "$_mb" "$_bad" "$_good"
else
bisect_checkout "$_mb" "a merge base must be tested"
return 1
fi
done
return 0
}

#
# "check_good_are_ancestors_of_bad" checks that all "good" revs are
# ancestor of the "bad" rev.
#
# If that's not the case, we need to check the merge bases.
# If a merge base must be tested by the user we return 1 and
# otherwise 0.
#
check_good_are_ancestors_of_bad() {
test -f "$GIT_DIR/BISECT_ANCESTORS_OK" &&
return

_bad="$1"
_good=$(echo $2 | sed -e 's/\^//g')
_skip="$3"

# Bisecting with no good rev is ok
test -z "$_good" && return

_side=$(git rev-list $_good ^$_bad)
if test -n "$_side"; then
# Return if a checkout was done
check_merge_bases "$_bad" "$_good" "$_skip" || return
fi

: > "$GIT_DIR/BISECT_ANCESTORS_OK"

return 0
}

bisect_next() {
case "$#" in 0) ;; *) usage ;; esac
bisect_autostart
bisect_next_check good

# Get bad, good and skipped revs
bad=$(git rev-parse --verify refs/bisect/bad) &&
good=$(git for-each-ref --format='^%(objectname)' \
"refs/bisect/good-*" | tr '\012' ' ') &&
skip=$(git for-each-ref --format='%(objectname)' \
"refs/bisect/skip-*" | tr '\012' ' ') || exit

# Maybe some merge bases must be tested first
check_good_are_ancestors_of_bad "$bad" "$good" "$skip"
# Return now if a checkout has already been done
test "$?" -eq "1" && return

# Perform bisection computation, display and checkout
git bisect--helper --next-exit
# Perform all bisection computation, display and checkout
git bisect--helper --next-all
res=$?

# Check if we should exit because bisection is finished
Expand Down

0 comments on commit 0871984

Please sign in to comment.