Skip to content

Commit 59552fb

Browse files
ttaylorrgitster
authored andcommitted
midx: traverse the local MIDX first
When a repository has an alternate object directory configured, callers can traverse through each alternate's MIDX by walking the '->next' pointer. But, when 'prepare_multi_pack_index_one()' loads multiple MIDXs, it places the new ones at the front of this pointer chain, not at the end. This can be confusing for callers such as 'git repack -ad', causing test failures like in t7700.6 with 'GIT_TEST_MULTI_PACK_INDEX=1'. The occurs when dropping a pack known to the local MIDX with alternates configured that have their own MIDX. Since the alternate's MIDX is returned via 'get_multi_pack_index()', 'midx_contains_pack()' returns true (which is correct, since it traverses through the '->next' pointer to find the MIDX in the chain that does contain the requested object). But, we call 'clear_midx_file()' on 'the_repository', which drops the MIDX at the path of the first MIDX in the chain, which (in the case of t7700.6 is the one in the alternate). This patch addresses that by: - placing the local MIDX first in the chain when calling 'prepare_multi_pack_index_one()', and - introducing a new 'get_local_multi_pack_index()', which explicitly returns the repository-local MIDX, if any. Don't impose an additional order on the MIDX's '->next' pointer beyond that the first item in the chain must be local if one exists so that we avoid a quadratic insertion. Likewise, use 'get_local_multi_pack_index()' in 'remove_redundant_pack()' to fix the formerly broken t7700.6 when run with 'GIT_TEST_MULTI_PACK_INDEX=1'. Finally, note that the MIDX ordering invariant is only preserved by the insertion order in 'prepare_packed_git()', which traverses through the ODB's '->next' pointer, meaning we visit the local object store first. This fragility makes this an undesirable long-term solution if more callers are added, but it is acceptable for now since this is the only caller. Helped-by: Jeff King <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e08f7bb commit 59552fb

File tree

4 files changed

+19
-3
lines changed

4 files changed

+19
-3
lines changed

builtin/repack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list,
133133
static void remove_redundant_pack(const char *dir_name, const char *base_name)
134134
{
135135
struct strbuf buf = STRBUF_INIT;
136-
struct multi_pack_index *m = get_multi_pack_index(the_repository);
136+
struct multi_pack_index *m = get_local_multi_pack_index(the_repository);
137137
strbuf_addf(&buf, "%s.pack", base_name);
138138
if (m && midx_contains_pack(m, buf.buf))
139139
clear_midx_file(the_repository);

midx.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,12 @@ int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, i
402402
m = load_multi_pack_index(object_dir, local);
403403

404404
if (m) {
405-
m->next = r->objects->multi_pack_index;
406-
r->objects->multi_pack_index = m;
405+
struct multi_pack_index *mp = r->objects->multi_pack_index;
406+
if (mp) {
407+
m->next = mp->next;
408+
mp->next = m;
409+
} else
410+
r->objects->multi_pack_index = m;
407411
return 1;
408412
}
409413

packfile.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,17 @@ struct multi_pack_index *get_multi_pack_index(struct repository *r)
10271027
return r->objects->multi_pack_index;
10281028
}
10291029

1030+
struct multi_pack_index *get_local_multi_pack_index(struct repository *r)
1031+
{
1032+
struct multi_pack_index *m = get_multi_pack_index(r);
1033+
1034+
/* no need to iterate; we always put the local one first (if any) */
1035+
if (m && m->local)
1036+
return m;
1037+
1038+
return NULL;
1039+
}
1040+
10301041
struct packed_git *get_all_packs(struct repository *r)
10311042
{
10321043
struct multi_pack_index *m;

packfile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ void install_packed_git(struct repository *r, struct packed_git *pack);
5757
struct packed_git *get_packed_git(struct repository *r);
5858
struct list_head *get_packed_git_mru(struct repository *r);
5959
struct multi_pack_index *get_multi_pack_index(struct repository *r);
60+
struct multi_pack_index *get_local_multi_pack_index(struct repository *r);
6061
struct packed_git *get_all_packs(struct repository *r);
6162

6263
/*

0 commit comments

Comments
 (0)