Merge branch 'ak/refs-files-root-refs-cache'
The loose refs cache in the files backend has been updated to avoid caching root refs (like 'HEAD'), preventing them from being omitted from subsequent iterators that explicitly request them when a previous iterator populated the cache without them. * ak/refs-files-root-refs-cache: refs/files: keep root refs out of loose ref cache
This commit is contained in:
commit
af456b19ba
2 files changed
+41
-8
No files matched your search
+29
-8
@@ -481,8 +481,7 @@ static void add_root_refs(struct files_ref_store *refs,
|
||||
for_each_root_ref(refs, fill_root_ref, &data);
|
||||
}
|
||||
|
||||
static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs,
|
||||
unsigned int flags)
|
||||
static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs)
|
||||
{
|
||||
if (!refs->loose) {
|
||||
struct ref_dir *dir;
|
||||
@@ -499,9 +498,6 @@ static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs,
|
||||
|
||||
dir = get_ref_dir(refs->loose->root);
|
||||
|
||||
if (flags & REFS_FOR_EACH_INCLUDE_ROOT_REFS)
|
||||
add_root_refs(refs, dir);
|
||||
|
||||
/*
|
||||
* Add an incomplete entry for "refs/" (to be filled
|
||||
* lazily):
|
||||
@@ -511,6 +507,19 @@ static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs,
|
||||
return refs->loose;
|
||||
}
|
||||
|
||||
/*
|
||||
* Root refs are kept out of the loose ref cache because ref iterators must
|
||||
* only include them when requested with REFS_FOR_EACH_INCLUDE_ROOT_REFS.
|
||||
*/
|
||||
static struct ref_cache *create_root_ref_cache(struct files_ref_store *refs)
|
||||
{
|
||||
struct ref_cache *cache = create_ref_cache(&refs->base, NULL);
|
||||
|
||||
cache->root->flag &= ~REF_INCOMPLETE;
|
||||
add_root_refs(refs, get_ref_dir(cache->root));
|
||||
return cache;
|
||||
}
|
||||
|
||||
static int read_ref_internal(struct ref_store *ref_store, const char *refname,
|
||||
struct object_id *oid, struct strbuf *referent,
|
||||
unsigned int *type, int *failure_errno, int skip_packed_refs)
|
||||
@@ -1004,6 +1013,7 @@ struct files_ref_iterator {
|
||||
struct ref_iterator base;
|
||||
|
||||
struct ref_iterator *iter0;
|
||||
struct ref_cache *root_refs;
|
||||
struct repository *repo;
|
||||
unsigned int flags;
|
||||
};
|
||||
@@ -1053,6 +1063,7 @@ static void files_ref_iterator_release(struct ref_iterator *ref_iterator)
|
||||
struct files_ref_iterator *iter =
|
||||
(struct files_ref_iterator *)ref_iterator;
|
||||
ref_iterator_free(iter->iter0);
|
||||
free_ref_cache(iter->root_refs);
|
||||
}
|
||||
|
||||
static struct ref_iterator_vtable files_ref_iterator_vtable = {
|
||||
@@ -1068,6 +1079,7 @@ static struct ref_iterator *files_ref_iterator_begin(
|
||||
{
|
||||
struct files_ref_store *refs;
|
||||
struct ref_iterator *loose_iter, *packed_iter, *overlay_iter;
|
||||
struct ref_cache *root_refs = NULL;
|
||||
struct files_ref_iterator *iter;
|
||||
struct ref_iterator *ref_iterator;
|
||||
unsigned int required_flags = REF_STORE_READ;
|
||||
@@ -1094,9 +1106,17 @@ static struct ref_iterator *files_ref_iterator_begin(
|
||||
* disk, and re-reads it if not.
|
||||
*/
|
||||
|
||||
loose_iter = cache_ref_iterator_begin(get_loose_ref_cache(refs, flags),
|
||||
loose_iter = cache_ref_iterator_begin(get_loose_ref_cache(refs),
|
||||
prefix, ref_store->repo, 1);
|
||||
|
||||
if (flags & REFS_FOR_EACH_INCLUDE_ROOT_REFS) {
|
||||
root_refs = create_root_ref_cache(refs);
|
||||
loose_iter = overlay_ref_iterator_begin(
|
||||
cache_ref_iterator_begin(root_refs, prefix,
|
||||
ref_store->repo, 0),
|
||||
loose_iter);
|
||||
}
|
||||
|
||||
/*
|
||||
* The packed-refs file might contain broken references, for
|
||||
* example an old version of a reference that points at an
|
||||
@@ -1118,6 +1138,7 @@ static struct ref_iterator *files_ref_iterator_begin(
|
||||
ref_iterator = &iter->base;
|
||||
base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable);
|
||||
iter->iter0 = overlay_iter;
|
||||
iter->root_refs = root_refs;
|
||||
iter->repo = ref_store->repo;
|
||||
iter->flags = flags;
|
||||
|
||||
@@ -1490,7 +1511,7 @@ static int should_pack_refs(struct files_ref_store *refs,
|
||||
if (limit < 16)
|
||||
limit = 16;
|
||||
|
||||
iter = cache_ref_iterator_begin(get_loose_ref_cache(refs, 0), NULL,
|
||||
iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL,
|
||||
refs->base.repo, 0);
|
||||
while ((ret = ref_iterator_advance(iter)) == ITER_OK) {
|
||||
if (should_pack_ref(refs, &iter->ref, opts))
|
||||
@@ -1530,7 +1551,7 @@ static int files_optimize(struct ref_store *ref_store,
|
||||
|
||||
packed_refs_lock(refs->packed_ref_store, LOCK_DIE_ON_ERROR, &err);
|
||||
|
||||
iter = cache_ref_iterator_begin(get_loose_ref_cache(refs, 0), NULL,
|
||||
iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL,
|
||||
refs->base.repo, 0);
|
||||
while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
|
||||
/*
|
||||
|
||||
@@ -96,6 +96,18 @@ test_expect_success '--include-root-refs omits dangling symrefs' '
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success '--include-root-refs with --merged' '
|
||||
cat >expect <<-\EOF &&
|
||||
HEAD
|
||||
ORIG_HEAD
|
||||
EOF
|
||||
test_when_finished "git update-ref -d ORIG_HEAD" &&
|
||||
git update-ref ORIG_HEAD main &&
|
||||
git for-each-ref --format="%(refname)" --include-root-refs \
|
||||
--merged=main "*HEAD" >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'filtering with --points-at' '
|
||||
cat >expect <<-\EOF &&
|
||||
refs/heads/main
|
||||
|
||||
Reference in new issue
Block a user