summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bisect.h9
-rw-r--r--builtin/bisect--helper.c53
-rwxr-xr-xt/t6030-bisect-porcelain.sh18
3 files changed, 67 insertions, 13 deletions
diff --git a/bisect.h b/bisect.h
index 1015aeb8ea..ee3fd65f3b 100644
--- a/bisect.h
+++ b/bisect.h
@@ -62,6 +62,15 @@ enum bisect_error {
BISECT_INTERNAL_SUCCESS_MERGE_BASE = -11
};
+/*
+ * Stores how many good/bad commits we have stored for a bisect. nr_bad can
+ * only be 0 or 1.
+ */
+struct bisect_state {
+ unsigned int nr_good;
+ unsigned int nr_bad;
+};
+
enum bisect_error bisect_next_all(struct repository *r, const char *prefix);
int estimate_bisect_steps(int all);
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 8b2b259ff0..fa8024a864 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -329,12 +329,12 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
return 0;
}
-static int mark_good(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+static int inc_nr(const char *refname, const struct object_id *oid,
+ int flag, void *cb_data)
{
- int *m_good = (int *)cb_data;
- *m_good = 0;
- return 1;
+ unsigned int *nr = (unsigned int *)cb_data;
+ (*nr)++;
+ return 0;
}
static const char need_bad_and_good_revision_warning[] =
@@ -384,23 +384,48 @@ static int decide_next(const struct bisect_terms *terms,
vocab_good, vocab_bad, vocab_good, vocab_bad);
}
-static int bisect_next_check(const struct bisect_terms *terms,
- const char *current_term)
+static void bisect_status(struct bisect_state *state,
+ const struct bisect_terms *terms)
{
- int missing_good = 1, missing_bad = 1;
char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
char *good_glob = xstrfmt("%s-*", terms->term_good);
if (ref_exists(bad_ref))
- missing_bad = 0;
+ state->nr_bad = 1;
- for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
- (void *) &missing_good);
+ for_each_glob_ref_in(inc_nr, good_glob, "refs/bisect/",
+ (void *) &state->nr_good);
free(good_glob);
free(bad_ref);
+}
+
+static void bisect_print_status(const struct bisect_terms *terms)
+{
+ struct bisect_state state = { 0 };
+
+ bisect_status(&state, terms);
+
+ /* If we had both, we'd already be started, and shouldn't get here. */
+ if (state.nr_good && state.nr_bad)
+ return;
- return decide_next(terms, current_term, missing_good, missing_bad);
+ if (!state.nr_good && !state.nr_bad)
+ printf(_("status: waiting for both good and bad commits\n"));
+ else if (state.nr_good)
+ printf(Q_("status: waiting for bad commit, %d good commit known\n",
+ "status: waiting for bad commit, %d good commits known\n",
+ state.nr_good), state.nr_good);
+ else
+ printf(_("status: waiting for good commit(s), bad commit known\n"));
+}
+
+static int bisect_next_check(const struct bisect_terms *terms,
+ const char *current_term)
+{
+ struct bisect_state state = { 0 };
+ bisect_status(&state, terms);
+ return decide_next(terms, current_term, !state.nr_good, !state.nr_bad);
}
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
static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char *prefix)
{
- if (bisect_next_check(terms, NULL))
+ if (bisect_next_check(terms, NULL)) {
+ bisect_print_status(terms);
return BISECT_OK;
+ }
return bisect_next(terms, prefix);
}
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 5382e5d216..686f6d5c7f 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -1025,4 +1025,22 @@ test_expect_success 'bisect visualize with a filename with dash and space' '
git bisect visualize -p -- "-hello 2"
'
+test_expect_success 'bisect state output with multiple good commits' '
+ git bisect reset &&
+ git bisect start >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect good "$HASH1" >output &&
+ grep "waiting for bad commit, 1 good commit known" output &&
+ git bisect good "$HASH2" >output &&
+ grep "waiting for bad commit, 2 good commits known" output
+'
+
+test_expect_success 'bisect state output with bad commit' '
+ git bisect reset &&
+ git bisect start >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect bad "$HASH4" >output &&
+ grep -F "waiting for good commit(s), bad commit known" output
+'
+
test_done