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>
Derrick Stolee committed
Jul 12, 2018 at 15:39 UTC
9208e318f548d28c677203a222f02a31a15c5d0e
2 files changed
+69
-38
packfile.c
+63
-38
@@ -738,13 +738,14 @@ static void report_pack_garbage(struct string_list *list)
738
report_helper(list, seen_bits, first, list->nr);
739
}
740
741
-static void prepare_packed_git_one(struct repository *r, char *objdir, int local)
741
+void for_each_file_in_pack_dir(const char *objdir,
742
+ each_file_in_pack_dir_fn fn,
743
+ void *data)
744
{
745
struct strbuf path = STRBUF_INIT;
746
size_t dirnamelen;
747
DIR *dir;
748
struct dirent *de;
747
- struct string_list garbage = STRING_LIST_INIT_DUP;
749
750
strbuf_addstr(&path, objdir);
751
strbuf_addstr(&path, "/pack");
@@ -759,53 +760,77 @@ static void prepare_packed_git_one(struct repository *r, char *objdir, int local
760
strbuf_addch(&path, '/');
761
dirnamelen = path.len;
762
while ((de = readdir(dir)) != NULL) {
762
- struct packed_git *p;
763
- size_t base_len;
764
-
763
if (is_dot_or_dotdot(de->d_name))
764
continue;
765
766
strbuf_setlen(&path, dirnamelen);
767
strbuf_addstr(&path, de->d_name);
768
771
- base_len = path.len;
772
- if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
773
- /* Don't reopen a pack we already have. */
774
- for (p = r->objects->packed_git; p;
775
- p = p->next) {
776
- size_t len;
777
- if (strip_suffix(p->pack_name, ".pack", &len) &&
778
- len == base_len &&
779
- !memcmp(p->pack_name, path.buf, len))
780
- break;
781
- }
782
- if (p == NULL &&
783
- /*
784
- * See if it really is a valid .idx file with
785
- * corresponding .pack file that we can map.
786
- */
787
- (p = add_packed_git(path.buf, path.len, local)) != NULL)
788
- install_packed_git(r, p);
789
- }
790
-
791
- if (!report_garbage)
792
- continue;
793
-
794
- if (ends_with(de->d_name, ".idx") ||
795
- ends_with(de->d_name, ".pack") ||
796
- ends_with(de->d_name, ".bitmap") ||
797
- ends_with(de->d_name, ".keep") ||
798
- ends_with(de->d_name, ".promisor"))
799
- string_list_append(&garbage, path.buf);
800
- else
801
- report_garbage(PACKDIR_FILE_GARBAGE, path.buf);
769
+ fn(path.buf, path.len, de->d_name, data);
770
}
771
+
772
closedir(dir);
804
- report_pack_garbage(&garbage);
805
- string_list_clear(&garbage, 0);
773
strbuf_release(&path);
774
}
775
776
+struct prepare_pack_data {
777
+ struct repository *r;
778
+ struct string_list *garbage;
779
+ int local;
780
+};
781
+
782
+static void prepare_pack(const char *full_name, size_t full_name_len,
783
+ const char *file_name, void *_data)
784
+{
785
+ struct prepare_pack_data *data = (struct prepare_pack_data *)_data;
786
+ struct packed_git *p;
787
+ size_t base_len = full_name_len;
788
+
789
+ if (strip_suffix_mem(full_name, &base_len, ".idx")) {
790
+ /* Don't reopen a pack we already have. */
791
+ for (p = data->r->objects->packed_git; p; p = p->next) {
792
+ size_t len;
793
+ if (strip_suffix(p->pack_name, ".pack", &len) &&
794
+ len == base_len &&
795
+ !memcmp(p->pack_name, full_name, len))
796
+ break;
797
+ }
798
+
799
+ if (!p) {
800
+ p = add_packed_git(full_name, full_name_len, data->local);
801
+ if (p)
802
+ install_packed_git(data->r, p);
803
+ }
804
+ }
805
+
806
+ if (!report_garbage)
807
+ return;
808
+
809
+ if (ends_with(file_name, ".idx") ||
810
+ ends_with(file_name, ".pack") ||
811
+ ends_with(file_name, ".bitmap") ||
812
+ ends_with(file_name, ".keep") ||
813
+ ends_with(file_name, ".promisor"))
814
+ string_list_append(data->garbage, full_name);
815
+ else
816
+ report_garbage(PACKDIR_FILE_GARBAGE, full_name);
817
+}
818
+
819
+static void prepare_packed_git_one(struct repository *r, char *objdir, int local)
820
+{
821
+ struct prepare_pack_data data;
822
+ struct string_list garbage = STRING_LIST_INIT_DUP;
823
+
824
+ data.r = r;
825
+ data.garbage = &garbage;
826
+ data.local = local;
827
+
828
+ for_each_file_in_pack_dir(objdir, prepare_pack, &data);
829
+
830
+ report_pack_garbage(data.garbage);
831
+ string_list_clear(data.garbage, 0);
832
+}
833
+
834
static void prepare_packed_git(struct repository *r);
835
/*
836
* Give a fast, rough count of the number of objects in the repository. This
packfile.h
+6
@@ -28,6 +28,12 @@ extern char *sha1_pack_index_name(const unsigned char *sha1);
28
29
extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
30
31
+typedef void each_file_in_pack_dir_fn(const char *full_path, size_t full_path_len,
32
+ const char *file_pach, void *data);
33
+void for_each_file_in_pack_dir(const char *objdir,
34
+ each_file_in_pack_dir_fn fn,
35
+ void *data);
36
+
37
/* A hook to report invalid files in pack directory */
38
#define PACKDIR_FILE_PACK 1
39
#define PACKDIR_FILE_IDX 2