]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Revert "Merge branch 'ps/ref-peeled-tags' into next"
authorJunio C Hamano <gitster@pobox.com>
Tue, 4 Nov 2025 15:31:26 +0000 (07:31 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 4 Nov 2025 15:31:26 +0000 (07:31 -0800)
This reverts commit 8ac48a10de61267858d66383c34833e55a5e9d02, reversing
changes made to 9ab444edfb825dfbc555b3d7916df03071db94c3.

66 files changed:
bisect.c
builtin/bisect.c
builtin/checkout.c
builtin/describe.c
builtin/fetch.c
builtin/fsck.c
builtin/gc.c
builtin/ls-remote.c
builtin/name-rev.c
builtin/pack-objects.c
builtin/receive-pack.c
builtin/remote.c
builtin/replace.c
builtin/repo.c
builtin/rev-parse.c
builtin/show-branch.c
builtin/show-ref.c
builtin/submodule--helper.c
builtin/tag.c
builtin/verify-tag.c
builtin/worktree.c
commit-graph.c
delta-islands.c
fetch-pack.c
help.c
http-backend.c
log-tree.c
ls-refs.c
midx-write.c
negotiator/default.c
negotiator/skipping.c
notes.c
object-name.c
object.c
object.h
pseudo-merge.c
reachable.c
ref-filter.c
ref-filter.h
reflog.c
refs.c
refs.h
refs/debug.c
refs/files-backend.c
refs/iterator.c
refs/packed-backend.c
refs/ref-cache.c
refs/refs-internal.h
refs/reftable-backend.c
remote.c
repack-midx.c
replace-object.c
revision.c
server-info.c
shallow.c
submodule.c
t/for-each-ref-tests.sh
t/helper/test-reach.c
t/helper/test-ref-store.c
t/pack-refs-tests.sh
t/t0610-reftable-basics.sh
tag.c
tag.h
upload-pack.c
walker.c
worktree.c

index 326b59c0dc70e7fe67eeadfb2d691790262d7bbc..a6dc76b15c910b9963b556b66aa3d2c63834bed9 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -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;
 }
 
index 4cc118fb57df59dcb4b799550e82b703c26968b0..ccff4e1a1b2483860f9ab9916365d921ff2d20f5 100644 (file)
@@ -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;
 }
 
index 66b69df6e67234a5c67525abd4c432490ba561e9..f9453473fe2a20076fd878bfb921f96e4ff7cc39 100644 (file)
@@ -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;
 }
 
index 443546aaac96f0371b5414013b0ee41848633622..ffaf8d9f0aa6ea84a73770fbca596993a34843e5 100644 (file)
@@ -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;
 }
 
index 7052e6ff215ead8e05cde8395cc7c866c6208008..c7ff3480fb182711eccca1421798387a3391a6c4 100644 (file)
@@ -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;
 }
 
index c489582faa6650501906984164799403a61fd896..b1a650c6731d3268c65c2204af1975fe23e6d226 100644 (file)
@@ -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),
index aad1496f07bec076326669e289a560adb2ea9964..d212cbb9b847810a83856d74cba5edc5a99f1c38 100644 (file)
@@ -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) ||
index fe77829557f252d597040b3eb82ecebf374f4917..df09000b30de50e4a124d1928472780c3b62e8ff 100644 (file)
@@ -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);
        }
 
index 615f7d1aae498769109caf2da7bf9c31c13ce054..74512e54a38c45d37d73de0fd9e3aa861dcb757d 100644 (file)
@@ -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;
 }
 
index 4486b55e6d3230678d99927bd58752d9bd0b02df..0e4e9f80682fd654d64e568b26d17b871e9a9390 100644 (file)
@@ -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;
 
index e8ee0e73217aae4f3111a5fb273b851b92ca5339..c9288a9c7e382bd19193d8b94268e0d0bec2c7f8 100644 (file)
@@ -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;
 }
 
index 7ffc14ba15743a3dd4fba00c3d5c6ba7c44d3f31..8a7ed4299a4b5157c56144d705f4149226527b66 100644 (file)
@@ -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);
index 4c62c5ab58bd0ac7b8d9fd47e9a92166bd1eed9c..900b560a77d9d7696b8c25c5e9426359c8542f74 100644 (file)
@@ -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));
                }
        }
 
index f26640bd6ea1e75fc24de7fb80cc1cfd3eb54370..9d4749f79befa8e383424f9af1b28a6ffa9b9abe 100644 (file)
@@ -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);
index 9032cc6327c004d520d35f52e01a00a5d160c607..7b3711cf34f534d265c8eeb813235e9b2601077e 100644 (file)
@@ -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;
 }
 
