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);
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;
}
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)++;
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;
}
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;
}
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;
}
}
}
-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;
}
}
/* 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;
}
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;
}
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;
}
}
-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;
}
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.
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;
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),
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) ||
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);
}
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;
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;
}
}
* 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 */
}
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;
}
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;
}
}
-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;
}
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;
}
}
-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;
/*
* 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;
}
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);
/* 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;
}
/* 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;
}
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.
* 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;
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);
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));
}
}
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;
* 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);
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;
}
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,
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)
};
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);
}
}
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;
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;
}
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++;
}
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;
}
return -1;
if (format->format)
- pretty_print_ref(name, oid, NULL, format);
+ pretty_print_ref(name, oid, format);
return 0;
}
}
if (format.format)
- pretty_print_ref(name, &oid, NULL, &format);
+ pretty_print_ref(name, &oid, &format);
}
return had_error;
}
*
* 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;
}
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));
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;
/* 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;
}
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;
}
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 {
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,
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;
}
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),
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;
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;
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);
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];
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;
}
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));
}
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);
}
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;
}
}
}
-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,
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,
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;
}
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;
}
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;
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;
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
* 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);
}
}
-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;
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;
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);
}
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;
struct object_id delta_base_oid;
void *content;
- struct object *maybe_object;
struct object_info info;
} oi, oi_deref;
}
}
-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;
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)
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;
v->s = strbuf_detach(&s, NULL);
}
}
-
- return 0;
}
static const char *find_wholine(const char *who, int wholen, const char *buf)
}
}
-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;
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;
}
if (signature_checked)
signature_check_clear(&sigc);
-
- return 0;
}
static void find_subpos(const char *buf,
}
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++) {
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("");
* 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); */
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)
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)
*/
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;
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);
}
/*
* 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;
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;
}
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,
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;
/*
*/
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... */
* 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 {
* 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;
}
} 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) {
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
}
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);
struct ref_array_item {
struct object_id objectname;
- struct object_id peeled_oid;
const char *rest;
int flag;
unsigned int kind;
* 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);
/*
*/
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
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);
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 {
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;
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;
}
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;
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;
}
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,
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(
continue;
strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
- iter->ref.name, refname);
+ iter->refname, refname);
goto cleanup;
}
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)
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)
* 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
* 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;
* // 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)
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);
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;
}
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 =
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,
};
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;
}
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 =
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,
};
* 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;
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);
* 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;
}
REFNAME_ALLOW_ONELEVEL))
continue;
- iter->base.ref.name = diter->relative_path;
+ iter->base.refname = diter->relative_path;
return ITER_OK;
}
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 =
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,
};
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,
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) {
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 {
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)
{
}
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,
};
* 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)
* 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;
}
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;
}
}
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 =
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,
};
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;
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;
/*
if (cmp > 0)
return ITER_DONE;
- iter->base.ref = iter->iter0->ref;
-
if (iter->trim) {
/*
* It is nonsense to trim off characters that
* 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;
}
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 =
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,
};
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);
{
const char *p, *eol;
- memset(&iter->base.ref, 0, sizeof(iter->base.ref));
strbuf_reset(&iter->refname_buf);
/*
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 ||
!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)
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;
* 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);
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;
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 =
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,
};
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;
if (!iter)
cmp = +1;
else
- cmp = strcmp(iter->ref.name, update->refname);
+ cmp = strcmp(iter->refname, update->refname);
}
if (!cmp) {
}
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;
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) {
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,
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;
}
}
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 =
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,
};
*/
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;
};
/*
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.
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 */
struct reftable_iterator iter;
struct reftable_ref_record ref;
struct object_id oid;
- struct object_id peeled_oid;
char *prefix;
size_t prefix_len;
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,
&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;
}
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 =
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,
};
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);
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);
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;
}
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 =
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,
};
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);
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;
}
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)
* 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++)
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:
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;
}
#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;
}
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;
}
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;
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;
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;
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;
}
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;
}
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' '
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",
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;
}
'
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
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
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);
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);
}
}
-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)) {
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;
}
}
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) {
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" : "",
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;
}
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
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;
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;
}