6
6
#include "dir.h"
7
7
#include "argv-array.h"
8
8
#include "run-command.h"
9
+ #include "prompt.h"
9
10
10
11
static GIT_PATH_FUNC (git_path_bisect_terms , "BISECT_TERMS ")
11
12
static GIT_PATH_FUNC (git_path_bisect_expected_rev , "BISECT_EXPECTED_REV ")
@@ -21,6 +22,7 @@ static const char * const git_bisect_helper_usage[] = {
21
22
N_ ("git bisect--helper --bisect-reset [<commit>]" ),
22
23
N_ ("git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>" ),
23
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>]" ),
24
26
NULL
25
27
};
26
28
@@ -44,6 +46,9 @@ static void set_terms(struct bisect_terms *terms, const char *bad,
44
46
terms -> term_bad = xstrdup (bad );
45
47
}
46
48
49
+ static const char * vocab_bad = "bad|new" ;
50
+ static const char * vocab_good = "good|old" ;
51
+
47
52
/*
48
53
* Check whether the string `term` belongs to the set of strings
49
54
* included in the variable arguments.
@@ -262,6 +267,78 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
262
267
return 0 ;
263
268
}
264
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
+
265
342
int cmd_bisect__helper (int argc , const char * * argv , const char * prefix )
266
343
{
267
344
enum {
@@ -271,7 +348,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
271
348
CHECK_EXPECTED_REVS ,
272
349
BISECT_RESET ,
273
350
BISECT_WRITE ,
274
- CHECK_AND_SET_TERMS
351
+ CHECK_AND_SET_TERMS ,
352
+ BISECT_NEXT_CHECK
275
353
} cmdmode = 0 ;
276
354
int no_checkout = 0 , res = 0 , nolog = 0 ;
277
355
struct option options [] = {
@@ -289,6 +367,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
289
367
N_ ("write out the bisection state in BISECT_LOG" ), BISECT_WRITE ),
290
368
OPT_CMDMODE (0 , "check-and-set-terms" , & cmdmode ,
291
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 ),
292
372
OPT_BOOL (0 , "no-checkout" , & no_checkout ,
293
373
N_ ("update BISECT_HEAD instead of checking out the current commit" )),
294
374
OPT_BOOL (0 , "no-log" , & nolog ,
@@ -333,6 +413,12 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
333
413
set_terms (& terms , argv [2 ], argv [1 ]);
334
414
res = check_and_set_terms (& terms , argv [0 ]);
335
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 ;
336
422
default :
337
423
return error ("BUG: unknown subcommand '%d'" , cmdmode );
338
424
}
0 commit comments