index 10475a6b5edb2b15e642d1d1a3da8d6f470025a2..441babf2e350f94477422e9d1381c7e2b21dd939 100644 (file)
@@ -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)
index 4d4984e4e0c244b32d46affc658a699bb04f1c82..0b6f9edf86c24f0198163abc4140e0e8dae71279 100644 (file)
@@ -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++;
        }
 
index 35f6cf735e51cd5f65f1cba1991c3af756945b53..fcd73abe5336a9f8476087de44c1ee7f892effdd 100644 (file)
@@ -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;
 }
index 01eba90c5c7bb23fea867cb4d6ad46eb094e4c33..f0665af3acdf6caf056769900e20c17d4672d31c 100644 (file)
@@ -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;
 }
index 558121eaa1688e306c1028411c0a89940a343b1a..cd6bc11095d01aa03f15f00ac962d563bd690e32 100644 (file)
@@ -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;
 }
index b7f323b5e4d73e941025f97f459e3a6593350746..812774a5ca992c5523116811239bb5a2f505f677 100644 (file)
@@ -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;
 }
index 80be2ff2c39842675c962d262021a993e6b00cc5..474454db73d0946cba4e00ef3762263bd95252b6 100644 (file)
@@ -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));
 
index 7cfebc4162b0e079eae43cdabe1ed682ed38678f..36c94799d69d7af51020fe412ceea0d0b14cd878 100644 (file)
@@ -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;
 }
index 78c45d4a155c89f3964efea0491feca1aa5ec919..fe7a84bf2f97fa89882bbfda079d346c7de21ddd 100644 (file)
@@ -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,
diff --git a/help.c b/help.c
index 20e114432d7f856f6d2f296423e358ec309e45ff..5854dd4a7e468ba97068fb1884452015dcfd0256 100644 (file)
--- a/help.c
+++ b/help.c
@@ -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;
 }
 
index 273ed7266fbff1ef37467775c2d4f26a52c11f0b..52f0483dd309d73a1866a1b63161df0fe63d389f 100644 (file)
@@ -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;
index 1729b0c201271b147259482a448cf4bf07615a41..7d917f2a83d5aeed5e7343db4abfc7c73879919c 100644 (file)
@@ -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;
 }
index 8641281b86c55af82de185c4867f63f372ffa933..c47acde07f335bb146e06ea617fb15178ab5dc89 100644 (file)
--- a/ls-refs.c
+++ b/ls-refs.c
@@ -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);
 }
 
index 23e61cb00014282faadf6b5c29636139ad54b082..c73010df6d3a4fe5c241597500f35bf5a71188dd 100644 (file)
@@ -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;
 }
index 116dedcf83035db968103a73753000ed165fe87c..c479da9b09157077c0a8a4548c95fef35c95c0d4 100644 (file)
@@ -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,
index 0a272130fb1b6d2007b24a01ac003a438cf43c2a..616df6bf3af51ce58ec22f2e8471b8feec0c05c4 100644 (file)
@@ -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,
diff --git a/notes.c b/notes.c
index 8e00fd8c470dd2dec70619af537e9b06775eaf77..9a2e9181fe67d8019f12c97904b909a34fd7815c 100644 (file)
--- a/notes.c
+++ b/notes.c
@@ -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;
 }
 
index 72bdf4f86eb83c220c21e6e48d03fd0363a23e60..766c757042a38950f7b498dc7fa92b72befea264 100644 (file)
@@ -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;
        }
index e72b0ed4360e67e40d661aca8beb7bc3887d84b0..986114a6dba843ea412123dc9035bf67693a6afd 100644 (file)
--- a/object.c
+++ b/object.c
@@ -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;
 
index fd15eecce82d68f11c9e35214d05d98e3fff35f3..fa504a09c0a48dbab1a3f108cc438267ffc89cd4 100644 (file)
--- a/object.h
+++ b/object.h
@@ -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);
index a2d5bd85f95ebf269a3887698110d2af08258462..893b763fe45490875ea226eaffff0c7cb1dafb06 100644 (file)
@@ -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);
                }
 
index b753c395530b6d3212006742bbd4f1671a2e22a6..22266db5233df7ce9820e1359ca0605643478a27 100644 (file)
@@ -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;
index 7cfcd5c35549308dcee9c3654c858f5ebce02a36..30cc488d8ab6595afe125bbdc252020b939b2334 100644 (file)
@@ -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);
index 120221b47fa30dc05d5e57b34d0b30242e2ae23b..235c60f79c9a0f338661793f4b623813c11c075e 100644 (file)
@@ -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
index ac87e20c4f97fffbc933ab0d193cc72541cbfad9..65ef259b4f5e1e89c7b898fddcf170a95e1f7b75 100644 (file)
--- a/reflog.c
+++ b/reflog.c
@@ -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);
diff --git a/refs.c b/refs.c
index a41a94ae55bb43444015949e0871aeed42001694..965381367e0e53914040d77bea12975354c8b854 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -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)
diff --git a/refs.h b/refs.h
index 2dd7ac1a16aee9b72b83c4f9eb322dd725de4b11..4e6bd63aa86c540734e488027e0ff4af7149ad61 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -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);
 
