6
#include "dir.h"
7
#include "argv-array.h"
8
#include "run-command.h"
9
+#include "prompt.h"
10
11
static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
12
static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
22
N_("git bisect--helper --bisect-reset [<commit>]"),
23
N_("git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>"),
24
N_("git bisect--helper --bisect-check-and-set-terms <command> <good_term> <bad_term>"),
25
+ N_("git bisect--helper --bisect-next-check <good_term> <bad_term> [<term>]"),
26
NULL
27
};
28
46
terms->term_bad = xstrdup(bad);
47
}
48
49
+static const char *vocab_bad = "bad|new";
50
+static const char *vocab_good = "good|old";
51
+
52
/*
53
* Check whether the string `term` belongs to the set of strings
54
* included in the variable arguments.
267
return 0;
268
}
269
270
+static int mark_good(const char *refname, const struct object_id *oid,
271
+ int flag, void *cb_data)
272
+{
273
+ int *m_good = (int *)cb_data;
274
+ *m_good = 0;
275
+ return 1;
276
+}
277
+
278
+static const char *need_bad_and_good_revision_warning =
279
+ N_("You need to give me at least one %s and %s revision.\n"
280
+ "You can use \"git bisect %s\" and \"git bisect %s\" for that.");
281
+
282
+static const char *need_bisect_start_warning =
283
+ N_("You need to start by \"git bisect start\".\n"
284
+ "You then need to give me at least one %s and %s revision.\n"
285
+ "You can use \"git bisect %s\" and \"git bisect %s\" for that.");
286
+
287
+static int bisect_next_check(const struct bisect_terms *terms,
288
+ const char *current_term)
289
+{
290
+ int missing_good = 1, missing_bad = 1, retval = 0;
291
+ const char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
292
+ const char *good_glob = xstrfmt("%s-*", terms->term_good);
293
+
294
+ if (ref_exists(bad_ref))
295
+ missing_bad = 0;
296
+
297
+ for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
298
+ (void *) &missing_good);
299
+
300
+ if (!missing_good && !missing_bad)
301
+ goto finish;
302
+
303
+ if (!current_term) {
304
+ retval = -1;
305
+ goto finish;
306
+ }
307
+
308
+ if (missing_good && !missing_bad &&
309
+ !strcmp(current_term, terms->term_good)) {
310
+ char *yesno;
311
+ /*
312
+ * have bad (or new) but not good (or old). We could bisect
313
+ * although this is less optimum.
314
+ */
315
+ warning(_("bisecting only with a %s commit"), terms->term_bad);
316
+ if (!isatty(0))
317
+ goto finish;
318
+ /*
319
+ * TRANSLATORS: Make sure to include [Y] and [n] in your
320
+ * translation. The program will only accept English input
321
+ * at this point.
322
+ */
323
+ yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
324
+ if (starts_with(yesno, "N") || starts_with(yesno, "n"))
325
+ retval = -1;
326
+ goto finish;
327
+ }
328
+ if (!is_empty_or_missing_file(git_path_bisect_start())) {
329
+ retval = error(_(need_bad_and_good_revision_warning),
330
+ vocab_bad, vocab_good, vocab_bad, vocab_good);
331
+ } else {
332
+ retval = error(_(need_bisect_start_warning),
333
+ vocab_good, vocab_bad, vocab_good, vocab_bad);
334
+ }
335
+
336
+finish:
337
+ free((void *) good_glob);
338
+ free((void *) bad_ref);
339
+ return retval;
340
+}
341
+
342
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
343
{
344
enum {
348
CHECK_EXPECTED_REVS,
349
BISECT_RESET,
350
BISECT_WRITE,
274
- CHECK_AND_SET_TERMS
351
+ CHECK_AND_SET_TERMS,
352
+ BISECT_NEXT_CHECK
353
} cmdmode = 0;
354
int no_checkout = 0, res = 0, nolog = 0;
355
struct option options[] = {
367
N_("write out the bisection state in BISECT_LOG"), BISECT_WRITE),
368
OPT_CMDMODE(0, "check-and-set-terms", &cmdmode,
369
N_("check and set terms in a bisection state"), CHECK_AND_SET_TERMS),
370
+ OPT_CMDMODE(0, "bisect-next-check", &cmdmode,
371
+ N_("check whether bad or good terms exist"), BISECT_NEXT_CHECK),
372
OPT_BOOL(0, "no-checkout", &no_checkout,
373
N_("update BISECT_HEAD instead of checking out the current commit")),
374
OPT_BOOL(0, "no-log", &nolog,
413
set_terms(&terms, argv[2], argv[1]);
414
res = check_and_set_terms(&terms, argv[0]);
415
break;
416
+ case BISECT_NEXT_CHECK:
417
+ if (argc != 2 && argc != 3)
418
+ return error(_("--bisect-next-check requires 2 or 3 arguments"));
419
+ set_terms(&terms, argv[1], argv[0]);
420
+ res = bisect_next_check(&terms, argc == 3 ? argv[2] : NULL);
421
+ break;
422
default:
423
return error("BUG: unknown subcommand '%d'", cmdmode);
424
}