bisect--helper: implement "git bisect--helper"
This patch implements a new "git bisect--helper" builtin plumbing command that will be used to migrate "git-bisect.sh" to C. We start by implementing only the "--next-vars" option that will read bisect refs from "refs/bisect/", and then compute the next bisect step, and output shell variables ready to be eval'ed by the shell. At this step, "git bisect--helper" ignores the paths that may have been put in "$GIT_DIR/BISECT_NAMES". This will be fixed in a later patch. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Christian Couder committed
Mar 26, 2009 at 05:55 UTC
1bf072e3661eeef8d9721079a332e804b5678c7e
6 files changed
+105
Makefile
+1
@@ -533,6 +533,7 @@ BUILTIN_OBJS += builtin-add.o
533
BUILTIN_OBJS += builtin-annotate.o
534
BUILTIN_OBJS += builtin-apply.o
535
BUILTIN_OBJS += builtin-archive.o
536
+BUILTIN_OBJS += builtin-bisect--helper.o
537
BUILTIN_OBJS += builtin-blame.o
538
BUILTIN_OBJS += builtin-branch.o
539
BUILTIN_OBJS += builtin-bundle.o
bisect.c
+68
@@ -2,11 +2,18 @@
2
#include "commit.h"
3
#include "diff.h"
4
#include "revision.h"
5
+#include "refs.h"
6
+#include "list-objects.h"
7
#include "sha1-lookup.h"
8
#include "bisect.h"
9
10
static unsigned char (*skipped_sha1)[20];
11
static int skipped_sha1_nr;
12
+static int skipped_sha1_alloc;
13
+
14
+static const char **rev_argv;
15
+static int rev_argv_nr;
16
+static int rev_argv_alloc;
17
18
/* bits #0-15 in revision.h */
19
@@ -390,6 +397,33 @@ struct commit_list *find_bisection(struct commit_list *list,
397
return best;
398
}
399
400
+static int register_ref(const char *refname, const unsigned char *sha1,
401
+ int flags, void *cb_data)
402
+{
403
+ if (!strcmp(refname, "bad")) {
404
+ ALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);
405
+ rev_argv[rev_argv_nr++] = xstrdup(sha1_to_hex(sha1));
406
+ } else if (!prefixcmp(refname, "good-")) {
407
+ const char *hex = sha1_to_hex(sha1);
408
+ char *good = xmalloc(strlen(hex) + 2);
409
+ *good = '^';
410
+ memcpy(good + 1, hex, strlen(hex) + 1);
411
+ ALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);
412
+ rev_argv[rev_argv_nr++] = good;
413
+ } else if (!prefixcmp(refname, "skip-")) {
414
+ ALLOC_GROW(skipped_sha1, skipped_sha1_nr + 1,
415
+ skipped_sha1_alloc);
416
+ hashcpy(skipped_sha1[skipped_sha1_nr++], sha1);
417
+ }
418
+
419
+ return 0;
420
+}
421
+
422
+static int read_bisect_refs(void)
423
+{
424
+ return for_each_ref_in("refs/bisect/", register_ref, NULL);
425
+}
426
+
427
static int skipcmp(const void *a, const void *b)
428
{
429
return hashcmp(a, b);
@@ -444,3 +478,37 @@ struct commit_list *filter_skipped(struct commit_list *list,
478
479
return filtered;
480
}
481
+
482
+int bisect_next_vars(const char *prefix)
483
+{
484
+ struct rev_info revs;
485
+ int reaches = 0, all = 0;
486
+
487
+ init_revisions(&revs, prefix);
488
+ revs.abbrev = 0;
489
+ revs.commit_format = CMIT_FMT_UNSPECIFIED;
490
+
491
+ /* argv[0] will be ignored by setup_revisions */
492
+ ALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);
493
+ rev_argv[rev_argv_nr++] = xstrdup("bisect_rev_setup");
494
+
495
+ if (read_bisect_refs())
496
+ die("reading bisect refs failed");
497
+
498
+ ALLOC_GROW(rev_argv, rev_argv_nr + 1, rev_argv_alloc);
499
+ rev_argv[rev_argv_nr++] = xstrdup("--");
500
+
501
+ setup_revisions(rev_argv_nr, rev_argv, &revs, NULL);
502
+
503
+ revs.limited = 1;
504
+
505
+ if (prepare_revision_walk(&revs))
506
+ die("revision walk setup failed");
507
+ if (revs.tree_objects)
508
+ mark_edges_uninteresting(revs.commits, &revs, NULL);
509
+
510
+ revs.commits = find_bisection(revs.commits, &reaches, &all,
511
+ !!skipped_sha1_nr);
512
+
513
+ return show_bisect_vars(&revs, reaches, all, 0, 1);
514
+}
bisect.h
+7
@@ -9,7 +9,14 @@ extern struct commit_list *filter_skipped(struct commit_list *list,
9
struct commit_list **tried,
10
int show_all);
11
12
+/*
13
+ * The "show_all" parameter should be 0 if this function is called
14
+ * from outside "builtin-rev-list.c" as otherwise it would use
15
+ * static "revs" from this file.
16
+ */
17
extern int show_bisect_vars(struct rev_info *revs, int reaches, int all,
18
int show_all, int show_tried);
19
20
+extern int bisect_next_vars(const char *prefix);
21
+
22
#endif
builtin-bisect--helper.c
new
+27
@@ -0,0 +1,27 @@
1
+#include "builtin.h"
2
+#include "cache.h"
3
+#include "parse-options.h"
4
+#include "bisect.h"
5
+
6
+static const char * const git_bisect_helper_usage[] = {
7
+ "git bisect--helper --next-vars",
8
+ NULL
9
+};
10
+
11
+int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
12
+{
13
+ int next_vars = 0;
14
+ struct option options[] = {
15
+ OPT_BOOLEAN(0, "next-vars", &next_vars,
16
+ "output next bisect step variables"),
17
+ OPT_END()
18
+ };
19
+
20
+ argc = parse_options(argc, argv, options, git_bisect_helper_usage, 0);
21
+
22
+ if (!next_vars)
23
+ usage_with_options(git_bisect_helper_usage, options);
24
+
25
+ /* next-vars */
26
+ return bisect_next_vars(prefix);
27
+}
builtin.h
+1
@@ -25,6 +25,7 @@ extern int cmd_add(int argc, const char **argv, const char *prefix);
25
extern int cmd_annotate(int argc, const char **argv, const char *prefix);
26
extern int cmd_apply(int argc, const char **argv, const char *prefix);
27
extern int cmd_archive(int argc, const char **argv, const char *prefix);
28
+extern int cmd_bisect__helper(int argc, const char **argv, const char *prefix);
29
extern int cmd_blame(int argc, const char **argv, const char *prefix);
30
extern int cmd_branch(int argc, const char **argv, const char *prefix);
31
extern int cmd_bundle(int argc, const char **argv, const char *prefix);
git.c
+1
@@ -271,6 +271,7 @@ static void handle_internal_command(int argc, const char **argv)
271
{ "annotate", cmd_annotate, RUN_SETUP },
272
{ "apply", cmd_apply },
273
{ "archive", cmd_archive },
274
+ { "bisect--helper", cmd_bisect__helper, RUN_SETUP | NEED_WORK_TREE },
275
{ "blame", cmd_blame, RUN_SETUP },
276
{ "branch", cmd_branch, RUN_SETUP },
277
{ "bundle", cmd_bundle },