{"thread":{"id":"27906","subject":"[RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","startedAt":"2011-07-24T05:57:45Z","lastAt":"2011-07-26T13:28:15Z","messageCount":21,"participants":["Jon Seymour","Johannes Sixt","Junio C Hamano","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"171913","messageId":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":null,"subject":"[RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:45Z","receivedAt":"2011-07-24T05:57:45Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Currently git bisect assumes that the respository to be undamaged. This limits the usefulness\nof git bisect when working with damaged repositories.\n\nThis series introduces an option, --ignore-checkout-failure, which can be used with \n\"git bisect start\" to indicate that checkout failures should be tolerated for the life\nof the (new) bisection process. This allows git bisect to be used on damaged repositories. In\nparticular, it allows git bisect to be used to locate commits containing damaged trees.\n\nIf the --ignore-checkout-failure option is specified, then if git checkout fails either \nat the start of the bisection process or later while probing a new trial commit, then the \ncheckout failure will be noisily ignored and the HEAD reference will be updated to the \nintended commit. This may leave the working tree and index in an inconsistent state\nw.r.t the HEAD commit.\n\n\"git bisect reset\" uses the same logic to restore the original HEAD reference. This allows\n\"git bisect reset\" to work in circumstances where it might otherwise fail (for example, if \nthe current HEAD contains a damaged tree).\n\nJon Seymour (9):\n  bisect: add tests to document expected behaviour in presence of\n    broken trees.\n  bisect: introduce a --ignore-checkout-failure option to\n    bisect--helper.\n  bisect: implement support for --ignore-checkout-failure option\n  bisect: introduce a helper function to tolerate checkout failures.\n  bisect: replace existing calls to git checkout with\n    bisect_checkout_with_ignore\n  bisect: enable --ignore-checkout-failure in the porcelain.\n  bisect: better diagnostics, in case of mis-typed option.\n  bisect: add tests for --ignore-checkout-failure option.\n  bisect: add documentation for --ignore-checkout-failure option.\n\n Documentation/git-bisect.txt |   13 ++++-\n bisect.c                     |   18 ++++++-\n bisect.h                     |    2 +-\n builtin/bisect--helper.c     |    8 ++-\n git-bisect.sh                |   36 +++++++++++--\n t/t6030-bisect-porcelain.sh  |  119 ++++++++++++++++++++++++++++++++++++++++++\n 6 files changed, 186 insertions(+), 10 deletions(-)\n\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171914","messageId":"1311487074-25070-2-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 1/9] bisect: add tests to document expected behaviour in presence of broken trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:46Z","receivedAt":"2011-07-24T05:57:46Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Signed-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n t/t6030-bisect-porcelain.sh |   50 +++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 50 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex b5063b6..2c14fb0 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -573,5 +573,55 @@ test_expect_success 'erroring out when using bad path parameters' '\n '\n \n #\n+# This creates a broken branch which cannot be checked out because\n+# the tree created has been deleted.\n #\n+# H1-H2-H3-H4-H5-H6-H7  <--other\n+#            \\\n+#             S5-S6'-S7'-S8'-S9  <--broken\n+#\n+# Commits marked with ' have a missing tree.\n+#\n+test_expect_success 'broken branch creation' '\n+        git bisect reset &&\n+        git checkout -b broken $HASH4 &&\n+        add_line_into_file \"5(broken): first line on a broken branch\" hello2 &&\n+        BROKEN_HASH5=$(git rev-parse --verify HEAD) &&\n+        mkdir missing &&\n+        :> missing/MISSING &&\n+        git add missing/MISSING &&\n+        git commit -m \"Added file that will be deleted\"\n+        BROKEN_HASH6=$(git rev-parse --verify HEAD) &&\n+        add_line_into_file \"6(broken): second line on a broken branch\" hello2 &&\n+        BROKEN_HASH7=$(git rev-parse --verify HEAD) &&\n+        add_line_into_file \"7(broken): third line on a broken branch\" hello2 &&\n+        BROKEN_HASH8=$(git rev-parse --verify HEAD) &&\n+        git rm missing/MISSING &&\n+        git commit -m \"Remove missing file\"\n+        BROKEN_HASH9=$(git rev-parse --verify HEAD) &&\n+        rm .git/objects/39/f7e61a724187ab767d2e08442d9b6b9dab587d\n+'\n+\n+echo \"\" > expected.ok\n+cat > expected.missing-tree.default <<EOF\n+fatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d\n+EOF\n+cat > expected.missing-tree.ignored <<EOF\n+fatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d\n+warn: checkout failed. Updating HEAD directly. The working tree and index may be inconsistent.\n+EOF\n+\n+test_expect_success 'bisect fails if tree is broken on start commit' '\n+        git bisect reset &&\n+        test_must_fail git bisect start $BROKEN_HASH7 $HASH4 2>error.txt &&\n+        test_cmp expected.missing-tree.default error.txt\n+'\n+\n+test_expect_success 'bisect fails if tree is broken on trial commit' '\n+        git bisect reset &&\n+        test_must_fail git bisect start $BROKEN_HASH9 $HASH4 2>error.txt &&\n+        git update-ref --no-deref HEAD broken &&\n+        test_cmp expected.missing-tree.default error.txt\n+'\n+\n test_done\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171917","messageId":"1311487074-25070-3-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 2/9] bisect: introduce a --ignore-checkout-failure option to bisect--helper.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:47Z","receivedAt":"2011-07-24T05:57:47Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"This commit introduces an option --ignore-checkout-failure which will\nallow git-bisect to tolerate checkout failures.\n\nThis commit simply parses the option, but does not otherwise process it.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n bisect.c                 |    5 ++++-\n bisect.h                 |    2 +-\n builtin/bisect--helper.c |    8 ++++++--\n 3 files changed, 11 insertions(+), 4 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex dd7e8ed..ce04092 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -24,6 +24,7 @@ struct argv_array {\n \n static const char *argv_checkout[] = {\"checkout\", \"-q\", NULL, \"--\", NULL};\n static const char *argv_show_branch[] = {\"show-branch\", NULL, NULL};\n+static int module_ignore_checkout_failure = 0;\n \n /* bits #0-15 in revision.h */\n \n@@ -909,7 +910,7 @@ static void show_diff_tree(const char *prefix, struct commit *commit)\n  * the bisection process finished successfully.\n  * In this case the calling shell script should exit 0.\n  */\n-int bisect_next_all(const char *prefix)\n+int bisect_next_all(const char *prefix, const int ignore_checkout_failure)\n {\n \tstruct rev_info revs;\n \tstruct commit_list *tried;\n@@ -917,6 +918,8 @@ int bisect_next_all(const char *prefix)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[41];\n \n+\tmodule_ignore_checkout_failure = ignore_checkout_failure;\n+\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \ndiff --git a/bisect.h b/bisect.h\nindex 0862ce5..4851310 100644\n--- a/bisect.h\n+++ b/bisect.h\n@@ -27,7 +27,7 @@ struct rev_list_info {\n \tconst char *header_prefix;\n };\n \n-extern int bisect_next_all(const char *prefix);\n+extern int bisect_next_all(const char *prefix, const int ignore_checkout_failure);\n \n extern int estimate_bisect_steps(int all);\n \ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 5b22639..f531458 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -3,17 +3,21 @@\n #include \"parse-options.h\"\n #include \"bisect.h\"\n \n+\n static const char * const git_bisect_helper_usage[] = {\n-\t\"git bisect--helper --next-all\",\n+\t\"git bisect--helper --next-all [ --ignore-checkout-failure ]\",\n \tNULL\n };\n \n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tint next_all = 0;\n+\tint ignore_checkout_failure = 0;\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN(0, \"next-all\", &next_all,\n \t\t\t    \"perform 'git bisect next'\"),\n+\t\tOPT_BOOLEAN(0, \"ignore-checkout-failure\", &ignore_checkout_failure,\n+\t\t\t    \"ignore checkout failure\"),\n \t\tOPT_END()\n \t};\n \n@@ -24,5 +28,5 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options(git_bisect_helper_usage, options);\n \n \t/* next-all */\n-\treturn bisect_next_all(prefix);\n+\treturn bisect_next_all(prefix, ignore_checkout_failure);\n }\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171915","messageId":"1311487074-25070-4-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 3/9] bisect: implement support for --ignore-checkout-failure option","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:48Z","receivedAt":"2011-07-24T05:57:48Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"If the option is not specified, git bisect has the current behaviour\nin case of checkout failure. Specifically, it will exit immediately\nwith a non-zero status code.\n\nWith this commit, we allow checkout failures of damaged trees\nto be ignored. To allow the bisect to proceed, as expected we\nfall back to updating the HEAD ref directly.\n\nThis will leave the working tree and index in an inconsistent state, but\nthe user of --ignore-checkout-failure should expect that.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n bisect.c |   13 ++++++++++++-\n 1 files changed, 12 insertions(+), 1 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex ce04092..993c48b 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -24,6 +24,7 @@ struct argv_array {\n \n static const char *argv_checkout[] = {\"checkout\", \"-q\", NULL, \"--\", NULL};\n static const char *argv_show_branch[] = {\"show-branch\", NULL, NULL};\n+static const char *argv_update_ref[] = {\"update-ref\", \"--no-deref\", \"HEAD\", NULL, NULL};\n static int module_ignore_checkout_failure = 0;\n \n /* bits #0-15 in revision.h */\n@@ -716,8 +717,18 @@ static int bisect_checkout(char *bisect_rev_hex)\n \n \targv_checkout[2] = bisect_rev_hex;\n \tres = run_command_v_opt(argv_checkout, RUN_GIT_CMD);\n-\tif (res)\n+\tif (res) {\n+\t  if (!module_ignore_checkout_failure) {\n \t\texit(res);\n+\t  } else {\n+\t    fprintf(stderr, \"warn: checkout failed. Updating HEAD directly. The working tree and index may be inconsistent.\\n\");\n+\t    argv_update_ref[3] = bisect_rev_hex;\n+\t    res = run_command_v_opt(argv_update_ref, RUN_GIT_CMD);\n+\t    if (res) {\n+\t      die(\"update-ref --no-deref HEAD failed on %s\", bisect_rev_hex);\n+\t    }\n+\t  }\n+\t}\n \n \targv_show_branch[1] = bisect_rev_hex;\n \treturn run_command_v_opt(argv_show_branch, RUN_GIT_CMD);\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171918","messageId":"1311487074-25070-5-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 4/9] bisect: introduce a helper function to tolerate checkout failures.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:49Z","receivedAt":"2011-07-24T05:57:49Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"In the case that git bisect is being used on a repo with damaged trees,\ngit checkout may not succeed.\n\nThis function allows checkout to succeed even if the current commit\nreferences a damaged tree. This will be useful for git bisect reset, for example.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-bisect.sh |   19 +++++++++++++++++++\n 1 files changed, 19 insertions(+), 0 deletions(-)\n\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex b2186a8..486a860 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -34,6 +34,8 @@ require_work_tree\n _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n \n+IGNORE_CHECKOUT_FAILURE=$(test -f \"${GIT_DIR}/BISECT_IGNORE_CHECKOUT_FAILURE\" && cat \"${GIT_DIR}/BISECT_IGNORE_CHECKOUT_FAILURE\")\n+\n bisect_autostart() {\n \ttest -s \"$GIT_DIR/BISECT_START\" || {\n \t\t(\n@@ -325,6 +327,23 @@ bisect_visualize() {\n \teval '\"$@\"' --bisect -- $(cat \"$GIT_DIR/BISECT_NAMES\")\n }\n \n+bisect_checkout_with_ignore()\n+{\n+    ref=$1\n+    if test -z \"$IGNORE_CHECKOUT_FAILURE\"; then\n+\tgit checkout \"$ref\" -- || exit\n+    else\n+\tif git checkout \"$ref\" -- 2>/dev/null; then\n+\t# If the current tree contains missing objects\n+\t# git checkout will fail. It might be\n+\t# possible to recover from this if we update\n+\t# the HEAD first.\n+\t    git update-ref --no-deref HEAD \"$ref\" &&\n+\t    git checkout \"$ref\" -- || exit\n+\tfi\n+    fi\n+}\n+\n bisect_reset() {\n \ttest -s \"$GIT_DIR/BISECT_START\" || {\n \t\tgettext \"We are not bisecting.\"; echo\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171919","messageId":"1311487074-25070-6-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 5/9] bisect: replace existing calls to git checkout with bisect_checkout_with_ignore","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:50Z","receivedAt":"2011-07-24T05:57:50Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Signed-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-bisect.sh |    4 ++--\n 1 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 486a860..ecbd5bf 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -76,7 +76,7 @@ bisect_start() {\n \tthen\n \t\t# Reset to the rev from where we started.\n \t\tstart_head=$(cat \"$GIT_DIR/BISECT_START\")\n-\t\tgit checkout \"$start_head\" -- || exit\n+\t\tbisect_checkout_with_ignore \"$start_head\"\n \telse\n \t\t# Get rev from where we start.\n \t\tcase \"$head\" in\n@@ -359,7 +359,7 @@ bisect_reset() {\n \t*)\n \t    usage ;;\n \tesac\n-\tif git checkout \"$branch\" -- ; then\n+\tif ( bisect_checkout_with_ignore \"$branch\" ) ; then\n \t\tbisect_clean_state\n \telse\n \t\tdie \"$(eval_gettext \"Could not check out original HEAD '\\$branch'.\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171921","messageId":"1311487074-25070-7-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 6/9] bisect: enable --ignore-checkout-failure in the porcelain.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:51Z","receivedAt":"2011-07-24T05:57:51Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Signed-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-bisect.sh |   10 ++++++++--\n 1 files changed, 8 insertions(+), 2 deletions(-)\n\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ecbd5bf..f3913ba 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -3,7 +3,7 @@\n USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n         print this long help message.\n-git bisect start [<bad> [<good>...]] [--] [<pathspec>...]\n+git bisect start [--ignore-checkout-failure] [<bad> [<good>...]] [--] [<pathspec>...]\n         reset bisect state and start bisection.\n git bisect bad [<rev>]\n         mark <rev> a known-bad revision.\n@@ -116,6 +116,11 @@ bisect_start() {\n \t\tshift\n \t\tbreak\n \t\t;;\n+\t    --ignore-checkout-failure)\n+\t\tIGNORE_CHECKOUT_FAILURE=$arg\n+\t\techo \"$arg\" > $GIT_DIR/BISECT_IGNORE_CHECKOUT_FAILURE\n+\t\tshift\n+\t\t;;\n \t    *)\n \t\trev=$(git rev-parse -q --verify \"$arg^{commit}\") || {\n \t\t    test $has_double_dash -eq 1 &&\n@@ -293,7 +298,7 @@ bisect_next() {\n \tbisect_next_check good\n \n \t# Perform all bisection computation, display and checkout\n-\tgit bisect--helper --next-all\n+\tgit bisect--helper --next-all ${IGNORE_CHECKOUT_FAILURE}\n \tres=$?\n \n         # Check if we should exit because bisection is finished\n@@ -379,6 +384,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_LOG\" &&\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n+\trm -f \"$GIT_DIR/BISECT_IGNORE_CHECKOUT_FAILURE\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171916","messageId":"1311487074-25070-8-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 7/9] bisect: better diagnostics, in case of mis-typed option.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:52Z","receivedAt":"2011-07-24T05:57:52Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Signed-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n git-bisect.sh |    3 +++\n 1 files changed, 3 insertions(+), 0 deletions(-)\n\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex f3913ba..3ae1aa9 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -121,6 +121,9 @@ bisect_start() {\n \t\techo \"$arg\" > $GIT_DIR/BISECT_IGNORE_CHECKOUT_FAILURE\n \t\tshift\n \t\t;;\n+\t    --*)\n+\t\tdie \"unrecognised option: $arg\"\n+\t\t;;\n \t    *)\n \t\trev=$(git rev-parse -q --verify \"$arg^{commit}\") || {\n \t\t    test $has_double_dash -eq 1 &&\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171920","messageId":"1311487074-25070-9-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 8/9] bisect: add tests for --ignore-checkout-failure option.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:53Z","receivedAt":"2011-07-24T05:57:53Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Signed-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n t/t6030-bisect-porcelain.sh |   69 +++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 69 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 2c14fb0..32fb434 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -624,4 +624,73 @@ test_expect_success 'bisect fails if tree is broken on trial commit' '\n         test_cmp expected.missing-tree.default error.txt\n '\n \n+test_expect_success 'bisect: --ignore-checkout-failure - start commit bad' '\n+        git bisect reset &&\n+        git bisect start $BROKEN_HASH7 $HASH4 --ignore-checkout-failure 2>error.txt\n+        test_cmp expected.missing-tree.ignored error.txt &&\n+        broken6=$(git rev-parse HEAD) &&\n+        test \"$broken6\" = \"$BROKEN_HASH6\" &&\n+        git bisect reset\n+'\n+\n+test_expect_success 'bisect: --ignore-checkout-failure - trial commit bad' '\n+        git bisect reset &&\n+        git bisect start broken $HASH4 --ignore-checkout-failure 2>error.txt\n+        test_cmp expected.missing-tree.ignored error.txt &&\n+        broken6=$(git rev-parse HEAD) &&\n+        test \"$broken6\" = \"$BROKEN_HASH6\" &&\n+        git bisect reset\n+'\n+\n+test_expect_success 'bisect: --ignore-checkout-failure - target before breakage' '\n+        git bisect reset &&\n+        git bisect start broken $HASH4 --ignore-checkout-failure 2>error.txt\n+        test_cmp expected.missing-tree.ignored error.txt &&\n+        broken6=$(git rev-parse HEAD) &&\n+        test \"$broken6\" = \"$BROKEN_HASH6\" &&\n+        git bisect bad HEAD &&\n+        broken5=$(git rev-parse HEAD) &&\n+        test \"$broken5\" = \"$BROKEN_HASH5\" &&\n+        git bisect bad HEAD > my_bisect_log.txt &&\n+        broken4=$(git rev-parse HEAD) &&\n+        test \"$broken4\" = \"$HASH4\" &&\n+        echo \"$BROKEN_HASH5 is the first bad commit\" > expected.txt &&\n+        test_cmp expected.txt my_bisect_log.txt\n+        git bisect reset\n+'\n+\n+test_expect_success 'bisect: --ignore-checkout-failure - target in breakage' '\n+        git bisect reset &&\n+        git bisect start broken $HASH4 --ignore-checkout-failure 2>error.txt\n+        test_cmp expected.missing-tree.ignored error.txt &&\n+        broken6=$(git rev-parse HEAD) &&\n+        test \"$broken6\" = \"$BROKEN_HASH6\" &&\n+        git bisect bad HEAD &&\n+        broken5=$(git rev-parse HEAD) &&\n+        test \"$broken5\" = \"$BROKEN_HASH5\" &&\n+        git bisect good HEAD > my_bisect_log.txt &&\n+        broken6=$(git rev-parse HEAD) &&\n+        test \"$broken6\" = \"$BROKEN_HASH6\" &&\n+        echo \"$BROKEN_HASH6 is the first bad commit\" > expected.txt &&\n+        test_cmp expected.txt my_bisect_log.txt\n+        git bisect reset\n+'\n+\n+test_expect_success 'bisect: --ignore-checkout-failure - target after breakage' '\n+        git bisect reset &&\n+        git bisect start broken $HASH4 --ignore-checkout-failure 2>error.txt\n+        test_cmp expected.missing-tree.ignored error.txt &&\n+        broken6=$(git rev-parse HEAD) &&\n+        test \"$broken6\" = \"$BROKEN_HASH6\" &&\n+        git bisect good HEAD &&\n+        broken8=$(git rev-parse HEAD) &&\n+        test \"$broken8\" = \"$BROKEN_HASH8\" &&\n+        git bisect good HEAD > my_bisect_log.txt &&\n+        broken9=$(git rev-parse HEAD) &&\n+        test \"$broken9\" = \"$BROKEN_HASH9\" &&\n+        echo \"$BROKEN_HASH9 is the first bad commit\" > expected.txt &&\n+        test_cmp expected.txt my_bisect_log.txt\n+        git bisect reset\n+'\n+\n test_done\n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171922","messageId":"1311487074-25070-10-git-send-email-jon.seymour@gmail.com","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"[PATCH 9/9] bisect: add documentation for --ignore-checkout-failure option.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T05:57:54Z","receivedAt":"2011-07-24T05:57:54Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Signed-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n Documentation/git-bisect.txt |   13 ++++++++++++-\n 1 files changed, 12 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex ab60a18..f7412a1 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -17,7 +17,7 @@ The command takes various subcommands, and different options depending\n on the subcommand:\n \n  git bisect help\n- git bisect start [<bad> [<good>...]] [--] [<paths>...]\n+ git bisect start [--ignore-checkout-failure] [<bad> [<good>...]] [--] [<paths>...]\n  git bisect bad [<rev>]\n  git bisect good [<rev>...]\n  git bisect skip [(<rev>|<range>)...]\n@@ -263,6 +263,17 @@ rewind the tree to the pristine state.  Finally the script should exit\n with the status of the real test to let the \"git bisect run\" command loop\n determine the eventual outcome of the bisect session.\n \n+OPTIONS\n+-------\n+--ignore-checkout-failure::\n++\n+This option, specified on the \"git bisect start\" subcommand, causes\n+bisect to ignore checkout failures during the bisection process. This allows\n+git bisect to be used on repositories that contain damaged trees. The\n+user should expect that, in cases where checkout fails, the detached\n+HEAD refers to the trial commit, but the working tree and index\n+may differ from that commit.\n+\n EXAMPLES\n --------\n \n-- \n1.7.6.347.g96e0b.dirty\n"},{"id":"171928","messageId":"4E2BD251.6060306@kdbg.org","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2011-07-24T08:05:37Z","receivedAt":"2011-07-24T08:05:37Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 24.07.2011 07:57, schrieb Jon Seymour:\n> Currently git bisect assumes that the respository to be undamaged. This limits the usefulness\n> of git bisect when working with damaged repositories.\n\nSo, what? Isn't a broken repository also (almost) useless w.r.t. log,\ncheckout, rebase, reset, push, fetch...?\n\n> This series introduces an option, --ignore-checkout-failure, which can be used with \n> \"git bisect start\" to indicate that checkout failures should be tolerated for the life\n> of the (new) bisection process. This allows git bisect to be used on damaged repositories. In\n> particular, it allows git bisect to be used to locate commits containing damaged trees.\n\nI have to wonder: why do you care only about git-bisect? If you want to\nbe able to use a broken repository, aren't there many more commands that\nfail and for which you also want to have a similar work-around? Or is\ngit-bisect the only one where the work-around was missing?\n\n> If the --ignore-checkout-failure option is specified, then if git checkout fails either \n> at the start of the bisection process or later while probing a new trial commit, then the \n> checkout failure will be noisily ignored and the HEAD reference will be updated to the \n> intended commit. This may leave the working tree and index in an inconsistent state\n> w.r.t the HEAD commit.\n\nBut what is an inconsistent state good for? In general, it makes no\nsense to decide whether the result is \"good\" or \"bad\" when you know in\nadvance that the checked-out state is inconsistent.\n\n-- Hannes\n"},{"id":"171930","messageId":"CAH3Anrp7h+TkGgi1uZsfZKWkK3zDYa=eG2kjHRcmoPKvkZq59w@mail.gmail.com","threadId":"27906","inReplyTo":"4E2BD251.6060306@kdbg.org","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-24T08:54:11Z","receivedAt":"2011-07-24T08:54:11Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Sun, Jul 24, 2011 at 6:05 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 24.07.2011 07:57, schrieb Jon Seymour:\n>> Currently git bisect assumes that the respository to be undamaged. This limits the usefulness\n>> of git bisect when working with damaged repositories.\n>\n> So, what? Isn't a broken repository also (almost) useless w.r.t. log,\n> checkout, rebase, reset, push, fetch...?\n>\n\nThe broken or missing commits in a broken repository are useless, but\nall the other\ncommits and the things they reach may still be useful.\n\nWhen trying to recover such things, git bisect could be a useful tool,\nsince it would allow one to automate discovery of the broken regions\nof the graph. Once the broken regions have been isolated, grafts can\nbe used to cauterize the damaged regions, the remainder can be rescued\nwith git-filter-branch  and life goes on.\n\n>> This series introduces an option, --ignore-checkout-failure, which can be used with\n>> \"git bisect start\" to indicate that checkout failures should be tolerated for the life\n>> of the (new) bisection process. This allows git bisect to be used on damaged repositories. In\n>> particular, it allows git bisect to be used to locate commits containing damaged trees.\n>\n> I have to wonder: why do you care only about git-bisect? If you want to\n> be able to use a broken repository, aren't there many more commands that\n> fail and for which you also want to have a similar work-around? Or is\n> git-bisect the only one where the work-around was missing?\n>\n\ngit bisect is, in principle, a very useful tool for identifying\nregions of damage in a broken repo.\n\nI don't want to have to write another tool that does exactly what git\nbisect does except for the checkout function which, for the purpose of\nrepo rescue, I do not need.\n\n>\n> But what is an inconsistent state good for? In general, it makes no\n> sense to decide whether the result is \"good\" or \"bad\" when you know in\n> advance that the checked-out state is inconsistent.\n>\n\nThe inconsistent state is useful because I can use that state to\nprogress the bisection. In particular, I can write a test which checks\nto see whether this particular commit is broken (can't reach its\nparents or its tree). In fact, git status does just nicely for this\npurpose.\n\nAnd by using that test with git bisect I can discover the precise\nboundaries of the broken regions of the graph.\n\nOf course, I have no intention of doing any kind of development with a\nrepo in that state - the point is to only to make an existing tool\neven more useful - by helping it deal with broken repos too.\n\njon.\n"},{"id":"171964","messageId":"7v1uxfwmq3.fsf@alter.siamese.dyndns.org","threadId":"27906","inReplyTo":"1311487074-25070-1-git-send-email-jon.seymour@gmail.com","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-07-24T18:35:32Z","receivedAt":"2011-07-24T18:35:32Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jon Seymour <jon.seymour@gmail.com> writes:\n\n> ... In particular, it\n> allows git bisect to be used to locate commits containing damaged trees.\n\nI am afraid it wouldn't allow it, and I am not going to take this series\nthat adds an option to bisect to ignore errors during checkout.\n\nRemember that bisection is to find a single event in the history whose\neffect consistently persists in all the commits into the future from that\npoint.  For example, if you have this history:\n\n    ---A---B---C\n\nand there is a bitflip in a blob contained in the commit B's tree, you may\nnot be able to check it out. But that does _not_ mean you cannot check C\nout due to a corrupt object in B. The change going from B to C may be to\nremove that blob, for example. \"A tree that refers to a corrupt object was\nintroduced by this commit\" is not a single event whose effect cascades\nthrough the history into the future [*1*].\n\nBesides, if you have a corrupt commit, your history traversal may not even\nbe correct, as we won't be reading its parent pointers correctly.\n\nHaving said that, an option to bisect that does _not_ touch the index nor\nthe working tree at all may be a useful thing to have. The test you want\nto run on the candidate revisions bisect suggests may not need a working\ntree (e.g. it may be built around \"git grep -e foo $revision -- $path\"),\nand it may work just as well for the bisection you wanted to do in your\nbroken repository.\n\n[Footnote]\n\n*1* Theoretically, you could turn it into such by using a test that wants\nto traverse and verify all the objects reachable from the candidate\ncommit, e.g.\n\n    $ git rev-list --objects $rev | git pack-objects --stdout >/dev/null\n\nwhich would succeed on A, and fail on B and all the commits that reach B,\nincluding C. Was that what you had in mind?\n"},{"id":"171983","messageId":"CAH3AnrrVwodvtwWfaJCJqjuHThtv75jaWeDjvwRgdFbgXA3ziA@mail.gmail.com","threadId":"27906","inReplyTo":"7v1uxfwmq3.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-25T09:28:12Z","receivedAt":"2011-07-25T09:28:12Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Mon, Jul 25, 2011 at 4:35 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jon Seymour <jon.seymour@gmail.com> writes:\n>\n>> ... In particular, it\n>> allows git bisect to be used to locate commits containing damaged trees.\n>\n> I am afraid it wouldn't allow it, and I am not going to take this series\n> that adds an option to bisect to ignore errors during checkout.\n\nUnderstand that you don't wish to accept the series, but I do think\nyou are mistaken about whether it will work.\n\n>\n> Remember that bisection is to find a single event in the history whose\n> effect consistently persists in all the commits into the future from that\n> point.  For example, if you have this history:\n>\n>    ---A---B---C\n>\n> and there is a bitflip in a blob contained in the commit B's tree, you may\n> not be able to check it out. But that does _not_ mean you cannot check C\n> out due to a corrupt object in B. The change going from B to C may be to\n> remove that blob, for example. \"A tree that refers to a corrupt object was\n> introduced by this commit\" is not a single event whose effect cascades\n> through the history into the future [*1*].\n\nI don't think you understood my intention. Suppose, I have\n\nB4 - B5 - B6' - B7' - B8' - B9\n\nsuch that B6 and B7 and B8 all contain a damaged tree, but B4, B5 and B9 don't\nsince it contains a different tree, then:\n\n        git bisect start B8' B4 --ignore-checkout-failure &&\n\tgit bisect run eval \"git status >/dev/null 2>&1 || false\"\n\nwill stop with bisect/bad = B6'\n\nThis is exactly the result I wanted, and I discover B6' with a binary\nsearch, rather than a linear search.\n\n(I could also discover B8' with a binary search by reversing the sense\nof the test).\n\nIn other words, I don't understand why you say that it won't work -\nsince it clearly does work for the purposes which I intended.\n\nFor a real example, see [1].\n\n>\n> Besides, if you have a corrupt commit, your history traversal may not even\n> be correct, as we won't be reading its parent pointers correctly.\n>\n\nAgreed. This only works when you have dealt with broken commits by\napplying suitable grafts.\n\nI noticed a neat heuristic for doing this is to compute the diff\nbetween the first good commit after the broken\nregion and the first good dangling commit (as reported by fsck) - the\none with the smallest delta may well be\na suitable object to use as one end of the graft. [ needs to be sanity\nchecked, of course ]. It may not be perfect,\nbut when the objective is to get a consistent (in the sense of fsck),\nif incomplete repository, it may well do.\n\n> Having said that, an option to bisect that does _not_ touch the index nor\n> the working tree at all may be a useful thing to have. The test you want\n> to run on the candidate revisions bisect suggests may not need a working\n> tree (e.g. it may be built around \"git grep -e foo $revision -- $path\"),\n> and it may work just as well for the bisection you wanted to do in your\n> broken repository.\n>\n\nI am happy to do this, since clearly enables a superset of the cases\nhandled by --ignore-checkout-failure.\n\nI propose to do this with a new ref (perhaps BISECT_CURSOR) which will\nbe used in place of HEAD\nfor the purposes of driving the bisection algorithm if --no-checkout\nhas been specified on the\ngit bisect start command.\n\nAny comments?\n\njon.\n\n----------------\n[1] a test execution that shows that the bisection does, in fact, help\nto identify the boundaries of a broken region.\n\n(Note NEAREST could also be discovered with a binary search, but this\nisn't done in this example).\n\nexpecting success:\n        git bisect reset &&\n\tNEAREST=$(git rev-list broken | while read c\n\tdo\n\t    git ls-tree -r $c >/dev/null || {\n\t    \techo $c;\n\t\texit 0;\n\t    }\n\tdone) &&\n        git bisect start $NEAREST $HASH1 --ignore-checkout-failure &&\n\tgit bisect run eval \"git status >/dev/null 2>&1 || false\" >\nmy_bisect_log.txt &&\n        grep \"$BROKEN_HASH6 is the first bad commit\" my_bisect_log.txt\n\nWe are not bisecting.\nerror: Could not read 39f7e61a724187ab767d2e08442d9b6b9dab587d\nBisecting: 3 revisions left to test after this (roughly 2 steps)\nfatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d\nwarn: checkout failed. Updating HEAD directly. The working tree and\nindex may be inconsistent.\n[32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>.\nfatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d\nwarn: checkout failed. Updating HEAD directly. The working tree and\nindex may be inconsistent.\nfatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d\nwarn: checkout failed. Updating HEAD directly. The working tree and\nindex may be inconsistent.\n1b0312df05d867dc49f5d9f82617ee42cce1430d is the first bad commit\nok 49 - bisect: find the first inconsistent commit\n"},{"id":"171999","messageId":"7vhb6arzvj.fsf@alter.siamese.dyndns.org","threadId":"27906","inReplyTo":"CAH3AnrrVwodvtwWfaJCJqjuHThtv75jaWeDjvwRgdFbgXA3ziA@mail.gmail.com","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-07-25T18:14:56Z","receivedAt":"2011-07-25T18:14:56Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jon Seymour <jon.seymour@gmail.com> writes:\n\n> I don't think you understood my intention. Suppose, I have\n>\n> B4 - B5 - B6' - B7' - B8' - B9\n>\n> such that B6 and B7 and B8 all contain a damaged tree, but B4, B5 and B9 don't\n> since it contains a different tree, then:\n\nWhat prevents your disk from corrupting a blob that was in B6, modified by\ncommit B7, and then _reverted_ by commit B8? Then your checkout would fail\nat B6 and B8 but B7 will be fine.\n\nAs I wrote in my footnote, if your test is to find the most recent commit,\nstarting from which all the objects reachable from it are not corrupt (by\nusing \"rev-list --objects $commit | pack-objects\"), you could run your\nbisect by somehow first finding a good commit (B5) that passes the test,\nand after knowing a bad commit (B8) that does not pass (because it is\nmissing the single blob that is unreadable for B6 and B8), and then bisect\nusing a slightly less expensive test\n\n\trev-list --objects B5..$commit | pack-objects\n\nto find it in theory, but \"Being unable to check-out\" is not an isolated\nevent and cannot be used as the check as you seem to think.\n\n>> Having said that, an option to bisect that does _not_ touch the index nor\n>> the working tree at all may be a useful thing to have. The test you want\n>> to run on the candidate revisions bisect suggests may not need a working\n>> tree (e.g. it may be built around \"git grep -e foo $revision -- $path\"),\n>> and it may work just as well for the bisection you wanted to do in your\n>> broken repository.\n>\n> I am happy to do this, since clearly enables a superset of the cases\n> handled by --ignore-checkout-failure.\n>\n> I propose to do this with a new ref (perhaps BISECT_CURSOR) which will\n> be used in place of HEAD for the purposes of driving the bisection\n> algorithm if --no-checkout has been specified on the git bisect start\n> command.\n\nPros of using HEAD (i.e. the only change under the new mode would be that\nwe do not touch the index nor the working tree) is that the test you would\nneed to run in each step of bisection can use the familiar HEAD ref\ninstead of a strange BISECT_CURSOR, \"bisect reset\" will take you back from\nthe tentative detached HEAD state the usual way, and most likely the\nnecessary change to git-bisect.sh would be smaller. Cons of using HEAD\nwould be that the index and the working tree will be totally out-of-sync\nwith respect to HEAD during the bisection (by definition---as that is the\npoint of this new mode). One could argue that a naïve user might get\nconfused, but I am not sure how big a practical downside it would be.\n"},{"id":"172000","messageId":"4E2DBA84.3090405@kdbg.org","threadId":"27906","inReplyTo":"CAH3AnrrVwodvtwWfaJCJqjuHThtv75jaWeDjvwRgdFbgXA3ziA@mail.gmail.com","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2011-07-25T18:48:36Z","receivedAt":"2011-07-25T18:48:36Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 25.07.2011 11:28, schrieb Jon Seymour:\n> On Mon, Jul 25, 2011 at 4:35 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Jon Seymour <jon.seymour@gmail.com> writes:\n>>\n>>> ... In particular, it\n>>> allows git bisect to be used to locate commits containing damaged trees.\n>>\n>> I am afraid it wouldn't allow it, and I am not going to take this series\n>> that adds an option to bisect to ignore errors during checkout.\n> \n> Understand that you don't wish to accept the series, but I do think\n> you are mistaken about whether it will work.\n> \n>>\n>> Remember that bisection is to find a single event in the history whose\n>> effect consistently persists in all the commits into the future from that\n>> point.  For example, if you have this history:\n>>\n>>    ---A---B---C\n>>\n>> and there is a bitflip in a blob contained in the commit B's tree, you may\n>> not be able to check it out. But that does _not_ mean you cannot check C\n>> out due to a corrupt object in B. The change going from B to C may be to\n>> remove that blob, for example. \"A tree that refers to a corrupt object was\n>> introduced by this commit\" is not a single event whose effect cascades\n>> through the history into the future [*1*].\n> \n> I don't think you understood my intention. Suppose, I have\n> \n> B4 - B5 - B6' - B7' - B8' - B9\n> \n> such that B6 and B7 and B8 all contain a damaged tree, but B4, B5 and B9 don't\n> since it contains a different tree, then:\n> \n>         git bisect start B8' B4 --ignore-checkout-failure &&\n> \tgit bisect run eval \"git status >/dev/null 2>&1 || false\"\n> \n> will stop with bisect/bad = B6'\n> \n> This is exactly the result I wanted, and I discover B6' with a binary\n> search, rather than a linear search.\n> \n> (I could also discover B8' with a binary search by reversing the sense\n> of the test).\n\nThe fundamental preconditions of bisection are: that there is a single\nevent in the sequence, and that the effects of the event propagate to\nthe end of the sequence.\n\nJunio explainded, that the second precondition is violated. Therefore,\nyou cannot apply git-bisect to find brokenness in a repository *in general*.\n\nOf course, there may be special cases where stronger assumptions are\njustifiable, and your case may have been one of them.\n\n-- Hannes\n"},{"id":"172027","messageId":"CAH3Anrrq8xiYVwM-U6OMX7834ey_BxWBXj97bqWA=u8PZ2shjA@mail.gmail.com","threadId":"27906","inReplyTo":"7vhb6arzvj.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-25T23:27:51Z","receivedAt":"2011-07-25T23:27:51Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Tue, Jul 26, 2011 at 4:14 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jon Seymour <jon.seymour@gmail.com> writes:\n>\n>> I don't think you understood my intention. Suppose, I have\n>>\n>> B4 - B5 - B6' - B7' - B8' - B9\n>>\n>> such that B6 and B7 and B8 all contain a damaged tree, but B4, B5 and B9 don't\n>> since it contains a different tree, then:\n>\n> What prevents your disk from corrupting a blob that was in B6, modified by\n> commit B7, and then _reverted_ by commit B8? Then your checkout would fail\n> at B6 and B8 but B7 will be fine.\n\nBut that's ok.\n\nIf B7's tree is fine, then the tree at B7 (if not the exact history\nleading to the tree)\ncan be recovered by suitable grafts.\n\nAlso, the intent was not to use failure of git checkout as the test -\nthe intent was merely\nto prevent a failure of git checkout from progressing the bisection.\n\nThe test for badness is something that would be run at each point in\nthe process.\n\nI admit that git status is not a good test, since it is possible that\ngit update-ref --no-deref <target>\n && git checkout <target> will not restore a clean working tree and\nindex at each step,\neven for good commits.\n\nOf course, this is all rather academic since I agree your suggestion\nof a --no-checkout option is a more general purpose solution\nwhich can do all that --ignore-checkout-failure does and more.\n\n>\n> As I wrote in my footnote, if your test is to find the most recent commit,\n> starting from which all the objects reachable from it are not corrupt (by\n> using \"rev-list --objects $commit | pack-objects\"), you could run your\n> bisect by somehow first finding a good commit (B5) that passes the test,\n> and after knowing a bad commit (B8) that does not pass (because it is\n> missing the single blob that is unreadable for B6 and B8), and then bisect\n> using a slightly less expensive test\n>\n>        rev-list --objects B5..$commit | pack-objects\n>\n> to find it in theory, but \"Being unable to check-out\" is not an isolated\n> event and cannot be used as the check as you seem to think.\n>\n\nI agree - a test that actually traverses the graph reachable from the\ncommits each tree and visits each object is better.\n\nI'd tweak your snippet with --max-count=1, so that amount of work per\ncommit is limited.\n\nNote that running git bisect --no-checkout will still be useful here\nsince it will limit the number of iterations that need to\nbe tested in order to find B5, for example.\n\n>\n> Pros of using HEAD (i.e. the only change under the new mode would be that\n> we do not touch the index nor the working tree) is that the test you would\n> need to run in each step of bisection can use the familiar HEAD ref\n> instead of a strange BISECT_CURSOR, \"bisect reset\" will take you back from\n> the tentative detached HEAD state the usual way, and most likely the\n> necessary change to git-bisect.sh would be smaller. Cons of using HEAD\n> would be that the index and the working tree will be totally out-of-sync\n> with respect to HEAD during the bisection (by definition---as that is the\n> point of this new mode). One could argue that a naïve user might get\n> confused, but I am not sure how big a practical downside it would be.\n>\n>\n\nHow about a compromise such as:\n\n    --no-checkout[=<ref>]\n\nwhich defaults to HEAD, but can be specified as something else?\n\njon.\n"},{"id":"172028","messageId":"CAH3AnrrOdduUG_rS97fR_PRZAWb6y3uPa_oKDZenEX2gG-AvAQ@mail.gmail.com","threadId":"27906","inReplyTo":"4E2DBA84.3090405@kdbg.org","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-25T23:38:12Z","receivedAt":"2011-07-25T23:38:12Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Tue, Jul 26, 2011 at 4:48 AM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 25.07.2011 11:28, schrieb Jon Seymour:\n>> On Mon, Jul 25, 2011 at 4:35 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Jon Seymour <jon.seymour@gmail.com> writes:\n>\n> The fundamental preconditions of bisection are: that there is a single\n> event in the sequence, and that the effects of the event propagate to\n> the end of the sequence.\n\nMore correctly: the fundamental pre-condition of a single round of\nbisection finding an\nevent of interest is as you say.\n\nThere is nothing that prevents multiple rounds of bisection being\nused, if required.\n\nSo, in my examples, may produce a limit commit such that the graph\nbetween the limit and the tip\ncontains two regions of good commits and two regions of bad commits.\nSo, you keep applying rounds\nof bisection until the bad regions identified have no good commits.\n\n>\n> Junio explainded, that the second precondition is violated. Therefore,\n> you cannot apply git-bisect to find brokenness in a repository *in general*.\n>\n\nI never claimed that a single round of biseciton would be enough, in\ngeneral. Only that it would be useful to be able\nto apply a bisection algorithm to broken repositories.\n\nIt seems clear to me that bisection is a very useful tool for probling\nthe extent of corruption in a broken repo.\nIt is certainly not the only tool, may not work in all cases (broken\ncommits) and may not be all you need.\n\nAnyway, I agree that Junio's suggestion (e.g. --no-checkout) is a\nbetter and more generally applicable than my original\n(--ignore-checkout-failure) suggestion.\n\njon.\n"},{"id":"172040","messageId":"m3ei1dsd1x.fsf@localhost.localdomain","threadId":"27906","inReplyTo":"CAH3AnrrOdduUG_rS97fR_PRZAWb6y3uPa_oKDZenEX2gG-AvAQ@mail.gmail.com","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-07-26T07:43:40Z","receivedAt":"2011-07-26T07:43:40Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jon Seymour <jon.seymour@gmail.com> writes:\n> On Tue, Jul 26, 2011 at 4:48 AM, Johannes Sixt <j6t@kdbg.org> wrote:\n>> Am 25.07.2011 11:28, schrieb Jon Seymour:\n>>> On Mon, Jul 25, 2011 at 4:35 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>>> Jon Seymour <jon.seymour@gmail.com> writes:\n>>\n>> The fundamental preconditions of bisection are: that there is a single\n>> event in the sequence, and that the effects of the event propagate to\n>> the end of the sequence.\n> \n> More correctly: the fundamental pre-condition of a single round of\n> bisection finding an event of interest is as you say.\n> \n> There is nothing that prevents multiple rounds of bisection being\n> used, if required.\n\nNo, it is not true.  Think of bisection as in original application, as\nnumerical methods used to find root of one dimensional function.  It\nworks if there is single root between starting endpoints, or rather if\nendpoints have different signs.\n\nWhich means that it works in this case:\n\n\n                        bad bad bad\n                   BAD\n   good good good\n\n\nbut won't work in this case:\n\n\n\n   good good good               good good good\n                   bad bad bad\n\n-- \nJakub Narębski\n"},{"id":"172041","messageId":"CAH3Anrq=u1Ayw8UuzycdQOJZDaOot6RN-FUJMP4465R8itpMLg@mail.gmail.com","threadId":"27906","inReplyTo":"m3ei1dsd1x.fsf@localhost.localdomain","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-26T08:26:18Z","receivedAt":"2011-07-26T08:26:18Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"2011/7/26 Jakub Narebski <jnareb@gmail.com>:\n> No, it is not true.  Think of bisection as in original application, as\n> numerical methods used to find root of one dimensional function.  It\n> works if there is single root between starting endpoints, or rather if\n> endpoints have different signs.\n>\n\nAh, yes, I see you are correct.\n\nSorry!\n\njon.\n"},{"id":"172061","messageId":"CAH3AnroGQML+FV_Zh9u35bOBed00bk3qcQ1qA==RpmtTv1zz2w@mail.gmail.com","threadId":"27906","inReplyTo":"m3ei1dsd1x.fsf@localhost.localdomain","subject":"Re: [RFC 0/9] bisect: allow git bisect to be used with repos containing damaged trees.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2011-07-26T13:28:15Z","receivedAt":"2011-07-26T13:28:15Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"> Which means that it works in this case:\n>\n>\n>                        bad bad bad\n>                   BAD\n>   good good good\n>\n>\n> but won't work in this case:\n>\n>\n>\n>   good good good               good good good\n>                   bad bad bad\n>\n\nOf course, this doesn't mean that bisection is useless, only that you\nhave to choose the right kind of test!\n\nSo, while it is true that a commit local test such as those I was\nproposing (e.g. git ls-tree or even my suggested tweak git rev-list\n--objects --max-count=1) will be useless unless you happen to start\nwith the tip at the bad commit, it is not true that bisection in\ngeneral is useless.\n\nFor example, Junio's unconstrained git rev-list --objects | git\npack-objects test will be sufficient because a history that is\n\n    good good good bad bad bad good good good\n\naccording to a commit local test, will be:\n\n     bad bad bad bad bad bad bad good good good\n\nfrom the point of view of a test that reaches the entire graph\nreachable from a commit.\n\nIt will still be beneficial to do log(N) executions of git rev-list\n--objects instead of  N executions of the same.\n\njon.\n"}]}