Skip to content

Commit

Permalink
bisect: consistently write BISECT_EXPECTED_REV via the refdb
Browse files Browse the repository at this point in the history
We're inconsistently writing BISECT_EXPECTED_REV both via the filesystem
and via the refdb, which violates the newly established rules for how
special refs must be treated. This works alright in practice with the
reffiles reference backend, but will cause bugs once we gain additional
backends.

Fix this issue and consistently write BISECT_EXPECTED_REV via the refdb
so that it is no longer a special ref.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
pks-t authored and gitster committed Dec 14, 2023
1 parent 70c70de commit 0a06892
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 29 deletions.
25 changes: 4 additions & 21 deletions bisect.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,6 @@ static int read_bisect_refs(void)
}

static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")
static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
Expand Down Expand Up @@ -707,26 +706,10 @@ static enum bisect_error error_if_skipped_commits(struct commit_list *tried,

static int is_expected_rev(const struct object_id *oid)
{
const char *filename = git_path_bisect_expected_rev();
struct stat st;
struct strbuf str = STRBUF_INIT;
FILE *fp;
int res = 0;

if (stat(filename, &st) || !S_ISREG(st.st_mode))
struct object_id expected_oid;
if (read_ref("BISECT_EXPECTED_REV", &expected_oid))
return 0;

fp = fopen_or_warn(filename, "r");
if (!fp)
return 0;

if (strbuf_getline_lf(&str, fp) != EOF)
res = !strcmp(str.buf, oid_to_hex(oid));

strbuf_release(&str);
fclose(fp);

return res;
return oideq(oid, &expected_oid);
}

enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
Expand Down Expand Up @@ -1185,10 +1168,10 @@ int bisect_clean_state(void)
struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;
for_each_ref_in("refs/bisect", mark_for_removal, (void *) &refs_for_removal);
string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));
string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV"));
result = delete_refs("bisect: remove", &refs_for_removal, REF_NO_DEREF);
refs_for_removal.strdup_strings = 1;
string_list_clear(&refs_for_removal, 0);
unlink_or_warn(git_path_bisect_expected_rev());
unlink_or_warn(git_path_bisect_ancestors_ok());
unlink_or_warn(git_path_bisect_log());
unlink_or_warn(git_path_bisect_names());
Expand Down
8 changes: 2 additions & 6 deletions builtin/bisect.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "revision.h"

static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")
Expand Down Expand Up @@ -921,7 +920,6 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
const char *state;
int i, verify_expected = 1;
struct object_id oid, expected;
struct strbuf buf = STRBUF_INIT;
struct oid_array revs = OID_ARRAY_INIT;

if (!argc)
Expand Down Expand Up @@ -976,10 +974,8 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
oid_array_append(&revs, &commit->object.oid);
}

if (strbuf_read_file(&buf, git_path_bisect_expected_rev(), 0) < the_hash_algo->hexsz ||
get_oid_hex(buf.buf, &expected) < 0)
if (read_ref("BISECT_EXPECTED_REV", &expected))
verify_expected = 0; /* Ignore invalid file contents */
strbuf_release(&buf);

for (i = 0; i < revs.nr; i++) {
if (bisect_write(state, oid_to_hex(&revs.oid[i]), terms, 0)) {
Expand All @@ -988,7 +984,7 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
}
if (verify_expected && !oideq(&revs.oid[i], &expected)) {
unlink_or_warn(git_path_bisect_ancestors_ok());
unlink_or_warn(git_path_bisect_expected_rev());
delete_ref(NULL, "BISECT_EXPECTED_REV", NULL, REF_NO_DEREF);
verify_expected = 0;
}
}
Expand Down
3 changes: 2 additions & 1 deletion refs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,8 @@ static int is_special_ref(const char *refname)
* There are some exceptions that you might expect to see on this list
* but which are handled exclusively via the reference backend:
*
* - BISECT_EXPECTED_REV
*
* - CHERRY_PICK_HEAD
*
* - HEAD
Expand All @@ -1857,7 +1859,6 @@ static int is_special_ref(const char *refname)
*/
static const char * const special_refs[] = {
"AUTO_MERGE",
"BISECT_EXPECTED_REV",
"FETCH_HEAD",
"MERGE_AUTOSTASH",
"MERGE_HEAD",
Expand Down
2 changes: 1 addition & 1 deletion t/t6030-bisect-porcelain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@ test_expect_success 'git bisect reset cleans bisection state properly' '
git bisect bad $HASH4 &&
git bisect reset &&
test -z "$(git for-each-ref "refs/bisect/*")" &&
test_path_is_missing ".git/BISECT_EXPECTED_REV" &&
test_ref_missing BISECT_EXPECTED_REV &&
test_path_is_missing ".git/BISECT_ANCESTORS_OK" &&
test_path_is_missing ".git/BISECT_LOG" &&
test_path_is_missing ".git/BISECT_RUN" &&
Expand Down

0 comments on commit 0a06892

Please sign in to comment.