diff options
Diffstat (limited to 'refs')
| -rw-r--r-- | refs/files-backend.c | 47 | ||||
| -rw-r--r-- | refs/iterator.c | 4 | ||||
| -rw-r--r-- | refs/packed-backend.c | 14 | ||||
| -rw-r--r-- | refs/ref-cache.c | 5 | ||||
| -rw-r--r-- | refs/ref-cache.h | 2 | ||||
| -rw-r--r-- | refs/refs-internal.h | 4 | ||||
| -rw-r--r-- | refs/reftable-backend.c | 60 |
7 files changed, 81 insertions, 55 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c index 7f6eefa960..8d6ec9458d 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "../git-compat-util.h" #include "../copy.h" #include "../environment.h" @@ -158,6 +156,7 @@ static void files_ref_store_release(struct ref_store *ref_store) free_ref_cache(refs->loose); free(refs->gitcommondir); ref_store_release(refs->packed_ref_store); + free(refs->packed_ref_store); } static void files_reflog_path(struct files_ref_store *refs, @@ -246,10 +245,13 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs, { struct object_id oid; int flag; + const char *referent = refs_resolve_ref_unsafe(&refs->base, + refname, + RESOLVE_REF_READING, + &oid, &flag); - if (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING, - &oid, &flag)) { - oidclr(&oid, the_repository->hash_algo); + if (!referent) { + oidclr(&oid, refs->base.repo->hash_algo); flag |= REF_ISBROKEN; } else if (is_null_oid(&oid)) { /* @@ -266,10 +268,14 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs, if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { if (!refname_is_safe(refname)) die("loose refname is dangerous: %s", refname); - oidclr(&oid, the_repository->hash_algo); + oidclr(&oid, refs->base.repo->hash_algo); flag |= REF_BAD_NAME | REF_ISBROKEN; } - add_entry_to_dir(dir, create_ref_entry(refname, &oid, flag)); + + if (!(flag & REF_ISSYMREF)) + referent = NULL; + + add_entry_to_dir(dir, create_ref_entry(refname, referent, &oid, flag)); } /* @@ -553,7 +559,8 @@ stat_ref: strbuf_rtrim(&sb_contents); buf = sb_contents.buf; - ret = parse_loose_ref_contents(buf, oid, referent, type, &myerr); + ret = parse_loose_ref_contents(ref_store->repo->hash_algo, buf, + oid, referent, type, &myerr); out: if (ret && !myerr) @@ -587,7 +594,8 @@ static int files_read_symbolic_ref(struct ref_store *ref_store, const char *refn return !(type & REF_ISSYMREF); } -int parse_loose_ref_contents(const char *buf, struct object_id *oid, +int parse_loose_ref_contents(const struct git_hash_algo *algop, + const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, int *failure_errno) { @@ -605,7 +613,7 @@ int parse_loose_ref_contents(const char *buf, struct object_id *oid, /* * FETCH_HEAD has additional data after the sha. */ - if (parse_oid_hex(buf, oid, &p) || + if (parse_oid_hex_algop(buf, oid, &p, algop) || (*p != '\0' && !isspace(*p))) { *type |= REF_ISBROKEN; *failure_errno = EINVAL; @@ -887,6 +895,8 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator) 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; } @@ -1153,7 +1163,7 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs, if (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, 0, &lock->old_oid, NULL)) - oidclr(&lock->old_oid, the_repository->hash_algo); + oidclr(&lock->old_oid, refs->base.repo->hash_algo); goto out; error_return: @@ -1999,7 +2009,8 @@ static int files_delete_reflog(struct ref_store *ref_store, return ret; } -static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data) +static int show_one_reflog_ent(struct files_ref_store *refs, struct strbuf *sb, + each_reflog_ent_fn fn, void *cb_data) { struct object_id ooid, noid; char *email_end, *message; @@ -2009,8 +2020,8 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *c /* old SP new SP name <email> SP time TAB msg LF */ if (!sb->len || sb->buf[sb->len - 1] != '\n' || - parse_oid_hex(p, &ooid, &p) || *p++ != ' ' || - parse_oid_hex(p, &noid, &p) || *p++ != ' ' || + parse_oid_hex_algop(p, &ooid, &p, refs->base.repo->hash_algo) || *p++ != ' ' || + parse_oid_hex_algop(p, &noid, &p, refs->base.repo->hash_algo) || *p++ != ' ' || !(email_end = strchr(p, '>')) || email_end[1] != ' ' || !(timestamp = parse_timestamp(email_end + 2, &message, 10)) || @@ -2109,7 +2120,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store, strbuf_splice(&sb, 0, 0, bp + 1, endp - (bp + 1)); scanp = bp; endp = bp + 1; - ret = show_one_reflog_ent(&sb, fn, cb_data); + ret = show_one_reflog_ent(refs, &sb, fn, cb_data); strbuf_reset(&sb); if (ret) break; @@ -2121,7 +2132,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store, * Process it, and we can end the loop. */ strbuf_splice(&sb, 0, 0, buf, endp - buf); - ret = show_one_reflog_ent(&sb, fn, cb_data); + ret = show_one_reflog_ent(refs, &sb, fn, cb_data); strbuf_reset(&sb); break; } @@ -2171,7 +2182,7 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store, return -1; while (!ret && !strbuf_getwholeline(&sb, logfp, '\n')) - ret = show_one_reflog_ent(&sb, fn, cb_data); + ret = show_one_reflog_ent(refs, &sb, fn, cb_data); fclose(logfp); strbuf_release(&sb); return ret; @@ -3036,7 +3047,7 @@ static int files_transaction_abort(struct ref_store *ref_store, return 0; } -static int ref_present(const char *refname, +static int ref_present(const char *refname, const char *referent UNUSED, const struct object_id *oid UNUSED, int flags UNUSED, void *cb_data) diff --git a/refs/iterator.c b/refs/iterator.c index d355ebf0d5..8e999d81fc 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -29,6 +29,7 @@ void base_ref_iterator_init(struct ref_iterator *iter, { iter->vtable = vtable; iter->refname = NULL; + iter->referent = NULL; iter->oid = NULL; iter->flags = 0; } @@ -199,6 +200,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; @@ -448,7 +450,7 @@ int do_for_each_ref_iterator(struct ref_iterator *iter, current_ref_iter = iter; while ((ok = ref_iterator_advance(iter)) == ITER_OK) { - retval = fn(iter->refname, iter->oid, iter->flags, cb_data); + retval = fn(iter->refname, iter->referent, iter->oid, iter->flags, cb_data); if (retval) { /* * If ref_iterator_abort() returns ITER_ERROR, diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 5209b0b212..f00106df14 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "../git-compat-util.h" #include "../config.h" #include "../dir.h" @@ -794,7 +792,7 @@ static int packed_read_raw_ref(struct ref_store *ref_store, const char *refname, return -1; } - if (get_oid_hex(rec, oid)) + if (get_oid_hex_algop(rec, oid, ref_store->repo->hash_algo)) die_invalid_line(refs->path, rec, snapshot->eof - rec); *type = REF_ISPACKED; @@ -879,7 +877,7 @@ static int next_record(struct packed_ref_iterator *iter) p = iter->pos; if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 2 || - parse_oid_hex(p, &iter->oid, &p) || + parse_oid_hex_algop(p, &iter->oid, &p, iter->repo->hash_algo) || !isspace(*p++)) die_invalid_line(iter->snapshot->refs->path, iter->pos, iter->eof - iter->pos); @@ -896,7 +894,7 @@ static int next_record(struct packed_ref_iterator *iter) if (!refname_is_safe(iter->base.refname)) die("packed refname is dangerous: %s", iter->base.refname); - oidclr(&iter->oid, the_repository->hash_algo); + oidclr(&iter->oid, iter->repo->hash_algo); iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN; } if (iter->snapshot->peeled == PEELED_FULLY || @@ -909,7 +907,7 @@ static int next_record(struct packed_ref_iterator *iter) if (iter->pos < iter->eof && *iter->pos == '^') { p = iter->pos + 1; if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 1 || - parse_oid_hex(p, &iter->peeled, &p) || + parse_oid_hex_algop(p, &iter->peeled, &p, iter->repo->hash_algo) || *p++ != '\n') die_invalid_line(iter->snapshot->refs->path, iter->pos, iter->eof - iter->pos); @@ -921,13 +919,13 @@ static int next_record(struct packed_ref_iterator *iter) * we suppress it if the reference is broken: */ if ((iter->base.flags & REF_ISBROKEN)) { - oidclr(&iter->peeled, the_repository->hash_algo); + oidclr(&iter->peeled, iter->repo->hash_algo); iter->base.flags &= ~REF_KNOWS_PEELED; } else { iter->base.flags |= REF_KNOWS_PEELED; } } else { - oidclr(&iter->peeled, the_repository->hash_algo); + oidclr(&iter->peeled, iter->repo->hash_algo); } return ITER_OK; diff --git a/refs/ref-cache.c b/refs/ref-cache.c index 4ce519bbc8..35bae7e05d 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -34,6 +34,7 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry) } struct ref_entry *create_ref_entry(const char *refname, + const char *referent, const struct object_id *oid, int flag) { struct ref_entry *ref; @@ -41,6 +42,8 @@ struct ref_entry *create_ref_entry(const char *refname, FLEX_ALLOC_STR(ref, name, refname); oidcpy(&ref->u.value.oid, oid); ref->flag = flag; + ref->u.value.referent = xstrdup_or_null(referent); + return ref; } @@ -66,6 +69,7 @@ static void free_ref_entry(struct ref_entry *entry) */ clear_ref_dir(&entry->u.subdir); } + free(entry->u.value.referent); free(entry); } @@ -431,6 +435,7 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator) 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; return ITER_OK; diff --git a/refs/ref-cache.h b/refs/ref-cache.h index 31ebe24f6c..5f04e518c3 100644 --- a/refs/ref-cache.h +++ b/refs/ref-cache.h @@ -42,6 +42,7 @@ struct ref_value { * referred to by the last reference in the symlink chain. */ struct object_id oid; + char *referent; }; /* @@ -173,6 +174,7 @@ struct ref_entry *create_dir_entry(struct ref_cache *cache, const char *dirname, size_t len); struct ref_entry *create_ref_entry(const char *refname, + const char *referent, const struct object_id *oid, int flag); /* diff --git a/refs/refs-internal.h b/refs/refs-internal.h index a905e187cd..2313c830d8 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -300,6 +300,7 @@ enum do_for_each_ref_flags { struct ref_iterator { struct ref_iterator_vtable *vtable; const char *refname; + const char *referent; const struct object_id *oid; unsigned int flags; }; @@ -711,7 +712,8 @@ struct ref_store { * Parse contents of a loose ref file. *failure_errno maybe be set to EINVAL for * invalid contents. */ -int parse_loose_ref_contents(const char *buf, struct object_id *oid, +int parse_loose_ref_contents(const struct git_hash_algo *algop, + const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, int *failure_errno); diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index b5a1a526df..8b7ffbf66f 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "../git-compat-util.h" #include "../abspath.h" #include "../chdir-notify.h" @@ -201,7 +199,8 @@ static void fill_reftable_log_record(struct reftable_log_record *log, const stru log->value.update.tz_offset = sign * atoi(tz_begin); } -static int read_ref_without_reload(struct reftable_stack *stack, +static int read_ref_without_reload(struct reftable_ref_store *refs, + struct reftable_stack *stack, const char *refname, struct object_id *oid, struct strbuf *referent, @@ -220,7 +219,7 @@ static int read_ref_without_reload(struct reftable_stack *stack, *type |= REF_ISSYMREF; } else if (reftable_ref_record_val1(&ref)) { oidread(oid, reftable_ref_record_val1(&ref), - the_repository->hash_algo); + refs->base.repo->hash_algo); } else { /* We got a tombstone, which should not happen. */ BUG("unhandled reference value type %d", ref.value_type); @@ -455,6 +454,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) struct reftable_ref_iterator *iter = (struct reftable_ref_iterator *)ref_iterator; struct reftable_ref_store *refs = iter->refs; + const char *referent = NULL; while (!iter->err) { int flags = 0; @@ -487,16 +487,19 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) switch (iter->ref.value_type) { case REFTABLE_REF_VAL1: oidread(&iter->oid, iter->ref.value.val1, - the_repository->hash_algo); + refs->base.repo->hash_algo); break; case REFTABLE_REF_VAL2: oidread(&iter->oid, iter->ref.value.val2.value, - the_repository->hash_algo); + refs->base.repo->hash_algo); break; case REFTABLE_REF_SYMREF: - if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname, - RESOLVE_REF_READING, &iter->oid, &flags)) - oidclr(&iter->oid, the_repository->hash_algo); + referent = refs_resolve_ref_unsafe(&iter->refs->base, + iter->ref.refname, + RESOLVE_REF_READING, + &iter->oid, &flags); + if (!referent) + oidclr(&iter->oid, refs->base.repo->hash_algo); break; default: BUG("unhandled reference value type %d", iter->ref.value_type); @@ -508,7 +511,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) if (check_refname_format(iter->ref.refname, REFNAME_ALLOW_ONELEVEL)) { if (!refname_is_safe(iter->ref.refname)) die(_("refname is dangerous: %s"), iter->ref.refname); - oidclr(&iter->oid, the_repository->hash_algo); + oidclr(&iter->oid, refs->base.repo->hash_algo); flags |= REF_BAD_NAME | REF_ISBROKEN; } @@ -523,6 +526,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) continue; iter->base.refname = iter->ref.refname; + iter->base.referent = referent; iter->base.oid = &iter->oid; iter->base.flags = flags; @@ -551,7 +555,7 @@ static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator, if (iter->ref.value_type == REFTABLE_REF_VAL2) { oidread(peeled, iter->ref.value.val2.target_value, - the_repository->hash_algo); + iter->refs->base.repo->hash_algo); return 0; } @@ -659,7 +663,7 @@ static int reftable_be_read_raw_ref(struct ref_store *ref_store, if (ret) return ret; - ret = read_ref_without_reload(stack, refname, oid, referent, type); + ret = read_ref_without_reload(refs, stack, refname, oid, referent, type); if (ret < 0) return ret; if (ret > 0) { @@ -868,8 +872,8 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, goto done; } - ret = read_ref_without_reload(stack_for(refs, "HEAD", NULL), "HEAD", &head_oid, - &head_referent, &head_type); + ret = read_ref_without_reload(refs, stack_for(refs, "HEAD", NULL), "HEAD", + &head_oid, &head_referent, &head_type); if (ret < 0) goto done; ret = 0; @@ -936,7 +940,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, string_list_insert(&affected_refnames, new_update->refname); } - ret = read_ref_without_reload(stack, rewritten_ref, + ret = read_ref_without_reload(refs, stack, rewritten_ref, ¤t_oid, &referent, &u->type); if (ret < 0) goto done; @@ -1500,7 +1504,8 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) memcpy(logs[logs_nr].value.update.old_hash, old_ref.value.val1, GIT_MAX_RAWSZ); logs_nr++; - ret = read_ref_without_reload(arg->stack, "HEAD", &head_oid, &head_referent, &head_type); + ret = read_ref_without_reload(arg->refs, arg->stack, "HEAD", &head_oid, + &head_referent, &head_type); if (ret < 0) goto done; append_head_reflog = (head_type & REF_ISSYMREF) && !strcmp(head_referent.buf, arg->oldname); @@ -1790,15 +1795,16 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store * ref_iterator_select, NULL); } -static int yield_log_record(struct reftable_log_record *log, +static int yield_log_record(struct reftable_ref_store *refs, + struct reftable_log_record *log, each_reflog_ent_fn fn, void *cb_data) { struct object_id old_oid, new_oid; const char *full_committer; - oidread(&old_oid, log->value.update.old_hash, the_repository->hash_algo); - oidread(&new_oid, log->value.update.new_hash, the_repository->hash_algo); + oidread(&old_oid, log->value.update.old_hash, refs->base.repo->hash_algo); + oidread(&new_oid, log->value.update.new_hash, refs->base.repo->hash_algo); /* * When both the old object ID and the new object ID are null @@ -1841,7 +1847,7 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store, break; } - ret = yield_log_record(&log, fn, cb_data); + ret = yield_log_record(refs, &log, fn, cb_data); if (ret) break; } @@ -1886,7 +1892,7 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store, } for (i = logs_nr; i--;) { - ret = yield_log_record(&logs[i], fn, cb_data); + ret = yield_log_record(refs, &logs[i], fn, cb_data); if (ret) goto done; } @@ -2200,7 +2206,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, goto done; if (reftable_ref_record_val1(&ref_record)) oidread(&oid, reftable_ref_record_val1(&ref_record), - the_repository->hash_algo); + ref_store->repo->hash_algo); prepare_fn(refname, &oid, policy_cb_data); while (1) { @@ -2216,9 +2222,9 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, } oidread(&old_oid, log.value.update.old_hash, - the_repository->hash_algo); + ref_store->repo->hash_algo); oidread(&new_oid, log.value.update.new_hash, - the_repository->hash_algo); + ref_store->repo->hash_algo); /* * Skip over the reflog existence marker. We will add it back @@ -2250,9 +2256,9 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, *dest = logs[i]; oidread(&old_oid, logs[i].value.update.old_hash, - the_repository->hash_algo); + ref_store->repo->hash_algo); oidread(&new_oid, logs[i].value.update.new_hash, - the_repository->hash_algo); + ref_store->repo->hash_algo); if (should_prune_fn(&old_oid, &new_oid, logs[i].value.update.email, (timestamp_t)logs[i].value.update.time, @@ -2269,7 +2275,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash && reftable_ref_record_val1(&ref_record)) - oidread(&arg.update_oid, last_hash, the_repository->hash_algo); + oidread(&arg.update_oid, last_hash, ref_store->repo->hash_algo); arg.refs = refs; arg.records = rewritten; |
