Code

bisect: make "git bisect" use new "--next-all" bisect-helper function
authorChristian Couder <chriscool@tuxfamily.org>
Sat, 9 May 2009 15:55:47 +0000 (17:55 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sun, 10 May 2009 21:30:33 +0000 (14:30 -0700)
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 <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
bisect.c
bisect.h
builtin-bisect--helper.c
git-bisect.sh

index 09102daba8ac508ea3457bb43fcac0f0fd83ebeb..f57b62cdddb7ff96acaabdee6e4bfc551d8a195f 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -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;
@@ -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);
index 0b5d122a7b2dbe9778c35ee79d8a256980da53f6..fb744fdb79e1dd4a46cd3f2759b73747d8e79fbd 100644 (file)
--- a/bisect.h
+++ b/bisect.h
@@ -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);
 
index aca7018d834a27c60326d84fa26da5bb1f9ab797..cb3e15511611240cbc3ea53a1a591fdee19ba0b9 100644 (file)
@@ -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);
 }
index 786b7b9110a096fa7810e0dcc51ad8321f1a6f95..8969553658bb5f4f2191f370062af9af33989d88 100755 (executable)
@@ -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
@@ -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