From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthieu Moy Subject: [PATCH v9 4/5] bisect: add the terms old/new Date: Thu, 25 Jun 2015 20:50:56 +0200 Message-ID: <1435258257-29047-5-git-send-email-Matthieu.Moy@imag.fr> References: <1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr> <1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr> Cc: git@vger.kernel.org, antoine.delaite@ensimag.grenoble-inp.fr, louis--alexandre.stuber@ensimag.grenoble-inp.fr, chriscool@tuxfamily.org, thomasxnguy@gmail.com, valentinduperray@gmail.com, Louis Stuber , Valentin Duperray , Franck Jonas , Lucien Kong , Thomas Nguy , Huynh Khoi Nguyen Nguyen , Matthieu Moy To: gitster@pobox.com X-From: git-owner@vger.kernel.org Thu Jun 25 20:51:37 2015 Return-path: Envelope-to: gcvg-git-2@plane.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Z8CFF-0000Bq-8N for gcvg-git-2@plane.gmane.org; Thu, 25 Jun 2015 20:51:29 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752065AbbFYSvV (ORCPT ); Thu, 25 Jun 2015 14:51:21 -0400 Received: from mx1.imag.fr ([129.88.30.5]:46284 "EHLO shiva.imag.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751927AbbFYSvP (ORCPT ); Thu, 25 Jun 2015 14:51:15 -0400 Received: from clopinette.imag.fr (clopinette.imag.fr [129.88.34.215]) by shiva.imag.fr (8.13.8/8.13.8) with ESMTP id t5PIp03Q023835 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 25 Jun 2015 20:51:00 +0200 Received: from anie.imag.fr (anie.imag.fr [129.88.7.32]) by clopinette.imag.fr (8.13.8/8.13.8) with ESMTP id t5PIp2k3024593; Thu, 25 Jun 2015 20:51:02 +0200 Received: from moy by anie.imag.fr with local (Exim 4.80) (envelope-from ) id 1Z8CEo-00080B-Fc; Thu, 25 Jun 2015 20:51:02 +0200 X-Mailer: git-send-email 2.4.4.414.g318df7a.dirty In-Reply-To: <1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.0.1 (shiva.imag.fr [129.88.30.5]); Thu, 25 Jun 2015 20:51:01 +0200 (CEST) X-IMAG-MailScanner-Information: Please contact MI2S MIM for more information X-MailScanner-ID: t5PIp03Q023835 X-IMAG-MailScanner: Found to be clean X-IMAG-MailScanner-SpamCheck: X-IMAG-MailScanner-From: moy@imag.fr MailScanner-NULL-Check: 1435863062.94134@mLkBsOMjTj321T3w8A/7SQ Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: From: Antoine Delaite When not looking for a regression during a bisect but for a fix or a change in another given property, it can be confusing to use 'good' and 'bad'. This patch introduce `git bisect new` and `git bisect old` as an alternative to 'bad' and good': the commits which have a certain property must be marked as `new` and the ones which do not as `old`. The output will be the first commit after the change in the property. During a new/old bisect session you cannot use bad/good commands and vice-versa. Some commands are still not available for old/new: * git rev-list --bisect does not treat the revs/bisect/new and revs/bisect/old-SHA1 files. Old discussions: - http://thread.gmane.org/gmane.comp.version-control.git/86063 introduced bisect fix unfixed to find fix. - http://thread.gmane.org/gmane.comp.version-control.git/182398 discussion around bisect yes/no or old/new. - http://thread.gmane.org/gmane.comp.version-control.git/199758 last discussion and reviews New discussions: - http://thread.gmane.org/gmane.comp.version-control.git/271320 ( v2 1/7-4/7 ) - http://comments.gmane.org/gmane.comp.version-control.git/271343 ( v2 5/7-7/7 ) Signed-off-by: Antoine Delaite Signed-off-by: Louis Stuber Signed-off-by: Valentin Duperray Signed-off-by: Franck Jonas Signed-off-by: Lucien Kong Signed-off-by: Thomas Nguy Signed-off-by: Huynh Khoi Nguyen Nguyen Signed-off-by: Matthieu Moy --- Documentation/git-bisect.txt | 48 ++++++++++++++++++++++++++++++++++++++++++-- bisect.c | 11 +++++++--- git-bisect.sh | 43 +++++++++++++++++++++++++-------------- t/t6030-bisect-porcelain.sh | 38 +++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 20 deletions(-) diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 4cb52a7..3c3021a 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -18,8 +18,8 @@ on the subcommand: git bisect help git bisect start [--no-checkout] [ [...]] [--] [...] - git bisect bad [] - git bisect good [...] + git bisect (bad|new) [] + git bisect (good|old) [...] git bisect skip [(|)...] git bisect reset [] git bisect visualize @@ -104,6 +104,35 @@ For example, `git bisect reset HEAD` will leave you on the current bisection commit and avoid switching commits at all, while `git bisect reset bisect/bad` will check out the first bad revision. + +Alternative terms: bisect new and bisect old +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are not at ease with the terms "bad" and "good", perhaps +because you are looking for the commit that introduced a fix, you can +alternatively use "new" and "old" instead. +But note that you cannot mix "bad" and good" with "new" and "old". + +------------------------------------------------ +git bisect new [] +------------------------------------------------ + +Marks the commit as new, e.g. "the bug is no longer there", if you are looking +for a commit that fixed a bug, or "the feature that used to work is now broken +at this point", if you are looking for a commit that introduced a bug. +It is the equivalent of "git bisect bad []". + +------------------------------------------------ +git bisect old [...] +------------------------------------------------ + +Marks the commit as old, as the opposite of 'git bisect new'. +It is the equivalent of "git bisect good [...]". + +You must run `git bisect start` without commits as argument and run +`git bisect new `/`git bisect old ...` after to add the +commits. + Bisect visualize ~~~~~~~~~~~~~~~~ @@ -379,6 +408,21 @@ In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit has at least one parent whose reachable graph is fully traversable in the sense required by 'git pack objects'. +* Look for a fix instead of a regression in the code ++ +------------ +$ git bisect start +$ git bisect new HEAD # current commit is marked as new +$ git bisect old HEAD~10 # the tenth commit from now is marked as old +------------ ++ +Let's consider the last commit has a given property, and that we are looking +for the commit which introduced this property. For each commit the bisection +guide us to, we will test if the property is present. If it is we will mark +the commit as new with 'git bisect new', otherwise we will mark it as old. +At the end of the bisect session, the result will be the first new commit (e.g +the first one with the property). + SEE ALSO -------- diff --git a/bisect.c b/bisect.c index c5f96eb..d447b65 100644 --- a/bisect.c +++ b/bisect.c @@ -746,6 +746,11 @@ static void handle_bad_merge_base(void) "This means the bug has been fixed " "between %s and [%s].\n", bad_hex, bad_hex, good_hex); + } else if (!strcmp(name_bad, "new") && !strcmp(name_good, "old")) { + fprintf(stderr, "The merge base %s is new.\n" + "The property has changed " + "between %s and [%s].\n", + bad_hex, bad_hex, good_hex); } else { fprintf(stderr, "The merge base %s is %s.\n" "This means the first '%s' commit is " @@ -778,11 +783,11 @@ static void handle_skipped_merge_base(const unsigned char *mb) } /* - * "check_merge_bases" checks that merge bases are not "bad". + * "check_merge_bases" checks that merge bases are not "bad" (or "new"). * - * - If one is "bad", it means the user assumed something wrong + * - If one is "bad" (or "new"), it means the user assumed something wrong * and we must exit with a non 0 error code. - * - If one is "good", that's good, we have nothing to do. + * - If one is "good" (or "old"), that's good, we have nothing to do. * - 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. */ diff --git a/git-bisect.sh b/git-bisect.sh index 7bb18db..569898b 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -1,14 +1,16 @@ #!/bin/sh -USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]' +USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]' LONG_USAGE='git bisect help print this long help message. git bisect start [--no-checkout] [ [...]] [--] [...] reset bisect state and start bisection. -git bisect bad [] - mark a known-bad revision. -git bisect good [...] - mark ... known-good revisions. +git bisect (bad|new) [] + mark a known-bad revision/ + a revision after change in a given property. +git bisect (good|old) [...] + mark ... known-good revisions/ + revisions before change in a given property. git bisect skip [(|)...] mark ... untestable revisions. git bisect next @@ -77,9 +79,7 @@ bisect_start() { orig_args=$(git rev-parse --sq-quote "$@") bad_seen=0 eval='' - # revision_seen is true if a git bisect start - # has revision as arguments - revision_seen=0 + must_write_terms=0 if test "z$(git rev-parse --is-bare-repository)" != zfalse then mode=--no-checkout @@ -105,7 +105,12 @@ bisect_start() { break } - revision_seen=1 + # The user ran "git bisect start + # ", hence did not explicitly specify + # the terms, but we are already starting to + # set references named with the default terms, + # and won't be able to change afterwards. + must_write_terms=1 case $bad_seen in 0) state=$NAME_BAD ; bad_seen=1 ;; @@ -178,7 +183,7 @@ bisect_start() { } && git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" && eval "$eval true" && - if test $revision_seen -eq 1 && test ! -s "$GIT_DIR/BISECT_TERMS" + if test $must_write_terms -eq 1 && test ! -s "$GIT_DIR/BISECT_TERMS" then echo "$NAME_BAD" >"$GIT_DIR/BISECT_TERMS" && echo "$NAME_GOOD" >>"$GIT_DIR/BISECT_TERMS" @@ -288,7 +293,7 @@ bisect_next_check() { false ;; t,,"$NAME_GOOD") - # have bad but not good. we could bisect although + # have bad (or new) but not good (or old). we could bisect although # this is less optimum. eval_gettextln "Warning: bisecting only with a \$NAME_BAD commit." >&2 if test -t 0 @@ -529,7 +534,7 @@ get_terms () { check_and_set_terms () { cmd="$1" case "$cmd" in - bad|good) + bad|good|new|old) if test -s "$GIT_DIR/BISECT_TERMS" && test "$cmd" != "$NAME_BAD" && test "$cmd" != "$NAME_GOOD" then die "$(eval_gettext "Invalid command: you're currently in a \$NAME_BAD/\$NAME_GOOD bisect.")" @@ -543,14 +548,22 @@ check_and_set_terms () { fi NAME_BAD="bad" NAME_GOOD="good" ;; + new|old) + if ! test -s "$GIT_DIR/BISECT_TERMS" + then + echo "new" >"$GIT_DIR/BISECT_TERMS" && + echo "old" >>"$GIT_DIR/BISECT_TERMS" + fi + NAME_BAD="new" + NAME_GOOD="old" ;; esac ;; esac } bisect_voc () { case "$1" in - bad) echo "bad" ;; - good) echo "good" ;; + bad) echo "bad|old" ;; + good) echo "good|new" ;; esac } @@ -566,7 +579,7 @@ case "$#" in git bisect -h ;; start) bisect_start "$@" ;; - bad|good) + bad|good|new|old) bisect_state "$cmd" "$@" ;; skip) bisect_skip "$@" ;; diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 9e2c203..983c503 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -759,4 +759,42 @@ test_expect_success '"git bisect bad HEAD" behaves as "git bisect bad"' ' git bisect reset ' +test_expect_success 'bisect starts with only one new' ' + git bisect reset && + git bisect start && + git bisect new $HASH4 && + git bisect next +' + +test_expect_success 'bisect does not start with only one old' ' + git bisect reset && + git bisect start && + git bisect old $HASH1 && + test_must_fail git bisect next +' + +test_expect_success 'bisect start with one new and old' ' + git bisect reset && + git bisect start && + git bisect old $HASH1 && + git bisect new $HASH4 && + git bisect new && + git bisect new >bisect_result && + grep "$HASH2 is the first new commit" bisect_result && + git bisect log >log_to_replay.txt && + git bisect reset +' + +test_expect_success 'bisect replay with old and new' ' + git bisect replay log_to_replay.txt >bisect_result && + grep "$HASH2 is the first new commit" bisect_result && + git bisect reset +' + +test_expect_success 'bisect cannot mix old/new and good/bad' ' + git bisect start && + git bisect bad $HASH4 && + test_must_fail git bisect old $HASH1 +' + test_done -- 2.4.4.414.g318df7a.dirty