diff --git a/builtin/bisect.c b/builtin/bisect.c index e7c2d2f3bb0f4a..dccf0be6bbb1d8 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -663,6 +663,11 @@ static int bisect_successful(struct bisect_terms *terms) refs_read_ref(get_main_ref_store(the_repository), bad_ref, &oid); commit = lookup_commit_reference_by_name(bad_ref); + if (!commit) { + error(_("could not find commit for '%s'"), bad_ref); + free(bad_ref); + return BISECT_FAILED; + } repo_format_commit_message(the_repository, commit, "%s", &commit_name, &pp); @@ -806,9 +811,11 @@ static enum bisect_error bisect_start(struct bisect_terms *terms, int argc, */ head = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), "HEAD", 0, &head_oid, &flags); - if (!head) + if (!head) { if (repo_get_oid(the_repository, "HEAD", &head_oid)) return error(_("bad HEAD - I need a HEAD")); + head = "HEAD"; + } /* * Check if we are bisecting diff --git a/builtin/diff.c b/builtin/diff.c index 4b46e394cecb8d..18b1083e984a35 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -579,9 +579,13 @@ int cmd_diff(int argc, obj = deref_tag(the_repository, obj, NULL, 0); if (!obj) die(_("invalid object '%s' given."), name); - if (obj->type == OBJ_COMMIT) - obj = &repo_get_commit_tree(the_repository, - ((struct commit *)obj))->object; + if (obj->type == OBJ_COMMIT) { + struct tree *tree = repo_get_commit_tree( + the_repository, (struct commit *)obj); + if (!tree) + die(_("unable to read tree object for commit '%s'"), name); + obj = &tree->object; + } if (obj->type == OBJ_TREE) { if (sdiff.skip && bitmap_get(sdiff.skip, i)) diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c index 264df6259a0411..0993418e630dec 100644 --- a/builtin/mailsplit.c +++ b/builtin/mailsplit.c @@ -225,14 +225,14 @@ static int split_mbox(const char *file, const char *dir, int allow_bare, FILE *f = !strcmp(file, "-") ? stdin : fopen(file, "r"); int file_done = 0; - if (isatty(fileno(f))) - warning(_("reading patches from stdin/tty...")); - if (!f) { error_errno("cannot open mbox %s", file); goto out; } + if (isatty(fileno(f))) + warning(_("reading patches from stdin/tty...")); + do { peek = fgetc(f); if (peek == EOF) { diff --git a/diffcore-break.c b/diffcore-break.c index 17b5ad1fedeb3b..b5bcc956ccb831 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -289,6 +289,8 @@ void diffcore_merge_broken(void) */ for (j = i + 1; j < q->nr; j++) { struct diff_filepair *pp = q->queue[j]; + if (!pp) + continue; if (pp->broken_pair && !strcmp(pp->one->path, pp->two->path) && !strcmp(p->one->path, pp->two->path)) { diff --git a/pack-bitmap.c b/pack-bitmap.c index e8a82945cc319e..ca7998c10b4876 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -523,6 +523,10 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, if (midx->base_midx) { bitmap_git->base = prepare_midx_bitmap_git(midx->base_midx); + if (!bitmap_git->base) { + warning(_("could not open bitmap for base MIDX")); + goto cleanup; + } bitmap_git->base_nr = bitmap_git->base->base_nr + 1; } else { bitmap_git->base_nr = 0; diff --git a/reftable/stack.c b/reftable/stack.c index 1fba96ddb3366f..3fc3c0b2d1e9c4 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -171,7 +171,8 @@ void reftable_stack_destroy(struct reftable_stack *st) st->merged = NULL; } - err = read_lines(st->list_file, &names); + if (st->list_file) + err = read_lines(st->list_file, &names); if (err < 0) { REFTABLE_FREE_AND_NULL(names); } diff --git a/remote.c b/remote.c index 00723b385e1d52..887e388f9cac68 100644 --- a/remote.c +++ b/remote.c @@ -2681,6 +2681,8 @@ static int remote_tracking(struct remote *remote, const char *refname, { char *dst; + if (!remote) + BUG("remote_tracking() called with NULL remote"); dst = apply_refspecs(&remote->fetch, refname); if (!dst) return -1; /* no tracking ref for refname at remote */ diff --git a/replay.c b/replay.c index da531d5bc68add..b38cd5efe49c50 100644 --- a/replay.c +++ b/replay.c @@ -36,12 +36,16 @@ static struct commit *peel_committish(struct repository *repo, { struct object *obj; struct object_id oid; + struct commit *commit; if (repo_get_oid(repo, name, &oid)) die(_("'%s' is not a valid commit-ish for %s"), name, mode); obj = parse_object_or_die(repo, &oid, name); - return (struct commit *)repo_peel_to_type(repo, name, 0, obj, - OBJ_COMMIT); + commit = (struct commit *)repo_peel_to_type(repo, name, 0, obj, + OBJ_COMMIT); + if (!commit) + die(_("'%s' does not point to a commit for %s"), name, mode); + return commit; } static char *get_author(const char *message) diff --git a/revision.c b/revision.c index e91d7e1f11356a..7f3999b5510b07 100644 --- a/revision.c +++ b/revision.c @@ -1903,8 +1903,13 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags, return 0; while (1) { it = get_reference(revs, arg, &oid, 0); - if (!it && revs->ignore_missing) - return 0; + if (!it) { + if (revs->ignore_missing) + return 0; + if (revs->do_not_die_on_missing_objects) + return 0; + return -1; + } if (it->type != OBJ_TAG) break; if (!((struct tag*)it)->tagged) diff --git a/shallow.c b/shallow.c index 07cae44ae52a04..c567cc3c69fe4c 100644 --- a/shallow.c +++ b/shallow.c @@ -359,7 +359,9 @@ struct write_shallow_data { static int write_one_shallow(const struct commit_graft *graft, void *cb_data) { struct write_shallow_data *data = cb_data; - const char *hex = oid_to_hex(&graft->oid); + char hex[GIT_MAX_HEXSZ + 1]; + + oid_to_hex_r(hex, &graft->oid); if (graft->nr_parent != -1) return 0; if (data->flags & QUICK) { @@ -370,8 +372,7 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data) struct commit *c = lookup_commit(the_repository, &graft->oid); if (!c || !(c->object.flags & SEEN)) { if (data->flags & VERBOSE) - printf("Removing %s from .git/shallow\n", - oid_to_hex(&c->object.oid)); + printf("Removing %s from .git/shallow\n", hex); return 0; } } diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index dff442da2090b5..cc070019bee9fa 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -489,6 +489,24 @@ test_expect_success 'rev-list dies for missing objects on cmd line' ' done ' +test_expect_success '--exclude-promisor-objects with ^@ on missing object' ' + rm -rf repo && + test_create_repo repo && + test_commit -C repo foo && + test_commit -C repo bar && + + COMMIT=$(git -C repo rev-parse foo) && + promise_and_delete "$COMMIT" && + + git -C repo config core.repositoryformatversion 1 && + git -C repo config extensions.partialclone "arbitrary string" && + + # Ensure that "$COMMIT^@" is handled gracefully even though the + # actual commits are missing. + git -C repo rev-list --exclude-promisor-objects "$COMMIT^@" >out && + test_must_be_empty out +' + test_expect_success 'single promisor remote can be re-initialized gracefully' ' # ensure one promisor is in the promisors list rm -rf repo &&