packfile: generalize pack directory list

In anticipation of sharing the pack directory listing with the
multi-pack-index, generalize prepare_packed_git_one() into
for_each_file_in_pack_dir().

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Derrick Stolee 2018-07-12 15:39:25 -04:00 committed by Junio C Hamano
parent 2c3813354b
commit 9208e318f5
2 changed files with 69 additions and 38 deletions

View File

@ -738,13 +738,14 @@ static void report_pack_garbage(struct string_list *list)
report_helper(list, seen_bits, first, list->nr); report_helper(list, seen_bits, first, list->nr);
} }


static void prepare_packed_git_one(struct repository *r, char *objdir, int local) void for_each_file_in_pack_dir(const char *objdir,
each_file_in_pack_dir_fn fn,
void *data)
{ {
struct strbuf path = STRBUF_INIT; struct strbuf path = STRBUF_INIT;
size_t dirnamelen; size_t dirnamelen;
DIR *dir; DIR *dir;
struct dirent *de; struct dirent *de;
struct string_list garbage = STRING_LIST_INIT_DUP;


strbuf_addstr(&path, objdir); strbuf_addstr(&path, objdir);
strbuf_addstr(&path, "/pack"); strbuf_addstr(&path, "/pack");
@ -759,51 +760,75 @@ static void prepare_packed_git_one(struct repository *r, char *objdir, int local
strbuf_addch(&path, '/'); strbuf_addch(&path, '/');
dirnamelen = path.len; dirnamelen = path.len;
while ((de = readdir(dir)) != NULL) { while ((de = readdir(dir)) != NULL) {
struct packed_git *p;
size_t base_len;

if (is_dot_or_dotdot(de->d_name)) if (is_dot_or_dotdot(de->d_name))
continue; continue;


strbuf_setlen(&path, dirnamelen); strbuf_setlen(&path, dirnamelen);
strbuf_addstr(&path, de->d_name); strbuf_addstr(&path, de->d_name);


base_len = path.len; fn(path.buf, path.len, de->d_name, data);
if (strip_suffix_mem(path.buf, &base_len, ".idx")) { }
/* Don't reopen a pack we already have. */
for (p = r->objects->packed_git; p; closedir(dir);
p = p->next) { strbuf_release(&path);
size_t len; }
if (strip_suffix(p->pack_name, ".pack", &len) &&
len == base_len && struct prepare_pack_data {
!memcmp(p->pack_name, path.buf, len)) struct repository *r;
break; struct string_list *garbage;
} int local;
if (p == NULL && };
/*
* See if it really is a valid .idx file with static void prepare_pack(const char *full_name, size_t full_name_len,
* corresponding .pack file that we can map. const char *file_name, void *_data)
*/ {
(p = add_packed_git(path.buf, path.len, local)) != NULL) struct prepare_pack_data *data = (struct prepare_pack_data *)_data;
install_packed_git(r, p); struct packed_git *p;
size_t base_len = full_name_len;

if (strip_suffix_mem(full_name, &base_len, ".idx")) {
/* Don't reopen a pack we already have. */
for (p = data->r->objects->packed_git; p; p = p->next) {
size_t len;
if (strip_suffix(p->pack_name, ".pack", &len) &&
len == base_len &&
!memcmp(p->pack_name, full_name, len))
break;
} }


if (!report_garbage) if (!p) {
continue; p = add_packed_git(full_name, full_name_len, data->local);

if (p)
if (ends_with(de->d_name, ".idx") || install_packed_git(data->r, p);
ends_with(de->d_name, ".pack") || }
ends_with(de->d_name, ".bitmap") ||
ends_with(de->d_name, ".keep") ||
ends_with(de->d_name, ".promisor"))
string_list_append(&garbage, path.buf);
else
report_garbage(PACKDIR_FILE_GARBAGE, path.buf);
} }
closedir(dir);
report_pack_garbage(&garbage); if (!report_garbage)
string_list_clear(&garbage, 0); return;
strbuf_release(&path);
if (ends_with(file_name, ".idx") ||
ends_with(file_name, ".pack") ||
ends_with(file_name, ".bitmap") ||
ends_with(file_name, ".keep") ||
ends_with(file_name, ".promisor"))
string_list_append(data->garbage, full_name);
else
report_garbage(PACKDIR_FILE_GARBAGE, full_name);
}

static void prepare_packed_git_one(struct repository *r, char *objdir, int local)
{
struct prepare_pack_data data;
struct string_list garbage = STRING_LIST_INIT_DUP;

data.r = r;
data.garbage = &garbage;
data.local = local;

for_each_file_in_pack_dir(objdir, prepare_pack, &data);

report_pack_garbage(data.garbage);
string_list_clear(data.garbage, 0);
} }


static void prepare_packed_git(struct repository *r); static void prepare_packed_git(struct repository *r);

View File

@ -28,6 +28,12 @@ extern char *sha1_pack_index_name(const unsigned char *sha1);


extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path); extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);


typedef void each_file_in_pack_dir_fn(const char *full_path, size_t full_path_len,
const char *file_pach, void *data);
void for_each_file_in_pack_dir(const char *objdir,
each_file_in_pack_dir_fn fn,
void *data);

/* A hook to report invalid files in pack directory */ /* A hook to report invalid files in pack directory */
#define PACKDIR_FILE_PACK 1 #define PACKDIR_FILE_PACK 1
#define PACKDIR_FILE_IDX 2 #define PACKDIR_FILE_IDX 2