Skip to content

Commit 0cf1def

Browse files
cdowngitster
authored andcommitted
bisect: output state before we are ready to compute bisection
Commit 73c6de0 ("bisect: don't use invalid oid as rev when starting") changes the behaviour of `git bisect` to consider invalid oids as pathspecs again, as in the old shell implementation. While that behaviour may be desirable, it can also cause confusion. For example, while bisecting in a particular repo I encountered this: $ git bisect start d93ff48803f0 v6.3 $ ...which led to me sitting for a few moments, wondering why there's no printout stating the first rev to check. It turns out that the tag was actually "6.3", not "v6.3", and thus the bisect was still silently started with only a bad rev, because d93ff48803f0 was a valid oid and "v6.3" was silently considered to be a pathspec. While this behaviour may be desirable, it can be confusing, especially with different repo conventions either using or not using "v" before release names, or when a branch name or tag is simply misspelled on the command line. In order to avoid situations like this, make it more clear what we're waiting for: $ git bisect start d93ff48803f0 v6.3 status: waiting for good commit(s), bad commit known We already have good output once the bisect process has begun in earnest, so we don't need to do anything more there. Signed-off-by: Chris Down <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e54793a commit 0cf1def

File tree

3 files changed

+67
-13
lines changed

3 files changed

+67
-13
lines changed

bisect.h

+9
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ enum bisect_error {
6262
BISECT_INTERNAL_SUCCESS_MERGE_BASE = -11
6363
};
6464

65+
/*
66+
* Stores how many good/bad commits we have stored for a bisect. nr_bad can
67+
* only be 0 or 1.
68+
*/
69+
struct bisect_state {
70+
unsigned int nr_good;
71+
unsigned int nr_bad;
72+
};
73+
6574
enum bisect_error bisect_next_all(struct repository *r, const char *prefix);
6675

6776
int estimate_bisect_steps(int all);

builtin/bisect--helper.c

+40-13
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,12 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
329329
return 0;
330330
}
331331

332-
static int mark_good(const char *refname, const struct object_id *oid,
333-
int flag, void *cb_data)
332+
static int inc_nr(const char *refname, const struct object_id *oid,
333+
int flag, void *cb_data)
334334
{
335-
int *m_good = (int *)cb_data;
336-
*m_good = 0;
337-
return 1;
335+
unsigned int *nr = (unsigned int *)cb_data;
336+
(*nr)++;
337+
return 0;
338338
}
339339

340340
static const char need_bad_and_good_revision_warning[] =
@@ -384,23 +384,48 @@ static int decide_next(const struct bisect_terms *terms,
384384
vocab_good, vocab_bad, vocab_good, vocab_bad);
385385
}
386386

387-
static int bisect_next_check(const struct bisect_terms *terms,
388-
const char *current_term)
387+
static void bisect_status(struct bisect_state *state,
388+
const struct bisect_terms *terms)
389389
{
390-
int missing_good = 1, missing_bad = 1;
391390
char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
392391
char *good_glob = xstrfmt("%s-*", terms->term_good);
393392

394393
if (ref_exists(bad_ref))
395-
missing_bad = 0;
394+
state->nr_bad = 1;
396395

397-
for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
398-
(void *) &missing_good);
396+
for_each_glob_ref_in(inc_nr, good_glob, "refs/bisect/",
397+
(void *) &state->nr_good);
399398

400399
free(good_glob);
401400
free(bad_ref);
401+
}
402+
403+
static void bisect_print_status(const struct bisect_terms *terms)
404+
{
405+
struct bisect_state state = { 0 };
406+
407+
bisect_status(&state, terms);
408+
409+
/* If we had both, we'd already be started, and shouldn't get here. */
410+
if (state.nr_good && state.nr_bad)
411+
return;
402412

403-
return decide_next(terms, current_term, missing_good, missing_bad);
413+
if (!state.nr_good && !state.nr_bad)
414+
printf(_("status: waiting for both good and bad commits\n"));
415+
else if (state.nr_good)
416+
printf(Q_("status: waiting for bad commit, %d good commit known\n",
417+
"status: waiting for bad commit, %d good commits known\n",
418+
state.nr_good), state.nr_good);
419+
else
420+
printf(_("status: waiting for good commit(s), bad commit known\n"));
421+
}
422+
423+
static int bisect_next_check(const struct bisect_terms *terms,
424+
const char *current_term)
425+
{
426+
struct bisect_state state = { 0 };
427+
bisect_status(&state, terms);
428+
return decide_next(terms, current_term, !state.nr_good, !state.nr_bad);
404429
}
405430

406431
static int get_terms(struct bisect_terms *terms)
@@ -606,8 +631,10 @@ static enum bisect_error bisect_next(struct bisect_terms *terms, const char *pre
606631

607632
static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char *prefix)
608633
{
609-
if (bisect_next_check(terms, NULL))
634+
if (bisect_next_check(terms, NULL)) {
635+
bisect_print_status(terms);
610636
return BISECT_OK;
637+
}
611638

612639
return bisect_next(terms, prefix);
613640
}

t/t6030-bisect-porcelain.sh

+18
Original file line numberDiff line numberDiff line change
@@ -1025,4 +1025,22 @@ test_expect_success 'bisect visualize with a filename with dash and space' '
10251025
git bisect visualize -p -- "-hello 2"
10261026
'
10271027

1028+
test_expect_success 'bisect state output with multiple good commits' '
1029+
git bisect reset &&
1030+
git bisect start >output &&
1031+
grep "waiting for both good and bad commits" output &&
1032+
git bisect good "$HASH1" >output &&
1033+
grep "waiting for bad commit, 1 good commit known" output &&
1034+
git bisect good "$HASH2" >output &&
1035+
grep "waiting for bad commit, 2 good commits known" output
1036+
'
1037+
1038+
test_expect_success 'bisect state output with bad commit' '
1039+
git bisect reset &&
1040+
git bisect start >output &&
1041+
grep "waiting for both good and bad commits" output &&
1042+
git bisect bad "$HASH4" >output &&
1043+
grep -F "waiting for good commit(s), bad commit known" output
1044+
'
1045+
10281046
test_done

0 commit comments

Comments
 (0)