{"thread":{"id":"18563","subject":"[PATCH 08/10] bisect--helper: implement \"git bisect--helper\"","startedAt":"2009-03-26T04:55:54Z","lastAt":"2009-03-26T06:49:19Z","messageCount":2,"participants":["Christian Couder","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":10},"messages":[{"id":"109484","messageId":"20090326055554.e91bf6ba.chriscool@tuxfamily.org","threadId":"18563","inReplyTo":null,"subject":"[PATCH 08/10] bisect--helper: implement \"git bisect--helper\"","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-03-26T04:55:54Z","receivedAt":"2009-03-26T04:55:54Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This patch implements a new \"git bisect--helper\" builtin plumbing\ncommand that will be used to migrate \"git-bisect.sh\" to C.\n\nWe start by implementing only the \"--next-vars\" option that will\nread bisect refs from \"refs/bisect/\", and then compute the next\nbisect step, and output shell variables ready to be eval'ed by\nthe shell.\n\nAt this step, \"git bisect--helper\" ignores the paths that may\nhave been put in \"$GIT_DIR/BISECT_NAMES\". This will be fixed in a\nlater patch.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n Makefile                 |    1 +\n bisect.c                 |   67 ++++++++++++++++++++++++++++++++++++++++++++++\n bisect.h                 |    7 +++++\n builtin-bisect--helper.c |   27 ++++++++++++++++++\n builtin.h                |    1 +\n git.c                    |    1 +\n 6 files changed, 104 insertions(+), 0 deletions(-)\n create mode 100644 builtin-bisect--helper.c\n\ndiff --git a/Makefile b/Makefile\nindex 9fa2928..006c27b 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -521,6 +521,7 @@ BUILTIN_OBJS += builtin-add.o\n BUILTIN_OBJS += builtin-annotate.o\n BUILTIN_OBJS += builtin-apply.o\n BUILTIN_OBJS += builtin-archive.o\n+BUILTIN_OBJS += builtin-bisect--helper.o\n BUILTIN_OBJS += builtin-blame.o\n BUILTIN_OBJS += builtin-branch.o\n BUILTIN_OBJS += builtin-bundle.o\ndiff --git a/bisect.c b/bisect.c\nindex 39189f2..ce62696 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -2,6 +2,8 @@\n #include \"commit.h\"\n #include \"diff.h\"\n #include \"revision.h\"\n+#include \"refs.h\"\n+#include \"list-objects.h\"\n #include \"bisect.h\"\n \n \n@@ -9,6 +11,10 @@ static unsigned char (*skipped_sha1)[20];\n static int skipped_sha1_nr;\n static int skipped_sha1_alloc;\n \n+static const char **rev_argv;\n+static int rev_argv_nr;\n+static int rev_argv_alloc;\n+\n /* bits #0-15 in revision.h */\n \n #define COUNTED\t\t(1u<<16)\n@@ -391,6 +397,33 @@ struct commit_list *find_bisection(struct commit_list *list,\n \treturn best;\n }\n \n+static int register_ref(const char *refname, const unsigned char *sha1,\n+\t\t\tint flags, void *cb_data)\n+{\n+\tif (!strcmp(refname, \"bad\")) {\n+\t\tALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);\n+\t\trev_argv[rev_argv_nr++] = xstrdup(sha1_to_hex(sha1));\n+\t} else if (!prefixcmp(refname, \"good-\")) {\n+\t\tconst char *hex = sha1_to_hex(sha1);\n+\t\tchar *good = xmalloc(strlen(hex) + 2);\n+\t\t*good = '^';\n+\t\tmemcpy(good + 1, hex, strlen(hex) + 1);\n+\t\tALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);\n+\t\trev_argv[rev_argv_nr++] = good;\n+\t} else if (!prefixcmp(refname, \"skip-\")) {\n+\t\tALLOC_GROW(skipped_sha1, skipped_sha1_nr + 1,\n+\t\t\t   skipped_sha1_alloc);\n+\t\thashcpy(skipped_sha1[skipped_sha1_nr++], sha1);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int read_bisect_refs(void)\n+{\n+\treturn for_each_bisect_ref(register_ref, NULL);\n+}\n+\n static int skipcmp(const void *a, const void *b)\n {\n \treturn hashcmp(a, b);\n@@ -451,3 +484,37 @@ struct commit_list *filter_skipped(struct commit_list *list,\n \n \treturn filtered;\n }\n+\n+int bisect_next_vars(const char *prefix)\n+{\n+\tstruct rev_info revs;\n+\tint reaches = 0, all = 0;\n+\n+\tinit_revisions(&revs, prefix);\n+\trevs.abbrev = 0;\n+\trevs.commit_format = CMIT_FMT_UNSPECIFIED;\n+\n+\t/* argv[0] will be ignored by setup_revisions */\n+\tALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);\n+\trev_argv[rev_argv_nr++] = xstrdup(\"bisect_rev_setup\");\n+\n+\tif (read_bisect_refs())\n+\t\tdie(\"reading bisect refs failed\");\n+\n+\tALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);\n+\trev_argv[rev_argv_nr++] = xstrdup(\"--\");\n+\n+\tsetup_revisions(rev_argv_nr, rev_argv, &revs, NULL);\n+\n+\trevs.limited = 1;\n+\n+\tif (prepare_revision_walk(&revs))\n+\t\tdie(\"revision walk setup failed\");\n+\tif (revs.tree_objects)\n+\t\tmark_edges_uninteresting(revs.commits, &revs, NULL);\n+\n+\trevs.commits = find_bisection(revs.commits, &reaches, &all,\n+\t\t\t\t      !!skipped_sha1_nr);\n+\n+\treturn show_bisect_vars(&revs, reaches, all, 0, 1);\n+}\ndiff --git a/bisect.h b/bisect.h\nindex 2489630..05eea17 100644\n--- a/bisect.h\n+++ b/bisect.h\n@@ -9,7 +9,14 @@ extern struct commit_list *filter_skipped(struct commit_list *list,\n \t\t\t\t\t  struct commit_list **tried,\n \t\t\t\t\t  int show_all);\n \n+/*\n+ * The \"show_all\" parameter should be 0 if this function is called\n+ * from outside \"builtin-rev-list.c\" as otherwise it would use\n+ * static \"revs\" from this file.\n+ */\n extern int show_bisect_vars(struct rev_info *revs, int reaches, int all,\n \t\t\t    int show_all, int show_tried);\n \n+extern int bisect_next_vars(const char *prefix);\n+\n #endif\ndiff --git a/builtin-bisect--helper.c b/builtin-bisect--helper.c\nnew file mode 100644\nindex 0000000..8fe7787\n--- /dev/null\n+++ b/builtin-bisect--helper.c\n@@ -0,0 +1,27 @@\n+#include \"builtin.h\"\n+#include \"cache.h\"\n+#include \"parse-options.h\"\n+#include \"bisect.h\"\n+\n+static const char * const git_bisect_helper_usage[] = {\n+\t\"git bisect--helper --next-vars\",\n+\tNULL\n+};\n+\n+int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n+{\n+\tint next_vars = 0;\n+\tstruct option options[] = {\n+\t\tOPT_BOOLEAN(0, \"next-vars\", &next_vars,\n+\t\t\t    \"output next bisect step variables\"),\n+\t\tOPT_END()\n+\t};\n+\n+\targc = parse_options(argc, argv, options, git_bisect_helper_usage, 0);\n+\n+\tif (!next_vars)\n+\t\tusage_with_options(git_bisect_helper_usage, options);\n+\n+\t/* next-vars */\n+\treturn bisect_next_vars(prefix);\n+}\ndiff --git a/builtin.h b/builtin.h\nindex 1495cf6..425ff8e 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -25,6 +25,7 @@ extern int cmd_add(int argc, const char **argv, const char *prefix);\n extern int cmd_annotate(int argc, const char **argv, const char *prefix);\n extern int cmd_apply(int argc, const char **argv, const char *prefix);\n extern int cmd_archive(int argc, const char **argv, const char *prefix);\n+extern int cmd_bisect__helper(int argc, const char **argv, const char *prefix);\n extern int cmd_blame(int argc, const char **argv, const char *prefix);\n extern int cmd_branch(int argc, const char **argv, const char *prefix);\n extern int cmd_bundle(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex c2b181e..a553926 100644\n--- a/git.c\n+++ b/git.c\n@@ -271,6 +271,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"annotate\", cmd_annotate, RUN_SETUP },\n \t\t{ \"apply\", cmd_apply },\n \t\t{ \"archive\", cmd_archive },\n+\t\t{ \"bisect--helper\", cmd_bisect__helper, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"blame\", cmd_blame, RUN_SETUP },\n \t\t{ \"branch\", cmd_branch, RUN_SETUP },\n \t\t{ \"bundle\", cmd_bundle },\n-- \n1.6.2.1.317.g3d804\n"},{"id":"109493","messageId":"7v3ad0srrk.fsf@gitster.siamese.dyndns.org","threadId":"18563","inReplyTo":"20090326055554.e91bf6ba.chriscool@tuxfamily.org","subject":"Re: [PATCH 08/10] bisect--helper: implement \"git bisect--helper\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-26T06:49:19Z","receivedAt":"2009-03-26T06:49:19Z","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 patch implements a new \"git bisect--helper\" builtin plumbing\n> command that will be used to migrate \"git-bisect.sh\" to C.\n>\n> We start by implementing only the \"--next-vars\" option that will\n> read bisect refs from \"refs/bisect/\", and then compute the next\n> bisect step, and output shell variables ready to be eval'ed by\n> the shell.\n>\n> At this step, \"git bisect--helper\" ignores the paths that may\n> have been put in \"$GIT_DIR/BISECT_NAMES\". This will be fixed in a\n> later patch.\n\nVery nicely done.\n\n> +static int read_bisect_refs(void)\n> +{\n> +\treturn for_each_bisect_ref(register_ref, NULL);\n> +}\n\nThis is only a minor point, but I do not foresee anybody other than\nbisect--helper (and later bisect) running for_each_bisect_ref().  It might\nmake sense to redo [01/10] to introduce\n\n\tfor_each_ref_in(const char *prefix, each_ref_fn fn, void *cb)\n\nand change this call site to:\n\n\treturn for_each_ref_in(\"refs/bisect/\", register_ref, NULL);\n\nNeedless to say, for_each_{ref,tag_ref,branch_ref,remote_ref}() can be\nredefined in terms of for_each_ref_in() so that we can lose these\nhardcoded length of prefix strings from the code.\n"}]}