Git fork

Merge branch 'ps/object-store-midx-dedup-info' into ps/packfile-store

* ps/object-store-midx-dedup-info:
midx: compute paths via their source
midx: stop duplicating info redundant with its owning source
midx: write multi-pack indices via their source
midx: load multi-pack indices via their source
midx: drop redundant `struct repository` parameter
odb: simplify calling `link_alt_odb_entry()`
odb: return newly created in-memory sources
odb: consistently use "dir" to refer to alternate's directory
odb: allow `odb_find_source()` to fail
odb: store locality in object database sources

+254 -248
+2 -2
builtin/commit-graph.c
··· 102 102 if (opts.progress) 103 103 flags |= COMMIT_GRAPH_WRITE_PROGRESS; 104 104 105 - source = odb_find_source(the_repository->objects, opts.obj_dir); 105 + source = odb_find_source_or_die(the_repository->objects, opts.obj_dir); 106 106 graph_name = get_commit_graph_filename(source); 107 107 chain_name = get_commit_graph_chain_filename(source); 108 108 if (open_commit_graph(graph_name, &fd, &st)) ··· 291 291 git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0)) 292 292 flags |= COMMIT_GRAPH_WRITE_BLOOM_FILTERS; 293 293 294 - source = odb_find_source(the_repository->objects, opts.obj_dir); 294 + source = odb_find_source_or_die(the_repository->objects, opts.obj_dir); 295 295 296 296 if (opts.reachable) { 297 297 if (write_commit_graph_reachable(source, flags, &write_opts))
+24 -7
builtin/multi-pack-index.c
··· 65 65 char **value = opt->value; 66 66 free(*value); 67 67 if (unset) 68 - *value = xstrdup(repo_get_object_directory(the_repository)); 68 + *value = xstrdup(the_repository->objects->sources->path); 69 69 else 70 70 *value = real_pathdup(arg, 1); 71 71 return 0; 72 + } 73 + 74 + static struct odb_source *handle_object_dir_option(struct repository *repo) 75 + { 76 + struct odb_source *source = odb_find_source(repo->objects, opts.object_dir); 77 + if (!source) 78 + source = odb_add_to_alternates_memory(repo->objects, opts.object_dir); 79 + return source; 72 80 } 73 81 74 82 static struct option common_opts[] = { ··· 140 148 N_("refs snapshot for selecting bitmap commits")), 141 149 OPT_END(), 142 150 }; 151 + struct odb_source *source; 143 152 int ret; 144 153 145 154 opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE; ··· 158 167 if (argc) 159 168 usage_with_options(builtin_multi_pack_index_write_usage, 160 169 options); 170 + source = handle_object_dir_option(repo); 161 171 162 172 FREE_AND_NULL(options); 163 173 ··· 166 176 167 177 read_packs_from_stdin(&packs); 168 178 169 - ret = write_midx_file_only(repo, opts.object_dir, &packs, 179 + ret = write_midx_file_only(source, &packs, 170 180 opts.preferred_pack, 171 181 opts.refs_snapshot, opts.flags); 172 182 ··· 177 187 178 188 } 179 189 180 - ret = write_midx_file(repo, opts.object_dir, opts.preferred_pack, 190 + ret = write_midx_file(source, opts.preferred_pack, 181 191 opts.refs_snapshot, opts.flags); 182 192 183 193 free(opts.refs_snapshot); ··· 194 204 N_("force progress reporting"), MIDX_PROGRESS), 195 205 OPT_END(), 196 206 }; 207 + struct odb_source *source; 208 + 197 209 options = add_common_options(builtin_multi_pack_index_verify_options); 198 210 199 211 trace2_cmd_mode(argv[0]); ··· 206 218 if (argc) 207 219 usage_with_options(builtin_multi_pack_index_verify_usage, 208 220 options); 221 + source = handle_object_dir_option(the_repository); 209 222 210 223 FREE_AND_NULL(options); 211 224 212 - return verify_midx_file(the_repository, opts.object_dir, opts.flags); 225 + return verify_midx_file(source, opts.flags); 213 226 } 214 227 215 228 static int cmd_multi_pack_index_expire(int argc, const char **argv, ··· 222 235 N_("force progress reporting"), MIDX_PROGRESS), 223 236 OPT_END(), 224 237 }; 238 + struct odb_source *source; 239 + 225 240 options = add_common_options(builtin_multi_pack_index_expire_options); 226 241 227 242 trace2_cmd_mode(argv[0]); ··· 234 249 if (argc) 235 250 usage_with_options(builtin_multi_pack_index_expire_usage, 236 251 options); 252 + source = handle_object_dir_option(the_repository); 237 253 238 254 FREE_AND_NULL(options); 239 255 240 - return expire_midx_packs(the_repository, opts.object_dir, opts.flags); 256 + return expire_midx_packs(source, opts.flags); 241 257 } 242 258 243 259 static int cmd_multi_pack_index_repack(int argc, const char **argv, ··· 252 268 N_("force progress reporting"), MIDX_PROGRESS), 253 269 OPT_END(), 254 270 }; 271 + struct odb_source *source; 255 272 256 273 options = add_common_options(builtin_multi_pack_index_repack_options); 257 274 ··· 266 283 if (argc) 267 284 usage_with_options(builtin_multi_pack_index_repack_usage, 268 285 options); 286 + source = handle_object_dir_option(the_repository); 269 287 270 288 FREE_AND_NULL(options); 271 289 272 - return midx_repack(the_repository, opts.object_dir, 273 - (size_t)opts.batch_size, opts.flags); 290 + return midx_repack(source, (size_t)opts.batch_size, opts.flags); 274 291 } 275 292 276 293 int cmd_multi_pack_index(int argc,
+1 -1
builtin/pack-objects.c
··· 1741 1741 struct multi_pack_index *m = get_multi_pack_index(source); 1742 1742 struct pack_entry e; 1743 1743 1744 - if (m && fill_midx_entry(the_repository, oid, &e, m)) { 1744 + if (m && fill_midx_entry(m, oid, &e)) { 1745 1745 want = want_object_in_pack_one(e.p, oid, exclude, found_pack, found_offset, found_mtime); 1746 1746 if (want != -1) 1747 1747 return want;
+4 -3
builtin/repack.c
··· 223 223 static void remove_redundant_pack(const char *dir_name, const char *base_name) 224 224 { 225 225 struct strbuf buf = STRBUF_INIT; 226 - struct multi_pack_index *m = get_multi_pack_index(the_repository->objects->sources); 226 + struct odb_source *source = the_repository->objects->sources; 227 + struct multi_pack_index *m = get_multi_pack_index(source); 227 228 strbuf_addf(&buf, "%s.pack", base_name); 228 - if (m && m->local && midx_contains_pack(m, buf.buf)) 229 + if (m && source->local && midx_contains_pack(m, buf.buf)) 229 230 clear_midx_file(the_repository); 230 231 strbuf_insertf(&buf, 0, "%s/", dir_name); 231 232 unlink_pack_path(buf.buf, 1); ··· 1711 1712 unsigned flags = 0; 1712 1713 if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0)) 1713 1714 flags |= MIDX_WRITE_INCREMENTAL; 1714 - write_midx_file(the_repository, repo_get_object_directory(the_repository), 1715 + write_midx_file(the_repository->objects->sources, 1715 1716 NULL, NULL, flags); 1716 1717 } 1717 1718
+53 -63
midx-write.c
··· 26 26 #define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t)) 27 27 28 28 extern int midx_checksum_valid(struct multi_pack_index *m); 29 - extern void clear_midx_files_ext(const char *object_dir, const char *ext, 29 + extern void clear_midx_files_ext(struct odb_source *source, const char *ext, 30 30 const char *keep_hash); 31 - extern void clear_incremental_midx_files_ext(const char *object_dir, 31 + extern void clear_incremental_midx_files_ext(struct odb_source *source, 32 32 const char *ext, 33 33 const char **keep_hashes, 34 34 uint32_t hashes_nr); ··· 112 112 struct string_list *to_include; 113 113 114 114 struct repository *repo; 115 + struct odb_source *source; 115 116 }; 116 117 117 118 static int should_include_pack(const struct write_midx_context *ctx, ··· 648 649 } 649 650 650 651 static void write_midx_reverse_index(struct write_midx_context *ctx, 651 - const char *object_dir, 652 652 unsigned char *midx_hash) 653 653 { 654 654 struct strbuf buf = STRBUF_INIT; ··· 657 657 trace2_region_enter("midx", "write_midx_reverse_index", ctx->repo); 658 658 659 659 if (ctx->incremental) 660 - get_split_midx_filename_ext(ctx->repo->hash_algo, &buf, 661 - object_dir, midx_hash, 662 - MIDX_EXT_REV); 660 + get_split_midx_filename_ext(ctx->source, &buf, 661 + midx_hash, MIDX_EXT_REV); 663 662 else 664 - get_midx_filename_ext(ctx->repo->hash_algo, &buf, object_dir, 663 + get_midx_filename_ext(ctx->source, &buf, 665 664 midx_hash, MIDX_EXT_REV); 666 665 667 666 tmp_file = write_rev_file_order(ctx->repo, NULL, ctx->pack_order, ··· 836 835 } 837 836 838 837 static int write_midx_bitmap(struct write_midx_context *ctx, 839 - const char *object_dir, 840 838 const unsigned char *midx_hash, 841 839 struct packing_data *pdata, 842 840 struct commit **commits, ··· 852 850 trace2_region_enter("midx", "write_midx_bitmap", ctx->repo); 853 851 854 852 if (ctx->incremental) 855 - get_split_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name, 856 - object_dir, midx_hash, 857 - MIDX_EXT_BITMAP); 853 + get_split_midx_filename_ext(ctx->source, &bitmap_name, 854 + midx_hash, MIDX_EXT_BITMAP); 858 855 else 859 - get_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name, 860 - object_dir, midx_hash, MIDX_EXT_BITMAP); 856 + get_midx_filename_ext(ctx->source, &bitmap_name, 857 + midx_hash, MIDX_EXT_BITMAP); 861 858 862 859 if (flags & MIDX_WRITE_BITMAP_HASH_CACHE) 863 860 options |= BITMAP_OPT_HASH_CACHE; ··· 913 910 return ret; 914 911 } 915 912 916 - static struct multi_pack_index *lookup_multi_pack_index(struct repository *r, 917 - const char *object_dir) 918 - { 919 - struct odb_source *source = odb_find_source(r->objects, object_dir); 920 - return get_multi_pack_index(source); 921 - } 922 - 923 913 static int fill_packs_from_midx(struct write_midx_context *ctx, 924 914 const char *preferred_pack_name, uint32_t flags) 925 915 { ··· 942 932 */ 943 933 if (flags & MIDX_WRITE_REV_INDEX || 944 934 preferred_pack_name) { 945 - if (prepare_midx_pack(ctx->repo, m, 946 - m->num_packs_in_base + i)) { 935 + if (prepare_midx_pack(m, m->num_packs_in_base + i)) { 947 936 error(_("could not load pack")); 948 937 return 1; 949 938 } ··· 989 978 for (i = 0; i < ARRAY_SIZE(midx_exts); i++) { 990 979 const unsigned char *hash = get_midx_checksum(m); 991 980 992 - get_midx_filename_ext(m->repo->hash_algo, &from, m->object_dir, 981 + get_midx_filename_ext(m->source, &from, 993 982 hash, midx_exts[i].non_split); 994 - get_split_midx_filename_ext(m->repo->hash_algo, &to, 995 - m->object_dir, hash, 983 + get_split_midx_filename_ext(m->source, &to, hash, 996 984 midx_exts[i].split); 997 985 998 986 if (link(from.buf, to.buf) < 0 && errno != ENOENT) { ··· 1011 999 return ret; 1012 1000 } 1013 1001 1014 - static void clear_midx_files(struct repository *r, const char *object_dir, 1002 + static void clear_midx_files(struct odb_source *source, 1015 1003 const char **hashes, uint32_t hashes_nr, 1016 1004 unsigned incremental) 1017 1005 { ··· 1030 1018 uint32_t i, j; 1031 1019 1032 1020 for (i = 0; i < ARRAY_SIZE(exts); i++) { 1033 - clear_incremental_midx_files_ext(object_dir, exts[i], 1021 + clear_incremental_midx_files_ext(source, exts[i], 1034 1022 hashes, hashes_nr); 1035 1023 for (j = 0; j < hashes_nr; j++) 1036 - clear_midx_files_ext(object_dir, exts[i], hashes[j]); 1024 + clear_midx_files_ext(source, exts[i], hashes[j]); 1037 1025 } 1038 1026 1039 1027 if (incremental) 1040 - get_midx_filename(r->hash_algo, &buf, object_dir); 1028 + get_midx_filename(source, &buf); 1041 1029 else 1042 - get_midx_chain_filename(&buf, object_dir); 1030 + get_midx_chain_filename(source, &buf); 1043 1031 1044 1032 if (unlink(buf.buf) && errno != ENOENT) 1045 1033 die_errno(_("failed to clear multi-pack-index at %s"), buf.buf); ··· 1047 1035 strbuf_release(&buf); 1048 1036 } 1049 1037 1050 - static int write_midx_internal(struct repository *r, const char *object_dir, 1038 + static int write_midx_internal(struct odb_source *source, 1051 1039 struct string_list *packs_to_include, 1052 1040 struct string_list *packs_to_drop, 1053 1041 const char *preferred_pack_name, 1054 1042 const char *refs_snapshot, 1055 1043 unsigned flags) 1056 1044 { 1045 + struct repository *r = source->odb->repo; 1057 1046 struct strbuf midx_name = STRBUF_INIT; 1058 1047 unsigned char midx_hash[GIT_MAX_RAWSZ]; 1059 1048 uint32_t i, start_pack; ··· 1071 1060 trace2_region_enter("midx", "write_midx_internal", r); 1072 1061 1073 1062 ctx.repo = r; 1063 + ctx.source = source; 1074 1064 1075 1065 ctx.incremental = !!(flags & MIDX_WRITE_INCREMENTAL); 1076 1066 1077 1067 if (ctx.incremental) 1078 1068 strbuf_addf(&midx_name, 1079 1069 "%s/pack/multi-pack-index.d/tmp_midx_XXXXXX", 1080 - object_dir); 1070 + source->path); 1081 1071 else 1082 - get_midx_filename(r->hash_algo, &midx_name, object_dir); 1072 + get_midx_filename(source, &midx_name); 1083 1073 if (safe_create_leading_directories(r, midx_name.buf)) 1084 1074 die_errno(_("unable to create leading directories of %s"), 1085 1075 midx_name.buf); 1086 1076 1087 1077 if (!packs_to_include || ctx.incremental) { 1088 - struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir); 1078 + struct multi_pack_index *m = get_multi_pack_index(source); 1089 1079 if (m && !midx_checksum_valid(m)) { 1090 1080 warning(_("ignoring existing multi-pack-index; checksum mismatch")); 1091 1081 m = NULL; ··· 1116 1106 if (flags & MIDX_WRITE_BITMAP && load_midx_revindex(m)) { 1117 1107 error(_("could not load reverse index for MIDX %s"), 1118 1108 hash_to_hex_algop(get_midx_checksum(m), 1119 - m->repo->hash_algo)); 1109 + m->source->odb->repo->hash_algo)); 1120 1110 result = 1; 1121 1111 goto cleanup; 1122 1112 } ··· 1139 1129 1140 1130 ctx.to_include = packs_to_include; 1141 1131 1142 - for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &ctx); 1132 + for_each_file_in_pack_dir(source->path, add_pack_to_midx, &ctx); 1143 1133 stop_progress(&ctx.progress); 1144 1134 1145 1135 if ((ctx.m && ctx.nr == ctx.m->num_packs + ctx.m->num_packs_in_base) && ··· 1159 1149 * corresponding bitmap (or one wasn't requested). 1160 1150 */ 1161 1151 if (!want_bitmap) 1162 - clear_midx_files_ext(object_dir, "bitmap", NULL); 1152 + clear_midx_files_ext(source, "bitmap", NULL); 1163 1153 goto cleanup; 1164 1154 } 1165 1155 } ··· 1327 1317 if (ctx.incremental) { 1328 1318 struct strbuf lock_name = STRBUF_INIT; 1329 1319 1330 - get_midx_chain_filename(&lock_name, object_dir); 1320 + get_midx_chain_filename(source, &lock_name); 1331 1321 hold_lock_file_for_update(&lk, lock_name.buf, LOCK_DIE_ON_ERROR); 1332 1322 strbuf_release(&lock_name); 1333 1323 ··· 1390 1380 1391 1381 if (flags & MIDX_WRITE_REV_INDEX && 1392 1382 git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0)) 1393 - write_midx_reverse_index(&ctx, object_dir, midx_hash); 1383 + write_midx_reverse_index(&ctx, midx_hash); 1394 1384 1395 1385 if (flags & MIDX_WRITE_BITMAP) { 1396 1386 struct packing_data pdata; ··· 1413 1403 FREE_AND_NULL(ctx.entries); 1414 1404 ctx.entries_nr = 0; 1415 1405 1416 - if (write_midx_bitmap(&ctx, object_dir, 1406 + if (write_midx_bitmap(&ctx, 1417 1407 midx_hash, &pdata, commits, commits_nr, 1418 1408 flags) < 0) { 1419 1409 error(_("could not write multi-pack bitmap")); ··· 1446 1436 if (link_midx_to_chain(ctx.base_midx) < 0) 1447 1437 return -1; 1448 1438 1449 - get_split_midx_filename_ext(r->hash_algo, &final_midx_name, 1450 - object_dir, midx_hash, MIDX_EXT_MIDX); 1439 + get_split_midx_filename_ext(source, &final_midx_name, 1440 + midx_hash, MIDX_EXT_MIDX); 1451 1441 1452 1442 if (rename_tempfile(&incr, final_midx_name.buf) < 0) { 1453 1443 error_errno(_("unable to rename new multi-pack-index layer")); ··· 1480 1470 if (commit_lock_file(&lk) < 0) 1481 1471 die_errno(_("could not write multi-pack-index")); 1482 1472 1483 - clear_midx_files(r, object_dir, keep_hashes, 1473 + clear_midx_files(source, keep_hashes, 1484 1474 ctx.num_multi_pack_indexes_before + 1, 1485 1475 ctx.incremental); 1486 1476 ··· 1509 1499 return result; 1510 1500 } 1511 1501 1512 - int write_midx_file(struct repository *r, const char *object_dir, 1502 + int write_midx_file(struct odb_source *source, 1513 1503 const char *preferred_pack_name, 1514 1504 const char *refs_snapshot, unsigned flags) 1515 1505 { 1516 - return write_midx_internal(r, object_dir, NULL, NULL, 1506 + return write_midx_internal(source, NULL, NULL, 1517 1507 preferred_pack_name, refs_snapshot, 1518 1508 flags); 1519 1509 } 1520 1510 1521 - int write_midx_file_only(struct repository *r, const char *object_dir, 1511 + int write_midx_file_only(struct odb_source *source, 1522 1512 struct string_list *packs_to_include, 1523 1513 const char *preferred_pack_name, 1524 1514 const char *refs_snapshot, unsigned flags) 1525 1515 { 1526 - return write_midx_internal(r, object_dir, packs_to_include, NULL, 1516 + return write_midx_internal(source, packs_to_include, NULL, 1527 1517 preferred_pack_name, refs_snapshot, flags); 1528 1518 } 1529 1519 1530 - int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags) 1520 + int expire_midx_packs(struct odb_source *source, unsigned flags) 1531 1521 { 1532 1522 uint32_t i, *count, result = 0; 1533 1523 struct string_list packs_to_drop = STRING_LIST_INIT_DUP; 1534 - struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir); 1524 + struct multi_pack_index *m = get_multi_pack_index(source); 1535 1525 struct progress *progress = NULL; 1536 1526 1537 1527 if (!m) ··· 1544 1534 1545 1535 if (flags & MIDX_PROGRESS) 1546 1536 progress = start_delayed_progress( 1547 - r, 1537 + source->odb->repo, 1548 1538 _("Counting referenced objects"), 1549 1539 m->num_objects); 1550 1540 for (i = 0; i < m->num_objects; i++) { ··· 1556 1546 1557 1547 if (flags & MIDX_PROGRESS) 1558 1548 progress = start_delayed_progress( 1559 - r, 1549 + source->odb->repo, 1560 1550 _("Finding and deleting unreferenced packfiles"), 1561 1551 m->num_packs); 1562 1552 for (i = 0; i < m->num_packs; i++) { ··· 1566 1556 if (count[i]) 1567 1557 continue; 1568 1558 1569 - if (prepare_midx_pack(r, m, i)) 1559 + if (prepare_midx_pack(m, i)) 1570 1560 continue; 1571 1561 1572 1562 if (m->packs[i]->pack_keep || m->packs[i]->is_cruft) ··· 1584 1574 free(count); 1585 1575 1586 1576 if (packs_to_drop.nr) 1587 - result = write_midx_internal(r, object_dir, NULL, 1577 + result = write_midx_internal(source, NULL, 1588 1578 &packs_to_drop, NULL, NULL, flags); 1589 1579 1590 1580 string_list_clear(&packs_to_drop, 0); ··· 1612 1602 return 0; 1613 1603 } 1614 1604 1615 - static int want_included_pack(struct repository *r, 1616 - struct multi_pack_index *m, 1605 + static int want_included_pack(struct multi_pack_index *m, 1617 1606 int pack_kept_objects, 1618 1607 uint32_t pack_int_id) 1619 1608 { 1620 1609 struct packed_git *p; 1621 - if (prepare_midx_pack(r, m, pack_int_id)) 1610 + if (prepare_midx_pack(m, pack_int_id)) 1622 1611 return 0; 1623 1612 p = m->packs[pack_int_id]; 1624 1613 if (!pack_kept_objects && p->pack_keep) ··· 1640 1629 repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects); 1641 1630 1642 1631 for (i = 0; i < m->num_packs; i++) { 1643 - if (!want_included_pack(r, m, pack_kept_objects, i)) 1632 + if (!want_included_pack(m, pack_kept_objects, i)) 1644 1633 continue; 1645 1634 1646 1635 include_pack[i] = 1; ··· 1664 1653 for (i = 0; i < m->num_packs; i++) { 1665 1654 pack_info[i].pack_int_id = i; 1666 1655 1667 - if (prepare_midx_pack(r, m, i)) 1656 + if (prepare_midx_pack(m, i)) 1668 1657 continue; 1669 1658 1670 1659 pack_info[i].mtime = m->packs[i]->mtime; ··· 1683 1672 struct packed_git *p = m->packs[pack_int_id]; 1684 1673 uint64_t expected_size; 1685 1674 1686 - if (!want_included_pack(r, m, pack_kept_objects, pack_int_id)) 1675 + if (!want_included_pack(m, pack_kept_objects, pack_int_id)) 1687 1676 continue; 1688 1677 1689 1678 /* ··· 1710 1699 free(pack_info); 1711 1700 } 1712 1701 1713 - int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, unsigned flags) 1702 + int midx_repack(struct odb_source *source, size_t batch_size, unsigned flags) 1714 1703 { 1704 + struct repository *r = source->odb->repo; 1715 1705 int result = 0; 1716 1706 uint32_t i, packs_to_repack = 0; 1717 1707 unsigned char *include_pack; 1718 1708 struct child_process cmd = CHILD_PROCESS_INIT; 1719 1709 FILE *cmd_in; 1720 - struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir); 1710 + struct multi_pack_index *m = get_multi_pack_index(source); 1721 1711 1722 1712 /* 1723 1713 * When updating the default for these configuration ··· 1751 1741 1752 1742 strvec_push(&cmd.args, "pack-objects"); 1753 1743 1754 - strvec_pushf(&cmd.args, "%s/pack/pack", object_dir); 1744 + strvec_pushf(&cmd.args, "%s/pack/pack", source->path); 1755 1745 1756 1746 if (delta_base_offset) 1757 1747 strvec_push(&cmd.args, "--delta-base-offset"); ··· 1792 1782 goto cleanup; 1793 1783 } 1794 1784 1795 - result = write_midx_internal(r, object_dir, NULL, NULL, NULL, NULL, 1785 + result = write_midx_internal(source, NULL, NULL, NULL, NULL, 1796 1786 flags); 1797 1787 1798 1788 cleanup:
+63 -72
midx.c
··· 16 16 #define MIDX_PACK_ERROR ((void *)(intptr_t)-1) 17 17 18 18 int midx_checksum_valid(struct multi_pack_index *m); 19 - void clear_midx_files_ext(const char *object_dir, const char *ext, 19 + void clear_midx_files_ext(struct odb_source *source, const char *ext, 20 20 const char *keep_hash); 21 - void clear_incremental_midx_files_ext(const char *object_dir, const char *ext, 21 + void clear_incremental_midx_files_ext(struct odb_source *source, const char *ext, 22 22 char **keep_hashes, 23 23 uint32_t hashes_nr); 24 24 int cmp_idx_or_pack_name(const char *idx_or_pack_name, ··· 26 26 27 27 const unsigned char *get_midx_checksum(struct multi_pack_index *m) 28 28 { 29 - return m->data + m->data_len - m->repo->hash_algo->rawsz; 29 + return m->data + m->data_len - m->source->odb->repo->hash_algo->rawsz; 30 30 } 31 31 32 - void get_midx_filename(const struct git_hash_algo *hash_algo, 33 - struct strbuf *out, const char *object_dir) 32 + void get_midx_filename(struct odb_source *source, struct strbuf *out) 34 33 { 35 - get_midx_filename_ext(hash_algo, out, object_dir, NULL, NULL); 34 + get_midx_filename_ext(source, out, NULL, NULL); 36 35 } 37 36 38 - void get_midx_filename_ext(const struct git_hash_algo *hash_algo, 39 - struct strbuf *out, const char *object_dir, 37 + void get_midx_filename_ext(struct odb_source *source, struct strbuf *out, 40 38 const unsigned char *hash, const char *ext) 41 39 { 42 - strbuf_addf(out, "%s/pack/multi-pack-index", object_dir); 40 + strbuf_addf(out, "%s/pack/multi-pack-index", source->path); 43 41 if (ext) 44 - strbuf_addf(out, "-%s.%s", hash_to_hex_algop(hash, hash_algo), ext); 42 + strbuf_addf(out, "-%s.%s", hash_to_hex_algop(hash, source->odb->repo->hash_algo), ext); 45 43 } 46 44 47 45 static int midx_read_oid_fanout(const unsigned char *chunk_start, ··· 95 93 return 0; 96 94 } 97 95 98 - static struct multi_pack_index *load_multi_pack_index_one(struct repository *r, 99 - const char *object_dir, 100 - const char *midx_name, 101 - int local) 96 + static struct multi_pack_index *load_multi_pack_index_one(struct odb_source *source, 97 + const char *midx_name) 102 98 { 99 + struct repository *r = source->odb->repo; 103 100 struct multi_pack_index *m = NULL; 104 101 int fd; 105 102 struct stat st; ··· 129 126 midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0); 130 127 close(fd); 131 128 132 - FLEX_ALLOC_STR(m, object_dir, object_dir); 129 + CALLOC_ARRAY(m, 1); 133 130 m->data = midx_map; 134 131 m->data_len = midx_size; 135 - m->local = local; 136 - m->repo = r; 132 + m->source = source; 137 133 138 134 m->signature = get_be32(m->data); 139 135 if (m->signature != MIDX_SIGNATURE) ··· 224 220 return NULL; 225 221 } 226 222 227 - void get_midx_chain_dirname(struct strbuf *buf, const char *object_dir) 223 + void get_midx_chain_dirname(struct odb_source *source, struct strbuf *buf) 228 224 { 229 - strbuf_addf(buf, "%s/pack/multi-pack-index.d", object_dir); 225 + strbuf_addf(buf, "%s/pack/multi-pack-index.d", source->path); 230 226 } 231 227 232 - void get_midx_chain_filename(struct strbuf *buf, const char *object_dir) 228 + void get_midx_chain_filename(struct odb_source *source, struct strbuf *buf) 233 229 { 234 - get_midx_chain_dirname(buf, object_dir); 230 + get_midx_chain_dirname(source, buf); 235 231 strbuf_addstr(buf, "/multi-pack-index-chain"); 236 232 } 237 233 238 - void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo, 239 - struct strbuf *buf, const char *object_dir, 234 + void get_split_midx_filename_ext(struct odb_source *source, struct strbuf *buf, 240 235 const unsigned char *hash, const char *ext) 241 236 { 242 - get_midx_chain_dirname(buf, object_dir); 237 + get_midx_chain_dirname(source, buf); 243 238 strbuf_addf(buf, "/multi-pack-index-%s.%s", 244 - hash_to_hex_algop(hash, hash_algo), ext); 239 + hash_to_hex_algop(hash, source->odb->repo->hash_algo), ext); 245 240 } 246 241 247 242 static int open_multi_pack_index_chain(const struct git_hash_algo *hash_algo, ··· 297 292 return 1; 298 293 } 299 294 300 - static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r, 301 - const char *object_dir, 302 - int local, 295 + static struct multi_pack_index *load_midx_chain_fd_st(struct odb_source *source, 303 296 int fd, struct stat *st, 304 297 int *incomplete_chain) 305 298 { 299 + const struct git_hash_algo *hash_algo = source->odb->repo->hash_algo; 306 300 struct multi_pack_index *midx_chain = NULL; 307 301 struct strbuf buf = STRBUF_INIT; 308 302 int valid = 1; 309 303 uint32_t i, count; 310 304 FILE *fp = xfdopen(fd, "r"); 311 305 312 - count = st->st_size / (r->hash_algo->hexsz + 1); 306 + count = st->st_size / (hash_algo->hexsz + 1); 313 307 314 308 for (i = 0; i < count; i++) { 315 309 struct multi_pack_index *m; ··· 318 312 if (strbuf_getline_lf(&buf, fp) == EOF) 319 313 break; 320 314 321 - if (get_oid_hex_algop(buf.buf, &layer, r->hash_algo)) { 315 + if (get_oid_hex_algop(buf.buf, &layer, hash_algo)) { 322 316 warning(_("invalid multi-pack-index chain: line '%s' " 323 317 "not a hash"), 324 318 buf.buf); ··· 329 323 valid = 0; 330 324 331 325 strbuf_reset(&buf); 332 - get_split_midx_filename_ext(r->hash_algo, &buf, object_dir, 326 + get_split_midx_filename_ext(source, &buf, 333 327 layer.hash, MIDX_EXT_MIDX); 334 - m = load_multi_pack_index_one(r, object_dir, buf.buf, local); 328 + m = load_multi_pack_index_one(source, buf.buf); 335 329 336 330 if (m) { 337 331 if (add_midx_to_chain(m, midx_chain)) { ··· 354 348 return midx_chain; 355 349 } 356 350 357 - static struct multi_pack_index *load_multi_pack_index_chain(struct repository *r, 358 - const char *object_dir, 359 - int local) 351 + static struct multi_pack_index *load_multi_pack_index_chain(struct odb_source *source) 360 352 { 361 353 struct strbuf chain_file = STRBUF_INIT; 362 354 struct stat st; 363 355 int fd; 364 356 struct multi_pack_index *m = NULL; 365 357 366 - get_midx_chain_filename(&chain_file, object_dir); 367 - if (open_multi_pack_index_chain(r->hash_algo, chain_file.buf, &fd, &st)) { 358 + get_midx_chain_filename(source, &chain_file); 359 + if (open_multi_pack_index_chain(source->odb->repo->hash_algo, chain_file.buf, &fd, &st)) { 368 360 int incomplete; 369 361 /* ownership of fd is taken over by load function */ 370 - m = load_midx_chain_fd_st(r, object_dir, local, fd, &st, 371 - &incomplete); 362 + m = load_midx_chain_fd_st(source, fd, &st, &incomplete); 372 363 } 373 364 374 365 strbuf_release(&chain_file); 375 366 return m; 376 367 } 377 368 378 - struct multi_pack_index *load_multi_pack_index(struct repository *r, 379 - const char *object_dir, 380 - int local) 369 + struct multi_pack_index *load_multi_pack_index(struct odb_source *source) 381 370 { 382 371 struct strbuf midx_name = STRBUF_INIT; 383 372 struct multi_pack_index *m; 384 373 385 - get_midx_filename(r->hash_algo, &midx_name, object_dir); 374 + get_midx_filename(source, &midx_name); 386 375 387 - m = load_multi_pack_index_one(r, object_dir, 388 - midx_name.buf, local); 376 + m = load_multi_pack_index_one(source, midx_name.buf); 389 377 if (!m) 390 - m = load_multi_pack_index_chain(r, object_dir, local); 378 + m = load_multi_pack_index_chain(source); 391 379 392 380 strbuf_release(&midx_name); 393 381 ··· 450 438 return pack_int_id - m->num_packs_in_base; 451 439 } 452 440 453 - int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, 441 + int prepare_midx_pack(struct multi_pack_index *m, 454 442 uint32_t pack_int_id) 455 443 { 444 + struct repository *r = m->source->odb->repo; 456 445 struct strbuf pack_name = STRBUF_INIT; 457 446 struct strbuf key = STRBUF_INIT; 458 447 struct packed_git *p; ··· 464 453 if (m->packs[pack_int_id]) 465 454 return 0; 466 455 467 - strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir, 456 + strbuf_addf(&pack_name, "%s/pack/%s", m->source->path, 468 457 m->pack_names[pack_int_id]); 469 458 470 459 /* pack_map holds the ".pack" name, but we have the .idx */ ··· 475 464 strhash(key.buf), key.buf, 476 465 struct packed_git, packmap_ent); 477 466 if (!p) { 478 - p = add_packed_git(r, pack_name.buf, pack_name.len, m->local); 467 + p = add_packed_git(r, pack_name.buf, pack_name.len, 468 + m->source->local); 479 469 if (p) { 480 470 install_packed_git(r, p); 481 471 list_add_tail(&p->mru, &r->objects->packed_git_mru); ··· 507 497 508 498 #define MIDX_CHUNK_BITMAPPED_PACKS_WIDTH (2 * sizeof(uint32_t)) 509 499 510 - int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m, 500 + int nth_bitmapped_pack(struct multi_pack_index *m, 511 501 struct bitmapped_pack *bp, uint32_t pack_int_id) 512 502 { 513 503 uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id); ··· 515 505 if (!m->chunk_bitmapped_packs) 516 506 return error(_("MIDX does not contain the BTMP chunk")); 517 507 518 - if (prepare_midx_pack(r, m, pack_int_id)) 508 + if (prepare_midx_pack(m, pack_int_id)) 519 509 return error(_("could not load bitmapped pack %"PRIu32), pack_int_id); 520 510 521 511 bp->p = m->packs[local_pack_int_id]; ··· 534 524 uint32_t *result) 535 525 { 536 526 int ret = bsearch_hash(oid->hash, m->chunk_oid_fanout, 537 - m->chunk_oid_lookup, m->repo->hash_algo->rawsz, 527 + m->chunk_oid_lookup, 528 + m->source->odb->repo->hash_algo->rawsz, 538 529 result); 539 530 if (result) 540 531 *result += m->num_objects_in_base; ··· 565 556 n = midx_for_object(&m, n); 566 557 567 558 oidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n), 568 - m->repo->hash_algo); 559 + m->source->odb->repo->hash_algo); 569 560 return oid; 570 561 } 571 562 ··· 600 591 (off_t)pos * MIDX_CHUNK_OFFSET_WIDTH); 601 592 } 602 593 603 - int fill_midx_entry(struct repository *r, 594 + int fill_midx_entry(struct multi_pack_index *m, 604 595 const struct object_id *oid, 605 - struct pack_entry *e, 606 - struct multi_pack_index *m) 596 + struct pack_entry *e) 607 597 { 608 598 uint32_t pos; 609 599 uint32_t pack_int_id; ··· 615 605 midx_for_object(&m, pos); 616 606 pack_int_id = nth_midxed_pack_int_id(m, pos); 617 607 618 - if (prepare_midx_pack(r, m, pack_int_id)) 608 + if (prepare_midx_pack(m, pack_int_id)) 619 609 return 0; 620 610 p = m->packs[pack_int_id - m->num_packs_in_base]; 621 611 ··· 723 713 return 0; 724 714 } 725 715 726 - int prepare_multi_pack_index_one(struct odb_source *source, int local) 716 + int prepare_multi_pack_index_one(struct odb_source *source) 727 717 { 728 718 struct repository *r = source->odb->repo; 729 719 ··· 734 724 if (source->midx) 735 725 return 1; 736 726 737 - source->midx = load_multi_pack_index(r, source->path, local); 727 + source->midx = load_multi_pack_index(source); 738 728 739 729 return !!source->midx; 740 730 } 741 731 742 732 int midx_checksum_valid(struct multi_pack_index *m) 743 733 { 744 - return hashfile_checksum_valid(m->repo->hash_algo, 734 + return hashfile_checksum_valid(m->source->odb->repo->hash_algo, 745 735 m->data, m->data_len); 746 736 } 747 737 ··· 768 758 die_errno(_("failed to remove %s"), full_path); 769 759 } 770 760 771 - void clear_midx_files_ext(const char *object_dir, const char *ext, 761 + void clear_midx_files_ext(struct odb_source *source, const char *ext, 772 762 const char *keep_hash) 773 763 { 774 764 struct clear_midx_data data; ··· 782 772 } 783 773 data.ext = ext; 784 774 785 - for_each_file_in_pack_dir(object_dir, 775 + for_each_file_in_pack_dir(source->path, 786 776 clear_midx_file_ext, 787 777 &data); 788 778 ··· 791 781 free(data.keep); 792 782 } 793 783 794 - void clear_incremental_midx_files_ext(const char *object_dir, const char *ext, 784 + void clear_incremental_midx_files_ext(struct odb_source *source, const char *ext, 795 785 char **keep_hashes, 796 786 uint32_t hashes_nr) 797 787 { ··· 807 797 data.keep_nr = hashes_nr; 808 798 data.ext = ext; 809 799 810 - for_each_file_in_pack_subdir(object_dir, "multi-pack-index.d", 800 + for_each_file_in_pack_subdir(source->path, "multi-pack-index.d", 811 801 clear_midx_file_ext, &data); 812 802 813 803 for (i = 0; i < hashes_nr; i++) ··· 819 809 { 820 810 struct strbuf midx = STRBUF_INIT; 821 811 822 - get_midx_filename(r->hash_algo, &midx, r->objects->sources->path); 812 + get_midx_filename(r->objects->sources, &midx); 823 813 824 814 if (r->objects) { 825 815 struct odb_source *source; ··· 834 824 if (remove_path(midx.buf)) 835 825 die(_("failed to clear multi-pack-index at %s"), midx.buf); 836 826 837 - clear_midx_files_ext(r->objects->sources->path, MIDX_EXT_BITMAP, NULL); 838 - clear_midx_files_ext(r->objects->sources->path, MIDX_EXT_REV, NULL); 827 + clear_midx_files_ext(r->objects->sources, MIDX_EXT_BITMAP, NULL); 828 + clear_midx_files_ext(r->objects->sources, MIDX_EXT_REV, NULL); 839 829 840 830 strbuf_release(&midx); 841 831 } ··· 879 869 display_progress(progress, _n); \ 880 870 } while (0) 881 871 882 - int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags) 872 + int verify_midx_file(struct odb_source *source, unsigned flags) 883 873 { 874 + struct repository *r = source->odb->repo; 884 875 struct pair_pos_vs_id *pairs = NULL; 885 876 uint32_t i; 886 877 struct progress *progress = NULL; 887 - struct multi_pack_index *m = load_multi_pack_index(r, object_dir, 1); 878 + struct multi_pack_index *m = load_multi_pack_index(source); 888 879 struct multi_pack_index *curr; 889 880 verify_midx_error = 0; 890 881 ··· 893 884 struct stat sb; 894 885 struct strbuf filename = STRBUF_INIT; 895 886 896 - get_midx_filename(r->hash_algo, &filename, object_dir); 887 + get_midx_filename(source, &filename); 897 888 898 889 if (!stat(filename.buf, &sb)) { 899 890 error(_("multi-pack-index file exists, but failed to parse")); ··· 911 902 _("Looking for referenced packfiles"), 912 903 m->num_packs + m->num_packs_in_base); 913 904 for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) { 914 - if (prepare_midx_pack(r, m, i)) 905 + if (prepare_midx_pack(m, i)) 915 906 midx_report("failed to load pack in position %d", i); 916 907 917 908 display_progress(progress, i + 1); ··· 988 979 989 980 nth_midxed_object_oid(&oid, m, pairs[i].pos); 990 981 991 - if (!fill_midx_entry(r, &oid, &e, m)) { 982 + if (!fill_midx_entry(m, &oid, &e)) { 992 983 midx_report(_("failed to load pack entry for oid[%d] = %s"), 993 984 pairs[i].pos, oid_to_hex(&oid)); 994 985 continue;
+17 -25
midx.h
··· 35 35 "GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL" 36 36 37 37 struct multi_pack_index { 38 + struct odb_source *source; 39 + 38 40 const unsigned char *data; 39 41 size_t data_len; 40 42 ··· 50 52 uint32_t num_objects; 51 53 int preferred_pack_idx; 52 54 53 - int local; 54 55 int has_chain; 55 56 56 57 const unsigned char *chunk_pack_names; ··· 71 72 72 73 const char **pack_names; 73 74 struct packed_git **packs; 74 - 75 - struct repository *repo; 76 - 77 - char object_dir[FLEX_ARRAY]; 78 75 }; 79 76 80 77 #define MIDX_PROGRESS (1 << 0) ··· 89 86 #define MIDX_EXT_MIDX "midx" 90 87 91 88 const unsigned char *get_midx_checksum(struct multi_pack_index *m); 92 - void get_midx_filename(const struct git_hash_algo *hash_algo, 93 - struct strbuf *out, const char *object_dir); 94 - void get_midx_filename_ext(const struct git_hash_algo *hash_algo, 95 - struct strbuf *out, const char *object_dir, 89 + void get_midx_filename(struct odb_source *source, struct strbuf *out); 90 + void get_midx_filename_ext(struct odb_source *source, struct strbuf *out, 96 91 const unsigned char *hash, const char *ext); 97 - void get_midx_chain_dirname(struct strbuf *buf, const char *object_dir); 98 - void get_midx_chain_filename(struct strbuf *buf, const char *object_dir); 99 - void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo, 100 - struct strbuf *buf, const char *object_dir, 92 + void get_midx_chain_dirname(struct odb_source *source, struct strbuf *out); 93 + void get_midx_chain_filename(struct odb_source *source, struct strbuf *out); 94 + void get_split_midx_filename_ext(struct odb_source *source, struct strbuf *buf, 101 95 const unsigned char *hash, const char *ext); 102 96 103 - struct multi_pack_index *load_multi_pack_index(struct repository *r, 104 - const char *object_dir, 105 - int local); 106 - int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id); 97 + struct multi_pack_index *load_multi_pack_index(struct odb_source *source); 98 + int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id); 107 99 struct packed_git *nth_midxed_pack(struct multi_pack_index *m, 108 100 uint32_t pack_int_id); 109 - int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m, 101 + int nth_bitmapped_pack(struct multi_pack_index *m, 110 102 struct bitmapped_pack *bp, uint32_t pack_int_id); 111 103 int bsearch_one_midx(const struct object_id *oid, struct multi_pack_index *m, 112 104 uint32_t *result); ··· 118 110 struct object_id *nth_midxed_object_oid(struct object_id *oid, 119 111 struct multi_pack_index *m, 120 112 uint32_t n); 121 - int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m); 113 + int fill_midx_entry(struct multi_pack_index *m, const struct object_id *oid, struct pack_entry *e); 122 114 int midx_contains_pack(struct multi_pack_index *m, 123 115 const char *idx_or_pack_name); 124 116 int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id); 125 - int prepare_multi_pack_index_one(struct odb_source *source, int local); 117 + int prepare_multi_pack_index_one(struct odb_source *source); 126 118 127 119 /* 128 120 * Variant of write_midx_file which writes a MIDX containing only the packs 129 121 * specified in packs_to_include. 130 122 */ 131 - int write_midx_file(struct repository *r, const char *object_dir, 123 + int write_midx_file(struct odb_source *source, 132 124 const char *preferred_pack_name, const char *refs_snapshot, 133 125 unsigned flags); 134 - int write_midx_file_only(struct repository *r, const char *object_dir, 126 + int write_midx_file_only(struct odb_source *source, 135 127 struct string_list *packs_to_include, 136 128 const char *preferred_pack_name, 137 129 const char *refs_snapshot, unsigned flags); 138 130 void clear_midx_file(struct repository *r); 139 - int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags); 140 - int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags); 141 - int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, unsigned flags); 131 + int verify_midx_file(struct odb_source *source, unsigned flags); 132 + int expire_midx_packs(struct odb_source *source, unsigned flags); 133 + int midx_repack(struct odb_source *source, size_t batch_size, unsigned flags); 142 134 143 135 void close_midx(struct multi_pack_index *m); 144 136
+32 -32
odb.c
··· 139 139 const char *relative_base, 140 140 int depth); 141 141 142 - static int link_alt_odb_entry(struct object_database *odb, 143 - const struct strbuf *entry, 144 - const char *relative_base, 145 - int depth, 146 - const char *normalized_objdir) 142 + static struct odb_source *link_alt_odb_entry(struct object_database *odb, 143 + const char *dir, 144 + const char *relative_base, 145 + int depth) 147 146 { 148 - struct odb_source *alternate; 147 + struct odb_source *alternate = NULL; 149 148 struct strbuf pathbuf = STRBUF_INIT; 150 149 struct strbuf tmp = STRBUF_INIT; 151 150 khiter_t pos; 152 - int ret = -1; 153 151 154 - if (!is_absolute_path(entry->buf) && relative_base) { 152 + if (!is_absolute_path(dir) && relative_base) { 155 153 strbuf_realpath(&pathbuf, relative_base, 1); 156 154 strbuf_addch(&pathbuf, '/'); 157 155 } 158 - strbuf_addbuf(&pathbuf, entry); 156 + strbuf_addstr(&pathbuf, dir); 159 157 160 158 if (!strbuf_realpath(&tmp, pathbuf.buf, 0)) { 161 159 error(_("unable to normalize alternate object path: %s"), ··· 171 169 while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') 172 170 strbuf_setlen(&pathbuf, pathbuf.len - 1); 173 171 174 - if (!alt_odb_usable(odb, &pathbuf, normalized_objdir, &pos)) 172 + strbuf_reset(&tmp); 173 + strbuf_realpath(&tmp, odb->sources->path, 1); 174 + 175 + if (!alt_odb_usable(odb, &pathbuf, tmp.buf, &pos)) 175 176 goto error; 176 177 177 178 CALLOC_ARRAY(alternate, 1); 178 179 alternate->odb = odb; 180 + alternate->local = false; 179 181 /* pathbuf.buf is already in r->objects->source_by_path */ 180 182 alternate->path = strbuf_detach(&pathbuf, NULL); 181 183 ··· 188 190 189 191 /* recursively add alternates */ 190 192 read_info_alternates(odb, alternate->path, depth + 1); 191 - ret = 0; 193 + 192 194 error: 193 195 strbuf_release(&tmp); 194 196 strbuf_release(&pathbuf); 195 - return ret; 197 + return alternate; 196 198 } 197 199 198 200 static const char *parse_alt_odb_entry(const char *string, ··· 227 229 static void link_alt_odb_entries(struct object_database *odb, const char *alt, 228 230 int sep, const char *relative_base, int depth) 229 231 { 230 - struct strbuf objdirbuf = STRBUF_INIT; 231 - struct strbuf entry = STRBUF_INIT; 232 + struct strbuf dir = STRBUF_INIT; 232 233 233 234 if (!alt || !*alt) 234 235 return; ··· 239 240 return; 240 241 } 241 242 242 - strbuf_realpath(&objdirbuf, odb->sources->path, 1); 243 - 244 243 while (*alt) { 245 - alt = parse_alt_odb_entry(alt, sep, &entry); 246 - if (!entry.len) 244 + alt = parse_alt_odb_entry(alt, sep, &dir); 245 + if (!dir.len) 247 246 continue; 248 - link_alt_odb_entry(odb, &entry, 249 - relative_base, depth, objdirbuf.buf); 247 + link_alt_odb_entry(odb, dir.buf, relative_base, depth); 250 248 } 251 - strbuf_release(&entry); 252 - strbuf_release(&objdirbuf); 249 + strbuf_release(&dir); 253 250 } 254 251 255 252 static void read_info_alternates(struct object_database *odb, ··· 272 269 } 273 270 274 271 void odb_add_to_alternates_file(struct object_database *odb, 275 - const char *reference) 272 + const char *dir) 276 273 { 277 274 struct lock_file lock = LOCK_INIT; 278 275 char *alts = repo_git_path(odb->repo, "objects/info/alternates"); ··· 289 286 struct strbuf line = STRBUF_INIT; 290 287 291 288 while (strbuf_getline(&line, in) != EOF) { 292 - if (!strcmp(reference, line.buf)) { 289 + if (!strcmp(dir, line.buf)) { 293 290 found = 1; 294 291 break; 295 292 } ··· 305 302 if (found) { 306 303 rollback_lock_file(&lock); 307 304 } else { 308 - fprintf_or_die(out, "%s\n", reference); 305 + fprintf_or_die(out, "%s\n", dir); 309 306 if (commit_lock_file(&lock)) 310 307 die_errno(_("unable to move new alternates file into place")); 311 308 if (odb->loaded_alternates) 312 - link_alt_odb_entries(odb, reference, 313 - '\n', NULL, 0); 309 + link_alt_odb_entries(odb, dir, '\n', NULL, 0); 314 310 } 315 311 free(alts); 316 312 } 317 313 318 - void odb_add_to_alternates_memory(struct object_database *odb, 319 - const char *reference) 314 + struct odb_source *odb_add_to_alternates_memory(struct object_database *odb, 315 + const char *dir) 320 316 { 321 317 /* 322 318 * Make sure alternates are initialized, or else our entry may be 323 319 * overwritten when they are. 324 320 */ 325 321 odb_prepare_alternates(odb); 326 - 327 - link_alt_odb_entries(odb, reference, 328 - '\n', NULL, 0); 322 + return link_alt_odb_entry(odb, dir, NULL, 0); 329 323 } 330 324 331 325 struct odb_source *odb_set_temporary_primary_source(struct object_database *odb, ··· 463 457 free(obj_dir_real); 464 458 strbuf_release(&odb_path_real); 465 459 460 + return source; 461 + } 462 + 463 + struct odb_source *odb_find_source_or_die(struct object_database *odb, const char *obj_dir) 464 + { 465 + struct odb_source *source = odb_find_source(odb, obj_dir); 466 466 if (!source) 467 467 die(_("could not find object directory matching %s"), obj_dir); 468 468 return source;
+15 -4
odb.h
··· 64 64 struct multi_pack_index *midx; 65 65 66 66 /* 67 + * Figure out whether this is the local source of the owning 68 + * repository, which would typically be its ".git/objects" directory. 69 + * This local object directory is usually where objects would be 70 + * written to. 71 + */ 72 + bool local; 73 + 74 + /* 67 75 * This is a temporary object store created by the tmp_objdir 68 76 * facility. Disable ref updates since the objects in the store 69 77 * might be discarded on rollback. ··· 178 186 void odb_clear(struct object_database *o); 179 187 180 188 /* 181 - * Find source by its object directory path. Dies in case the source couldn't 182 - * be found. 189 + * Find source by its object directory path. Returns a `NULL` pointer in case 190 + * the source could not be found. 183 191 */ 184 192 struct odb_source *odb_find_source(struct object_database *odb, const char *obj_dir); 193 + 194 + /* Same as `odb_find_source()`, but dies in case the source doesn't exist. */ 195 + struct odb_source *odb_find_source_or_die(struct object_database *odb, const char *obj_dir); 185 196 186 197 /* 187 198 * Replace the current writable object directory with the specified temporary ··· 257 268 * recursive alternates it points to), but do not modify the on-disk alternates 258 269 * file. 259 270 */ 260 - void odb_add_to_alternates_memory(struct object_database *odb, 261 - const char *dir); 271 + struct odb_source *odb_add_to_alternates_memory(struct object_database *odb, 272 + const char *dir); 262 273 263 274 /* 264 275 * Read an object from the database. Returns the object data and assigns object
+7 -8
pack-bitmap.c
··· 216 216 static struct repository *bitmap_repo(struct bitmap_index *bitmap_git) 217 217 { 218 218 if (bitmap_is_midx(bitmap_git)) 219 - return bitmap_git->midx->repo; 219 + return bitmap_git->midx->source->odb->repo; 220 220 return bitmap_git->pack->repo; 221 221 } 222 222 ··· 418 418 { 419 419 struct strbuf buf = STRBUF_INIT; 420 420 if (midx->has_chain) 421 - get_split_midx_filename_ext(midx->repo->hash_algo, &buf, 422 - midx->object_dir, 421 + get_split_midx_filename_ext(midx->source, &buf, 423 422 get_midx_checksum(midx), 424 423 MIDX_EXT_BITMAP); 425 424 else 426 - get_midx_filename_ext(midx->repo->hash_algo, &buf, 427 - midx->object_dir, get_midx_checksum(midx), 425 + get_midx_filename_ext(midx->source, &buf, 426 + get_midx_checksum(midx), 428 427 MIDX_EXT_BITMAP); 429 428 430 429 return strbuf_detach(&buf, NULL); ··· 463 462 464 463 if (bitmap_git->pack || bitmap_git->midx) { 465 464 struct strbuf buf = STRBUF_INIT; 466 - get_midx_filename(midx->repo->hash_algo, &buf, midx->object_dir); 465 + get_midx_filename(midx->source, &buf); 467 466 trace2_data_string("bitmap", bitmap_repo(bitmap_git), 468 467 "ignoring extra midx bitmap file", buf.buf); 469 468 close(fd); ··· 493 492 } 494 493 495 494 for (i = 0; i < bitmap_git->midx->num_packs + bitmap_git->midx->num_packs_in_base; i++) { 496 - if (prepare_midx_pack(bitmap_repo(bitmap_git), bitmap_git->midx, i)) { 495 + if (prepare_midx_pack(bitmap_git->midx, i)) { 497 496 warning(_("could not open pack %s"), 498 497 bitmap_git->midx->pack_names[i]); 499 498 goto cleanup; ··· 2466 2465 struct multi_pack_index *m = bitmap_git->midx; 2467 2466 for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) { 2468 2467 struct bitmapped_pack pack; 2469 - if (nth_bitmapped_pack(r, bitmap_git->midx, &pack, i) < 0) { 2468 + if (nth_bitmapped_pack(bitmap_git->midx, &pack, i) < 0) { 2470 2469 warning(_("unable to load pack: '%s', disabling pack-reuse"), 2471 2470 bitmap_git->midx->pack_names[i]); 2472 2471 free(packs);
+7 -7
pack-revindex.c
··· 379 379 * not want to accidentally call munmap() in the middle of the 380 380 * MIDX. 381 381 */ 382 - trace2_data_string("load_midx_revindex", m->repo, 382 + trace2_data_string("load_midx_revindex", m->source->odb->repo, 383 383 "source", "midx"); 384 384 m->revindex_data = (const uint32_t *)m->chunk_revindex; 385 385 return 0; 386 386 } 387 387 388 - trace2_data_string("load_midx_revindex", m->repo, 388 + trace2_data_string("load_midx_revindex", m->source->odb->repo, 389 389 "source", "rev"); 390 390 391 391 if (m->has_chain) 392 - get_split_midx_filename_ext(m->repo->hash_algo, &revindex_name, 393 - m->object_dir, get_midx_checksum(m), 392 + get_split_midx_filename_ext(m->source, &revindex_name, 393 + get_midx_checksum(m), 394 394 MIDX_EXT_REV); 395 395 else 396 - get_midx_filename_ext(m->repo->hash_algo, &revindex_name, 397 - m->object_dir, get_midx_checksum(m), 396 + get_midx_filename_ext(m->source, &revindex_name, 397 + get_midx_checksum(m), 398 398 MIDX_EXT_REV); 399 399 400 - ret = load_revindex_from_disk(m->repo->hash_algo, 400 + ret = load_revindex_from_disk(m->source->odb->repo->hash_algo, 401 401 revindex_name.buf, 402 402 m->num_objects, 403 403 &m->revindex_map,
+6 -7
packfile.c
··· 935 935 report_garbage(PACKDIR_FILE_GARBAGE, full_name); 936 936 } 937 937 938 - static void prepare_packed_git_one(struct odb_source *source, int local) 938 + static void prepare_packed_git_one(struct odb_source *source) 939 939 { 940 940 struct string_list garbage = STRING_LIST_INIT_DUP; 941 941 struct prepare_pack_data data = { 942 942 .m = source->midx, 943 943 .r = source->odb->repo, 944 944 .garbage = &garbage, 945 - .local = local, 945 + .local = source->local, 946 946 }; 947 947 948 948 for_each_file_in_pack_dir(source->path, prepare_pack, &data); ··· 1037 1037 1038 1038 odb_prepare_alternates(r->objects); 1039 1039 for (source = r->objects->sources; source; source = source->next) { 1040 - int local = (source == r->objects->sources); 1041 - prepare_multi_pack_index_one(source, local); 1042 - prepare_packed_git_one(source, local); 1040 + prepare_multi_pack_index_one(source); 1041 + prepare_packed_git_one(source); 1043 1042 } 1044 1043 rearrange_packed_git(r); 1045 1044 ··· 1092 1091 if (!m) 1093 1092 continue; 1094 1093 for (uint32_t i = 0; i < m->num_packs + m->num_packs_in_base; i++) 1095 - prepare_midx_pack(r, m, i); 1094 + prepare_midx_pack(m, i); 1096 1095 } 1097 1096 1098 1097 return r->objects->packed_git; ··· 2078 2077 prepare_packed_git(r); 2079 2078 2080 2079 for (struct odb_source *source = r->objects->sources; source; source = source->next) 2081 - if (source->midx && fill_midx_entry(r, oid, e, source->midx)) 2080 + if (source->midx && fill_midx_entry(source->midx, oid, e)) 2082 2081 return 1; 2083 2082 2084 2083 if (!r->objects->packed_git)
+1
repository.c
··· 168 168 if (!repo->objects->sources) { 169 169 CALLOC_ARRAY(repo->objects->sources, 1); 170 170 repo->objects->sources->odb = repo->objects; 171 + repo->objects->sources->local = true; 171 172 repo->objects->sources_tail = &repo->objects->sources->next; 172 173 } 173 174 expand_base_dir(&repo->objects->sources->path, o->object_dir,
+18 -13
t/helper/test-read-midx.c
··· 11 11 #include "gettext.h" 12 12 #include "pack-revindex.h" 13 13 14 + static struct multi_pack_index *setup_midx(const char *object_dir) 15 + { 16 + struct odb_source *source; 17 + setup_git_directory(); 18 + source = odb_find_source(the_repository->objects, object_dir); 19 + if (!source) 20 + source = odb_add_to_alternates_memory(the_repository->objects, 21 + object_dir); 22 + return load_multi_pack_index(source); 23 + } 24 + 14 25 static int read_midx_file(const char *object_dir, const char *checksum, 15 26 int show_objects) 16 27 { 17 28 uint32_t i; 18 29 struct multi_pack_index *m; 19 30 20 - setup_git_directory(); 21 - m = load_multi_pack_index(the_repository, object_dir, 1); 31 + m = setup_midx(object_dir); 22 32 23 33 if (!m) 24 34 return 1; ··· 56 66 for (i = 0; i < m->num_packs; i++) 57 67 printf("%s\n", m->pack_names[i]); 58 68 59 - printf("object-dir: %s\n", m->object_dir); 69 + printf("object-dir: %s\n", m->source->path); 60 70 61 71 if (show_objects) { 62 72 struct object_id oid; ··· 65 75 for (i = 0; i < m->num_objects; i++) { 66 76 nth_midxed_object_oid(&oid, m, 67 77 i + m->num_objects_in_base); 68 - fill_midx_entry(the_repository, &oid, &e, m); 78 + fill_midx_entry(m, &oid, &e); 69 79 70 80 printf("%s %"PRIu64"\t%s\n", 71 81 oid_to_hex(&oid), e.offset, e.p->pack_name); ··· 81 91 { 82 92 struct multi_pack_index *m; 83 93 84 - setup_git_directory(); 85 - m = load_multi_pack_index(the_repository, object_dir, 1); 94 + m = setup_midx(object_dir); 86 95 if (!m) 87 96 return 1; 88 97 printf("%s\n", hash_to_hex(get_midx_checksum(m))); ··· 96 105 struct multi_pack_index *midx = NULL; 97 106 uint32_t preferred_pack; 98 107 99 - setup_git_directory(); 100 - 101 - midx = load_multi_pack_index(the_repository, object_dir, 1); 108 + midx = setup_midx(object_dir); 102 109 if (!midx) 103 110 return 1; 104 111 ··· 119 126 struct bitmapped_pack pack; 120 127 uint32_t i; 121 128 122 - setup_git_directory(); 123 - 124 - midx = load_multi_pack_index(the_repository, object_dir, 1); 129 + midx = setup_midx(object_dir); 125 130 if (!midx) 126 131 return 1; 127 132 128 133 for (i = 0; i < midx->num_packs + midx->num_packs_in_base; i++) { 129 - if (nth_bitmapped_pack(the_repository, midx, &pack, i) < 0) { 134 + if (nth_bitmapped_pack(midx, &pack, i) < 0) { 130 135 close_midx(midx); 131 136 return 1; 132 137 }
+4 -4
t/t5319-multi-pack-index.sh
··· 28 28 EOF 29 29 if test $NUM_PACKS -ge 1 30 30 then 31 - ls $OBJECT_DIR/pack/ | grep idx | sort 31 + ls "$OBJECT_DIR"/pack/ | grep idx | sort 32 32 fi && 33 33 printf "object-dir: $OBJECT_DIR\n" 34 34 } >expect && 35 - test-tool read-midx $OBJECT_DIR >actual && 35 + test-tool read-midx "$OBJECT_DIR" >actual && 36 36 test_cmp expect actual 37 37 } 38 38 ··· 305 305 306 306 ofs=$(git show-index <objects/pack/test-BC-$bc.idx | grep $b | 307 307 cut -d" " -f1) && 308 - printf "%s %s\tobjects/pack/test-BC-%s.pack\n" \ 308 + printf "%s %s\t./objects/pack/test-BC-%s.pack\n" \ 309 309 "$b" "$ofs" "$bc" >expect && 310 310 grep ^$b out >actual && 311 311 ··· 639 639 ( cd ../objects64 && pwd ) >.git/objects/info/alternates && 640 640 midx64=$(git multi-pack-index --object-dir=../objects64 write) 641 641 ) && 642 - midx_read_expect 1 63 5 objects64 " large-offsets" 642 + midx_read_expect 1 63 5 "$(pwd)/objects64" " large-offsets" 643 643 ' 644 644 645 645 test_expect_success 'verify multi-pack-index with 64-bit offsets' '