{"thread":{"id":"7351","subject":"[RFC/PATCH] Bisect: implement \"git bisect run <cmd>...\" to automatically bisect.","startedAt":"2007-03-22T06:08:59Z","lastAt":"2007-03-22T21:59:48Z","messageCount":3,"participants":["Christian Couder","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"37718","messageId":"20070322070859.a86c0cb4.chriscool@tuxfamily.org","threadId":"7351","inReplyTo":null,"subject":"[RFC/PATCH] Bisect: implement \"git bisect run <cmd>...\" to automatically bisect.","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2007-03-22T06:08:59Z","receivedAt":"2007-03-22T06:08:59Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This idea was suggested by Bill Lear\n(Message-ID: <17920.38942.364466.642979@lisa.zopyra.com>)\nand I think it is a very good one.\n\nThis patch adds a new test file for \"git bisect run\", but there\nis currently only one basic test.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n git-bisect.sh         |   54 +++++++++++++++++++++++++++++++++++++++++++--\n t/t6030-bisect-run.sh |   57 +++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 108 insertions(+), 3 deletions(-)\n create mode 100755 t/t6030-bisect-run.sh\n\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex b1c3a6b..53dff7d 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,14 +1,15 @@\n #!/bin/sh\n \n-USAGE='[start|bad|good|next|reset|visualize|replay|log]'\n+USAGE='[start|bad|good|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect start [<pathspec>]\treset bisect state and start bisection.\n git bisect bad [<rev>]\t\tmark <rev> a known-bad revision.\n git bisect good [<rev>...]\tmark <rev>... known-good revisions.\n git bisect next\t\t\tfind next bisection to test and check it out.\n git bisect reset [<branch>]\tfinish bisection search and go back to branch.\n git bisect visualize            show bisect status in gitk.\n-git bisect replay <logfile>\treplay bisection log\n-git bisect log\t\t\tshow bisect log.'\n+git bisect replay <logfile>\treplay bisection log.\n+git bisect log\t\t\tshow bisect log.\n+git bisect run <cmd>... \tuse <cmd>... to automatically bisect.'\n \n . git-sh-setup\n require_work_tree\n@@ -185,6 +186,7 @@ bisect_reset() {\n \t\trm -f \"$GIT_DIR/refs/heads/bisect\" \"$GIT_DIR/head-name\"\n \t\trm -f \"$GIT_DIR/BISECT_LOG\"\n \t\trm -f \"$GIT_DIR/BISECT_NAMES\"\n+\t\trm -f \"$GIT_DIR/BISECT_RUN\"\n \tfi\n }\n \n@@ -220,6 +222,50 @@ bisect_replay () {\n \tbisect_auto_next\n }\n \n+bisect_run () {\n+    while true\n+    do\n+      echo \"running $@\"\n+      \"$@\"\n+      res=$?\n+\n+      # Check for really bad run error.\n+      if [ $res -lt 0 -o $res -ge 128 ]; then\n+\t  echo >&2 \"bisect run failed:\"\n+\t  echo >&2 \"exit code $res from '$@' is < 0 or >= 128\"\n+\t  exit $res\n+      fi\n+\n+      # Use \"git-bisect good\" or \"git-bisect bad\"\n+      # depending on run success or failure.\n+      # We cannot use bisect_good or bisect_bad functions\n+      # because they can exit.\n+      if [ $res -gt 0 ]; then\n+\t  next_bisect='git-bisect bad'\n+      else\n+\t  next_bisect='git-bisect good'\n+      fi\n+\n+      $next_bisect > \"$GIT_DIR/BISECT_RUN\"\n+      res=$?\n+\n+      cat \"$GIT_DIR/BISECT_RUN\"\n+\n+      if [ $res -ne 0 ]; then\n+\t  echo >&2 \"bisect run failed:\"\n+\t  echo >&2 \"$next_bisect exited with error code $res\"\n+\t  exit $res\n+      fi\n+\n+      if grep \"is first bad commit\" \"$GIT_DIR/BISECT_RUN\" > /dev/null; then\n+\t  echo \"bisect run success\"\n+\t  exit 0;\n+      fi\n+\n+    done\n+}\n+\n+\n case \"$#\" in\n 0)\n     usage ;;\n@@ -244,6 +290,8 @@ case \"$#\" in\n \tbisect_replay \"$@\" ;;\n     log)\n \tcat \"$GIT_DIR/BISECT_LOG\" ;;\n+    run)\n+        bisect_run \"$@\" ;;\n     *)\n         usage ;;\n     esac\ndiff --git a/t/t6030-bisect-run.sh b/t/t6030-bisect-run.sh\nnew file mode 100755\nindex 0000000..39c7228\n--- /dev/null\n+++ b/t/t6030-bisect-run.sh\n@@ -0,0 +1,57 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Christian Couder\n+#\n+test_description='Tests git-bisect run functionality'\n+\n+. ./test-lib.sh\n+\n+add_line_into_file()\n+{\n+    _line=$1\n+    _file=$2\n+\n+    if [ -f \"$_file\" ]; then\n+        echo \"$_line\" >> $_file || return $?\n+        MSG=\"Add <$_line> into <$_file>.\"\n+    else\n+        echo \"$_line\" > $_file || return $?\n+        git add $_file || return $?\n+        MSG=\"Create file <$_file> with <$_line> inside.\"\n+    fi\n+\n+    git-commit -m \"$MSG\" $_file\n+}\n+\n+HASH1=\n+HASH3=\n+HASH4=\n+\n+test_expect_success \\\n+    'set up basic repo with 1 file (hello) and 4 commits' \\\n+    'add_line_into_file \"1: Hello World\" hello &&\n+     add_line_into_file \"2: A new day for git\" hello &&\n+     add_line_into_file \"3: Another new day for git\" hello &&\n+     add_line_into_file \"4: Ciao for now\" hello &&\n+     HASH1=$(git rev-list HEAD | tail -1) &&\n+     HASH3=$(git rev-list HEAD | head -2 | tail -1) &&\n+     HASH4=$(git rev-list HEAD | head -1)'\n+\n+# We want to automatically find the commit that\n+# introduced \"Another\" into hello.\n+test_expect_success \\\n+    'git bisect run simple case' \\\n+    'echo \"#!/bin/sh\" > test_script.sh &&\n+     echo \"grep Another hello > /dev/null\" >> test_script.sh &&\n+     echo \"test \\$? -ne 0\" >> test_script.sh &&\n+     chmod +x test_script.sh &&\n+     git bisect start &&\n+     git bisect good $HASH1 &&\n+     git bisect bad $HASH4 &&\n+     git bisect run ./test_script.sh > my_bisect_log.txt &&\n+     grep \"$HASH3 is first bad commit\" my_bisect_log.txt'\n+\n+#\n+#\n+test_done\n+\n-- \n1.5.1.rc1.13.g0872-dirty\n"},{"id":"37722","messageId":"7vejnhwy0y.fsf@assigned-by-dhcp.cox.net","threadId":"7351","inReplyTo":"20070322070859.a86c0cb4.chriscool@tuxfamily.org","subject":"Re: [RFC/PATCH] Bisect: implement \"git bisect run <cmd>...\" to automatically bisect.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-22T07:14:05Z","receivedAt":"2007-03-22T07:14:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <chriscool@tuxfamily.org> writes:\n\n> This idea was suggested by Bill Lear\n> (Message-ID: <17920.38942.364466.642979@lisa.zopyra.com>)\n> and I think it is a very good one.\n\nNicely done.\n\nPeople often find that during bisect they want to have a\nnear-constant tweaks (e.g., s/#define DEBUG 0/#define DEBUG 1/\nin a header file, or \"revision that does not have this commit\nneeds this patch applied to work around other problem this\nbisection is not interested in\") applied to the revision being\ntested.  \n\nTo cope with such a situation, after the inner git-bisect finds\nthe next revision to test, with the \"run\" script, the user can\napply that tweak before compiling, run the real test, and after\nthe test decides if the revision (possibly with the needed\ntweaks) passed the test, rewind the tree to the pristine state.\nFinally the \"run\" script can exit with the status of the real\ntest to let \"git-bisect run\" command loop to know the outcome.\n\nWhen you write a documentation for this patch, the above issue\nshould be addressed, as this is often asked on and off the list.\n\n> @@ -220,6 +222,50 @@ bisect_replay () {\n>  \tbisect_auto_next\n>  }\n>  \n> +bisect_run () {\n> +    while true\n> +    do\n> +      echo \"running $@\"\n> +      \"$@\"\n> +      res=$?\n> +\n> +      # Check for really bad run error.\n> +      if [ $res -lt 0 -o $res -ge 128 ]; then\n> +\t  echo >&2 \"bisect run failed:\"\n> +\t  echo >&2 \"exit code $res from '$@' is < 0 or >= 128\"\n> +\t  exit $res\n> +      fi\n\nI am not sure if this flexibility/leniency is desirable.  It\ncertainly allows a sloppily written shell script that exits with\nany random small-positive values to report a badness, which may\nbe handy, but allowing sloppiness might lead to wasted time\nafter all.  I dunno.  A more strict convention that says the run\nscript should exit 1 to signal \"bad, please continue\", 0 for\n\"good, please continue\" and other values for \"no good, abort\"\nmight be less error prone.\n\nIn any case, the exit status convention needs documentation.\n\nA program that does \"exit(-1)\" leaves $? = 255 (see exit(3)\nmanual page, the value is chopped with \"& 0377\"), so the test\nfor -ge 128 is certainly good; I do not know if any system gives\nnegative values, but the check shouldn't hurt.  As a style, I\nwould have written that as:\n\n\tif test $res -lt 0 || test $res -ge 128\n        then\n        \t...\n\nbut that is probably a bit old-fashioned.  \n\n> +      # Use \"git-bisect good\" or \"git-bisect bad\"\n> +      # depending on run success or failure.\n> +      # We cannot use bisect_good or bisect_bad functions\n> +      # because they can exit.\n> +      if [ $res -gt 0 ]; then\n> +\t  next_bisect='git-bisect bad'\n> +      else\n> +\t  next_bisect='git-bisect good'\n> +      fi\n> +\n> +      $next_bisect > \"$GIT_DIR/BISECT_RUN\"\n\n\nIf their exiting, and possibly variable assignments, are the\nonly problem, you can run that in subshell, can't you?  Like:\n\n\t( $next_bisect >\"$GIT_DIR/BISECT_RUN\" )\n\n> +      res=$?\n"},{"id":"37762","messageId":"200703222259.49089.chriscool@tuxfamily.org","threadId":"7351","inReplyTo":"7vejnhwy0y.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC/PATCH] Bisect: implement \"git bisect run <cmd>...\" to automatically bisect.","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2007-03-22T21:59:48Z","receivedAt":"2007-03-22T21:59:48Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Junio C Hamano a écrit :\n\n[...]\n\n> > +      # Check for really bad run error.\n> > +      if [ $res -lt 0 -o $res -ge 128 ]; then\n> > +\t  echo >&2 \"bisect run failed:\"\n> > +\t  echo >&2 \"exit code $res from '$@' is < 0 or >= 128\"\n> > +\t  exit $res\n> > +      fi\n>\n> I am not sure if this flexibility/leniency is desirable.  It\n> certainly allows a sloppily written shell script that exits with\n> any random small-positive values to report a badness, which may\n> be handy, but allowing sloppiness might lead to wasted time\n> after all.  I dunno.  A more strict convention that says the run\n> script should exit 1 to signal \"bad, please continue\", 0 for\n> \"good, please continue\" and other values for \"no good, abort\"\n> might be less error prone.\n\nPerhaps, but when running \"git bisect run make\" to automatically find the \ncommit that broke the build, it would fail because make will usually return \n2 in case of error. \n\nIt seems that there are few standards for exit code, so whatever convention \nwe choose will not work in all cases.\n\n> In any case, the exit status convention needs documentation.\n\nYes, I will work on it.\n\n[...]\n\n> > +      # Use \"git-bisect good\" or \"git-bisect bad\"\n> > +      # depending on run success or failure.\n> > +      # We cannot use bisect_good or bisect_bad functions\n> > +      # because they can exit.\n> > +      if [ $res -gt 0 ]; then\n> > +\t  next_bisect='git-bisect bad'\n> > +      else\n> > +\t  next_bisect='git-bisect good'\n> > +      fi\n> > +\n> > +      $next_bisect > \"$GIT_DIR/BISECT_RUN\"\n>\n> If their exiting, and possibly variable assignments, are the\n> only problem, you can run that in subshell, can't you?  Like:\n>\n> \t( $next_bisect >\"$GIT_DIR/BISECT_RUN\" )\n\nYou are right. I will submit an updated patch with this change and some \ndocumentation.\n\nThanks,\nChristian.\n"}]}