{"thread":{"id":"13102","subject":"[PATCH 1/2] bisect: make \"start\", \"good\" and \"skip\" succeed or fail atomically","startedAt":"2008-04-14T03:41:45Z","lastAt":"2008-04-14T03:41:45Z","messageCount":1,"participants":["Christian Couder"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"74301","messageId":"20080414054145.e2d5e253.chriscool@tuxfamily.org","threadId":"13102","inReplyTo":null,"subject":"[PATCH 1/2] bisect: make \"start\", \"good\" and \"skip\" succeed or fail atomically","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2008-04-14T03:41:45Z","receivedAt":"2008-04-14T03:41:45Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Before this patch, when \"git bisect start\", \"git bisect good\" or\n\"git bisect skip\" were called with many revisions, they could fail\nafter having already marked some revisions as \"good\", \"bad\" or\n\"skip\".\n\nThis could be especilally bad for \"git bisect start\" because as\nthe file \".git/BISECT_NAMES\" would not have been written, there\nwould have been no attempt to clear the marked revisions on a\n\"git bisect reset\". That's because if there is no\n\".git/BISECT_NAMES\" file, nothing is done to clean things up, as\nthe bisect session is not supposed to have started.\n\nWhile at it, let's also create the \".git/BISECT_START\" file, only\nafter \".git/BISECT_NAMES\" as been created.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n git-bisect.sh               |   14 ++++++++++----\n t/t6030-bisect-porcelain.sh |    7 ++++++-\n 2 files changed, 16 insertions(+), 5 deletions(-)\n\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 408775a..6b43461 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -69,6 +69,7 @@ bisect_start() {\n \thead=$(GIT_DIR=\"$GIT_DIR\" git symbolic-ref HEAD) ||\n \thead=$(GIT_DIR=\"$GIT_DIR\" git rev-parse --verify HEAD) ||\n \tdie \"Bad HEAD - I need a HEAD\"\n+\tstart_head=''\n \tcase \"$head\" in\n \trefs/heads/bisect)\n \t\tif [ -s \"$GIT_DIR/BISECT_START\" ]; then\n@@ -82,7 +83,7 @@ bisect_start() {\n \t\t# This error message should only be triggered by cogito usage,\n \t\t# and cogito users should understand it relates to cg-seek.\n \t\t[ -s \"$GIT_DIR/head-name\" ] && die \"won't bisect on seeked tree\"\n-\t\techo \"${head#refs/heads/}\" >\"$GIT_DIR/BISECT_START\"\n+\t\tstart_head=\"${head#refs/heads/}\"\n \t\t;;\n \t*)\n \t\tdie \"Bad HEAD - strange symbolic ref\"\n@@ -103,6 +104,7 @@ bisect_start() {\n \tdone\n \torig_args=$(sq \"$@\")\n \tbad_seen=0\n+\teval=''\n \twhile [ $# -gt 0 ]; do\n \t    arg=\"$1\"\n \t    case \"$arg\" in\n@@ -120,13 +122,15 @@ bisect_start() {\n \t\t0) state='bad' ; bad_seen=1 ;;\n \t\t*) state='good' ;;\n \t\tesac\n-\t\tbisect_write \"$state\" \"$rev\" 'nolog'\n+\t\teval=\"$eval bisect_write '$state' '$rev' 'nolog'; \"\n \t\tshift\n \t\t;;\n \t    esac\n \tdone\n \n \tsq \"$@\" >\"$GIT_DIR/BISECT_NAMES\"\n+\ttest -n \"$start_head\" && echo \"$start_head\" >\"$GIT_DIR/BISECT_START\"\n+\teval \"$eval\"\n \techo \"git-bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\"\n \tbisect_auto_next\n }\n@@ -157,12 +161,14 @@ bisect_state() {\n \t\tbisect_write \"$state\" \"$rev\" ;;\n \t2,bad|*,good|*,skip)\n \t\tshift\n+\t\teval=''\n \t\tfor rev in \"$@\"\n \t\tdo\n \t\t\tsha=$(git rev-parse --verify \"$rev^{commit}\") ||\n \t\t\t\tdie \"Bad rev input: $rev\"\n-\t\t\tbisect_write \"$state\" \"$sha\"\n-\t\tdone ;;\n+\t\t\teval=\"$eval bisect_write '$state' '$sha'; \"\n+\t\tdone\n+\t\teval \"$eval\" ;;\n \t*,bad)\n \t\tdie \"'git bisect bad' can take only one argument.\" ;;\n \t*)\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 32d6118..5e3e544 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -71,8 +71,12 @@ test_expect_success 'bisect start with one bad and good' '\n \tgit bisect next\n '\n \n-test_expect_success 'bisect good and bad fails if not given only revs' '\n+test_expect_success 'bisect fails if given any junk instead of revs' '\n \tgit bisect reset &&\n+\ttest_must_fail git bisect start foo $HASH1 -- &&\n+\ttest_must_fail git bisect start $HASH4 $HASH1 bar -- &&\n+\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n+\ttest_must_fail ls .git/BISECT_* &&\n \tgit bisect start &&\n \ttest_must_fail git bisect good foo $HASH1 &&\n \ttest_must_fail git bisect good $HASH1 bar &&\n@@ -80,6 +84,7 @@ test_expect_success 'bisect good and bad fails if not given only revs' '\n \ttest_must_fail git bisect bad $HASH3 $HASH4 &&\n \ttest_must_fail git bisect skip bar $HASH3 &&\n \ttest_must_fail git bisect skip $HASH1 foo &&\n+\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n \tgit bisect good $HASH1 &&\n \tgit bisect bad $HASH4\n '\n-- \n1.5.5.50.ge6e82.dirty\n"}]}