diff options
| author | Junio C Hamano <gitster@pobox.com> | 2025-11-04 07:31:26 -0800 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-11-04 07:31:26 -0800 |
| commit | 8c6e6b27379b98269620f5f20397425ba358a1bb (patch) | |
| tree | f5c35ea7c977e5ee3df8a3cbfb4b29a732d66e1a | |
| parent | Revert "Merge branch 'kn/refs-optim-cleanup' into next" (diff) | |
| download | git-8c6e6b27379b98269620f5f20397425ba358a1bb.tar.gz git-8c6e6b27379b98269620f5f20397425ba358a1bb.zip | |
Revert "Merge branch 'ps/ref-peeled-tags' into next"
This reverts commit 8ac48a10de61267858d66383c34833e55a5e9d02, reversing
changes made to 9ab444edfb825dfbc555b3d7916df03071db94c3.
66 files changed, 834 insertions, 783 deletions
@@ -450,20 +450,21 @@ void find_bisection(struct commit_list **commit_list, int *reaches, clear_commit_weight(&commit_weight); } -static int register_ref(const struct reference *ref, void *cb_data UNUSED) +static int register_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flags UNUSED, void *cb_data UNUSED) { struct strbuf good_prefix = STRBUF_INIT; strbuf_addstr(&good_prefix, term_good); strbuf_addstr(&good_prefix, "-"); - if (!strcmp(ref->name, term_bad)) { + if (!strcmp(refname, term_bad)) { free(current_bad_oid); current_bad_oid = xmalloc(sizeof(*current_bad_oid)); - oidcpy(current_bad_oid, ref->oid); - } else if (starts_with(ref->name, good_prefix.buf)) { - oid_array_append(&good_revs, ref->oid); - } else if (starts_with(ref->name, "skip-")) { - oid_array_append(&skipped_revs, ref->oid); + oidcpy(current_bad_oid, oid); + } else if (starts_with(refname, good_prefix.buf)) { + oid_array_append(&good_revs, oid); + } else if (starts_with(refname, "skip-")) { + oid_array_append(&skipped_revs, oid); } strbuf_release(&good_prefix); @@ -1177,11 +1178,14 @@ int estimate_bisect_steps(int all) return (e < 3 * x) ? n : n - 1; } -static int mark_for_removal(const struct reference *ref, void *cb_data) +static int mark_for_removal(const char *refname, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flag UNUSED, void *cb_data) { struct string_list *refs = cb_data; - char *bisect_ref = xstrfmt("refs/bisect%s", ref->name); - string_list_append(refs, bisect_ref); + char *ref = xstrfmt("refs/bisect%s", refname); + string_list_append(refs, ref); return 0; } diff --git a/builtin/bisect.c b/builtin/bisect.c index 4cc118fb57..ccff4e1a1b 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -363,7 +363,10 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd) return 0; } -static int inc_nr(const struct reference *ref UNUSED, void *cb_data) +static int inc_nr(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flag UNUSED, void *cb_data) { unsigned int *nr = (unsigned int *)cb_data; (*nr)++; @@ -551,11 +554,12 @@ finish: return res; } -static int add_bisect_ref(const struct reference *ref, void *cb) +static int add_bisect_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flags UNUSED, void *cb) { struct add_bisect_ref_data *data = cb; - add_pending_oid(data->revs, ref->name, ref->oid, data->object_flags); + add_pending_oid(data->revs, refname, oid, data->object_flags); return 0; } @@ -1166,9 +1170,12 @@ static int bisect_visualize(struct bisect_terms *terms, int argc, return run_command(&cmd); } -static int get_first_good(const struct reference *ref, void *cb_data) +static int get_first_good(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, void *cb_data) { - oidcpy(cb_data, ref->oid); + oidcpy(cb_data, oid); return 1; } diff --git a/builtin/checkout.c b/builtin/checkout.c index 66b69df6e6..f9453473fe 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1063,9 +1063,11 @@ static void update_refs_for_switch(const struct checkout_opts *opts, report_tracking(new_branch_info); } -static int add_pending_uninteresting_ref(const struct reference *ref, void *cb_data) +static int add_pending_uninteresting_ref(const char *refname, const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, void *cb_data) { - add_pending_oid(cb_data, ref->name, ref->oid, UNINTERESTING); + add_pending_oid(cb_data, refname, oid, UNINTERESTING); return 0; } diff --git a/builtin/describe.c b/builtin/describe.c index 443546aaac..ffaf8d9f0a 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -154,19 +154,20 @@ static void add_to_known_names(const char *path, } } -static int get_name(const struct reference *ref, void *cb_data UNUSED) +static int get_name(const char *path, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { int is_tag = 0; struct object_id peeled; int is_annotated, prio; const char *path_to_match = NULL; - if (skip_prefix(ref->name, "refs/tags/", &path_to_match)) { + if (skip_prefix(path, "refs/tags/", &path_to_match)) { is_tag = 1; } else if (all) { if ((exclude_patterns.nr || patterns.nr) && - !skip_prefix(ref->name, "refs/heads/", &path_to_match) && - !skip_prefix(ref->name, "refs/remotes/", &path_to_match)) { + !skip_prefix(path, "refs/heads/", &path_to_match) && + !skip_prefix(path, "refs/remotes/", &path_to_match)) { /* Only accept reference of known type if there are match/exclude patterns */ return 0; } @@ -208,10 +209,10 @@ static int get_name(const struct reference *ref, void *cb_data UNUSED) } /* Is it annotated? */ - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) { - is_annotated = !oideq(ref->oid, &peeled); + if (!peel_iterated_oid(the_repository, oid, &peeled)) { + is_annotated = !oideq(oid, &peeled); } else { - oidcpy(&peeled, ref->oid); + oidcpy(&peeled, oid); is_annotated = 0; } @@ -228,8 +229,7 @@ static int get_name(const struct reference *ref, void *cb_data UNUSED) else prio = 0; - add_to_known_names(all ? ref->name + 5 : ref->name + 10, - &peeled, prio, ref->oid); + add_to_known_names(all ? path + 5 : path + 10, &peeled, prio, oid); return 0; } diff --git a/builtin/fetch.c b/builtin/fetch.c index 7052e6ff21..c7ff3480fb 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -289,11 +289,13 @@ static struct refname_hash_entry *refname_hash_add(struct hashmap *map, return ent; } -static int add_one_refname(const struct reference *ref, void *cbdata) +static int add_one_refname(const char *refname, const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, void *cbdata) { struct hashmap *refname_map = cbdata; - (void) refname_hash_add(refname_map, ref->name, ref->oid); + (void) refname_hash_add(refname_map, refname, oid); return 0; } @@ -1414,11 +1416,14 @@ static void set_option(struct transport *transport, const char *name, const char } -static int add_oid(const struct reference *ref, void *cb_data) +static int add_oid(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, void *cb_data) { struct oid_array *oids = cb_data; - oid_array_append(oids, ref->oid); + oid_array_append(oids, oid); return 0; } diff --git a/builtin/fsck.c b/builtin/fsck.c index c489582faa..b1a650c673 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -530,13 +530,14 @@ static int fsck_handle_reflog(const char *logname, void *cb_data) return 0; } -static int fsck_handle_ref(const struct reference *ref, void *cb_data UNUSED) +static int fsck_handle_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { struct object *obj; - obj = parse_object(the_repository, ref->oid); + obj = parse_object(the_repository, oid); if (!obj) { - if (is_promisor_object(the_repository, ref->oid)) { + if (is_promisor_object(the_repository, oid)) { /* * Increment default_refs anyway, because this is a * valid ref. @@ -545,19 +546,19 @@ static int fsck_handle_ref(const struct reference *ref, void *cb_data UNUSED) return 0; } error(_("%s: invalid sha1 pointer %s"), - ref->name, oid_to_hex(ref->oid)); + refname, oid_to_hex(oid)); errors_found |= ERROR_REACHABLE; /* We'll continue with the rest despite the error.. */ return 0; } - if (obj->type != OBJ_COMMIT && is_branch(ref->name)) { - error(_("%s: not a commit"), ref->name); + if (obj->type != OBJ_COMMIT && is_branch(refname)) { + error(_("%s: not a commit"), refname); errors_found |= ERROR_REFS; } default_refs++; obj->flags |= USED; fsck_put_object_name(&fsck_walk_options, - ref->oid, "%s", ref->name); + oid, "%s", refname); mark_object_reachable(obj); return 0; @@ -579,19 +580,13 @@ static void get_default_heads(void) worktrees = get_worktrees(); for (p = worktrees; *p; p++) { struct worktree *wt = *p; - struct strbuf refname = STRBUF_INIT; + struct strbuf ref = STRBUF_INIT; - strbuf_worktree_ref(wt, &refname, "HEAD"); - fsck_head_link(refname.buf, &head_points_at, &head_oid); - if (head_points_at && !is_null_oid(&head_oid)) { - struct reference ref = { - .name = refname.buf, - .oid = &head_oid, - }; - - fsck_handle_ref(&ref, NULL); - } - strbuf_release(&refname); + strbuf_worktree_ref(wt, &ref, "HEAD"); + fsck_head_link(ref.buf, &head_points_at, &head_oid); + if (head_points_at && !is_null_oid(&head_oid)) + fsck_handle_ref(ref.buf, NULL, &head_oid, 0, NULL); + strbuf_release(&ref); if (include_reflogs) refs_for_each_reflog(get_worktree_ref_store(wt), diff --git a/builtin/gc.c b/builtin/gc.c index aad1496f07..d212cbb9b8 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1103,21 +1103,24 @@ struct cg_auto_data { int limit; }; -static int dfs_on_ref(const struct reference *ref, void *cb_data) +static int dfs_on_ref(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, + void *cb_data) { struct cg_auto_data *data = (struct cg_auto_data *)cb_data; int result = 0; - const struct object_id *maybe_peeled = ref->oid; struct object_id peeled; struct commit_list *stack = NULL; struct commit *commit; - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) - maybe_peeled = &peeled; - if (odb_read_object_info(the_repository->objects, maybe_peeled, NULL) != OBJ_COMMIT) + if (!peel_iterated_oid(the_repository, oid, &peeled)) + oid = &peeled; + if (odb_read_object_info(the_repository->objects, oid, NULL) != OBJ_COMMIT) return 0; - commit = lookup_commit(the_repository, maybe_peeled); + commit = lookup_commit(the_repository, oid); if (!commit) return 0; if (repo_parse_commit(the_repository, commit) || diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index fe77829557..df09000b30 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -156,7 +156,7 @@ int cmd_ls_remote(int argc, continue; if (!tail_match(&pattern, ref->name)) continue; - item = ref_array_push(&ref_array, ref->name, &ref->old_oid, NULL); + item = ref_array_push(&ref_array, ref->name, &ref->old_oid); item->symref = xstrdup_or_null(ref->symref); } diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 615f7d1aae..74512e54a3 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -339,9 +339,10 @@ static int cmp_by_tag_and_age(const void *a_, const void *b_) return a->taggerdate != b->taggerdate; } -static int name_ref(const struct reference *ref, void *cb_data) +static int name_ref(const char *path, const char *referent UNUSED, const struct object_id *oid, + int flags UNUSED, void *cb_data) { - struct object *o = parse_object(the_repository, ref->oid); + struct object *o = parse_object(the_repository, oid); struct name_ref_data *data = cb_data; int can_abbreviate_output = data->tags_only && data->name_only; int deref = 0; @@ -349,14 +350,14 @@ static int name_ref(const struct reference *ref, void *cb_data) struct commit *commit = NULL; timestamp_t taggerdate = TIME_MAX; - if (data->tags_only && !starts_with(ref->name, "refs/tags/")) + if (data->tags_only && !starts_with(path, "refs/tags/")) return 0; if (data->exclude_filters.nr) { struct string_list_item *item; for_each_string_list_item(item, &data->exclude_filters) { - if (subpath_matches(ref->name, item->string) >= 0) + if (subpath_matches(path, item->string) >= 0) return 0; } } @@ -377,7 +378,7 @@ static int name_ref(const struct reference *ref, void *cb_data) * shouldn't stop when seeing 'refs/tags/v1.4' matches * 'refs/tags/v*'. We should show it as 'v1.4'. */ - switch (subpath_matches(ref->name, item->string)) { + switch (subpath_matches(path, item->string)) { case -1: /* did not match */ break; case 0: /* matched fully */ @@ -405,13 +406,13 @@ static int name_ref(const struct reference *ref, void *cb_data) } if (o && o->type == OBJ_COMMIT) { commit = (struct commit *)o; - from_tag = starts_with(ref->name, "refs/tags/"); + from_tag = starts_with(path, "refs/tags/"); if (taggerdate == TIME_MAX) taggerdate = commit->date; } - add_to_tip_table(ref->oid, ref->name, can_abbreviate_output, - commit, taggerdate, from_tag, deref); + add_to_tip_table(oid, path, can_abbreviate_output, commit, taggerdate, + from_tag, deref); return 0; } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 4486b55e6d..0e4e9f8068 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -831,14 +831,15 @@ static enum write_one_status write_one(struct hashfile *f, return WRITE_ONE_WRITTEN; } -static int mark_tagged(const struct reference *ref, void *cb_data UNUSED) +static int mark_tagged(const char *path UNUSED, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { struct object_id peeled; - struct object_entry *entry = packlist_find(&to_pack, ref->oid); + struct object_entry *entry = packlist_find(&to_pack, oid); if (entry) entry->tagged = 1; - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) { + if (!peel_iterated_oid(the_repository, oid, &peeled)) { entry = packlist_find(&to_pack, &peeled); if (entry) entry->tagged = 1; @@ -3304,13 +3305,13 @@ static void add_tag_chain(const struct object_id *oid) } } -static int add_ref_tag(const struct reference *ref, void *cb_data UNUSED) +static int add_ref_tag(const char *tag UNUSED, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { struct object_id peeled; - if (!reference_get_peeled_oid(the_repository, ref, &peeled) && - obj_is_packed(&peeled)) - add_tag_chain(ref->oid); + if (!peel_iterated_oid(the_repository, oid, &peeled) && obj_is_packed(&peeled)) + add_tag_chain(oid); return 0; } @@ -4526,16 +4527,19 @@ static void record_recent_commit(struct commit *commit, void *data UNUSED) oid_array_append(&recent_objects, &commit->object.oid); } -static int mark_bitmap_preferred_tip(const struct reference *ref, void *data UNUSED) +static int mark_bitmap_preferred_tip(const char *refname, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, + void *data UNUSED) { - const struct object_id *maybe_peeled = ref->oid; struct object_id peeled; struct object *object; - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) - maybe_peeled = &peeled; + if (!peel_iterated_oid(the_repository, oid, &peeled)) + oid = &peeled; - object = parse_object_or_die(the_repository, maybe_peeled, ref->name); + object = parse_object_or_die(the_repository, oid, refname); if (object->type == OBJ_COMMIT) object->flags |= NEEDS_BITMAP; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index e8ee0e7321..c9288a9c7e 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -305,12 +305,13 @@ static void show_ref(const char *path, const struct object_id *oid) } } -static int show_ref_cb(const struct reference *ref, void *data) +static int show_ref_cb(const char *path_full, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *data) { struct oidset *seen = data; - const char *path = strip_namespace(ref->name); + const char *path = strip_namespace(path_full); - if (ref_is_hidden(path, ref->name, &hidden_refs)) + if (ref_is_hidden(path, path_full, &hidden_refs)) return 0; /* @@ -319,13 +320,13 @@ static int show_ref_cb(const struct reference *ref, void *data) * transfer but will otherwise ignore them. */ if (!path) { - if (oidset_insert(seen, ref->oid)) + if (oidset_insert(seen, oid)) return 0; path = ".have"; } else { - oidset_insert(seen, ref->oid); + oidset_insert(seen, oid); } - show_ref(path, ref->oid); + show_ref(path, oid); return 0; } diff --git a/builtin/remote.c b/builtin/remote.c index 7ffc14ba15..8a7ed4299a 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -570,14 +570,17 @@ struct branches_for_remote { struct known_remotes *keep; }; -static int add_branch_for_removal(const struct reference *ref, void *cb_data) +static int add_branch_for_removal(const char *refname, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, void *cb_data) { struct branches_for_remote *branches = cb_data; struct refspec_item refspec; struct known_remote *kr; memset(&refspec, 0, sizeof(refspec)); - refspec.dst = (char *)ref->name; + refspec.dst = (char *)refname; if (remote_find_tracking(branches->remote, &refspec)) return 0; free(refspec.src); @@ -585,7 +588,7 @@ static int add_branch_for_removal(const struct reference *ref, void *cb_data) /* don't delete a branch if another remote also uses it */ for (kr = branches->keep->list; kr; kr = kr->next) { memset(&refspec, 0, sizeof(refspec)); - refspec.dst = (char *)ref->name; + refspec.dst = (char *)refname; if (!remote_find_tracking(kr->remote, &refspec)) { free(refspec.src); return 0; @@ -593,16 +596,16 @@ static int add_branch_for_removal(const struct reference *ref, void *cb_data) } /* don't delete non-remote-tracking refs */ - if (!starts_with(ref->name, "refs/remotes/")) { + if (!starts_with(refname, "refs/remotes/")) { /* advise user how to delete local branches */ - if (starts_with(ref->name, "refs/heads/")) + if (starts_with(refname, "refs/heads/")) string_list_append(branches->skipped, - abbrev_branch(ref->name)); + abbrev_branch(refname)); /* silently skip over other non-remote refs */ return 0; } - string_list_append(branches->branches, ref->name); + string_list_append(branches->branches, refname); return 0; } @@ -710,18 +713,18 @@ out: return error; } -static int rename_one_ref(const struct reference *ref, void *cb_data) +static int rename_one_ref(const char *old_refname, const char *referent, + const struct object_id *oid, + int flags, void *cb_data) { struct strbuf new_referent = STRBUF_INIT; struct strbuf new_refname = STRBUF_INIT; struct rename_info *rename = cb_data; - const struct object_id *oid = ref->oid; - const char *referent = ref->target; int error; - compute_renamed_ref(rename, ref->name, &new_refname); + compute_renamed_ref(rename, old_refname, &new_refname); - if (ref->flags & REF_ISSYMREF) { + if (flags & REF_ISSYMREF) { /* * Stupidly enough `referent` is not pointing to the immediate * target of a symref, but it's the recursively resolved value. @@ -729,25 +732,25 @@ static int rename_one_ref(const struct reference *ref, void *cb_data) * unborn symrefs don't have any value for the `referent` at all. */ referent = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), - ref->name, RESOLVE_REF_NO_RECURSE, + old_refname, RESOLVE_REF_NO_RECURSE, NULL, NULL); compute_renamed_ref(rename, referent, &new_referent); oid = NULL; } - error = ref_transaction_delete(rename->transaction, ref->name, + error = ref_transaction_delete(rename->transaction, old_refname, oid, referent, REF_NO_DEREF, NULL, rename->err); if (error < 0) goto out; error = ref_transaction_update(rename->transaction, new_refname.buf, oid, null_oid(the_hash_algo), - (ref->flags & REF_ISSYMREF) ? new_referent.buf : NULL, NULL, + (flags & REF_ISSYMREF) ? new_referent.buf : NULL, NULL, REF_SKIP_CREATE_REFLOG | REF_NO_DEREF | REF_SKIP_OID_VERIFICATION, NULL, rename->err); if (error < 0) goto out; - error = rename_one_reflog(ref->name, oid, rename); + error = rename_one_reflog(old_refname, oid, rename); if (error < 0) goto out; @@ -1122,16 +1125,19 @@ static void free_remote_ref_states(struct ref_states *states) string_list_clear_func(&states->push, clear_push_info); } -static int append_ref_to_tracked_list(const struct reference *ref, void *cb_data) +static int append_ref_to_tracked_list(const char *refname, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags, void *cb_data) { struct ref_states *states = cb_data; struct refspec_item refspec; - if (ref->flags & REF_ISSYMREF) + if (flags & REF_ISSYMREF) return 0; memset(&refspec, 0, sizeof(refspec)); - refspec.dst = (char *)ref->name; + refspec.dst = (char *)refname; if (!remote_find_tracking(states->remote, &refspec)) { string_list_append(&states->tracked, abbrev_branch(refspec.src)); free(refspec.src); diff --git a/builtin/replace.c b/builtin/replace.c index 4c62c5ab58..900b560a77 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -47,27 +47,30 @@ struct show_data { enum replace_format format; }; -static int show_reference(const struct reference *ref, void *cb_data) +static int show_reference(const char *refname, + const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, void *cb_data) { struct show_data *data = cb_data; - if (!wildmatch(data->pattern, ref->name, 0)) { + if (!wildmatch(data->pattern, refname, 0)) { if (data->format == REPLACE_FORMAT_SHORT) - printf("%s\n", ref->name); + printf("%s\n", refname); else if (data->format == REPLACE_FORMAT_MEDIUM) - printf("%s -> %s\n", ref->name, oid_to_hex(ref->oid)); + printf("%s -> %s\n", refname, oid_to_hex(oid)); else { /* data->format == REPLACE_FORMAT_LONG */ struct object_id object; enum object_type obj_type, repl_type; - if (repo_get_oid(data->repo, ref->name, &object)) - return error(_("failed to resolve '%s' as a valid ref"), ref->name); + if (repo_get_oid(data->repo, refname, &object)) + return error(_("failed to resolve '%s' as a valid ref"), refname); obj_type = odb_read_object_info(data->repo->objects, &object, NULL); - repl_type = odb_read_object_info(data->repo->objects, ref->oid, NULL); + repl_type = odb_read_object_info(data->repo->objects, oid, NULL); - printf("%s (%s) -> %s (%s)\n", ref->name, type_name(obj_type), - oid_to_hex(ref->oid), type_name(repl_type)); + printf("%s (%s) -> %s (%s)\n", refname, type_name(obj_type), + oid_to_hex(oid), type_name(repl_type)); } } diff --git a/builtin/repo.c b/builtin/repo.c index f26640bd6e..9d4749f79b 100644 --- a/builtin/repo.c +++ b/builtin/repo.c @@ -366,13 +366,16 @@ struct count_references_data { struct progress *progress; }; -static int count_references(const struct reference *ref, void *cb_data) +static int count_references(const char *refname, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, void *cb_data) { struct count_references_data *data = cb_data; struct ref_stats *stats = data->stats; size_t ref_count; - switch (ref_kind_from_refname(ref->name)) { + switch (ref_kind_from_refname(refname)) { case FILTER_REFS_BRANCHES: stats->branches++; break; @@ -393,7 +396,7 @@ static int count_references(const struct reference *ref, void *cb_data) * While iterating through references for counting, also add OIDs in * preparation for the path walk. */ - add_pending_oid(data->revs, NULL, ref->oid, 0); + add_pending_oid(data->revs, NULL, oid, 0); ref_count = get_total_reference_count(stats); display_progress(data->progress, ref_count); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 9032cc6327..7b3711cf34 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -217,17 +217,19 @@ static int show_default(void) return 0; } -static int show_reference(const struct reference *ref, void *cb_data UNUSED) +static int show_reference(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { - if (ref_excluded(&ref_excludes, ref->name)) + if (ref_excluded(&ref_excludes, refname)) return 0; - show_rev(NORMAL, ref->oid, ref->name); + show_rev(NORMAL, oid, refname); return 0; } -static int anti_reference(const struct reference *ref, void *cb_data UNUSED) +static int anti_reference(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { - show_rev(REVERSED, ref->oid, ref->name); + show_rev(REVERSED, oid, refname); return 0; } diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 10475a6b5e..441babf2e3 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -413,32 +413,34 @@ static int append_ref(const char *refname, const struct object_id *oid, return 0; } -static int append_head_ref(const struct reference *ref, void *cb_data UNUSED) +static int append_head_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { struct object_id tmp; int ofs = 11; - if (!starts_with(ref->name, "refs/heads/")) + if (!starts_with(refname, "refs/heads/")) return 0; /* If both heads/foo and tags/foo exists, get_sha1 would * get confused. */ - if (repo_get_oid(the_repository, ref->name + ofs, &tmp) || !oideq(&tmp, ref->oid)) + if (repo_get_oid(the_repository, refname + ofs, &tmp) || !oideq(&tmp, oid)) ofs = 5; - return append_ref(ref->name + ofs, ref->oid, 0); + return append_ref(refname + ofs, oid, 0); } -static int append_remote_ref(const struct reference *ref, void *cb_data UNUSED) +static int append_remote_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data UNUSED) { struct object_id tmp; int ofs = 13; - if (!starts_with(ref->name, "refs/remotes/")) + if (!starts_with(refname, "refs/remotes/")) return 0; /* If both heads/foo and tags/foo exists, get_sha1 would * get confused. */ - if (repo_get_oid(the_repository, ref->name + ofs, &tmp) || !oideq(&tmp, ref->oid)) + if (repo_get_oid(the_repository, refname + ofs, &tmp) || !oideq(&tmp, oid)) ofs = 5; - return append_ref(ref->name + ofs, ref->oid, 0); + return append_ref(refname + ofs, oid, 0); } static int append_tag_ref(const char *refname, const struct object_id *oid, @@ -452,26 +454,27 @@ static int append_tag_ref(const char *refname, const struct object_id *oid, static const char *match_ref_pattern = NULL; static int match_ref_slash = 0; -static int append_matching_ref(const struct reference *ref, void *cb_data) +static int append_matching_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag, void *cb_data) { /* we want to allow pattern hold/<asterisk> to show all * branches under refs/heads/hold/, and v0.99.9? to show * refs/tags/v0.99.9a and friends. */ const char *tail; - int slash = count_slashes(ref->name); - for (tail = ref->name; *tail && match_ref_slash < slash; ) + int slash = count_slashes(refname); + for (tail = refname; *tail && match_ref_slash < slash; ) if (*tail++ == '/') slash--; if (!*tail) return 0; if (wildmatch(match_ref_pattern, tail, 0)) return 0; - if (starts_with(ref->name, "refs/heads/")) - return append_head_ref(ref, cb_data); - if (starts_with(ref->name, "refs/tags/")) - return append_tag_ref(ref->name, ref->oid, ref->flags, cb_data); - return append_ref(ref->name, ref->oid, 0); + if (starts_with(refname, "refs/heads/")) + return append_head_ref(refname, NULL, oid, flag, cb_data); + if (starts_with(refname, "refs/tags/")) + return append_tag_ref(refname, oid, flag, cb_data); + return append_ref(refname, oid, 0); } static void snarf_refs(int head, int remotes) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 4d4984e4e0..0b6f9edf86 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -31,31 +31,31 @@ struct show_one_options { }; static void show_one(const struct show_one_options *opts, - const struct reference *ref) + const char *refname, const struct object_id *oid) { const char *hex; struct object_id peeled; - if (!odb_has_object(the_repository->objects, ref->oid, + if (!odb_has_object(the_repository->objects, oid, HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR)) - die("git show-ref: bad ref %s (%s)", ref->name, - oid_to_hex(ref->oid)); + die("git show-ref: bad ref %s (%s)", refname, + oid_to_hex(oid)); if (opts->quiet) return; - hex = repo_find_unique_abbrev(the_repository, ref->oid, opts->abbrev); + hex = repo_find_unique_abbrev(the_repository, oid, opts->abbrev); if (opts->hash_only) printf("%s\n", hex); else - printf("%s %s\n", hex, ref->name); + printf("%s %s\n", hex, refname); if (!opts->deref_tags) return; - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) { + if (!peel_iterated_oid(the_repository, oid, &peeled)) { hex = repo_find_unique_abbrev(the_repository, &peeled, opts->abbrev); - printf("%s %s^{}\n", hex, ref->name); + printf("%s %s^{}\n", hex, refname); } } @@ -66,25 +66,26 @@ struct show_ref_data { int show_head; }; -static int show_ref(const struct reference *ref, void *cbdata) +static int show_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cbdata) { struct show_ref_data *data = cbdata; - if (data->show_head && !strcmp(ref->name, "HEAD")) + if (data->show_head && !strcmp(refname, "HEAD")) goto match; if (data->patterns) { - int reflen = strlen(ref->name); + int reflen = strlen(refname); const char **p = data->patterns, *m; while ((m = *p++) != NULL) { int len = strlen(m); if (len > reflen) continue; - if (memcmp(m, ref->name + reflen - len, len)) + if (memcmp(m, refname + reflen - len, len)) continue; if (len == reflen) goto match; - if (ref->name[reflen - len - 1] == '/') + if (refname[reflen - len - 1] == '/') goto match; } return 0; @@ -93,15 +94,18 @@ static int show_ref(const struct reference *ref, void *cbdata) match: data->found_match++; - show_one(data->show_one_opts, ref); + show_one(data->show_one_opts, refname, oid); return 0; } -static int add_existing(const struct reference *ref, void *cbdata) +static int add_existing(const char *refname, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flag UNUSED, void *cbdata) { struct string_list *list = (struct string_list *)cbdata; - string_list_insert(list, ref->name); + string_list_insert(list, refname); return 0; } @@ -175,18 +179,12 @@ static int cmd_show_ref__verify(const struct show_one_options *show_one_opts, if ((starts_with(*refs, "refs/") || refname_is_safe(*refs)) && !refs_read_ref(get_main_ref_store(the_repository), *refs, &oid)) { - struct reference ref = { - .name = *refs, - .oid = &oid, - }; - - show_one(show_one_opts, &ref); - } else if (!show_one_opts->quiet) { + show_one(show_one_opts, *refs, &oid); + } + else if (!show_one_opts->quiet) die("'%s' - not a valid ref", *refs); - } else { + else return 1; - } - refs++; } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 35f6cf735e..fcd73abe53 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -593,12 +593,16 @@ static void print_status(unsigned int flags, char state, const char *path, printf("\n"); } -static int handle_submodule_head_ref(const struct reference *ref, void *cb_data) +static int handle_submodule_head_ref(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, + void *cb_data) { struct object_id *output = cb_data; - if (ref->oid) - oidcpy(output, ref->oid); + if (oid) + oidcpy(output, oid); return 0; } diff --git a/builtin/tag.c b/builtin/tag.c index 01eba90c5c..f0665af3ac 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -153,7 +153,7 @@ static int verify_tag(const char *name, const char *ref UNUSED, return -1; if (format->format) - pretty_print_ref(name, oid, NULL, format); + pretty_print_ref(name, oid, format); return 0; } diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index 558121eaa1..cd6bc11095 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -67,7 +67,7 @@ int cmd_verify_tag(int argc, } if (format.format) - pretty_print_ref(name, &oid, NULL, &format); + pretty_print_ref(name, &oid, &format); } return had_error; } diff --git a/builtin/worktree.c b/builtin/worktree.c index b7f323b5e4..812774a5ca 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -635,7 +635,11 @@ static void print_preparing_worktree_line(int detach, * * Returns 0 on failure and non-zero on success. */ -static int first_valid_ref(const struct reference *ref UNUSED, void *cb_data UNUSED) +static int first_valid_ref(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, + void *cb_data UNUSED) { return 1; } diff --git a/commit-graph.c b/commit-graph.c index 80be2ff2c3..474454db73 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1851,16 +1851,18 @@ struct refs_cb_data { struct progress *progress; }; -static int add_ref_to_set(const struct reference *ref, void *cb_data) +static int add_ref_to_set(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, void *cb_data) { - const struct object_id *maybe_peeled = ref->oid; struct object_id peeled; struct refs_cb_data *data = (struct refs_cb_data *)cb_data; - if (!reference_get_peeled_oid(data->repo, ref, &peeled)) - maybe_peeled = &peeled; - if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) == OBJ_COMMIT) - oidset_insert(data->commits, maybe_peeled); + if (!peel_iterated_oid(data->repo, oid, &peeled)) + oid = &peeled; + if (odb_read_object_info(data->repo->objects, oid, NULL) == OBJ_COMMIT) + oidset_insert(data->commits, oid); display_progress(data->progress, oidset_size(data->commits)); diff --git a/delta-islands.c b/delta-islands.c index 7cfebc4162..36c94799d6 100644 --- a/delta-islands.c +++ b/delta-islands.c @@ -390,7 +390,8 @@ static void add_ref_to_island(kh_str_t *remote_islands, const char *island_name, rl->hash += sha_core; } -static int find_island_for_ref(const struct reference *ref, void *cb) +static int find_island_for_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flags UNUSED, void *cb) { struct island_load_data *ild = cb; @@ -405,7 +406,7 @@ static int find_island_for_ref(const struct reference *ref, void *cb) /* walk backwards to get last-one-wins ordering */ for (i = ild->nr - 1; i >= 0; i--) { - if (!regexec(&ild->rx[i], ref->name, + if (!regexec(&ild->rx[i], refname, ARRAY_SIZE(matches), matches, 0)) break; } @@ -427,10 +428,10 @@ static int find_island_for_ref(const struct reference *ref, void *cb) if (island_name.len) strbuf_addch(&island_name, '-'); - strbuf_add(&island_name, ref->name + match->rm_so, match->rm_eo - match->rm_so); + strbuf_add(&island_name, refname + match->rm_so, match->rm_eo - match->rm_so); } - add_ref_to_island(ild->remote_islands, island_name.buf, ref->oid); + add_ref_to_island(ild->remote_islands, island_name.buf, oid); strbuf_release(&island_name); return 0; } diff --git a/fetch-pack.c b/fetch-pack.c index 78c45d4a15..fe7a84bf2f 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -188,9 +188,13 @@ static int rev_list_insert_ref(struct fetch_negotiator *negotiator, return 0; } -static int rev_list_insert_ref_oid(const struct reference *ref, void *cb_data) +static int rev_list_insert_ref_oid(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, + void *cb_data) { - return rev_list_insert_ref(cb_data, ref->oid); + return rev_list_insert_ref(cb_data, oid); } enum ack_type { @@ -612,9 +616,13 @@ static int mark_complete(const struct object_id *oid) return 0; } -static int mark_complete_oid(const struct reference *ref, void *cb_data UNUSED) +static int mark_complete_oid(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, + void *cb_data UNUSED) { - return mark_complete(ref->oid); + return mark_complete(oid); } static void mark_recent_complete_commits(struct fetch_pack_args *args, @@ -851,16 +851,18 @@ struct similar_ref_cb { struct string_list *similar_refs; }; -static int append_similar_ref(const struct reference *ref, void *cb_data) +static int append_similar_ref(const char *refname, const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, void *cb_data) { struct similar_ref_cb *cb = (struct similar_ref_cb *)(cb_data); - char *branch = strrchr(ref->name, '/') + 1; + char *branch = strrchr(refname, '/') + 1; /* A remote branch of the same name is deemed similar */ - if (starts_with(ref->name, "refs/remotes/") && + if (starts_with(refname, "refs/remotes/") && !strcmp(branch, cb->base_ref)) string_list_append_nodup(cb->similar_refs, - refs_shorten_unambiguous_ref(get_main_ref_store(the_repository), ref->name, 1)); + refs_shorten_unambiguous_ref(get_main_ref_store(the_repository), refname, 1)); return 0; } diff --git a/http-backend.c b/http-backend.c index 273ed7266f..52f0483dd3 100644 --- a/http-backend.c +++ b/http-backend.c @@ -513,17 +513,18 @@ static void run_service(const char **argv, int buffer_input) exit(1); } -static int show_text_ref(const struct reference *ref, void *cb_data) +static int show_text_ref(const char *name, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data) { - const char *name_nons = strip_namespace(ref->name); + const char *name_nons = strip_namespace(name); struct strbuf *buf = cb_data; - struct object *o = parse_object(the_repository, ref->oid); + struct object *o = parse_object(the_repository, oid); if (!o) return 0; - strbuf_addf(buf, "%s\t%s\n", oid_to_hex(ref->oid), name_nons); + strbuf_addf(buf, "%s\t%s\n", oid_to_hex(oid), name_nons); if (o->type == OBJ_TAG) { - o = deref_tag(the_repository, o, ref->name, 0); + o = deref_tag(the_repository, o, name, 0); if (!o) return 0; strbuf_addf(buf, "%s\t%s^{}\n", oid_to_hex(&o->oid), @@ -568,20 +569,21 @@ static void get_info_refs(struct strbuf *hdr, char *arg UNUSED) strbuf_release(&buf); } -static int show_head_ref(const struct reference *ref, void *cb_data) +static int show_head_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag, void *cb_data) { struct strbuf *buf = cb_data; - if (ref->flags & REF_ISSYMREF) { + if (flag & REF_ISSYMREF) { const char *target = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), - ref->name, + refname, RESOLVE_REF_READING, NULL, NULL); if (target) strbuf_addf(buf, "ref: %s\n", strip_namespace(target)); } else { - strbuf_addf(buf, "%s\n", oid_to_hex(ref->oid)); + strbuf_addf(buf, "%s\n", oid_to_hex(oid)); } return 0; diff --git a/log-tree.c b/log-tree.c index 1729b0c201..7d917f2a83 100644 --- a/log-tree.c +++ b/log-tree.c @@ -147,7 +147,9 @@ static int ref_filter_match(const char *refname, return 1; } -static int add_ref_decoration(const struct reference *ref, void *cb_data) +static int add_ref_decoration(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flags UNUSED, + void *cb_data) { int i; struct object *obj; @@ -156,16 +158,16 @@ static int add_ref_decoration(const struct reference *ref, void *cb_data) struct decoration_filter *filter = (struct decoration_filter *)cb_data; const char *git_replace_ref_base = ref_namespace[NAMESPACE_REPLACE].ref; - if (filter && !ref_filter_match(ref->name, filter)) + if (filter && !ref_filter_match(refname, filter)) return 0; - if (starts_with(ref->name, git_replace_ref_base)) { + if (starts_with(refname, git_replace_ref_base)) { struct object_id original_oid; if (!replace_refs_enabled(the_repository)) return 0; - if (get_oid_hex(ref->name + strlen(git_replace_ref_base), + if (get_oid_hex(refname + strlen(git_replace_ref_base), &original_oid)) { - warning("invalid replace ref %s", ref->name); + warning("invalid replace ref %s", refname); return 0; } obj = parse_object(the_repository, &original_oid); @@ -174,10 +176,10 @@ static int add_ref_decoration(const struct reference *ref, void *cb_data) return 0; } - objtype = odb_read_object_info(the_repository->objects, ref->oid, NULL); + objtype = odb_read_object_info(the_repository->objects, oid, NULL); if (objtype < 0) return 0; - obj = lookup_object_by_type(the_repository, ref->oid, objtype); + obj = lookup_object_by_type(the_repository, oid, objtype); for (i = 0; i < ARRAY_SIZE(ref_namespace); i++) { struct ref_namespace_info *info = &ref_namespace[i]; @@ -185,24 +187,24 @@ static int add_ref_decoration(const struct reference *ref, void *cb_data) if (!info->decoration) continue; if (info->exact) { - if (!strcmp(ref->name, info->ref)) { + if (!strcmp(refname, info->ref)) { deco_type = info->decoration; break; } - } else if (starts_with(ref->name, info->ref)) { + } else if (starts_with(refname, info->ref)) { deco_type = info->decoration; break; } } - add_name_decoration(deco_type, ref->name, obj); + add_name_decoration(deco_type, refname, obj); while (obj->type == OBJ_TAG) { if (!obj->parsed) parse_object(the_repository, &obj->oid); obj = ((struct tag *)obj)->tagged; if (!obj) break; - add_name_decoration(DECORATION_REF_TAG, ref->name, obj); + add_name_decoration(DECORATION_REF_TAG, refname, obj); } return 0; } @@ -75,42 +75,42 @@ struct ls_refs_data { unsigned unborn : 1; }; -static int send_ref(const struct reference *ref, void *cb_data) +static int send_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag, void *cb_data) { struct ls_refs_data *data = cb_data; - const char *refname_nons = strip_namespace(ref->name); + const char *refname_nons = strip_namespace(refname); strbuf_reset(&data->buf); - if (ref_is_hidden(refname_nons, ref->name, &data->hidden_refs)) + if (ref_is_hidden(refname_nons, refname, &data->hidden_refs)) return 0; if (!ref_match(&data->prefixes, refname_nons)) return 0; - if (ref->oid) - strbuf_addf(&data->buf, "%s %s", oid_to_hex(ref->oid), refname_nons); + if (oid) + strbuf_addf(&data->buf, "%s %s", oid_to_hex(oid), refname_nons); else strbuf_addf(&data->buf, "unborn %s", refname_nons); - if (data->symrefs && ref->flags & REF_ISSYMREF) { - int unused_flag; + if (data->symrefs && flag & REF_ISSYMREF) { struct object_id unused; const char *symref_target = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), - ref->name, + refname, 0, &unused, - &unused_flag); + &flag); if (!symref_target) - die("'%s' is a symref but it is not?", ref->name); + die("'%s' is a symref but it is not?", refname); strbuf_addf(&data->buf, " symref-target:%s", strip_namespace(symref_target)); } - if (data->peel && ref->oid) { + if (data->peel && oid) { struct object_id peeled; - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) strbuf_addf(&data->buf, " peeled:%s", oid_to_hex(&peeled)); } @@ -131,17 +131,9 @@ static void send_possibly_unborn_head(struct ls_refs_data *data) if (!refs_resolve_ref_unsafe(get_main_ref_store(the_repository), namespaced.buf, 0, &oid, &flag)) return; /* bad ref */ oid_is_null = is_null_oid(&oid); - if (!oid_is_null || - (data->unborn && data->symrefs && (flag & REF_ISSYMREF))) { - struct reference ref = { - .name = namespaced.buf, - .oid = oid_is_null ? NULL : &oid, - .flags = flag, - }; - - send_ref(&ref, data); - } + (data->unborn && data->symrefs && (flag & REF_ISSYMREF))) + send_ref(namespaced.buf, NULL, oid_is_null ? NULL : &oid, flag, data); strbuf_release(&namespaced); } diff --git a/midx-write.c b/midx-write.c index 23e61cb000..c73010df6d 100644 --- a/midx-write.c +++ b/midx-write.c @@ -697,27 +697,28 @@ static void prepare_midx_packing_data(struct packing_data *pdata, trace2_region_leave("midx", "prepare_midx_packing_data", ctx->repo); } -static int add_ref_to_pending(const struct reference *ref, void *cb_data) +static int add_ref_to_pending(const char *refname, const char *referent UNUSED, + const struct object_id *oid, + int flag, void *cb_data) { struct rev_info *revs = (struct rev_info*)cb_data; - const struct object_id *maybe_peeled = ref->oid; struct object_id peeled; struct object *object; - if ((ref->flags & REF_ISSYMREF) && (ref->flags & REF_ISBROKEN)) { - warning("symbolic ref is dangling: %s", ref->name); + if ((flag & REF_ISSYMREF) && (flag & REF_ISBROKEN)) { + warning("symbolic ref is dangling: %s", refname); return 0; } - if (!reference_get_peeled_oid(revs->repo, ref, &peeled)) - maybe_peeled = &peeled; + if (!peel_iterated_oid(revs->repo, oid, &peeled)) + oid = &peeled; - object = parse_object_or_die(revs->repo, maybe_peeled, ref->name); + object = parse_object_or_die(revs->repo, oid, refname); if (object->type != OBJ_COMMIT) return 0; add_pending_object(revs, object, ""); - if (bitmap_is_preferred_refname(revs->repo, ref->name)) + if (bitmap_is_preferred_refname(revs->repo, refname)) object->flags |= NEEDS_BITMAP; return 0; } diff --git a/negotiator/default.c b/negotiator/default.c index 116dedcf83..c479da9b09 100644 --- a/negotiator/default.c +++ b/negotiator/default.c @@ -38,10 +38,11 @@ static void rev_list_push(struct negotiation_state *ns, } } -static int clear_marks(const struct reference *ref, void *cb_data UNUSED) +static int clear_marks(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, + void *cb_data UNUSED) { - struct object *o = deref_tag(the_repository, parse_object(the_repository, ref->oid), - ref->name, 0); + struct object *o = deref_tag(the_repository, parse_object(the_repository, oid), refname, 0); if (o && o->type == OBJ_COMMIT) clear_commit_marks((struct commit *)o, diff --git a/negotiator/skipping.c b/negotiator/skipping.c index 0a272130fb..616df6bf3a 100644 --- a/negotiator/skipping.c +++ b/negotiator/skipping.c @@ -75,10 +75,11 @@ static struct entry *rev_list_push(struct data *data, struct commit *commit, int return entry; } -static int clear_marks(const struct reference *ref, void *cb_data UNUSED) +static int clear_marks(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, + void *cb_data UNUSED) { - struct object *o = deref_tag(the_repository, parse_object(the_repository, ref->oid), - ref->name, 0); + struct object *o = deref_tag(the_repository, parse_object(the_repository, oid), refname, 0); if (o && o->type == OBJ_COMMIT) clear_commit_marks((struct commit *)o, @@ -938,11 +938,13 @@ out: return ret; } -static int string_list_add_one_ref(const struct reference *ref, void *cb) +static int string_list_add_one_ref(const char *refname, const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flag UNUSED, void *cb) { struct string_list *refs = cb; - if (!unsorted_string_list_has_string(refs, ref->name)) - string_list_append(refs, ref->name); + if (!unsorted_string_list_has_string(refs, refname)) + string_list_append(refs, refname); return 0; } diff --git a/object-name.c b/object-name.c index 72bdf4f86e..766c757042 100644 --- a/object-name.c +++ b/object-name.c @@ -1446,16 +1446,18 @@ struct handle_one_ref_cb { struct commit_list **list; }; -static int handle_one_ref(const struct reference *ref, void *cb_data) +static int handle_one_ref(const char *path, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, + void *cb_data) { struct handle_one_ref_cb *cb = cb_data; struct commit_list **list = cb->list; - struct object *object = parse_object(cb->repo, ref->oid); + struct object *object = parse_object(cb->repo, oid); if (!object) return 0; if (object->type == OBJ_TAG) { - object = deref_tag(cb->repo, object, ref->name, - strlen(ref->name)); + object = deref_tag(cb->repo, object, path, + strlen(path)); if (!object) return 0; } @@ -209,12 +209,11 @@ struct object *lookup_object_by_type(struct repository *r, enum peel_status peel_object(struct repository *r, const struct object_id *name, - struct object_id *oid, - unsigned flags) + struct object_id *oid) { struct object *o = lookup_unknown_object(r, name); - if (o->type == OBJ_NONE || flags & PEEL_OBJECT_VERIFY_OBJECT_TYPE) { + if (o->type == OBJ_NONE) { int type = odb_read_object_info(r->objects, name, NULL); if (type < 0 || !object_as_type(o, type, 0)) return PEEL_INVALID; @@ -223,20 +222,7 @@ enum peel_status peel_object(struct repository *r, if (o->type != OBJ_TAG) return PEEL_NON_TAG; - while (o && o->type == OBJ_TAG) { - o = parse_object(r, &o->oid); - if (o && o->type == OBJ_TAG && ((struct tag *)o)->tagged) { - o = ((struct tag *)o)->tagged; - - if (flags & PEEL_OBJECT_VERIFY_OBJECT_TYPE) { - int type = odb_read_object_info(r->objects, &o->oid, NULL); - if (type < 0 || !object_as_type(o, type, 0)) - return PEEL_INVALID; - } - } else { - o = NULL; - } - } + o = deref_tag_noverify(r, o); if (!o) return PEEL_INVALID; @@ -288,17 +288,6 @@ enum peel_status { PEEL_BROKEN = -4 }; -enum peel_object_flags { - /* - * Always verify the object type, even in the case where the looked-up - * object already has an object type. This can be useful when the - * stored object type may be invalid. One such case is when looking up - * objects via tags, where we blindly trust the object type declared by - * the tag. - */ - PEEL_OBJECT_VERIFY_OBJECT_TYPE = (1 << 0), -}; - /* * Peel the named object; i.e., if the object is a tag, resolve the * tag recursively until a non-tag is found. If successful, store the @@ -307,9 +296,7 @@ enum peel_object_flags { * and leave oid unchanged. */ enum peel_status peel_object(struct repository *r, - const struct object_id *name, - struct object_id *oid, - unsigned flags); + const struct object_id *name, struct object_id *oid); struct object_list *object_list_insert(struct object *item, struct object_list **list_p); diff --git a/pseudo-merge.c b/pseudo-merge.c index a2d5bd85f9..893b763fe4 100644 --- a/pseudo-merge.c +++ b/pseudo-merge.c @@ -221,25 +221,28 @@ void load_pseudo_merges_from_config(struct repository *r, } } -static int find_pseudo_merge_group_for_ref(const struct reference *ref, void *_data) +static int find_pseudo_merge_group_for_ref(const char *refname, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, + void *_data) { struct bitmap_writer *writer = _data; - const struct object_id *maybe_peeled = ref->oid; struct object_id peeled; struct commit *c; uint32_t i; int has_bitmap; - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) - maybe_peeled = &peeled; + if (!peel_iterated_oid(the_repository, oid, &peeled)) + oid = &peeled; - c = lookup_commit(the_repository, maybe_peeled); + c = lookup_commit(the_repository, oid); if (!c) return 0; - if (!packlist_find(writer->to_pack, maybe_peeled)) + if (!packlist_find(writer->to_pack, oid)) return 0; - has_bitmap = bitmap_writer_has_bitmapped_object_id(writer, maybe_peeled); + has_bitmap = bitmap_writer_has_bitmapped_object_id(writer, oid); for (i = 0; i < writer->pseudo_merge_groups.nr; i++) { struct pseudo_merge_group *group; @@ -249,7 +252,7 @@ static int find_pseudo_merge_group_for_ref(const struct reference *ref, void *_d size_t j; group = writer->pseudo_merge_groups.items[i].util; - if (regexec(group->pattern, ref->name, ARRAY_SIZE(captures), + if (regexec(group->pattern, refname, ARRAY_SIZE(captures), captures, 0)) continue; @@ -266,7 +269,7 @@ static int find_pseudo_merge_group_for_ref(const struct reference *ref, void *_d if (group_name.len) strbuf_addch(&group_name, '-'); - strbuf_add(&group_name, ref->name + match->rm_so, + strbuf_add(&group_name, refname + match->rm_so, match->rm_eo - match->rm_so); } diff --git a/reachable.c b/reachable.c index b753c39553..22266db523 100644 --- a/reachable.c +++ b/reachable.c @@ -83,17 +83,18 @@ static void add_rebase_files(struct rev_info *revs) free_worktrees(worktrees); } -static int add_one_ref(const struct reference *ref, void *cb_data) +static int add_one_ref(const char *path, const char *referent UNUSED, const struct object_id *oid, + int flag, void *cb_data) { struct rev_info *revs = (struct rev_info *)cb_data; struct object *object; - if ((ref->flags & REF_ISSYMREF) && (ref->flags & REF_ISBROKEN)) { - warning("symbolic ref is dangling: %s", ref->name); + if ((flag & REF_ISSYMREF) && (flag & REF_ISBROKEN)) { + warning("symbolic ref is dangling: %s", path); return 0; } - object = parse_object_or_die(the_repository, ref->oid, ref->name); + object = parse_object_or_die(the_repository, oid, path); add_pending_object(revs, object, ""); return 0; diff --git a/ref-filter.c b/ref-filter.c index 7cfcd5c355..30cc488d8a 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -91,7 +91,6 @@ static struct expand_data { struct object_id delta_base_oid; void *content; - struct object *maybe_object; struct object_info info; } oi, oi_deref; @@ -1476,29 +1475,11 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_ } } -static struct object *get_or_parse_object(struct expand_data *data, const char *refname, - struct strbuf *err, int *eaten) -{ - if (!data->maybe_object) { - data->maybe_object = parse_object_buffer(the_repository, &data->oid, data->type, - data->size, data->content, eaten); - if (!data->maybe_object) { - strbuf_addf(err, _("parse_object_buffer failed on %s for %s"), - oid_to_hex(&data->oid), refname); - return NULL; - } - } - - return data->maybe_object; -} - /* See grab_values */ -static int grab_tag_values(struct atom_value *val, int deref, - struct expand_data *data, const char *refname, - struct strbuf *err, int *eaten) +static void grab_tag_values(struct atom_value *val, int deref, struct object *obj) { - struct tag *tag = NULL; int i; + struct tag *tag = (struct tag *) obj; for (i = 0; i < used_atom_cnt; i++) { const char *name = used_atom[i].name; @@ -1506,14 +1487,6 @@ static int grab_tag_values(struct atom_value *val, int deref, struct atom_value *v = &val[i]; if (!!deref != (*name == '*')) continue; - - if (!tag) { - tag = (struct tag *) get_or_parse_object(data, refname, - err, eaten); - if (!tag) - return -1; - } - if (deref) name++; if (atom_type == ATOM_TAG) @@ -1523,35 +1496,22 @@ static int grab_tag_values(struct atom_value *val, int deref, else if (atom_type == ATOM_OBJECT && tag->tagged) v->s = xstrdup(oid_to_hex(&tag->tagged->oid)); } - - return 0; } /* See grab_values */ -static int grab_commit_values(struct atom_value *val, int deref, - struct expand_data *data, const char *refname, - struct strbuf *err, int *eaten) +static void grab_commit_values(struct atom_value *val, int deref, struct object *obj) { int i; - struct commit *commit = NULL; + struct commit *commit = (struct commit *) obj; for (i = 0; i < used_atom_cnt; i++) { const char *name = used_atom[i].name; enum atom_type atom_type = used_atom[i].atom_type; struct atom_value *v = &val[i]; - if (!!deref != (*name == '*')) continue; if (deref) name++; - - if (!commit) { - commit = (struct commit *) get_or_parse_object(data, refname, - err, eaten); - if (!commit) - return -1; - } - if (atom_type == ATOM_TREE && grab_oid(name, "tree", get_commit_tree_oid(commit), v, &used_atom[i])) continue; @@ -1571,8 +1531,6 @@ static int grab_commit_values(struct atom_value *val, int deref, v->s = strbuf_detach(&s, NULL); } } - - return 0; } static const char *find_wholine(const char *who, int wholen, const char *buf) @@ -1801,12 +1759,10 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void } } -static int grab_signature(struct atom_value *val, int deref, - struct expand_data *data, const char *refname, - struct strbuf *err, int *eaten) +static void grab_signature(struct atom_value *val, int deref, struct object *obj) { int i; - struct commit *commit = NULL; + struct commit *commit = (struct commit *) obj; struct signature_check sigc = { 0 }; int signature_checked = 0; @@ -1834,13 +1790,6 @@ static int grab_signature(struct atom_value *val, int deref, continue; if (!signature_checked) { - if (!commit) { - commit = (struct commit *) get_or_parse_object(data, refname, - err, eaten); - if (!commit) - return -1; - } - check_commit_signature(commit, &sigc); signature_checked = 1; } @@ -1894,8 +1843,6 @@ static int grab_signature(struct atom_value *val, int deref, if (signature_checked) signature_check_clear(&sigc); - - return 0; } static void find_subpos(const char *buf, @@ -1973,8 +1920,9 @@ static void append_lines(struct strbuf *out, const char *buf, unsigned long size } static void grab_describe_values(struct atom_value *val, int deref, - struct expand_data *data) + struct object *obj) { + struct commit *commit = (struct commit *)obj; int i; for (i = 0; i < used_atom_cnt; i++) { @@ -1996,7 +1944,7 @@ static void grab_describe_values(struct atom_value *val, int deref, cmd.git_cmd = 1; strvec_push(&cmd.args, "describe"); strvec_pushv(&cmd.args, atom->u.describe_args.v); - strvec_push(&cmd.args, oid_to_hex(&data->oid)); + strvec_push(&cmd.args, oid_to_hex(&commit->object.oid)); if (pipe_command(&cmd, NULL, 0, &out, 0, &err, 0) < 0) { error(_("failed to run 'describe'")); v->s = xstrdup(""); @@ -2118,36 +2066,24 @@ static void fill_missing_values(struct atom_value *val) * pointed at by the ref itself; otherwise it is the object the * ref (which is a tag) refers to. */ -static int grab_values(struct atom_value *val, int deref, struct expand_data *data, - const char *refname, struct strbuf *err, int *eaten) +static void grab_values(struct atom_value *val, int deref, struct object *obj, struct expand_data *data) { void *buf = data->content; - int ret; - switch (data->type) { + switch (obj->type) { case OBJ_TAG: - ret = grab_tag_values(val, deref, data, refname, err, eaten); - if (ret < 0) - goto out; - + grab_tag_values(val, deref, obj); grab_sub_body_contents(val, deref, data); grab_person("tagger", val, deref, buf); - grab_describe_values(val, deref, data); + grab_describe_values(val, deref, obj); break; case OBJ_COMMIT: - ret = grab_commit_values(val, deref, data, refname, err, eaten); - if (ret < 0) - goto out; - + grab_commit_values(val, deref, obj); grab_sub_body_contents(val, deref, data); grab_person("author", val, deref, buf); grab_person("committer", val, deref, buf); - - ret = grab_signature(val, deref, data, refname, err, eaten); - if (ret < 0) - goto out; - - grab_describe_values(val, deref, data); + grab_signature(val, deref, obj); + grab_describe_values(val, deref, obj); break; case OBJ_TREE: /* grab_tree_values(val, deref, obj, buf, sz); */ @@ -2158,12 +2094,8 @@ static int grab_values(struct atom_value *val, int deref, struct expand_data *da grab_sub_body_contents(val, deref, data); break; default: - die("Eh? Object of type %d?", data->type); + die("Eh? Object of type %d?", obj->type); } - - ret = 0; -out: - return ret; } static inline char *copy_advance(char *dst, const char *src) @@ -2360,41 +2292,38 @@ static const char *get_refname(struct used_atom *atom, struct ref_array_item *re return show_ref(&atom->u.refname, ref->refname); } -static int get_object(struct ref_array_item *ref, int deref, +static int get_object(struct ref_array_item *ref, int deref, struct object **obj, struct expand_data *oi, struct strbuf *err) { - /* parse_object_buffer() will set eaten to 1 if free() will be needed */ - int eaten = 0; - int ret; - + /* parse_object_buffer() will set eaten to 0 if free() will be needed */ + int eaten = 1; if (oi->info.contentp) { /* We need to know that to use parse_object_buffer properly */ oi->info.sizep = &oi->size; oi->info.typep = &oi->type; } - if (odb_read_object_info_extended(the_repository->objects, &oi->oid, &oi->info, - OBJECT_INFO_LOOKUP_REPLACE)) { - ret = strbuf_addf_ret(err, -1, _("missing object %s for %s"), - oid_to_hex(&oi->oid), ref->refname); - goto out; - } + OBJECT_INFO_LOOKUP_REPLACE)) + return strbuf_addf_ret(err, -1, _("missing object %s for %s"), + oid_to_hex(&oi->oid), ref->refname); if (oi->info.disk_sizep && oi->disk_size < 0) BUG("Object size is less than zero."); if (oi->info.contentp) { - ret = grab_values(ref->value, deref, oi, ref->refname, err, &eaten); - if (ret < 0) - goto out; + *obj = parse_object_buffer(the_repository, &oi->oid, oi->type, oi->size, oi->content, &eaten); + if (!*obj) { + if (!eaten) + free(oi->content); + return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"), + oid_to_hex(&oi->oid), ref->refname); + } + grab_values(ref->value, deref, *obj, oi); } grab_common_values(ref->value, deref, oi); - ret = 0; - -out: if (!eaten) free(oi->content); - return ret; + return 0; } static void populate_worktree_map(struct hashmap *map, struct worktree **worktrees) @@ -2447,6 +2376,7 @@ static char *get_worktree_path(const struct ref_array_item *ref) */ static int populate_value(struct ref_array_item *ref, struct strbuf *err) { + struct object *obj; int i; struct object_info empty = OBJECT_INFO_INIT; int ahead_behind_atoms = 0; @@ -2634,32 +2564,24 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err) oi.oid = ref->objectname; - if (get_object(ref, 0, &oi, err)) + if (get_object(ref, 0, &obj, &oi, err)) return -1; /* * If there is no atom that wants to know about tagged * object, we are done. */ - if (!need_tagged || (oi.type != OBJ_TAG)) + if (!need_tagged || (obj->type != OBJ_TAG)) return 0; /* * If it is a tag object, see if we use the peeled value. If we do, * grab the peeled OID. */ - if (need_tagged) { - if (!is_null_oid(&ref->peeled_oid)) { - oidcpy(&oi_deref.oid, &ref->peeled_oid); - } else if (!peel_object(the_repository, &oi.oid, &oi_deref.oid, - PEEL_OBJECT_VERIFY_OBJECT_TYPE)) { - /* We managed to peel the object ourselves. */ - } else { - die("bad tag"); - } - } + if (need_tagged && peel_iterated_oid(the_repository, &obj->oid, &oi_deref.oid)) + die("bad tag"); - return get_object(ref, 1, &oi_deref, err); + return get_object(ref, 1, &obj, &oi_deref, err); } /* @@ -2885,15 +2807,12 @@ static int match_points_at(struct oid_array *points_at, * Callers can then fill in other struct members at their leisure. */ static struct ref_array_item *new_ref_array_item(const char *refname, - const struct object_id *oid, - const struct object_id *peeled_oid) + const struct object_id *oid) { struct ref_array_item *ref; FLEX_ALLOC_STR(ref, refname, refname); oidcpy(&ref->objectname, oid); - if (peeled_oid) - oidcpy(&ref->peeled_oid, peeled_oid); ref->rest = NULL; return ref; @@ -2907,10 +2826,9 @@ static void ref_array_append(struct ref_array *array, struct ref_array_item *ref struct ref_array_item *ref_array_push(struct ref_array *array, const char *refname, - const struct object_id *oid, - const struct object_id *peeled_oid) + const struct object_id *oid) { - struct ref_array_item *ref = new_ref_array_item(refname, oid, peeled_oid); + struct ref_array_item *ref = new_ref_array_item(refname, oid); ref_array_append(array, ref); return ref; } @@ -2953,25 +2871,25 @@ static int filter_ref_kind(struct ref_filter *filter, const char *refname) return ref_kind_from_refname(refname); } -static struct ref_array_item *apply_ref_filter(const struct reference *ref, - struct ref_filter *filter) +static struct ref_array_item *apply_ref_filter(const char *refname, const char *referent, const struct object_id *oid, + int flag, struct ref_filter *filter) { - struct ref_array_item *item; + struct ref_array_item *ref; struct commit *commit = NULL; unsigned int kind; - if (ref->flags & REF_BAD_NAME) { - warning(_("ignoring ref with broken name %s"), ref->name); + if (flag & REF_BAD_NAME) { + warning(_("ignoring ref with broken name %s"), refname); return NULL; } - if (ref->flags & REF_ISBROKEN) { - warning(_("ignoring broken ref %s"), ref->name); + if (flag & REF_ISBROKEN) { + warning(_("ignoring broken ref %s"), refname); return NULL; } /* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */ - kind = filter_ref_kind(filter, ref->name); + kind = filter_ref_kind(filter, refname); /* * Generally HEAD refs are printed with special description denoting a rebase, @@ -2984,13 +2902,13 @@ static struct ref_array_item *apply_ref_filter(const struct reference *ref, else if (!(kind & filter->kind)) return NULL; - if (!filter_pattern_match(filter, ref->name)) + if (!filter_pattern_match(filter, refname)) return NULL; - if (filter_exclude_match(filter, ref->name)) + if (filter_exclude_match(filter, refname)) return NULL; - if (filter->points_at.nr && !match_points_at(&filter->points_at, ref->oid, ref->name)) + if (filter->points_at.nr && !match_points_at(&filter->points_at, oid, refname)) return NULL; /* @@ -3000,7 +2918,7 @@ static struct ref_array_item *apply_ref_filter(const struct reference *ref, */ if (filter->reachable_from || filter->unreachable_from || filter->with_commit || filter->no_commit || filter->verbose) { - commit = lookup_commit_reference_gently(the_repository, ref->oid, 1); + commit = lookup_commit_reference_gently(the_repository, oid, 1); if (!commit) return NULL; /* We perform the filtering for the '--contains' option... */ @@ -3018,13 +2936,13 @@ static struct ref_array_item *apply_ref_filter(const struct reference *ref, * to do its job and the resulting list may yet to be pruned * by maxcount logic. */ - item = new_ref_array_item(ref->name, ref->oid, ref->peeled_oid); - item->commit = commit; - item->flag = ref->flags; - item->kind = kind; - item->symref = xstrdup_or_null(ref->target); + ref = new_ref_array_item(refname, oid); + ref->commit = commit; + ref->flag = flag; + ref->kind = kind; + ref->symref = xstrdup_or_null(referent); - return item; + return ref; } struct ref_filter_cbdata { @@ -3036,14 +2954,14 @@ struct ref_filter_cbdata { * A call-back given to for_each_ref(). Filter refs and keep them for * later object processing. */ -static int filter_one(const struct reference *ref, void *cb_data) +static int filter_one(const char *refname, const char *referent, const struct object_id *oid, int flag, void *cb_data) { struct ref_filter_cbdata *ref_cbdata = cb_data; - struct ref_array_item *item; + struct ref_array_item *ref; - item = apply_ref_filter(ref, ref_cbdata->filter); - if (item) - ref_array_append(ref_cbdata->array, item); + ref = apply_ref_filter(refname, referent, oid, flag, ref_cbdata->filter); + if (ref) + ref_array_append(ref_cbdata->array, ref); return 0; } @@ -3072,17 +2990,17 @@ struct ref_filter_and_format_cbdata { } internal; }; -static int filter_and_format_one(const struct reference *ref, void *cb_data) +static int filter_and_format_one(const char *refname, const char *referent, const struct object_id *oid, int flag, void *cb_data) { struct ref_filter_and_format_cbdata *ref_cbdata = cb_data; - struct ref_array_item *item; + struct ref_array_item *ref; struct strbuf output = STRBUF_INIT, err = STRBUF_INIT; - item = apply_ref_filter(ref, ref_cbdata->filter); - if (!item) + ref = apply_ref_filter(refname, referent, oid, flag, ref_cbdata->filter); + if (!ref) return 0; - if (format_ref_array_item(item, ref_cbdata->format, &output, &err)) + if (format_ref_array_item(ref, ref_cbdata->format, &output, &err)) die("%s", err.buf); if (output.len || !ref_cbdata->format->array_opts.omit_empty) { @@ -3092,7 +3010,7 @@ static int filter_and_format_one(const struct reference *ref, void *cb_data) strbuf_release(&output); strbuf_release(&err); - free_array_item(item); + free_array_item(ref); /* * Increment the running count of refs that match the filter. If @@ -3665,14 +3583,13 @@ void print_formatted_ref_array(struct ref_array *array, struct ref_format *forma } void pretty_print_ref(const char *name, const struct object_id *oid, - const struct object_id *peeled_oid, struct ref_format *format) { struct ref_array_item *ref_item; struct strbuf output = STRBUF_INIT; struct strbuf err = STRBUF_INIT; - ref_item = new_ref_array_item(name, oid, peeled_oid); + ref_item = new_ref_array_item(name, oid); ref_item->kind = ref_kind_from_refname(name); if (format_ref_array_item(ref_item, format, &output, &err)) die("%s", err.buf); diff --git a/ref-filter.h b/ref-filter.h index 120221b47f..235c60f79c 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -41,7 +41,6 @@ enum ref_sorting_order { struct ref_array_item { struct object_id objectname; - struct object_id peeled_oid; const char *rest; int flag; unsigned int kind; @@ -188,7 +187,6 @@ void print_formatted_ref_array(struct ref_array *array, struct ref_format *forma * name must be a fully qualified refname. */ void pretty_print_ref(const char *name, const struct object_id *oid, - const struct object_id *peeled_oid, struct ref_format *format); /* @@ -197,8 +195,7 @@ void pretty_print_ref(const char *name, const struct object_id *oid, */ struct ref_array_item *ref_array_push(struct ref_array *array, const char *refname, - const struct object_id *oid, - const struct object_id *peeled_oid); + const struct object_id *oid); /* * If the provided format includes ahead-behind atoms, then compute the @@ -423,13 +423,16 @@ int should_expire_reflog_ent_verbose(struct object_id *ooid, return expire; } -static int push_tip_to_list(const struct reference *ref, void *cb_data) +static int push_tip_to_list(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags, void *cb_data) { struct commit_list **list = cb_data; struct commit *tip_commit; - if (ref->flags & REF_ISSYMREF) + if (flags & REF_ISSYMREF) return 0; - tip_commit = lookup_commit_reference_gently(the_repository, ref->oid, 1); + tip_commit = lookup_commit_reference_gently(the_repository, oid, 1); if (!tip_commit) return 0; commit_list_insert(tip_commit, list); @@ -426,19 +426,17 @@ int refs_ref_exists(struct ref_store *refs, const char *refname) NULL, NULL); } -static int for_each_filter_refs(const struct reference *ref, void *data) +static int for_each_filter_refs(const char *refname, const char *referent, + const struct object_id *oid, + int flags, void *data) { struct for_each_ref_filter *filter = data; - if (wildmatch(filter->pattern, ref->name, 0)) + if (wildmatch(filter->pattern, refname, 0)) return 0; - if (filter->prefix) { - struct reference skipped = *ref; - skip_prefix(skipped.name, filter->prefix, &skipped.name); - return filter->fn(&skipped, filter->cb_data); - } else { - return filter->fn(ref, filter->cb_data); - } + if (filter->prefix) + skip_prefix(refname, filter->prefix, &refname); + return filter->fn(refname, referent, oid, flags, filter->cb_data); } struct warn_if_dangling_data { @@ -449,15 +447,17 @@ struct warn_if_dangling_data { int dry_run; }; -static int warn_if_dangling_symref(const struct reference *ref, void *cb_data) +static int warn_if_dangling_symref(const char *refname, const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags, void *cb_data) { struct warn_if_dangling_data *d = cb_data; const char *resolves_to, *msg; - if (!(ref->flags & REF_ISSYMREF)) + if (!(flags & REF_ISSYMREF)) return 0; - resolves_to = refs_resolve_ref_unsafe(d->refs, ref->name, 0, NULL, NULL); + resolves_to = refs_resolve_ref_unsafe(d->refs, refname, 0, NULL, NULL); if (!resolves_to || !string_list_has_string(d->refnames, resolves_to)) { return 0; @@ -466,7 +466,7 @@ static int warn_if_dangling_symref(const struct reference *ref, void *cb_data) msg = d->dry_run ? _("%s%s will become dangling after %s is deleted\n") : _("%s%s has become dangling after %s was deleted\n"); - fprintf(d->fp, msg, d->indent, ref->name, resolves_to); + fprintf(d->fp, msg, d->indent, refname, resolves_to); return 0; } @@ -507,15 +507,8 @@ int refs_head_ref_namespaced(struct ref_store *refs, each_ref_fn fn, void *cb_da int flag; strbuf_addf(&buf, "%sHEAD", get_git_namespace()); - if (!refs_read_ref_full(refs, buf.buf, RESOLVE_REF_READING, &oid, &flag)) { - struct reference ref = { - .name = buf.buf, - .oid = &oid, - .flags = flag, - }; - - ret = fn(&ref, cb_data); - } + if (!refs_read_ref_full(refs, buf.buf, RESOLVE_REF_READING, &oid, &flag)) + ret = fn(buf.buf, NULL, &oid, flag, cb_data); strbuf_release(&buf); return ret; @@ -1748,15 +1741,8 @@ int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) int flag; if (refs_resolve_ref_unsafe(refs, "HEAD", RESOLVE_REF_READING, - &oid, &flag)) { - struct reference ref = { - .name = "HEAD", - .oid = &oid, - .flags = flag, - }; - - return fn(&ref, cb_data); - } + &oid, &flag)) + return fn("HEAD", NULL, &oid, flag, cb_data); return 0; } @@ -2324,16 +2310,14 @@ int refs_optimize(struct ref_store *refs, struct pack_refs_opts *opts) return refs->be->optimize(refs, opts); } -int reference_get_peeled_oid(struct repository *repo, - const struct reference *ref, - struct object_id *peeled_oid) +int peel_iterated_oid(struct repository *r, const struct object_id *base, struct object_id *peeled) { - if (ref->peeled_oid) { - oidcpy(peeled_oid, ref->peeled_oid); - return 0; - } + if (current_ref_iter && + (current_ref_iter->oid == base || + oideq(current_ref_iter->oid, base))) + return ref_iterator_peel(current_ref_iter, peeled); - return peel_object(repo, ref->oid, peeled_oid, 0) ? -1 : 0; + return peel_object(r, base, peeled) ? -1 : 0; } int refs_update_symref(struct ref_store *refs, const char *ref, @@ -2705,7 +2689,7 @@ enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs while ((ok = ref_iterator_advance(iter)) == ITER_OK) { if (skip && - string_list_has_string(skip, iter->ref.name)) + string_list_has_string(skip, iter->refname)) continue; if (transaction && ref_transaction_maybe_set_rejected( @@ -2714,7 +2698,7 @@ enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs continue; strbuf_addf(err, _("'%s' exists; cannot create '%s'"), - iter->ref.name, refname); + iter->refname, refname); goto cleanup; } @@ -2769,10 +2753,14 @@ struct do_for_each_reflog_help { void *cb_data; }; -static int do_for_each_reflog_helper(const struct reference *ref, void *cb_data) +static int do_for_each_reflog_helper(const char *refname, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, + void *cb_data) { struct do_for_each_reflog_help *hp = cb_data; - return hp->fn(ref->name, hp->cb_data); + return hp->fn(refname, hp->cb_data); } int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data) @@ -2988,24 +2976,25 @@ struct migration_data { uint64_t index; }; -static int migrate_one_ref(const struct reference *ref, void *cb_data) +static int migrate_one_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flags, void *cb_data) { struct migration_data *data = cb_data; struct strbuf symref_target = STRBUF_INIT; int ret; - if (ref->flags & REF_ISSYMREF) { - ret = refs_read_symbolic_ref(data->old_refs, ref->name, &symref_target); + if (flags & REF_ISSYMREF) { + ret = refs_read_symbolic_ref(data->old_refs, refname, &symref_target); if (ret < 0) goto done; - ret = ref_transaction_update(data->transaction, ref->name, NULL, null_oid(the_hash_algo), + ret = ref_transaction_update(data->transaction, refname, NULL, null_oid(the_hash_algo), symref_target.buf, NULL, REF_SKIP_CREATE_REFLOG | REF_NO_DEREF, NULL, data->errbuf); if (ret < 0) goto done; } else { - ret = ref_transaction_create(data->transaction, ref->name, ref->oid, NULL, + ret = ref_transaction_create(data->transaction, refname, oid, NULL, REF_SKIP_CREATE_REFLOG | REF_SKIP_OID_VERIFICATION, NULL, data->errbuf); if (ret < 0) @@ -333,74 +333,36 @@ struct ref_transaction; * stored in ref_iterator::flags. Other bits are for internal use * only: */ -enum reference_status { - /* Reference is a symbolic reference. */ - REF_ISSYMREF = (1 << 0), - /* Reference is a packed reference. */ - REF_ISPACKED = (1 << 1), +/* Reference is a symbolic reference. */ +#define REF_ISSYMREF 0x01 - /* - * Reference cannot be resolved to an object name: dangling symbolic - * reference (directly or indirectly), corrupt reference file, - * reference exists but name is bad, or symbolic reference refers to - * ill-formatted reference name. - */ - REF_ISBROKEN = (1 << 2), - - /* - * Reference name is not well formed. - * - * See git-check-ref-format(1) for the definition of well formed ref names. - */ - REF_BAD_NAME = (1 << 3), -}; - -/* A reference passed to `for_each_ref()`-style callbacks. */ -struct reference { - /* The fully-qualified name of the reference. */ - const char *name; - - /* The target of a symbolic ref. `NULL` for direct references. */ - const char *target; - - /* - * The object ID of a reference. Either the direct object ID or the - * resolved object ID in the case of a symbolic ref. May be the zero - * object ID in case the symbolic ref cannot be resolved. - */ - const struct object_id *oid; +/* Reference is a packed reference. */ +#define REF_ISPACKED 0x02 - /* - * An optional peeled object ID. This field _may_ be set for tags in - * case the peeled value is present in the backend. Please refer to - * `reference_get_peeled_oid()`. - */ - const struct object_id *peeled_oid; - - /* A bitfield of `enum reference_status` flags. */ - unsigned flags; -}; +/* + * Reference cannot be resolved to an object name: dangling symbolic + * reference (directly or indirectly), corrupt reference file, + * reference exists but name is bad, or symbolic reference refers to + * ill-formatted reference name. + */ +#define REF_ISBROKEN 0x04 /* - * Peel the tag to a non-tag commit. If present, this uses the peeled object ID - * exposed by the reference backend. Otherwise, the object is peeled via the - * object database, which is less efficient. + * Reference name is not well formed. * - * Return `0` if the reference could be peeled, a negative error code - * otherwise. + * See git-check-ref-format(1) for the definition of well formed ref names. */ -int reference_get_peeled_oid(struct repository *repo, - const struct reference *ref, - struct object_id *peeled_oid); +#define REF_BAD_NAME 0x08 /* * The signature for the callback function for the for_each_*() - * functions below. The memory pointed to by the `struct reference` - * argument is only guaranteed to be valid for the duration of a + * functions below. The memory pointed to by the refname and oid + * arguments is only guaranteed to be valid for the duration of a * single callback invocation. */ -typedef int each_ref_fn(const struct reference *ref, void *cb_data); +typedef int each_ref_fn(const char *refname, const char *referent, + const struct object_id *oid, int flags, void *cb_data); /* * The following functions invoke the specified callback function for @@ -1289,6 +1251,10 @@ int repo_migrate_ref_storage_format(struct repository *repo, * to the next entry, ref_iterator_advance() aborts the iteration, * frees the ref_iterator, and returns ITER_ERROR. * + * The reference currently being looked at can be peeled by calling + * ref_iterator_peel(). This function is often faster than peel_ref(), + * so it should be preferred when iterating over references. + * * Putting it all together, a typical iteration looks like this: * * int ok; @@ -1303,6 +1269,9 @@ int repo_migrate_ref_storage_format(struct repository *repo, * // Access information about the current reference: * if (!(iter->flags & REF_ISSYMREF)) * printf("%s is %s\n", iter->refname, oid_to_hex(iter->oid)); + * + * // If you need to peel the reference: + * ref_iterator_peel(iter, &oid); * } * * if (ok != ITER_DONE) @@ -1393,6 +1362,13 @@ enum ref_iterator_seek_flag { int ref_iterator_seek(struct ref_iterator *ref_iterator, const char *refname, unsigned int flags); +/* + * If possible, peel the reference currently being viewed by the + * iterator. Return 0 on success. + */ +int ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled); + /* Free the reference iterator and any associated resources. */ void ref_iterator_free(struct ref_iterator *ref_iterator); diff --git a/refs/debug.c b/refs/debug.c index f38991c02a..c59c1728a3 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -168,9 +168,11 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator) trace_printf_key(&trace_refs, "iterator_advance: (%d)\n", res); else trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n", - diter->iter->ref.name); + diter->iter->refname); - diter->base.ref = diter->iter->ref; + diter->base.refname = diter->iter->refname; + diter->base.oid = diter->iter->oid; + diter->base.flags = diter->iter->flags; return res; } @@ -185,6 +187,16 @@ static int debug_ref_iterator_seek(struct ref_iterator *ref_iterator, return res; } +static int debug_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct debug_ref_iterator *diter = + (struct debug_ref_iterator *)ref_iterator; + int res = diter->iter->vtable->peel(diter->iter, peeled); + trace_printf_key(&trace_refs, "iterator_peel: %s: %d\n", diter->iter->refname, res); + return res; +} + static void debug_ref_iterator_release(struct ref_iterator *ref_iterator) { struct debug_ref_iterator *diter = @@ -196,6 +208,7 @@ static void debug_ref_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable debug_ref_iterator_vtable = { .advance = debug_ref_iterator_advance, .seek = debug_ref_iterator_seek, + .peel = debug_ref_iterator_peel, .release = debug_ref_iterator_release, }; diff --git a/refs/files-backend.c b/refs/files-backend.c index f4809edda8..054cf42f4e 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -961,23 +961,26 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator) while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) { if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY && - parse_worktree_ref(iter->iter0->ref.name, NULL, NULL, + parse_worktree_ref(iter->iter0->refname, NULL, NULL, NULL) != REF_WORKTREE_CURRENT) continue; if ((iter->flags & DO_FOR_EACH_OMIT_DANGLING_SYMREFS) && - (iter->iter0->ref.flags & REF_ISSYMREF) && - (iter->iter0->ref.flags & REF_ISBROKEN)) + (iter->iter0->flags & REF_ISSYMREF) && + (iter->iter0->flags & REF_ISBROKEN)) continue; if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && - !ref_resolves_to_object(iter->iter0->ref.name, + !ref_resolves_to_object(iter->iter0->refname, iter->repo, - iter->iter0->ref.oid, - iter->iter0->ref.flags)) + iter->iter0->oid, + iter->iter0->flags)) continue; - iter->base.ref = iter->iter0->ref; + iter->base.refname = iter->iter0->refname; + iter->base.oid = iter->iter0->oid; + iter->base.flags = iter->iter0->flags; + iter->base.referent = iter->iter0->referent; return ITER_OK; } @@ -993,6 +996,15 @@ static int files_ref_iterator_seek(struct ref_iterator *ref_iterator, return ref_iterator_seek(iter->iter0, refname, flags); } +static int files_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct files_ref_iterator *iter = + (struct files_ref_iterator *)ref_iterator; + + return ref_iterator_peel(iter->iter0, peeled); +} + static void files_ref_iterator_release(struct ref_iterator *ref_iterator) { struct files_ref_iterator *iter = @@ -1003,6 +1015,7 @@ static void files_ref_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable files_ref_iterator_vtable = { .advance = files_ref_iterator_advance, .seek = files_ref_iterator_seek, + .peel = files_ref_iterator_peel, .release = files_ref_iterator_release, }; @@ -1354,29 +1367,30 @@ static void prune_refs(struct files_ref_store *refs, struct ref_to_prune **refs_ * Return true if the specified reference should be packed. */ static int should_pack_ref(struct files_ref_store *refs, - const struct reference *ref, + const char *refname, + const struct object_id *oid, unsigned int ref_flags, struct pack_refs_opts *opts) { struct string_list_item *item; /* Do not pack per-worktree refs: */ - if (parse_worktree_ref(ref->name, NULL, NULL, NULL) != + if (parse_worktree_ref(refname, NULL, NULL, NULL) != REF_WORKTREE_SHARED) return 0; /* Do not pack symbolic refs: */ - if (ref->flags & REF_ISSYMREF) + if (ref_flags & REF_ISSYMREF) return 0; /* Do not pack broken refs: */ - if (!ref_resolves_to_object(ref->name, refs->base.repo, ref->oid, ref->flags)) + if (!ref_resolves_to_object(refname, refs->base.repo, oid, ref_flags)) return 0; - if (ref_excluded(opts->exclusions, ref->name)) + if (ref_excluded(opts->exclusions, refname)) return 0; for_each_string_list_item(item, opts->includes) - if (!wildmatch(item->string, ref->name, 0)) + if (!wildmatch(item->string, refname, 0)) return 1; return 0; @@ -1429,7 +1443,8 @@ static int should_pack_refs(struct files_ref_store *refs, iter = cache_ref_iterator_begin(get_loose_ref_cache(refs, 0), NULL, refs->base.repo, 0); while ((ret = ref_iterator_advance(iter)) == ITER_OK) { - if (should_pack_ref(refs, &iter->ref, opts)) + if (should_pack_ref(refs, iter->refname, iter->oid, + iter->flags, opts)) refcount++; if (refcount >= limit) { ref_iterator_free(iter); @@ -1474,24 +1489,24 @@ static int files_pack_refs(struct ref_store *ref_store, * in the packed ref cache. If the reference should be * pruned, also add it to refs_to_prune. */ - if (!should_pack_ref(refs, &iter->ref, opts)) + if (!should_pack_ref(refs, iter->refname, iter->oid, iter->flags, opts)) continue; /* * Add a reference creation for this reference to the * packed-refs transaction: */ - if (ref_transaction_update(transaction, iter->ref.name, - iter->ref.oid, NULL, NULL, NULL, + if (ref_transaction_update(transaction, iter->refname, + iter->oid, NULL, NULL, NULL, REF_NO_DEREF, NULL, &err)) die("failure preparing to create packed reference %s: %s", - iter->ref.name, err.buf); + iter->refname, err.buf); /* Schedule the loose reference for pruning if requested. */ if ((opts->flags & PACK_REFS_PRUNE)) { struct ref_to_prune *n; - FLEX_ALLOC_STR(n, name, iter->ref.name); - oidcpy(&n->oid, iter->ref.oid); + FLEX_ALLOC_STR(n, name, iter->refname); + oidcpy(&n->oid, iter->oid); n->next = refs_to_prune; refs_to_prune = n; } @@ -2379,7 +2394,7 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) REFNAME_ALLOW_ONELEVEL)) continue; - iter->base.ref.name = diter->relative_path; + iter->base.refname = diter->relative_path; return ITER_OK; } @@ -2393,6 +2408,12 @@ static int files_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSED, BUG("ref_iterator_seek() called for reflog_iterator"); } +static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED, + struct object_id *peeled UNUSED) +{ + BUG("ref_iterator_peel() called for reflog_iterator"); +} + static void files_reflog_iterator_release(struct ref_iterator *ref_iterator) { struct files_reflog_iterator *iter = @@ -2403,6 +2424,7 @@ static void files_reflog_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable files_reflog_iterator_vtable = { .advance = files_reflog_iterator_advance, .seek = files_reflog_iterator_seek, + .peel = files_reflog_iterator_peel, .release = files_reflog_iterator_release, }; @@ -3143,11 +3165,14 @@ static int parse_and_write_reflog(struct files_ref_store *refs, return 0; } -static int ref_present(const struct reference *ref, void *cb_data) +static int ref_present(const char *refname, const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, + void *cb_data) { struct string_list *affected_refnames = cb_data; - return string_list_has_string(affected_refnames, ref->name); + return string_list_has_string(affected_refnames, refname); } static int files_transaction_finish_initial(struct files_ref_store *refs, diff --git a/refs/iterator.c b/refs/iterator.c index d79aa5ec82..17ef841d8a 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -21,6 +21,12 @@ int ref_iterator_seek(struct ref_iterator *ref_iterator, const char *refname, return ref_iterator->vtable->seek(ref_iterator, refname, flags); } +int ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + return ref_iterator->vtable->peel(ref_iterator, peeled); +} + void ref_iterator_free(struct ref_iterator *ref_iterator) { if (ref_iterator) { @@ -35,7 +41,10 @@ void base_ref_iterator_init(struct ref_iterator *iter, struct ref_iterator_vtable *vtable) { iter->vtable = vtable; - memset(&iter->ref, 0, sizeof(iter->ref)); + iter->refname = NULL; + iter->referent = NULL; + iter->oid = NULL; + iter->flags = 0; } struct empty_ref_iterator { @@ -54,6 +63,12 @@ static int empty_ref_iterator_seek(struct ref_iterator *ref_iterator UNUSED, return 0; } +static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator UNUSED, + struct object_id *peeled UNUSED) +{ + BUG("peel called for empty iterator"); +} + static void empty_ref_iterator_release(struct ref_iterator *ref_iterator UNUSED) { } @@ -61,6 +76,7 @@ static void empty_ref_iterator_release(struct ref_iterator *ref_iterator UNUSED) static struct ref_iterator_vtable empty_ref_iterator_vtable = { .advance = empty_ref_iterator_advance, .seek = empty_ref_iterator_seek, + .peel = empty_ref_iterator_peel, .release = empty_ref_iterator_release, }; @@ -111,8 +127,8 @@ enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree, * latter. */ if (iter_worktree) { - int cmp = strcmp(iter_worktree->ref.name, - iter_common->ref.name); + int cmp = strcmp(iter_worktree->refname, + iter_common->refname); if (cmp < 0) return ITER_SELECT_0; else if (!cmp) @@ -123,7 +139,7 @@ enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree, * We now know that the lexicographically-next ref is a common * ref. When the common ref is a shared one we return it. */ - if (parse_worktree_ref(iter_common->ref.name, NULL, NULL, + if (parse_worktree_ref(iter_common->refname, NULL, NULL, NULL) == REF_WORKTREE_SHARED) return ITER_SELECT_1; @@ -196,7 +212,10 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator) } if (selection & ITER_YIELD_CURRENT) { - iter->base.ref = (*iter->current)->ref; + iter->base.referent = (*iter->current)->referent; + iter->base.refname = (*iter->current)->refname; + iter->base.oid = (*iter->current)->oid; + iter->base.flags = (*iter->current)->flags; return ITER_OK; } } @@ -227,6 +246,18 @@ static int merge_ref_iterator_seek(struct ref_iterator *ref_iterator, return 0; } +static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct merge_ref_iterator *iter = + (struct merge_ref_iterator *)ref_iterator; + + if (!iter->current) { + BUG("peel called before advance for merge iterator"); + } + return ref_iterator_peel(*iter->current, peeled); +} + static void merge_ref_iterator_release(struct ref_iterator *ref_iterator) { struct merge_ref_iterator *iter = @@ -238,6 +269,7 @@ static void merge_ref_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable merge_ref_iterator_vtable = { .advance = merge_ref_iterator_advance, .seek = merge_ref_iterator_seek, + .peel = merge_ref_iterator_peel, .release = merge_ref_iterator_release, }; @@ -281,7 +313,7 @@ static enum iterator_selection overlay_iterator_select( else if (!front) return ITER_SELECT_1; - cmp = strcmp(front->ref.name, back->ref.name); + cmp = strcmp(front->refname, back->refname); if (cmp < 0) return ITER_SELECT_0; @@ -339,7 +371,7 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator) int ok; while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) { - int cmp = compare_prefix(iter->iter0->ref.name, iter->prefix); + int cmp = compare_prefix(iter->iter0->refname, iter->prefix); if (cmp < 0) continue; /* @@ -350,8 +382,6 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator) if (cmp > 0) return ITER_DONE; - iter->base.ref = iter->iter0->ref; - if (iter->trim) { /* * It is nonsense to trim off characters that @@ -362,11 +392,15 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator) * one character left in the refname after * trimming, report it as a bug: */ - if (strlen(iter->base.ref.name) <= iter->trim) + if (strlen(iter->iter0->refname) <= iter->trim) BUG("attempt to trim too many characters"); - iter->base.ref.name += iter->trim; + iter->base.refname = iter->iter0->refname + iter->trim; + } else { + iter->base.refname = iter->iter0->refname; } + iter->base.oid = iter->iter0->oid; + iter->base.flags = iter->iter0->flags; return ITER_OK; } @@ -386,6 +420,15 @@ static int prefix_ref_iterator_seek(struct ref_iterator *ref_iterator, return ref_iterator_seek(iter->iter0, refname, flags); } +static int prefix_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct prefix_ref_iterator *iter = + (struct prefix_ref_iterator *)ref_iterator; + + return ref_iterator_peel(iter->iter0, peeled); +} + static void prefix_ref_iterator_release(struct ref_iterator *ref_iterator) { struct prefix_ref_iterator *iter = @@ -397,6 +440,7 @@ static void prefix_ref_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable prefix_ref_iterator_vtable = { .advance = prefix_ref_iterator_advance, .seek = prefix_ref_iterator_seek, + .peel = prefix_ref_iterator_peel, .release = prefix_ref_iterator_release, }; @@ -422,18 +466,23 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, return ref_iterator; } +struct ref_iterator *current_ref_iter = NULL; + int do_for_each_ref_iterator(struct ref_iterator *iter, each_ref_fn fn, void *cb_data) { int retval = 0, ok; + struct ref_iterator *old_ref_iter = current_ref_iter; + current_ref_iter = iter; while ((ok = ref_iterator_advance(iter)) == ITER_OK) { - retval = fn(&iter->ref, cb_data); + retval = fn(iter->refname, iter->referent, iter->oid, iter->flags, cb_data); if (retval) goto out; } out: + current_ref_iter = old_ref_iter; if (ok == ITER_ERROR) retval = -1; ref_iterator_free(iter); diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 1ab0c50393..a8c22a0a7f 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -882,7 +882,6 @@ static int next_record(struct packed_ref_iterator *iter) { const char *p, *eol; - memset(&iter->base.ref, 0, sizeof(iter->base.ref)); strbuf_reset(&iter->refname_buf); /* @@ -909,7 +908,7 @@ static int next_record(struct packed_ref_iterator *iter) if (iter->pos == iter->eof) return ITER_DONE; - iter->base.ref.flags = REF_ISPACKED; + iter->base.flags = REF_ISPACKED; p = iter->pos; if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 2 || @@ -917,7 +916,6 @@ static int next_record(struct packed_ref_iterator *iter) !isspace(*p++)) die_invalid_line(iter->snapshot->refs->path, iter->pos, iter->eof - iter->pos); - iter->base.ref.oid = &iter->oid; eol = memchr(p, '\n', iter->eof - p); if (!eol) @@ -925,22 +923,22 @@ static int next_record(struct packed_ref_iterator *iter) iter->pos, iter->eof - iter->pos); strbuf_add(&iter->refname_buf, p, eol - p); - iter->base.ref.name = iter->refname_buf.buf; + iter->base.refname = iter->refname_buf.buf; if (refname_contains_nul(&iter->refname_buf)) - die("packed refname contains embedded NULL: %s", iter->base.ref.name); + die("packed refname contains embedded NULL: %s", iter->base.refname); - if (check_refname_format(iter->base.ref.name, REFNAME_ALLOW_ONELEVEL)) { - if (!refname_is_safe(iter->base.ref.name)) + if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) { + if (!refname_is_safe(iter->base.refname)) die("packed refname is dangerous: %s", - iter->base.ref.name); + iter->base.refname); oidclr(&iter->oid, iter->repo->hash_algo); - iter->base.ref.flags |= REF_BAD_NAME | REF_ISBROKEN; + iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN; } if (iter->snapshot->peeled == PEELED_FULLY || (iter->snapshot->peeled == PEELED_TAGS && - starts_with(iter->base.ref.name, "refs/tags/"))) - iter->base.ref.flags |= REF_KNOWS_PEELED; + starts_with(iter->base.refname, "refs/tags/"))) + iter->base.flags |= REF_KNOWS_PEELED; iter->pos = eol + 1; @@ -958,12 +956,11 @@ static int next_record(struct packed_ref_iterator *iter) * definitely know the value of *this* reference. But * we suppress it if the reference is broken: */ - if ((iter->base.ref.flags & REF_ISBROKEN)) { + if ((iter->base.flags & REF_ISBROKEN)) { oidclr(&iter->peeled, iter->repo->hash_algo); - iter->base.ref.flags &= ~REF_KNOWS_PEELED; + iter->base.flags &= ~REF_KNOWS_PEELED; } else { - iter->base.ref.flags |= REF_KNOWS_PEELED; - iter->base.ref.peeled_oid = &iter->peeled; + iter->base.flags |= REF_KNOWS_PEELED; } } else { oidclr(&iter->peeled, iter->repo->hash_algo); @@ -979,15 +976,15 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator) int ok; while ((ok = next_record(iter)) == ITER_OK) { - const char *refname = iter->base.ref.name; + const char *refname = iter->base.refname; const char *prefix = iter->prefix; if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY && - !is_per_worktree_ref(iter->base.ref.name)) + !is_per_worktree_ref(iter->base.refname)) continue; if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && - !ref_resolves_to_object(iter->base.ref.name, iter->repo, + !ref_resolves_to_object(iter->base.refname, iter->repo, &iter->oid, iter->flags)) continue; @@ -1030,6 +1027,22 @@ static int packed_ref_iterator_seek(struct ref_iterator *ref_iterator, return 0; } +static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct packed_ref_iterator *iter = + (struct packed_ref_iterator *)ref_iterator; + + if ((iter->base.flags & REF_KNOWS_PEELED)) { + oidcpy(peeled, &iter->peeled); + return is_null_oid(&iter->peeled) ? -1 : 0; + } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) { + return -1; + } else { + return peel_object(iter->repo, &iter->oid, peeled) ? -1 : 0; + } +} + static void packed_ref_iterator_release(struct ref_iterator *ref_iterator) { struct packed_ref_iterator *iter = @@ -1043,6 +1056,7 @@ static void packed_ref_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable packed_ref_iterator_vtable = { .advance = packed_ref_iterator_advance, .seek = packed_ref_iterator_seek, + .peel = packed_ref_iterator_peel, .release = packed_ref_iterator_release, }; @@ -1180,6 +1194,7 @@ static struct ref_iterator *packed_ref_iterator_begin( iter->snapshot = snapshot; acquire_snapshot(snapshot); strbuf_init(&iter->refname_buf, 0); + iter->base.oid = &iter->oid; iter->repo = ref_store->repo; iter->flags = flags; @@ -1421,7 +1436,7 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re if (!iter) cmp = +1; else - cmp = strcmp(iter->ref.name, update->refname); + cmp = strcmp(iter->refname, update->refname); } if (!cmp) { @@ -1444,11 +1459,11 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re } goto error; - } else if (!oideq(&update->old_oid, iter->ref.oid)) { + } else if (!oideq(&update->old_oid, iter->oid)) { strbuf_addf(err, "cannot update ref '%s': " "is at %s but expected %s", update->refname, - oid_to_hex(iter->ref.oid), + oid_to_hex(iter->oid), oid_to_hex(&update->old_oid)); ret = REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE; @@ -1508,8 +1523,13 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re if (cmp < 0) { /* Pass the old reference through. */ - if (write_packed_entry(out, iter->ref.name, - iter->ref.oid, iter->ref.peeled_oid)) + + struct object_id peeled; + int peel_error = ref_iterator_peel(iter, &peeled); + + if (write_packed_entry(out, iter->refname, + iter->oid, + peel_error ? NULL : &peeled)) goto write_error; if ((ok = ref_iterator_advance(iter)) != ITER_OK) { @@ -1527,8 +1547,9 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re i++; } else { struct object_id peeled; - int peel_error = peel_object(refs->base.repo, &update->new_oid, - &peeled, PEEL_OBJECT_VERIFY_OBJECT_TYPE); + int peel_error = peel_object(refs->base.repo, + &update->new_oid, + &peeled); if (write_packed_entry(out, update->refname, &update->new_oid, diff --git a/refs/ref-cache.c b/refs/ref-cache.c index ffef01a597..e5e5df16d8 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -425,11 +425,10 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator) level->prefix_state = entry_prefix_state; level->index = -1; } else { - memset(&iter->base.ref, 0, sizeof(iter->base.ref)); - iter->base.ref.name = entry->name; - iter->base.ref.target = entry->u.value.referent; - iter->base.ref.oid = &entry->u.value.oid; - iter->base.ref.flags = entry->flag; + iter->base.refname = entry->name; + iter->base.referent = entry->u.value.referent; + iter->base.oid = &entry->u.value.oid; + iter->base.flags = entry->flag; return ITER_OK; } } @@ -546,6 +545,14 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator, return 0; } +static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct cache_ref_iterator *iter = + (struct cache_ref_iterator *)ref_iterator; + return peel_object(iter->repo, ref_iterator->oid, peeled) ? -1 : 0; +} + static void cache_ref_iterator_release(struct ref_iterator *ref_iterator) { struct cache_ref_iterator *iter = @@ -557,6 +564,7 @@ static void cache_ref_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable cache_ref_iterator_vtable = { .advance = cache_ref_iterator_advance, .seek = cache_ref_iterator_seek, + .peel = cache_ref_iterator_peel, .release = cache_ref_iterator_release, }; diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 4671517dad..4ef3bd75c6 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -249,7 +249,10 @@ const char *find_descendant_ref(const char *dirname, */ struct ref_iterator { struct ref_iterator_vtable *vtable; - struct reference ref; + const char *refname; + const char *referent; + const struct object_id *oid; + unsigned int flags; }; /* @@ -358,6 +361,12 @@ typedef int ref_iterator_seek_fn(struct ref_iterator *ref_iterator, const char *refname, unsigned int flags); /* + * Peels the current ref, returning 0 for success or -1 for failure. + */ +typedef int ref_iterator_peel_fn(struct ref_iterator *ref_iterator, + struct object_id *peeled); + +/* * Implementations of this function should free any resources specific * to the derived class. */ @@ -366,9 +375,23 @@ typedef void ref_iterator_release_fn(struct ref_iterator *ref_iterator); struct ref_iterator_vtable { ref_iterator_advance_fn *advance; ref_iterator_seek_fn *seek; + ref_iterator_peel_fn *peel; ref_iterator_release_fn *release; }; +/* + * current_ref_iter is a performance hack: when iterating over + * references using the for_each_ref*() functions, current_ref_iter is + * set to the reference iterator before calling the callback function. + * If the callback function calls peel_ref(), then peel_ref() first + * checks whether the reference to be peeled is the one referred to by + * the iterator (it usually is) and if so, asks the iterator for the + * peeled version of the reference if it is available. This avoids a + * refname lookup in a common case. current_ref_iter is set to NULL + * when the iteration is over. + */ +extern struct ref_iterator *current_ref_iter; + struct ref_store; /* refs backends */ diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 6bbfd5618d..d4b7928620 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -547,7 +547,6 @@ struct reftable_ref_iterator { struct reftable_iterator iter; struct reftable_ref_record ref; struct object_id oid; - struct object_id peeled_oid; char *prefix; size_t prefix_len; @@ -672,8 +671,6 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) case REFTABLE_REF_VAL2: oidread(&iter->oid, iter->ref.value.val2.value, refs->base.repo->hash_algo); - oidread(&iter->peeled_oid, iter->ref.value.val2.target_value, - refs->base.repo->hash_algo); break; case REFTABLE_REF_SYMREF: referent = refs_resolve_ref_unsafe(&iter->refs->base, @@ -707,13 +704,10 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) &iter->oid, flags)) continue; - memset(&iter->base.ref, 0, sizeof(iter->base.ref)); - iter->base.ref.name = iter->ref.refname; - iter->base.ref.target = referent; - iter->base.ref.oid = &iter->oid; - if (iter->ref.value_type == REFTABLE_REF_VAL2) - iter->base.ref.peeled_oid = &iter->peeled_oid; - iter->base.ref.flags = flags; + iter->base.refname = iter->ref.refname; + iter->base.referent = referent; + iter->base.oid = &iter->oid; + iter->base.flags = flags; break; } @@ -744,6 +738,21 @@ static int reftable_ref_iterator_seek(struct ref_iterator *ref_iterator, return iter->err; } +static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct reftable_ref_iterator *iter = + (struct reftable_ref_iterator *)ref_iterator; + + if (iter->ref.value_type == REFTABLE_REF_VAL2) { + oidread(peeled, iter->ref.value.val2.target_value, + iter->refs->base.repo->hash_algo); + return 0; + } + + return -1; +} + static void reftable_ref_iterator_release(struct ref_iterator *ref_iterator) { struct reftable_ref_iterator *iter = @@ -761,6 +770,7 @@ static void reftable_ref_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable reftable_ref_iterator_vtable = { .advance = reftable_ref_iterator_advance, .seek = reftable_ref_iterator_seek, + .peel = reftable_ref_iterator_peel, .release = reftable_ref_iterator_release, }; @@ -818,7 +828,7 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_ iter = xcalloc(1, sizeof(*iter)); base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable); - iter->base.ref.oid = &iter->oid; + iter->base.oid = &iter->oid; iter->flags = flags; iter->refs = refs; iter->exclude_patterns = filter_exclude_patterns(exclude_patterns); @@ -1632,8 +1642,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data ref.refname = (char *)u->refname; ref.update_index = ts; - peel_error = peel_object(arg->refs->base.repo, &u->new_oid, &peeled, - PEEL_OBJECT_VERIFY_OBJECT_TYPE); + peel_error = peel_object(arg->refs->base.repo, &u->new_oid, &peeled); if (!peel_error) { ref.value_type = REFTABLE_REF_VAL2; memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ); @@ -2063,7 +2072,7 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator) strbuf_reset(&iter->last_name); strbuf_addstr(&iter->last_name, iter->log.refname); - iter->base.ref.name = iter->log.refname; + iter->base.refname = iter->log.refname; break; } @@ -2083,6 +2092,13 @@ static int reftable_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSE return -1; } +static int reftable_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED, + struct object_id *peeled UNUSED) +{ + BUG("reftable reflog iterator cannot be peeled"); + return -1; +} + static void reftable_reflog_iterator_release(struct ref_iterator *ref_iterator) { struct reftable_reflog_iterator *iter = @@ -2095,6 +2111,7 @@ static void reftable_reflog_iterator_release(struct ref_iterator *ref_iterator) static struct ref_iterator_vtable reftable_reflog_iterator_vtable = { .advance = reftable_reflog_iterator_advance, .seek = reftable_reflog_iterator_seek, + .peel = reftable_reflog_iterator_peel, .release = reftable_reflog_iterator_release, }; @@ -2498,7 +2515,7 @@ static int write_reflog_expiry_table(struct reftable_writer *writer, void *cb_da ref.refname = (char *)arg->refname; ref.update_index = ts; - if (!peel_object(arg->refs->base.repo, &arg->update_oid, &peeled, 0)) { + if (!peel_object(arg->refs->base.repo, &arg->update_oid, &peeled)) { ref.value_type = REFTABLE_REF_VAL2; memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ); memcpy(ref.value.val2.value, arg->update_oid.hash, GIT_MAX_RAWSZ); @@ -2315,19 +2315,21 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb, return 1; } -static int one_local_ref(const struct reference *ref, void *cb_data) +static int one_local_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, + void *cb_data) { struct ref ***local_tail = cb_data; - struct ref *local_ref; + struct ref *ref; /* we already know it starts with refs/ to get here */ - if (check_refname_format(ref->name + 5, 0)) + if (check_refname_format(refname + 5, 0)) return 0; - local_ref = alloc_ref(ref->name); - oidcpy(&local_ref->new_oid, ref->oid); - **local_tail = local_ref; - *local_tail = &local_ref->next; + ref = alloc_ref(refname); + oidcpy(&ref->new_oid, oid); + **local_tail = ref; + *local_tail = &ref->next; return 0; } @@ -2400,14 +2402,15 @@ struct stale_heads_info { struct refspec *rs; }; -static int get_stale_heads_cb(const struct reference *ref, void *cb_data) +static int get_stale_heads_cb(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flags, void *cb_data) { struct stale_heads_info *info = cb_data; struct string_list matches = STRING_LIST_INIT_DUP; struct refspec_item query; int i, stale = 1; memset(&query, 0, sizeof(struct refspec_item)); - query.dst = (char *)ref->name; + query.dst = (char *)refname; refspec_find_all_matches(info->rs, &query, &matches); if (matches.nr == 0) @@ -2420,7 +2423,7 @@ static int get_stale_heads_cb(const struct reference *ref, void *cb_data) * overlapping refspecs, we need to go over all of the * matching refs. */ - if (ref->flags & REF_ISSYMREF) + if (flags & REF_ISSYMREF) goto clean_exit; for (i = 0; stale && i < matches.nr; i++) @@ -2428,8 +2431,8 @@ static int get_stale_heads_cb(const struct reference *ref, void *cb_data) stale = 0; if (stale) { - struct ref *linked_ref = make_linked_ref(ref->name, &info->stale_refs_tail); - oidcpy(&linked_ref->new_oid, ref->oid); + struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail); + oidcpy(&ref->new_oid, oid); } clean_exit: diff --git a/repack-midx.c b/repack-midx.c index 74bdfa3a6e..6f6202c5bc 100644 --- a/repack-midx.c +++ b/repack-midx.c @@ -16,23 +16,25 @@ struct midx_snapshot_ref_data { int preferred; }; -static int midx_snapshot_ref_one(const struct reference *ref, void *_data) +static int midx_snapshot_ref_one(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, void *_data) { struct midx_snapshot_ref_data *data = _data; - const struct object_id *maybe_peeled = ref->oid; struct object_id peeled; - if (!reference_get_peeled_oid(data->repo, ref, &peeled)) - maybe_peeled = &peeled; + if (!peel_iterated_oid(data->repo, oid, &peeled)) + oid = &peeled; - if (oidset_insert(&data->seen, maybe_peeled)) + if (oidset_insert(&data->seen, oid)) return 0; /* already seen */ - if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) != OBJ_COMMIT) + if (odb_read_object_info(data->repo->objects, oid, NULL) != OBJ_COMMIT) return 0; fprintf(data->f->fp, "%s%s\n", data->preferred ? "+" : "", - oid_to_hex(maybe_peeled)); + oid_to_hex(oid)); return 0; } diff --git a/replace-object.c b/replace-object.c index 03d0f1f083..3eae051074 100644 --- a/replace-object.c +++ b/replace-object.c @@ -8,27 +8,31 @@ #include "repository.h" #include "commit.h" -static int register_replace_ref(const struct reference *ref, void *cb_data) +static int register_replace_ref(const char *refname, + const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, + void *cb_data) { struct repository *r = cb_data; /* Get sha1 from refname */ - const char *slash = strrchr(ref->name, '/'); - const char *hash = slash ? slash + 1 : ref->name; + const char *slash = strrchr(refname, '/'); + const char *hash = slash ? slash + 1 : refname; struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj)); if (get_oid_hex_algop(hash, &repl_obj->original.oid, r->hash_algo)) { free(repl_obj); - warning(_("bad replace ref name: %s"), ref->name); + warning(_("bad replace ref name: %s"), refname); return 0; } /* Copy sha1 from the read ref */ - oidcpy(&repl_obj->replacement, ref->oid); + oidcpy(&repl_obj->replacement, oid); /* Register new object */ if (oidmap_put(&r->objects->replace_map, repl_obj)) - die(_("duplicate replace ref: %s"), ref->name); + die(_("duplicate replace ref: %s"), refname); return 0; } diff --git a/revision.c b/revision.c index 5f0850ae5c..cf5e6c1ec9 100644 --- a/revision.c +++ b/revision.c @@ -1644,17 +1644,19 @@ struct all_refs_cb { struct worktree *wt; }; -static int handle_one_ref(const struct reference *ref, void *cb_data) +static int handle_one_ref(const char *path, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, + void *cb_data) { struct all_refs_cb *cb = cb_data; struct object *object; - if (ref_excluded(&cb->all_revs->ref_excludes, ref->name)) + if (ref_excluded(&cb->all_revs->ref_excludes, path)) return 0; - object = get_reference(cb->all_revs, ref->name, ref->oid, cb->all_flags); - add_rev_cmdline(cb->all_revs, object, ref->name, REV_CMD_REF, cb->all_flags); - add_pending_object(cb->all_revs, object, ref->name); + object = get_reference(cb->all_revs, path, oid, cb->all_flags); + add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags); + add_pending_object(cb->all_revs, object, path); return 0; } diff --git a/server-info.c b/server-info.c index 4243e24edc..b9a710544a 100644 --- a/server-info.c +++ b/server-info.c @@ -148,21 +148,23 @@ out: return ret; } -static int add_info_ref(const struct reference *ref, void *cb_data) +static int add_info_ref(const char *path, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, + void *cb_data) { struct update_info_ctx *uic = cb_data; - struct object *o = parse_object(uic->repo, ref->oid); + struct object *o = parse_object(uic->repo, oid); if (!o) return -1; - if (uic_printf(uic, "%s %s\n", oid_to_hex(ref->oid), ref->name) < 0) + if (uic_printf(uic, "%s %s\n", oid_to_hex(oid), path) < 0) return -1; if (o->type == OBJ_TAG) { - o = deref_tag(uic->repo, o, ref->name, 0); + o = deref_tag(uic->repo, o, path, 0); if (o) if (uic_printf(uic, "%s %s^{}\n", - oid_to_hex(&o->oid), ref->name) < 0) + oid_to_hex(&o->oid), path) < 0) return -1; } return 0; @@ -626,10 +626,14 @@ static void paint_down(struct paint_info *info, const struct object_id *oid, free(tmp); } -static int mark_uninteresting(const struct reference *ref, void *cb_data UNUSED) +static int mark_uninteresting(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, + void *cb_data UNUSED) { struct commit *commit = lookup_commit_reference_gently(the_repository, - ref->oid, 1); + oid, 1); if (!commit) return 0; commit->object.flags |= UNINTERESTING; @@ -738,12 +742,16 @@ struct commit_array { size_t nr, alloc; }; -static int add_ref(const struct reference *ref, void *cb_data) +static int add_ref(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, + void *cb_data) { struct commit_array *ca = cb_data; ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc); ca->commits[ca->nr] = lookup_commit_reference_gently(the_repository, - ref->oid, 1); + oid, 1); if (ca->commits[ca->nr]) ca->nr++; return 0; diff --git a/submodule.c b/submodule.c index 40a5c6fb9d..35c55155f7 100644 --- a/submodule.c +++ b/submodule.c @@ -934,7 +934,10 @@ static void free_submodules_data(struct string_list *submodules) string_list_clear(submodules, 1); } -static int has_remote(const struct reference *ref UNUSED, void *cb_data UNUSED) +static int has_remote(const char *refname UNUSED, + const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, void *cb_data UNUSED) { return 1; } @@ -1252,10 +1255,13 @@ int push_unpushed_submodules(struct repository *r, return ret; } -static int append_oid_to_array(const struct reference *ref, void *data) +static int append_oid_to_array(const char *ref UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flags UNUSED, void *data) { struct oid_array *array = data; - oid_array_append(array, ref->oid); + oid_array_append(array, oid); return 0; } diff --git a/t/for-each-ref-tests.sh b/t/for-each-ref-tests.sh index 4593be5fd5..e3ad19298a 100644 --- a/t/for-each-ref-tests.sh +++ b/t/for-each-ref-tests.sh @@ -1809,9 +1809,7 @@ test_expect_success "${git_for_each_ref} reports broken tags" ' bad=$(git hash-object -w -t tag bad) && git update-ref refs/tags/broken-tag-bad $bad && test_must_fail ${git_for_each_ref} --format="%(*objectname)" \ - refs/tags/broken-tag-* && - test_must_fail ${git_for_each_ref} --format="%(*objectname)" \ - refs/tags/broken-tag-bad + refs/tags/broken-tag-* ' test_expect_success 'set up tag with signature and no blank lines' ' diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c index c58c93800f..028ec00306 100644 --- a/t/helper/test-reach.c +++ b/t/helper/test-reach.c @@ -63,7 +63,7 @@ int cmd__reach(int ac, const char **av) die("failed to resolve %s", buf.buf + 2); orig = parse_object(r, &oid); - peeled = deref_tag(the_repository, orig, NULL, 0); + peeled = deref_tag_noverify(the_repository, orig); if (!peeled) die("failed to load commit for input %s resulting in oid %s", diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index b1215947c5..83b06d39a3 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -154,9 +154,10 @@ static int cmd_rename_ref(struct ref_store *refs, const char **argv) return refs_rename_ref(refs, oldref, newref, logmsg); } -static int each_ref(const struct reference *ref, void *cb_data UNUSED) +static int each_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flags, void *cb_data UNUSED) { - printf("%s %s 0x%x\n", oid_to_hex(ref->oid), ref->name, ref->flags); + printf("%s %s 0x%x\n", oid_to_hex(oid), refname, flags); return 0; } diff --git a/t/pack-refs-tests.sh b/t/pack-refs-tests.sh index 095823d915..3dbcc01718 100644 --- a/t/pack-refs-tests.sh +++ b/t/pack-refs-tests.sh @@ -428,36 +428,4 @@ do ' done -test_expect_success 'pack-refs does not store invalid peeled tag value' ' - test_when_finished rm -rf repo && - git init repo && - ( - cd repo && - git commit --allow-empty --message initial && - - echo garbage >blob-content && - blob_id=$(git hash-object -w -t blob blob-content) && - - # Write an invalid tag into the object database. The tag itself - # is well-formed, but the tagged object is a blob while we - # claim that it is a commit. - cat >tag-content <<-EOF && - object $blob_id - type commit - tag bad-tag - tagger C O Mitter <committer@example.com> 1112354055 +0200 - - annotated - EOF - tag_id=$(git hash-object -w -t tag tag-content) && - git update-ref refs/tags/bad-tag "$tag_id" && - - # The packed-refs file should not contain the peeled object ID. - # If it did this would cause commands that use the peeled value - # to not notice this corrupted tag. - git pack-refs --all && - test_grep ! "^\^" .git/packed-refs - ) -' - test_done diff --git a/t/t0610-reftable-basics.sh b/t/t0610-reftable-basics.sh index 6575528f21..3ea5d51532 100755 --- a/t/t0610-reftable-basics.sh +++ b/t/t0610-reftable-basics.sh @@ -1135,32 +1135,4 @@ test_expect_success 'fetch: accessing FETCH_HEAD special ref works' ' test_cmp expect actual ' -test_expect_success 'writes do not persist peeled value for invalid tags' ' - test_when_finished rm -rf repo && - git init repo && - ( - cd repo && - git commit --allow-empty --message initial && - - # We cannot easily verify that the peeled value is not stored - # in the tables. Instead, we test this indirectly: we create - # two tags that both point to the same object, but they claim - # different object types. If we parse both tags we notice that - # the parsed tagged object has a mismatch between the two tags - # and bail out. - # - # If we instead use the persisted peeled value we would not - # even parse the tags. As such, we would not notice the - # discrepancy either and thus listing these tags would succeed. - git tag tag-1 -m "tag 1" && - git cat-file tag tag-1 >raw-tag && - sed "s/^type commit$/type blob/" <raw-tag >broken-tag && - broken_tag_id=$(git hash-object -w -t tag broken-tag) && - git update-ref refs/tags/tag-2 $broken_tag_id && - - test_must_fail git for-each-ref --format="%(*objectname)" refs/tags/ 2>err && - test_grep "bad tag pointer" err - ) -' - test_done @@ -94,6 +94,18 @@ struct object *deref_tag(struct repository *r, struct object *o, const char *war return o; } +struct object *deref_tag_noverify(struct repository *r, struct object *o) +{ + while (o && o->type == OBJ_TAG) { + o = parse_object(r, &o->oid); + if (o && o->type == OBJ_TAG && ((struct tag *)o)->tagged) + o = ((struct tag *)o)->tagged; + else + o = NULL; + } + return o; +} + struct tag *lookup_tag(struct repository *r, const struct object_id *oid) { struct object *obj = lookup_object(r, oid); @@ -16,6 +16,7 @@ int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, u int parse_tag(struct tag *item); void release_tag_memory(struct tag *t); struct object *deref_tag(struct repository *r, struct object *, const char *, int); +struct object *deref_tag_noverify(struct repository *r, struct object *); int gpg_verify_tag(const struct object_id *oid, const char *name_to_report, unsigned flags); struct object_id *get_tagged_oid(struct tag *tag); diff --git a/upload-pack.c b/upload-pack.c index 2d2b70cbf2..1e87ae9559 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -870,8 +870,8 @@ static void send_unshallow(struct upload_pack_data *data) } } -static int check_ref(const struct reference *ref, void *cb_data); - +static int check_ref(const char *refname_full, const char *referent UNUSED, const struct object_id *oid, + int flag, void *cb_data); static void deepen(struct upload_pack_data *data, int depth) { if (depth == INFINITE_DEPTH && !is_repository_shallow(the_repository)) { @@ -1224,12 +1224,13 @@ static int mark_our_ref(const char *refname, const char *refname_full, return 0; } -static int check_ref(const struct reference *ref, void *cb_data) +static int check_ref(const char *refname_full, const char *referent UNUSED,const struct object_id *oid, + int flag UNUSED, void *cb_data) { - const char *refname = strip_namespace(ref->name); + const char *refname = strip_namespace(refname_full); struct upload_pack_data *data = cb_data; - mark_our_ref(refname, ref->name, ref->oid, &data->hidden_refs); + mark_our_ref(refname, refname_full, oid, &data->hidden_refs); return 0; } @@ -1249,15 +1250,15 @@ static void format_session_id(struct strbuf *buf, struct upload_pack_data *d) { } static void write_v0_ref(struct upload_pack_data *data, - const struct reference *ref, - const char *refname_nons) + const char *refname, const char *refname_nons, + const struct object_id *oid) { static const char *capabilities = "multi_ack thin-pack side-band" " side-band-64k ofs-delta shallow deepen-since deepen-not" " deepen-relative no-progress include-tag multi_ack_detailed"; struct object_id peeled; - if (mark_our_ref(refname_nons, ref->name, ref->oid, &data->hidden_refs)) + if (mark_our_ref(refname_nons, refname, oid, &data->hidden_refs)) return; if (capabilities) { @@ -1267,7 +1268,7 @@ static void write_v0_ref(struct upload_pack_data *data, format_symref_info(&symref_info, &data->symref); format_session_id(&session_id, data); packet_fwrite_fmt(stdout, "%s %s%c%s%s%s%s%s%s%s object-format=%s agent=%s\n", - oid_to_hex(ref->oid), refname_nons, + oid_to_hex(oid), refname_nons, 0, capabilities, (data->allow_uor & ALLOW_TIP_SHA1) ? " allow-tip-sha1-in-want" : "", @@ -1283,33 +1284,35 @@ static void write_v0_ref(struct upload_pack_data *data, strbuf_release(&session_id); data->sent_capabilities = 1; } else { - packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(ref->oid), refname_nons); + packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(oid), refname_nons); } capabilities = NULL; - if (!reference_get_peeled_oid(the_repository, ref, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) packet_fwrite_fmt(stdout, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons); return; } -static int send_ref(const struct reference *ref, void *cb_data) +static int send_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, + int flag UNUSED, void *cb_data) { - write_v0_ref(cb_data, ref, strip_namespace(ref->name)); + write_v0_ref(cb_data, refname, strip_namespace(refname), oid); return 0; } -static int find_symref(const struct reference *ref, void *cb_data) +static int find_symref(const char *refname, const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flag, void *cb_data) { const char *symref_target; struct string_list_item *item; - int flag; - if ((ref->flags & REF_ISSYMREF) == 0) + if ((flag & REF_ISSYMREF) == 0) return 0; symref_target = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), - ref->name, 0, NULL, &flag); + refname, 0, NULL, &flag); if (!symref_target || (flag & REF_ISSYMREF) == 0) - die("'%s' is a symref but it is not?", ref->name); - item = string_list_append(cb_data, strip_namespace(ref->name)); + die("'%s' is a symref but it is not?", refname); + item = string_list_append(cb_data, strip_namespace(refname)); item->util = xstrdup(strip_namespace(symref_target)); return 0; } @@ -1442,12 +1445,8 @@ void upload_pack(const int advertise_refs, const int stateless_rpc, send_ref, &data); for_each_namespaced_ref_1(send_ref, &data); if (!data.sent_capabilities) { - struct reference ref = { - .name = "capabilities^{}", - .oid = null_oid(the_hash_algo), - }; - - write_v0_ref(&data, &ref, ref.name); + const char *refname = "capabilities^{}"; + write_v0_ref(&data, refname, refname, null_oid(the_hash_algo)); } /* * fflush stdout before calling advertise_shallow_grafts because send_ref @@ -226,10 +226,14 @@ static int interpret_target(struct walker *walker, char *target, struct object_i return -1; } -static int mark_complete(const struct reference *ref, void *cb_data UNUSED) +static int mark_complete(const char *path UNUSED, + const char *referent UNUSED, + const struct object_id *oid, + int flag UNUSED, + void *cb_data UNUSED) { struct commit *commit = lookup_commit_reference_gently(the_repository, - ref->oid, 1); + oid, 1); if (commit) { commit->object.flags |= COMPLETE; diff --git a/worktree.c b/worktree.c index 9308389cb6..a2a5f51f29 100644 --- a/worktree.c +++ b/worktree.c @@ -595,15 +595,8 @@ int other_head_refs(each_ref_fn fn, void *cb_data) if (refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname.buf, RESOLVE_REF_READING, - &oid, &flag)) { - struct reference ref = { - .name = refname.buf, - .oid = &oid, - .flags = flag, - }; - - ret = fn(&ref, cb_data); - } + &oid, &flag)) + ret = fn(refname.buf, NULL, &oid, flag, cb_data); if (ret) break; } |
