Git fork

packfile: split up responsibilities of `reprepare_packed_git()`

In `reprepare_packed_git()` we perform a couple of operations:

- We reload alternate object directories.

- We clear the loose object cache.

- We reprepare packfiles.

While the logic is hosted in "packfile.c", it clearly reaches into other
subsystems that aren't related to packfiles.

Split up the responsibility and introduce `odb_reprepare()` which now
becomes responsible for repreparing the whole object database. The
existing `reprepare_packed_git()` function is refactored accordingly and
only cares about reloading the packfile store now.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
78237ea5 c36ecc06

+55 -35
+1 -1
builtin/backfill.c
··· 53 53 * We likely have a new packfile. Add it to the packed list to 54 54 * avoid possible duplicate downloads of the same objects. 55 55 */ 56 - reprepare_packed_git(ctx->repo); 56 + odb_reprepare(ctx->repo->objects); 57 57 } 58 58 59 59 static int fill_missing_blobs(const char *path UNUSED,
+2 -2
builtin/gc.c
··· 1042 1042 die(FAILED_RUN, "rerere"); 1043 1043 1044 1044 report_garbage = report_pack_garbage; 1045 - reprepare_packed_git(the_repository); 1045 + odb_reprepare(the_repository->objects); 1046 1046 if (pack_garbage.nr > 0) { 1047 1047 close_object_store(the_repository->objects); 1048 1048 clean_pack_garbage(); ··· 1491 1491 struct packed_git *p; 1492 1492 struct repository *r = the_repository; 1493 1493 1494 - reprepare_packed_git(r); 1494 + odb_reprepare(r->objects); 1495 1495 for (p = get_all_packs(r); p; p = p->next) { 1496 1496 if (p->pack_size > max_size) { 1497 1497 second_largest_size = max_size;
+1 -1
builtin/receive-pack.c
··· 2389 2389 status = finish_command(&child); 2390 2390 if (status) 2391 2391 return "index-pack abnormal exit"; 2392 - reprepare_packed_git(the_repository); 2392 + odb_reprepare(the_repository->objects); 2393 2393 } 2394 2394 return NULL; 2395 2395 }
+1 -1
builtin/repack.c
··· 1685 1685 goto cleanup; 1686 1686 } 1687 1687 1688 - reprepare_packed_git(the_repository); 1688 + odb_reprepare(the_repository->objects); 1689 1689 1690 1690 if (delete_redundant) { 1691 1691 int opts = 0;
+1 -1
bulk-checkin.c
··· 90 90 91 91 strbuf_release(&packname); 92 92 /* Make objects we just wrote available to ourselves */ 93 - reprepare_packed_git(the_repository); 93 + odb_reprepare(the_repository->objects); 94 94 } 95 95 96 96 /*
+1 -1
connected.c
··· 72 72 * Before checking for promisor packs, be sure we have the 73 73 * latest pack-files loaded into memory. 74 74 */ 75 - reprepare_packed_git(the_repository); 75 + odb_reprepare(the_repository->objects); 76 76 do { 77 77 struct packed_git *p; 78 78
+2 -2
fetch-pack.c
··· 1983 1983 * remote is shallow, but this is a clone, there are 1984 1984 * no objects in repo to worry about. Accept any 1985 1985 * shallow points that exist in the pack (iow in repo 1986 - * after get_pack() and reprepare_packed_git()) 1986 + * after get_pack() and odb_reprepare()) 1987 1987 */ 1988 1988 struct oid_array extra = OID_ARRAY_INIT; 1989 1989 struct object_id *oid = si->shallow->oid; ··· 2108 2108 ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, 2109 2109 &si, pack_lockfiles); 2110 2110 } 2111 - reprepare_packed_git(the_repository); 2111 + odb_reprepare(the_repository->objects); 2112 2112 2113 2113 if (!args->cloning && args->deepen) { 2114 2114 struct check_connected_options opt = CHECK_CONNECTED_INIT;
+1 -1
object-name.c
··· 596 596 * or migrated from loose to packed. 597 597 */ 598 598 if (status == MISSING_OBJECT) { 599 - reprepare_packed_git(r); 599 + odb_reprepare(r->objects); 600 600 find_short_object_filename(&ds); 601 601 find_short_packed_object(&ds); 602 602 status = finish_object_disambiguation(&ds, oid);
+26 -1
odb.c
··· 694 694 695 695 /* Not a loose object; someone else may have just packed it. */ 696 696 if (!(flags & OBJECT_INFO_QUICK)) { 697 - reprepare_packed_git(odb->repo); 697 + odb_reprepare(odb->repo->objects); 698 698 if (find_pack_entry(odb->repo, real, &e)) 699 699 break; 700 700 } ··· 1040 1040 1041 1041 string_list_clear(&o->submodule_source_paths, 0); 1042 1042 } 1043 + 1044 + void odb_reprepare(struct object_database *o) 1045 + { 1046 + struct odb_source *source; 1047 + 1048 + obj_read_lock(); 1049 + 1050 + /* 1051 + * Reprepare alt odbs, in case the alternates file was modified 1052 + * during the course of this process. This only _adds_ odbs to 1053 + * the linked list, so existing odbs will continue to exist for 1054 + * the lifetime of the process. 1055 + */ 1056 + o->loaded_alternates = 0; 1057 + odb_prepare_alternates(o); 1058 + 1059 + for (source = o->sources; source; source = source->next) 1060 + odb_clear_loose_cache(source); 1061 + 1062 + o->approximate_object_count_valid = 0; 1063 + 1064 + packfile_store_reprepare(o->packfiles); 1065 + 1066 + obj_read_unlock(); 1067 + }
+6
odb.h
··· 162 162 void odb_clear(struct object_database *o); 163 163 164 164 /* 165 + * Clear caches, reload alternates and then reload object sources so that new 166 + * objects may become accessible. 167 + */ 168 + void odb_reprepare(struct object_database *o); 169 + 170 + /* 165 171 * Find source by its object directory path. Returns a `NULL` pointer in case 166 172 * the source could not be found. 167 173 */
+4 -22
packfile.c
··· 1002 1002 store->initialized = true; 1003 1003 } 1004 1004 1005 - void reprepare_packed_git(struct repository *r) 1005 + void packfile_store_reprepare(struct packfile_store *store) 1006 1006 { 1007 - struct odb_source *source; 1008 - 1009 - obj_read_lock(); 1010 - 1011 - /* 1012 - * Reprepare alt odbs, in case the alternates file was modified 1013 - * during the course of this process. This only _adds_ odbs to 1014 - * the linked list, so existing odbs will continue to exist for 1015 - * the lifetime of the process. 1016 - */ 1017 - r->objects->loaded_alternates = 0; 1018 - odb_prepare_alternates(r->objects); 1019 - 1020 - for (source = r->objects->sources; source; source = source->next) 1021 - odb_clear_loose_cache(source); 1022 - 1023 - r->objects->approximate_object_count_valid = 0; 1024 - r->objects->packfiles->initialized = false; 1025 - packfile_store_prepare(r->objects->packfiles); 1026 - obj_read_unlock(); 1007 + store->initialized = false; 1008 + packfile_store_prepare(store); 1027 1009 } 1028 1010 1029 1011 struct packed_git *get_packed_git(struct repository *r) ··· 1144 1126 * 1145 1127 * Other worrying sections could be the call to close_pack_fd(), 1146 1128 * which can close packs even with in-use windows, and to 1147 - * reprepare_packed_git(). Regarding the former, mmap doc says: 1129 + * odb_reprepare(). Regarding the former, mmap doc says: 1148 1130 * "closing the file descriptor does not unmap the region". And 1149 1131 * for the latter, it won't re-open already available packs. 1150 1132 */
+8 -1
packfile.h
··· 112 112 */ 113 113 void packfile_store_close(struct packfile_store *store); 114 114 115 + /* 116 + * Clear the packfile caches and try to look up any new packfiles that have 117 + * appeared since last preparing the packfiles store. 118 + * 119 + * This function must be called under the `odb_read_lock()`. 120 + */ 121 + void packfile_store_reprepare(struct packfile_store *store); 122 + 115 123 struct pack_window { 116 124 struct pack_window *next; 117 125 unsigned char *base; ··· 188 196 #define PACKDIR_FILE_GARBAGE 4 189 197 extern void (*report_garbage)(unsigned seen_bits, const char *path); 190 198 191 - void reprepare_packed_git(struct repository *r); 192 199 void install_packed_git(struct repository *r, struct packed_git *pack); 193 200 194 201 struct packed_git *get_packed_git(struct repository *r);
+1 -1
transport-helper.c
··· 450 450 } 451 451 strbuf_release(&buf); 452 452 453 - reprepare_packed_git(the_repository); 453 + odb_reprepare(the_repository->objects); 454 454 return 0; 455 455 } 456 456