aboutsummaryrefslogtreecommitdiffstats
path: root/bisect.c
diff options
context:
space:
mode:
Diffstat (limited to 'bisect.c')
-rw-r--r--bisect.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/bisect.c b/bisect.c
index 9e6a2b7f20..ec7487e683 100644
--- a/bisect.c
+++ b/bisect.c
@@ -22,8 +22,6 @@ static struct oid_array skipped_revs;
static struct object_id *current_bad_oid;
-static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
-
static const char *term_bad;
static const char *term_good;
@@ -441,7 +439,7 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
}
static int register_ref(const char *refname, const struct object_id *oid,
- int flags, void *cb_data)
+ int flags UNUSED, void *cb_data UNUSED)
{
struct strbuf good_prefix = STRBUF_INIT;
strbuf_addstr(&good_prefix, term_good);
@@ -648,11 +646,14 @@ static struct commit_list *managed_skipped(struct commit_list *list,
}
static void bisect_rev_setup(struct repository *r, struct rev_info *revs,
+ struct strvec *rev_argv,
const char *prefix,
const char *bad_format, const char *good_format,
int read_paths)
{
- struct strvec rev_argv = STRVEC_INIT;
+ struct setup_revision_opt opt = {
+ .free_removed_argv_elements = 1,
+ };
int i;
repo_init_revisions(r, revs, prefix);
@@ -660,17 +661,16 @@ static void bisect_rev_setup(struct repository *r, struct rev_info *revs,
revs->commit_format = CMIT_FMT_UNSPECIFIED;
/* rev_argv.argv[0] will be ignored by setup_revisions */
- strvec_push(&rev_argv, "bisect_rev_setup");
- strvec_pushf(&rev_argv, bad_format, oid_to_hex(current_bad_oid));
+ strvec_push(rev_argv, "bisect_rev_setup");
+ strvec_pushf(rev_argv, bad_format, oid_to_hex(current_bad_oid));
for (i = 0; i < good_revs.nr; i++)
- strvec_pushf(&rev_argv, good_format,
+ strvec_pushf(rev_argv, good_format,
oid_to_hex(good_revs.oid + i));
- strvec_push(&rev_argv, "--");
+ strvec_push(rev_argv, "--");
if (read_paths)
- read_bisect_paths(&rev_argv);
+ read_bisect_paths(rev_argv);
- setup_revisions(rev_argv.nr, rev_argv.v, revs, NULL);
- /* XXX leak rev_argv, as "revs" may still be pointing to it */
+ setup_revisions(rev_argv->nr, rev_argv->v, revs, &opt);
}
static void bisect_common(struct rev_info *revs)
@@ -727,20 +727,22 @@ static int is_expected_rev(const struct object_id *oid)
enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
int no_checkout)
{
- char bisect_rev_hex[GIT_MAX_HEXSZ + 1];
struct commit *commit;
struct pretty_print_context pp = {0};
struct strbuf commit_msg = STRBUF_INIT;
- oid_to_hex_r(bisect_rev_hex, bisect_rev);
update_ref(NULL, "BISECT_EXPECTED_REV", bisect_rev, NULL, 0, UPDATE_REFS_DIE_ON_ERR);
- argv_checkout[2] = bisect_rev_hex;
if (no_checkout) {
update_ref(NULL, "BISECT_HEAD", bisect_rev, NULL, 0,
UPDATE_REFS_DIE_ON_ERR);
} else {
- if (run_command_v_opt(argv_checkout, RUN_GIT_CMD))
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ cmd.git_cmd = 1;
+ strvec_pushl(&cmd.args, "checkout", "-q",
+ oid_to_hex(bisect_rev), "--", NULL);
+ if (run_command(&cmd))
/*
* Errors in `run_command()` itself, signaled by res < 0,
* and errors in the child process, signaled by res > 0
@@ -873,10 +875,11 @@ static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int
static int check_ancestors(struct repository *r, int rev_nr,
struct commit **rev, const char *prefix)
{
+ struct strvec rev_argv = STRVEC_INIT;
struct rev_info revs;
int res;
- bisect_rev_setup(r, &revs, prefix, "^%s", "%s", 0);
+ bisect_rev_setup(r, &revs, &rev_argv, prefix, "^%s", "%s", 0);
bisect_common(&revs);
res = (revs.commits != NULL);
@@ -884,6 +887,8 @@ static int check_ancestors(struct repository *r, int rev_nr,
/* Clean up objects used, as they will be reused. */
clear_commit_marks_many(rev_nr, rev, ALL_REV_FLAGS);
+ release_revisions(&revs);
+ strvec_clear(&rev_argv);
return res;
}
@@ -964,6 +969,7 @@ static void show_diff_tree(struct repository *r,
setup_revisions(ARRAY_SIZE(argv) - 1, argv, &opt, NULL);
log_tree_commit(&opt, commit);
+ release_revisions(&opt);
}
/*
@@ -1008,7 +1014,8 @@ void read_bisect_terms(const char **read_bad, const char **read_good)
*/
enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
{
- struct rev_info revs;
+ struct strvec rev_argv = STRVEC_INIT;
+ struct rev_info revs = REV_INFO_INIT;
struct commit_list *tried;
int reaches = 0, all = 0, nr, steps;
enum bisect_error res = BISECT_OK;
@@ -1033,9 +1040,9 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
res = check_good_are_ancestors_of_bad(r, prefix, no_checkout);
if (res)
- return res;
+ goto cleanup;
- bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1);
+ bisect_rev_setup(r, &revs, &rev_argv, prefix, "%s", "^%s", 1);
revs.first_parent_only = !!(bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY);
revs.limited = 1;
@@ -1052,20 +1059,22 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
*/
res = error_if_skipped_commits(tried, NULL);
if (res < 0)
- return res;
+ goto cleanup;
printf(_("%s was both %s and %s\n"),
oid_to_hex(current_bad_oid),
term_good,
term_bad);
- return BISECT_FAILED;
+ res = BISECT_FAILED;
+ goto cleanup;
}
if (!all) {
fprintf(stderr, _("No testable commit found.\n"
"Maybe you started with bad path arguments?\n"));
- return BISECT_NO_TESTABLE_COMMIT;
+ res = BISECT_NO_TESTABLE_COMMIT;
+ goto cleanup;
}
bisect_rev = &revs.commits->item->object.oid;
@@ -1085,7 +1094,8 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
* for negative return values for early returns up
* until the cmd_bisect__helper() caller.
*/
- return BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND;
+ res = BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND;
+ goto cleanup;
}
nr = all - reaches - 1;
@@ -1104,7 +1114,11 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
/* Clean up objects used, as they will be reused. */
repo_clear_commit_marks(r, ALL_REV_FLAGS);
- return bisect_checkout(bisect_rev, no_checkout);
+ res = bisect_checkout(bisect_rev, no_checkout);
+cleanup:
+ release_revisions(&revs);
+ strvec_clear(&rev_argv);
+ return res;
}
static inline int log2i(int n)
@@ -1146,8 +1160,9 @@ int estimate_bisect_steps(int all)
return (e < 3 * x) ? n : n - 1;
}
-static int mark_for_removal(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+static int mark_for_removal(const char *refname,
+ const struct object_id *oid UNUSED,
+ int flag UNUSED, void *cb_data)
{
struct string_list *refs = cb_data;
char *ref = xstrfmt("refs/bisect%s", refname);