mirror of
https://github.com/git/git.git
synced 2026-01-10 10:13:33 +00:00
Merge branch 'ps/ref-peeled-tags' into ps/ref-peeled-tags-fixes
* ps/ref-peeled-tags: t7004: do not chdir around in the main process ref-filter: fix stale parsed objects ref-filter: parse objects on demand ref-filter: detect broken tags when dereferencing them refs: don't store peeled object IDs for invalid tags object: add flag to `peel_object()` to verify object type refs: drop infrastructure to peel via iterators refs: drop `current_ref_iter` hack builtin/show-ref: convert to use `reference_get_peeled_oid()` ref-filter: propagate peeled object ID upload-pack: convert to use `reference_get_peeled_oid()` refs: expose peeled object ID via the iterator refs: refactor reference status flags refs: fully reset `struct ref_iterator::ref` on iteration refs: introduce `.ref` field for the base iterator refs: introduce wrapper struct for `each_ref_fn`
This commit is contained in:
17
refs/debug.c
17
refs/debug.c
@@ -168,11 +168,9 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
trace_printf_key(&trace_refs, "iterator_advance: (%d)\n", res);
|
||||
else
|
||||
trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n",
|
||||
diter->iter->refname);
|
||||
diter->iter->ref.name);
|
||||
|
||||
diter->base.refname = diter->iter->refname;
|
||||
diter->base.oid = diter->iter->oid;
|
||||
diter->base.flags = diter->iter->flags;
|
||||
diter->base.ref = diter->iter->ref;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -187,16 +185,6 @@ static int debug_ref_iterator_seek(struct ref_iterator *ref_iterator,
|
||||
return res;
|
||||
}
|
||||
|
||||
static int debug_ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
struct debug_ref_iterator *diter =
|
||||
(struct debug_ref_iterator *)ref_iterator;
|
||||
int res = diter->iter->vtable->peel(diter->iter, peeled);
|
||||
trace_printf_key(&trace_refs, "iterator_peel: %s: %d\n", diter->iter->refname, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void debug_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct debug_ref_iterator *diter =
|
||||
@@ -208,7 +196,6 @@ static void debug_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable debug_ref_iterator_vtable = {
|
||||
.advance = debug_ref_iterator_advance,
|
||||
.seek = debug_ref_iterator_seek,
|
||||
.peel = debug_ref_iterator_peel,
|
||||
.release = debug_ref_iterator_release,
|
||||
};
|
||||
|
||||
|
||||
@@ -961,26 +961,23 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
|
||||
while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
|
||||
if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
|
||||
parse_worktree_ref(iter->iter0->refname, NULL, NULL,
|
||||
parse_worktree_ref(iter->iter0->ref.name, NULL, NULL,
|
||||
NULL) != REF_WORKTREE_CURRENT)
|
||||
continue;
|
||||
|
||||
if ((iter->flags & DO_FOR_EACH_OMIT_DANGLING_SYMREFS) &&
|
||||
(iter->iter0->flags & REF_ISSYMREF) &&
|
||||
(iter->iter0->flags & REF_ISBROKEN))
|
||||
(iter->iter0->ref.flags & REF_ISSYMREF) &&
|
||||
(iter->iter0->ref.flags & REF_ISBROKEN))
|
||||
continue;
|
||||
|
||||
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
|
||||
!ref_resolves_to_object(iter->iter0->refname,
|
||||
!ref_resolves_to_object(iter->iter0->ref.name,
|
||||
iter->repo,
|
||||
iter->iter0->oid,
|
||||
iter->iter0->flags))
|
||||
iter->iter0->ref.oid,
|
||||
iter->iter0->ref.flags))
|
||||
continue;
|
||||
|
||||
iter->base.refname = iter->iter0->refname;
|
||||
iter->base.oid = iter->iter0->oid;
|
||||
iter->base.flags = iter->iter0->flags;
|
||||
iter->base.referent = iter->iter0->referent;
|
||||
iter->base.ref = iter->iter0->ref;
|
||||
|
||||
return ITER_OK;
|
||||
}
|
||||
@@ -996,15 +993,6 @@ static int files_ref_iterator_seek(struct ref_iterator *ref_iterator,
|
||||
return ref_iterator_seek(iter->iter0, refname, flags);
|
||||
}
|
||||
|
||||
static int files_ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
struct files_ref_iterator *iter =
|
||||
(struct files_ref_iterator *)ref_iterator;
|
||||
|
||||
return ref_iterator_peel(iter->iter0, peeled);
|
||||
}
|
||||
|
||||
static void files_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct files_ref_iterator *iter =
|
||||
@@ -1015,7 +1003,6 @@ static void files_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable files_ref_iterator_vtable = {
|
||||
.advance = files_ref_iterator_advance,
|
||||
.seek = files_ref_iterator_seek,
|
||||
.peel = files_ref_iterator_peel,
|
||||
.release = files_ref_iterator_release,
|
||||
};
|
||||
|
||||
@@ -1367,30 +1354,29 @@ static void prune_refs(struct files_ref_store *refs, struct ref_to_prune **refs_
|
||||
* Return true if the specified reference should be packed.
|
||||
*/
|
||||
static int should_pack_ref(struct files_ref_store *refs,
|
||||
const char *refname,
|
||||
const struct object_id *oid, unsigned int ref_flags,
|
||||
const struct reference *ref,
|
||||
struct pack_refs_opts *opts)
|
||||
{
|
||||
struct string_list_item *item;
|
||||
|
||||
/* Do not pack per-worktree refs: */
|
||||
if (parse_worktree_ref(refname, NULL, NULL, NULL) !=
|
||||
if (parse_worktree_ref(ref->name, 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(refname, refs->base.repo, oid, ref_flags))
|
||||
if (!ref_resolves_to_object(ref->name, refs->base.repo, ref->oid, ref->flags))
|
||||
return 0;
|
||||
|
||||
if (ref_excluded(opts->exclusions, refname))
|
||||
if (ref_excluded(opts->exclusions, ref->name))
|
||||
return 0;
|
||||
|
||||
for_each_string_list_item(item, opts->includes)
|
||||
if (!wildmatch(item->string, refname, 0))
|
||||
if (!wildmatch(item->string, ref->name, 0))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -1443,8 +1429,7 @@ static int should_pack_refs(struct files_ref_store *refs,
|
||||
iter = cache_ref_iterator_begin(get_loose_ref_cache(refs, 0), NULL,
|
||||
refs->base.repo, 0);
|
||||
while ((ret = ref_iterator_advance(iter)) == ITER_OK) {
|
||||
if (should_pack_ref(refs, iter->refname, iter->oid,
|
||||
iter->flags, opts))
|
||||
if (should_pack_ref(refs, &iter->ref, opts))
|
||||
refcount++;
|
||||
if (refcount >= limit) {
|
||||
ref_iterator_free(iter);
|
||||
@@ -1489,24 +1474,24 @@ static int files_pack_refs(struct ref_store *ref_store,
|
||||
* in the packed ref cache. If the reference should be
|
||||
* pruned, also add it to refs_to_prune.
|
||||
*/
|
||||
if (!should_pack_ref(refs, iter->refname, iter->oid, iter->flags, opts))
|
||||
if (!should_pack_ref(refs, &iter->ref, opts))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Add a reference creation for this reference to the
|
||||
* packed-refs transaction:
|
||||
*/
|
||||
if (ref_transaction_update(transaction, iter->refname,
|
||||
iter->oid, NULL, NULL, NULL,
|
||||
if (ref_transaction_update(transaction, iter->ref.name,
|
||||
iter->ref.oid, NULL, NULL, NULL,
|
||||
REF_NO_DEREF, NULL, &err))
|
||||
die("failure preparing to create packed reference %s: %s",
|
||||
iter->refname, err.buf);
|
||||
iter->ref.name, 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->refname);
|
||||
oidcpy(&n->oid, iter->oid);
|
||||
FLEX_ALLOC_STR(n, name, iter->ref.name);
|
||||
oidcpy(&n->oid, iter->ref.oid);
|
||||
n->next = refs_to_prune;
|
||||
refs_to_prune = n;
|
||||
}
|
||||
@@ -2394,7 +2379,7 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
REFNAME_ALLOW_ONELEVEL))
|
||||
continue;
|
||||
|
||||
iter->base.refname = diter->relative_path;
|
||||
iter->base.ref.name = diter->relative_path;
|
||||
return ITER_OK;
|
||||
}
|
||||
|
||||
@@ -2408,12 +2393,6 @@ static int files_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSED,
|
||||
BUG("ref_iterator_seek() called for reflog_iterator");
|
||||
}
|
||||
|
||||
static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
|
||||
struct object_id *peeled UNUSED)
|
||||
{
|
||||
BUG("ref_iterator_peel() called for reflog_iterator");
|
||||
}
|
||||
|
||||
static void files_reflog_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct files_reflog_iterator *iter =
|
||||
@@ -2424,7 +2403,6 @@ static void files_reflog_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable files_reflog_iterator_vtable = {
|
||||
.advance = files_reflog_iterator_advance,
|
||||
.seek = files_reflog_iterator_seek,
|
||||
.peel = files_reflog_iterator_peel,
|
||||
.release = files_reflog_iterator_release,
|
||||
};
|
||||
|
||||
@@ -3165,14 +3143,11 @@ static int parse_and_write_reflog(struct files_ref_store *refs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ref_present(const char *refname, const char *referent UNUSED,
|
||||
const struct object_id *oid UNUSED,
|
||||
int flags UNUSED,
|
||||
void *cb_data)
|
||||
static int ref_present(const struct reference *ref, void *cb_data)
|
||||
{
|
||||
struct string_list *affected_refnames = cb_data;
|
||||
|
||||
return string_list_has_string(affected_refnames, refname);
|
||||
return string_list_has_string(affected_refnames, ref->name);
|
||||
}
|
||||
|
||||
static int files_transaction_finish_initial(struct files_ref_store *refs,
|
||||
|
||||
@@ -21,12 +21,6 @@ int ref_iterator_seek(struct ref_iterator *ref_iterator, const char *refname,
|
||||
return ref_iterator->vtable->seek(ref_iterator, refname, flags);
|
||||
}
|
||||
|
||||
int ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
return ref_iterator->vtable->peel(ref_iterator, peeled);
|
||||
}
|
||||
|
||||
void ref_iterator_free(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
if (ref_iterator) {
|
||||
@@ -41,10 +35,7 @@ void base_ref_iterator_init(struct ref_iterator *iter,
|
||||
struct ref_iterator_vtable *vtable)
|
||||
{
|
||||
iter->vtable = vtable;
|
||||
iter->refname = NULL;
|
||||
iter->referent = NULL;
|
||||
iter->oid = NULL;
|
||||
iter->flags = 0;
|
||||
memset(&iter->ref, 0, sizeof(iter->ref));
|
||||
}
|
||||
|
||||
struct empty_ref_iterator {
|
||||
@@ -63,12 +54,6 @@ static int empty_ref_iterator_seek(struct ref_iterator *ref_iterator UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
|
||||
struct object_id *peeled UNUSED)
|
||||
{
|
||||
BUG("peel called for empty iterator");
|
||||
}
|
||||
|
||||
static void empty_ref_iterator_release(struct ref_iterator *ref_iterator UNUSED)
|
||||
{
|
||||
}
|
||||
@@ -76,7 +61,6 @@ 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,
|
||||
};
|
||||
|
||||
@@ -127,8 +111,8 @@ enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree,
|
||||
* latter.
|
||||
*/
|
||||
if (iter_worktree) {
|
||||
int cmp = strcmp(iter_worktree->refname,
|
||||
iter_common->refname);
|
||||
int cmp = strcmp(iter_worktree->ref.name,
|
||||
iter_common->ref.name);
|
||||
if (cmp < 0)
|
||||
return ITER_SELECT_0;
|
||||
else if (!cmp)
|
||||
@@ -139,7 +123,7 @@ enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree,
|
||||
* We now know that the lexicographically-next ref is a common
|
||||
* ref. When the common ref is a shared one we return it.
|
||||
*/
|
||||
if (parse_worktree_ref(iter_common->refname, NULL, NULL,
|
||||
if (parse_worktree_ref(iter_common->ref.name, NULL, NULL,
|
||||
NULL) == REF_WORKTREE_SHARED)
|
||||
return ITER_SELECT_1;
|
||||
|
||||
@@ -212,10 +196,7 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
}
|
||||
|
||||
if (selection & ITER_YIELD_CURRENT) {
|
||||
iter->base.referent = (*iter->current)->referent;
|
||||
iter->base.refname = (*iter->current)->refname;
|
||||
iter->base.oid = (*iter->current)->oid;
|
||||
iter->base.flags = (*iter->current)->flags;
|
||||
iter->base.ref = (*iter->current)->ref;
|
||||
return ITER_OK;
|
||||
}
|
||||
}
|
||||
@@ -246,18 +227,6 @@ static int merge_ref_iterator_seek(struct ref_iterator *ref_iterator,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
struct merge_ref_iterator *iter =
|
||||
(struct merge_ref_iterator *)ref_iterator;
|
||||
|
||||
if (!iter->current) {
|
||||
BUG("peel called before advance for merge iterator");
|
||||
}
|
||||
return ref_iterator_peel(*iter->current, peeled);
|
||||
}
|
||||
|
||||
static void merge_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct merge_ref_iterator *iter =
|
||||
@@ -269,7 +238,6 @@ static void merge_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable merge_ref_iterator_vtable = {
|
||||
.advance = merge_ref_iterator_advance,
|
||||
.seek = merge_ref_iterator_seek,
|
||||
.peel = merge_ref_iterator_peel,
|
||||
.release = merge_ref_iterator_release,
|
||||
};
|
||||
|
||||
@@ -313,7 +281,7 @@ static enum iterator_selection overlay_iterator_select(
|
||||
else if (!front)
|
||||
return ITER_SELECT_1;
|
||||
|
||||
cmp = strcmp(front->refname, back->refname);
|
||||
cmp = strcmp(front->ref.name, back->ref.name);
|
||||
|
||||
if (cmp < 0)
|
||||
return ITER_SELECT_0;
|
||||
@@ -371,7 +339,7 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
int ok;
|
||||
|
||||
while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
|
||||
int cmp = compare_prefix(iter->iter0->refname, iter->prefix);
|
||||
int cmp = compare_prefix(iter->iter0->ref.name, iter->prefix);
|
||||
if (cmp < 0)
|
||||
continue;
|
||||
/*
|
||||
@@ -382,6 +350,8 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
if (cmp > 0)
|
||||
return ITER_DONE;
|
||||
|
||||
iter->base.ref = iter->iter0->ref;
|
||||
|
||||
if (iter->trim) {
|
||||
/*
|
||||
* It is nonsense to trim off characters that
|
||||
@@ -392,15 +362,11 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
* one character left in the refname after
|
||||
* trimming, report it as a bug:
|
||||
*/
|
||||
if (strlen(iter->iter0->refname) <= iter->trim)
|
||||
if (strlen(iter->base.ref.name) <= iter->trim)
|
||||
BUG("attempt to trim too many characters");
|
||||
iter->base.refname = iter->iter0->refname + iter->trim;
|
||||
} else {
|
||||
iter->base.refname = iter->iter0->refname;
|
||||
iter->base.ref.name += iter->trim;
|
||||
}
|
||||
|
||||
iter->base.oid = iter->iter0->oid;
|
||||
iter->base.flags = iter->iter0->flags;
|
||||
return ITER_OK;
|
||||
}
|
||||
|
||||
@@ -420,15 +386,6 @@ static int prefix_ref_iterator_seek(struct ref_iterator *ref_iterator,
|
||||
return ref_iterator_seek(iter->iter0, refname, flags);
|
||||
}
|
||||
|
||||
static int prefix_ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
struct prefix_ref_iterator *iter =
|
||||
(struct prefix_ref_iterator *)ref_iterator;
|
||||
|
||||
return ref_iterator_peel(iter->iter0, peeled);
|
||||
}
|
||||
|
||||
static void prefix_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct prefix_ref_iterator *iter =
|
||||
@@ -440,7 +397,6 @@ static void prefix_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable prefix_ref_iterator_vtable = {
|
||||
.advance = prefix_ref_iterator_advance,
|
||||
.seek = prefix_ref_iterator_seek,
|
||||
.peel = prefix_ref_iterator_peel,
|
||||
.release = prefix_ref_iterator_release,
|
||||
};
|
||||
|
||||
@@ -466,23 +422,18 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
|
||||
return ref_iterator;
|
||||
}
|
||||
|
||||
struct ref_iterator *current_ref_iter = NULL;
|
||||
|
||||
int do_for_each_ref_iterator(struct ref_iterator *iter,
|
||||
each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
int retval = 0, ok;
|
||||
struct ref_iterator *old_ref_iter = current_ref_iter;
|
||||
|
||||
current_ref_iter = iter;
|
||||
while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
|
||||
retval = fn(iter->refname, iter->referent, iter->oid, iter->flags, cb_data);
|
||||
retval = fn(&iter->ref, cb_data);
|
||||
if (retval)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
current_ref_iter = old_ref_iter;
|
||||
if (ok == ITER_ERROR)
|
||||
retval = -1;
|
||||
ref_iterator_free(iter);
|
||||
|
||||
@@ -882,6 +882,7 @@ static int next_record(struct packed_ref_iterator *iter)
|
||||
{
|
||||
const char *p, *eol;
|
||||
|
||||
memset(&iter->base.ref, 0, sizeof(iter->base.ref));
|
||||
strbuf_reset(&iter->refname_buf);
|
||||
|
||||
/*
|
||||
@@ -908,7 +909,7 @@ static int next_record(struct packed_ref_iterator *iter)
|
||||
if (iter->pos == iter->eof)
|
||||
return ITER_DONE;
|
||||
|
||||
iter->base.flags = REF_ISPACKED;
|
||||
iter->base.ref.flags = REF_ISPACKED;
|
||||
p = iter->pos;
|
||||
|
||||
if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 2 ||
|
||||
@@ -916,6 +917,7 @@ static int next_record(struct packed_ref_iterator *iter)
|
||||
!isspace(*p++))
|
||||
die_invalid_line(iter->snapshot->refs->path,
|
||||
iter->pos, iter->eof - iter->pos);
|
||||
iter->base.ref.oid = &iter->oid;
|
||||
|
||||
eol = memchr(p, '\n', iter->eof - p);
|
||||
if (!eol)
|
||||
@@ -923,22 +925,22 @@ static int next_record(struct packed_ref_iterator *iter)
|
||||
iter->pos, iter->eof - iter->pos);
|
||||
|
||||
strbuf_add(&iter->refname_buf, p, eol - p);
|
||||
iter->base.refname = iter->refname_buf.buf;
|
||||
iter->base.ref.name = iter->refname_buf.buf;
|
||||
|
||||
if (refname_contains_nul(&iter->refname_buf))
|
||||
die("packed refname contains embedded NULL: %s", iter->base.refname);
|
||||
die("packed refname contains embedded NULL: %s", iter->base.ref.name);
|
||||
|
||||
if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) {
|
||||
if (!refname_is_safe(iter->base.refname))
|
||||
if (check_refname_format(iter->base.ref.name, REFNAME_ALLOW_ONELEVEL)) {
|
||||
if (!refname_is_safe(iter->base.ref.name))
|
||||
die("packed refname is dangerous: %s",
|
||||
iter->base.refname);
|
||||
iter->base.ref.name);
|
||||
oidclr(&iter->oid, iter->repo->hash_algo);
|
||||
iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN;
|
||||
iter->base.ref.flags |= REF_BAD_NAME | REF_ISBROKEN;
|
||||
}
|
||||
if (iter->snapshot->peeled == PEELED_FULLY ||
|
||||
(iter->snapshot->peeled == PEELED_TAGS &&
|
||||
starts_with(iter->base.refname, "refs/tags/")))
|
||||
iter->base.flags |= REF_KNOWS_PEELED;
|
||||
starts_with(iter->base.ref.name, "refs/tags/")))
|
||||
iter->base.ref.flags |= REF_KNOWS_PEELED;
|
||||
|
||||
iter->pos = eol + 1;
|
||||
|
||||
@@ -956,11 +958,12 @@ static int next_record(struct packed_ref_iterator *iter)
|
||||
* definitely know the value of *this* reference. But
|
||||
* we suppress it if the reference is broken:
|
||||
*/
|
||||
if ((iter->base.flags & REF_ISBROKEN)) {
|
||||
if ((iter->base.ref.flags & REF_ISBROKEN)) {
|
||||
oidclr(&iter->peeled, iter->repo->hash_algo);
|
||||
iter->base.flags &= ~REF_KNOWS_PEELED;
|
||||
iter->base.ref.flags &= ~REF_KNOWS_PEELED;
|
||||
} else {
|
||||
iter->base.flags |= REF_KNOWS_PEELED;
|
||||
iter->base.ref.flags |= REF_KNOWS_PEELED;
|
||||
iter->base.ref.peeled_oid = &iter->peeled;
|
||||
}
|
||||
} else {
|
||||
oidclr(&iter->peeled, iter->repo->hash_algo);
|
||||
@@ -976,15 +979,15 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
int ok;
|
||||
|
||||
while ((ok = next_record(iter)) == ITER_OK) {
|
||||
const char *refname = iter->base.refname;
|
||||
const char *refname = iter->base.ref.name;
|
||||
const char *prefix = iter->prefix;
|
||||
|
||||
if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
|
||||
!is_per_worktree_ref(iter->base.refname))
|
||||
!is_per_worktree_ref(iter->base.ref.name))
|
||||
continue;
|
||||
|
||||
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
|
||||
!ref_resolves_to_object(iter->base.refname, iter->repo,
|
||||
!ref_resolves_to_object(iter->base.ref.name, iter->repo,
|
||||
&iter->oid, iter->flags))
|
||||
continue;
|
||||
|
||||
@@ -1027,22 +1030,6 @@ static int packed_ref_iterator_seek(struct ref_iterator *ref_iterator,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
struct packed_ref_iterator *iter =
|
||||
(struct packed_ref_iterator *)ref_iterator;
|
||||
|
||||
if ((iter->base.flags & REF_KNOWS_PEELED)) {
|
||||
oidcpy(peeled, &iter->peeled);
|
||||
return is_null_oid(&iter->peeled) ? -1 : 0;
|
||||
} else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) {
|
||||
return -1;
|
||||
} else {
|
||||
return peel_object(iter->repo, &iter->oid, peeled) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void packed_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct packed_ref_iterator *iter =
|
||||
@@ -1056,7 +1043,6 @@ static void packed_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable packed_ref_iterator_vtable = {
|
||||
.advance = packed_ref_iterator_advance,
|
||||
.seek = packed_ref_iterator_seek,
|
||||
.peel = packed_ref_iterator_peel,
|
||||
.release = packed_ref_iterator_release,
|
||||
};
|
||||
|
||||
@@ -1194,7 +1180,6 @@ static struct ref_iterator *packed_ref_iterator_begin(
|
||||
iter->snapshot = snapshot;
|
||||
acquire_snapshot(snapshot);
|
||||
strbuf_init(&iter->refname_buf, 0);
|
||||
iter->base.oid = &iter->oid;
|
||||
iter->repo = ref_store->repo;
|
||||
iter->flags = flags;
|
||||
|
||||
@@ -1436,7 +1421,7 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
|
||||
if (!iter)
|
||||
cmp = +1;
|
||||
else
|
||||
cmp = strcmp(iter->refname, update->refname);
|
||||
cmp = strcmp(iter->ref.name, update->refname);
|
||||
}
|
||||
|
||||
if (!cmp) {
|
||||
@@ -1459,11 +1444,11 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
|
||||
}
|
||||
|
||||
goto error;
|
||||
} else if (!oideq(&update->old_oid, iter->oid)) {
|
||||
} else if (!oideq(&update->old_oid, iter->ref.oid)) {
|
||||
strbuf_addf(err, "cannot update ref '%s': "
|
||||
"is at %s but expected %s",
|
||||
update->refname,
|
||||
oid_to_hex(iter->oid),
|
||||
oid_to_hex(iter->ref.oid),
|
||||
oid_to_hex(&update->old_oid));
|
||||
ret = REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE;
|
||||
|
||||
@@ -1523,13 +1508,8 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
|
||||
|
||||
if (cmp < 0) {
|
||||
/* Pass the old reference through. */
|
||||
|
||||
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))
|
||||
if (write_packed_entry(out, iter->ref.name,
|
||||
iter->ref.oid, iter->ref.peeled_oid))
|
||||
goto write_error;
|
||||
|
||||
if ((ok = ref_iterator_advance(iter)) != ITER_OK) {
|
||||
@@ -1547,9 +1527,8 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
|
||||
i++;
|
||||
} else {
|
||||
struct object_id peeled;
|
||||
int peel_error = peel_object(refs->base.repo,
|
||||
&update->new_oid,
|
||||
&peeled);
|
||||
int peel_error = peel_object(refs->base.repo, &update->new_oid,
|
||||
&peeled, PEEL_OBJECT_VERIFY_OBJECT_TYPE);
|
||||
|
||||
if (write_packed_entry(out, update->refname,
|
||||
&update->new_oid,
|
||||
|
||||
@@ -425,10 +425,11 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
level->prefix_state = entry_prefix_state;
|
||||
level->index = -1;
|
||||
} else {
|
||||
iter->base.refname = entry->name;
|
||||
iter->base.referent = entry->u.value.referent;
|
||||
iter->base.oid = &entry->u.value.oid;
|
||||
iter->base.flags = entry->flag;
|
||||
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;
|
||||
return ITER_OK;
|
||||
}
|
||||
}
|
||||
@@ -545,14 +546,6 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
struct cache_ref_iterator *iter =
|
||||
(struct cache_ref_iterator *)ref_iterator;
|
||||
return peel_object(iter->repo, ref_iterator->oid, peeled) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void cache_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct cache_ref_iterator *iter =
|
||||
@@ -564,7 +557,6 @@ static void cache_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable cache_ref_iterator_vtable = {
|
||||
.advance = cache_ref_iterator_advance,
|
||||
.seek = cache_ref_iterator_seek,
|
||||
.peel = cache_ref_iterator_peel,
|
||||
.release = cache_ref_iterator_release,
|
||||
};
|
||||
|
||||
|
||||
@@ -249,10 +249,7 @@ const char *find_descendant_ref(const char *dirname,
|
||||
*/
|
||||
struct ref_iterator {
|
||||
struct ref_iterator_vtable *vtable;
|
||||
const char *refname;
|
||||
const char *referent;
|
||||
const struct object_id *oid;
|
||||
unsigned int flags;
|
||||
struct reference ref;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -360,12 +357,6 @@ typedef int ref_iterator_advance_fn(struct ref_iterator *ref_iterator);
|
||||
typedef int ref_iterator_seek_fn(struct ref_iterator *ref_iterator,
|
||||
const char *refname, unsigned int flags);
|
||||
|
||||
/*
|
||||
* Peels the current ref, returning 0 for success or -1 for failure.
|
||||
*/
|
||||
typedef int ref_iterator_peel_fn(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled);
|
||||
|
||||
/*
|
||||
* Implementations of this function should free any resources specific
|
||||
* to the derived class.
|
||||
@@ -375,23 +366,9 @@ typedef void ref_iterator_release_fn(struct ref_iterator *ref_iterator);
|
||||
struct ref_iterator_vtable {
|
||||
ref_iterator_advance_fn *advance;
|
||||
ref_iterator_seek_fn *seek;
|
||||
ref_iterator_peel_fn *peel;
|
||||
ref_iterator_release_fn *release;
|
||||
};
|
||||
|
||||
/*
|
||||
* current_ref_iter is a performance hack: when iterating over
|
||||
* references using the for_each_ref*() functions, current_ref_iter is
|
||||
* set to the reference iterator before calling the callback function.
|
||||
* If the callback function calls peel_ref(), then peel_ref() first
|
||||
* checks whether the reference to be peeled is the one referred to by
|
||||
* the iterator (it usually is) and if so, asks the iterator for the
|
||||
* peeled version of the reference if it is available. This avoids a
|
||||
* refname lookup in a common case. current_ref_iter is set to NULL
|
||||
* when the iteration is over.
|
||||
*/
|
||||
extern struct ref_iterator *current_ref_iter;
|
||||
|
||||
struct ref_store;
|
||||
|
||||
/* refs backends */
|
||||
|
||||
@@ -547,6 +547,7 @@ struct reftable_ref_iterator {
|
||||
struct reftable_iterator iter;
|
||||
struct reftable_ref_record ref;
|
||||
struct object_id oid;
|
||||
struct object_id peeled_oid;
|
||||
|
||||
char *prefix;
|
||||
size_t prefix_len;
|
||||
@@ -671,6 +672,8 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
case REFTABLE_REF_VAL2:
|
||||
oidread(&iter->oid, iter->ref.value.val2.value,
|
||||
refs->base.repo->hash_algo);
|
||||
oidread(&iter->peeled_oid, iter->ref.value.val2.target_value,
|
||||
refs->base.repo->hash_algo);
|
||||
break;
|
||||
case REFTABLE_REF_SYMREF:
|
||||
referent = refs_resolve_ref_unsafe(&iter->refs->base,
|
||||
@@ -704,10 +707,13 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
&iter->oid, flags))
|
||||
continue;
|
||||
|
||||
iter->base.refname = iter->ref.refname;
|
||||
iter->base.referent = referent;
|
||||
iter->base.oid = &iter->oid;
|
||||
iter->base.flags = flags;
|
||||
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;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -738,21 +744,6 @@ static int reftable_ref_iterator_seek(struct ref_iterator *ref_iterator,
|
||||
return iter->err;
|
||||
}
|
||||
|
||||
static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled)
|
||||
{
|
||||
struct reftable_ref_iterator *iter =
|
||||
(struct reftable_ref_iterator *)ref_iterator;
|
||||
|
||||
if (iter->ref.value_type == REFTABLE_REF_VAL2) {
|
||||
oidread(peeled, iter->ref.value.val2.target_value,
|
||||
iter->refs->base.repo->hash_algo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void reftable_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct reftable_ref_iterator *iter =
|
||||
@@ -770,7 +761,6 @@ static void reftable_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable reftable_ref_iterator_vtable = {
|
||||
.advance = reftable_ref_iterator_advance,
|
||||
.seek = reftable_ref_iterator_seek,
|
||||
.peel = reftable_ref_iterator_peel,
|
||||
.release = reftable_ref_iterator_release,
|
||||
};
|
||||
|
||||
@@ -828,7 +818,7 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
|
||||
|
||||
iter = xcalloc(1, sizeof(*iter));
|
||||
base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable);
|
||||
iter->base.oid = &iter->oid;
|
||||
iter->base.ref.oid = &iter->oid;
|
||||
iter->flags = flags;
|
||||
iter->refs = refs;
|
||||
iter->exclude_patterns = filter_exclude_patterns(exclude_patterns);
|
||||
@@ -1642,7 +1632,8 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
|
||||
ref.refname = (char *)u->refname;
|
||||
ref.update_index = ts;
|
||||
|
||||
peel_error = peel_object(arg->refs->base.repo, &u->new_oid, &peeled);
|
||||
peel_error = peel_object(arg->refs->base.repo, &u->new_oid, &peeled,
|
||||
PEEL_OBJECT_VERIFY_OBJECT_TYPE);
|
||||
if (!peel_error) {
|
||||
ref.value_type = REFTABLE_REF_VAL2;
|
||||
memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ);
|
||||
@@ -2072,7 +2063,7 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator)
|
||||
|
||||
strbuf_reset(&iter->last_name);
|
||||
strbuf_addstr(&iter->last_name, iter->log.refname);
|
||||
iter->base.refname = iter->log.refname;
|
||||
iter->base.ref.name = iter->log.refname;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2092,13 +2083,6 @@ static int reftable_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSE
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int reftable_reflog_iterator_peel(struct ref_iterator *ref_iterator UNUSED,
|
||||
struct object_id *peeled UNUSED)
|
||||
{
|
||||
BUG("reftable reflog iterator cannot be peeled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void reftable_reflog_iterator_release(struct ref_iterator *ref_iterator)
|
||||
{
|
||||
struct reftable_reflog_iterator *iter =
|
||||
@@ -2111,7 +2095,6 @@ static void reftable_reflog_iterator_release(struct ref_iterator *ref_iterator)
|
||||
static struct ref_iterator_vtable reftable_reflog_iterator_vtable = {
|
||||
.advance = reftable_reflog_iterator_advance,
|
||||
.seek = reftable_reflog_iterator_seek,
|
||||
.peel = reftable_reflog_iterator_peel,
|
||||
.release = reftable_reflog_iterator_release,
|
||||
};
|
||||
|
||||
@@ -2515,7 +2498,7 @@ static int write_reflog_expiry_table(struct reftable_writer *writer, void *cb_da
|
||||
ref.refname = (char *)arg->refname;
|
||||
ref.update_index = ts;
|
||||
|
||||
if (!peel_object(arg->refs->base.repo, &arg->update_oid, &peeled)) {
|
||||
if (!peel_object(arg->refs->base.repo, &arg->update_oid, &peeled, 0)) {
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user