index f38991c02ae8d6f04552ac9305170448efcacafa..c59c1728a3d31cfe4a79d0361b0dc77f1f1faf49 100644 (file)
@@ -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,
 };
 
index f4809edda8a5af6174099e4aa774f83b1c5f9189..054cf42f4eaac5e8e46b1f6dc084ac4655df7cee 100644 (file)
@@ -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,
index d79aa5ec82dc6fa0e129247533056e81d10d8b35..17ef841d8a3013c2a93ac97a1dfe0aa421e3e364 100644 (file)
@@ -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);
index 1ab0c5039301647d133b9672898a8262aa8a1568..a8c22a0a7ff8cdd09bf993b12c239e6eabea2a61 100644 (file)
@@ -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,
index ffef01a597579e8eae0258d3a828a9930eecc7fc..e5e5df16d85e4003277664d1d87ddad4a91bd234 100644 (file)
@@ -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,
 };
 
index 4671517dade968fa673c04235c0e1d87552c368e..4ef3bd75c6ae55e0e33beec4c73f986fe18c0cce 100644 (file)
@@ -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;
 };
 
 /*
@@ -357,6 +360,12 @@ typedef int ref_iterator_advance_fn(struct ref_iterator *ref_iterator);
 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 */
index 6bbfd5618dac16693c735994d29550da73403bf7..d4b792862024fcbc3aef284da390982ead7fe5ff 100644 (file)
@@ -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);
index 59b371512084eb8c7cb56ee7663da2b3f04df779..df9675cd330ed1e0a1c4256dc19d3e73828f2fb2 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -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:
index 74bdfa3a6e913f65679076689f723d64e351584d..6f6202c5bccd89a9087bd86a80b7f56d0678f7fb 100644 (file)
@@ -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;
 }
index 03d0f1f083bed991f1d066b788c891e30affea0f..3eae0510745eae0b6d1481167a12d10cc0f65e71 100644 (file)
@@ -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;
 }
index 5f0850ae5c9c1aec7838b0a9e05e2951a6f50fdd..cf5e6c1ec9e4e15d45f45e971866c996a04863b0 100644 (file)
@@ -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;
 }
 
index 4243e24edc4cb00102f8ce71176184182812c75f..b9a710544ab2854879593961dc9b2fc3350435ea 100644 (file)
@@ -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;
index 55b9cd9d3f29f14d938c6d986c72ad430d624d0b..d9cd4e219cb07dcce18356668420362086deb745 100644 (file)
--- a/shallow.c
+++ b/shallow.c
@@ -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;
index 40a5c6fb9d154574ee61ed15d3f2e02642e42b03..35c55155f7bf8379564d3664b34266e8debee681 100644 (file)
@@ -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;
 }
 
index 4593be5fd544a8359d458302b3807d6afee7b2de..e3ad19298accdeeb393b65fceb9e6bf97541cc8b 100644 (file)
@@ -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' '
index c58c93800f32320eb83ea192196776a9cc4223f1..028ec0030678284eba844e121c6eff88abdd3139 100644 (file)
@@ -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",
index b1215947c5e67a87a46f7705bfce38c36c3f2a72..83b06d39a362357f968ac9f01950df4655010559 100644 (file)
@@ -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;
 }
 
index 095823d915fd637e6212497566d3a76544d96caf..3dbcc01718e157cec951736b333aa16506bd11f8 100644 (file)
@@ -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
index 6575528f212716df5a47bf3e973a269cb0e8bf9a..3ea5d51532a8b88ac8e36d79613812ed4668234a 100755 (executable)
@@ -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
diff --git a/tag.c b/tag.c
index f5c232d2f1f36cecad575a612d5bb4bbf27ddffc..1d52686ee105f2ac168e9728716bc3f70c30cd57 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -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);
diff --git a/tag.h b/tag.h
index ef12a610372063aff01b78285a2b161a23675614..c49d7c19ad3c9087e8a115a7a0edcd0c14062520 100644 (file)
--- a/tag.h
+++ b/tag.h
@@ -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);
index 2d2b70cbf2dd0b57bbdbf50031a44fe4b148778f..1e87ae9559306325cfe665d493e7688df285e666 100644 (file)
@@ -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
index 409b646578a3d4b39b7f7feee3854f2b4662b2b0..80737545172bbddda4b881edcb1d36cbc1c51bca 100644 (file)
--- a/walker.c
+++ b/walker.c
@@ -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;
index 9308389cb6f0296b1cc21c33b95427211f840649..a2a5f51f29fca2b1862a8f08da583f45995f799f 100644 (file)
@@ -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;
        }