diff --git a/builtin/am.c b/builtin/am.c index 1bcc3606c5..9c82603f70 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1862,7 +1862,7 @@ next: */ if (!state->rebasing) { am_destroy(state); - close_all_packs(); + close_all_packs(the_repository->objects); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); } } diff --git a/builtin/clone.c b/builtin/clone.c index 101c27a593..7df5932b85 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -27,6 +27,7 @@ #include "connected.h" #include "packfile.h" #include "list-objects-filter-options.h" +#include "object-store.h" /* * Overall FIXMEs: @@ -1217,7 +1218,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) transport_disconnect(transport); if (option_dissociate) { - close_all_packs(); + close_all_packs(the_repository->objects); dissociate_from_references(); } diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 33343818c8..b28ff00be2 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -7,10 +7,12 @@ #include "cache.h" #include "config.h" #include "dir.h" +#include "repository.h" #include "builtin.h" #include "parse-options.h" #include "quote.h" #include "packfile.h" +#include "object-store.h" static unsigned long garbage; static off_t size_garbage; @@ -120,9 +122,9 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) struct strbuf loose_buf = STRBUF_INIT; struct strbuf pack_buf = STRBUF_INIT; struct strbuf garbage_buf = STRBUF_INIT; - if (!packed_git) + if (!get_packed_git(the_repository)) prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; if (open_pack_index(p)) diff --git a/builtin/fetch.c b/builtin/fetch.c index 8295f92b3e..dcdfc66f09 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1516,7 +1516,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) string_list_clear(&list, 0); - close_all_packs(); + close_all_packs(the_repository->objects); argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL); if (verbosity < 0) diff --git a/builtin/fsck.c b/builtin/fsck.c index 0922558683..13c0a8048e 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "commit.h" #include "tree.h" @@ -16,6 +17,7 @@ #include "streaming.h" #include "decorate.h" #include "packfile.h" +#include "object-store.h" #define REACHABLE 0x0001 #define SEEN 0x0002 @@ -719,9 +721,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) for_each_loose_object(mark_loose_for_connectivity, NULL, 0); for_each_packed_object(mark_packed_for_connectivity, NULL, 0); } else { + struct alternate_object_database *alt_odb_list; + fsck_object_dir(get_object_directory()); - prepare_alt_odb(); + prepare_alt_odb(the_repository); + alt_odb_list = the_repository->objects->alt_odb_list; for (alt = alt_odb_list; alt; alt = alt->next) fsck_object_dir(alt->path); @@ -733,7 +738,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) prepare_packed_git(); if (show_progress) { - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; + p = p->next) { if (open_pack_index(p)) continue; total += p->num_objects; @@ -741,7 +747,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) progress = start_progress(_("Checking objects"), total); } - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; + p = p->next) { /* verify gives error messages itself */ if (verify_pack(p, fsck_obj_buffer, progress, count)) diff --git a/builtin/gc.c b/builtin/gc.c index f51e5a6500..cef38e5427 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -11,6 +11,7 @@ */ #include "builtin.h" +#include "repository.h" #include "config.h" #include "tempfile.h" #include "lockfile.h" @@ -20,6 +21,7 @@ #include "argv-array.h" #include "commit.h" #include "packfile.h" +#include "object-store.h" #define FAILED_RUN "failed to run %s" @@ -173,7 +175,7 @@ static int too_many_packs(void) return 0; prepare_packed_git(); - for (cnt = 0, p = packed_git; p; p = p->next) { + for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; if (p->pack_keep) diff --git a/builtin/grep.c b/builtin/grep.c index 668cb8050a..5f32d2ce84 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -22,6 +22,7 @@ #include "pathspec.h" #include "submodule.h" #include "submodule-config.h" +#include "object-store.h" static char const * const grep_usage[] = { N_("git grep [] [-e] [...] [[--] ...]"), @@ -439,7 +440,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject, * object. */ grep_read_lock(); - add_to_alternates_memory(submodule.objectdir); + add_to_alternates_memory(submodule.objects->objectdir); grep_read_unlock(); if (oid) { diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 657a5dda06..d81473e722 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -13,6 +13,7 @@ #include "streaming.h" #include "thread-utils.h" #include "packfile.h" +#include "object-store.h" static const char index_pack_usage[] = "git index-pack [-v] [-o ] [--keep | --keep=] [--verify] [--strict] ( | --stdin [--fix-thin] [])"; diff --git a/builtin/merge.c b/builtin/merge.c index 8746c5e3e8..9db5a2cf16 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -412,7 +412,7 @@ static void finish(struct commit *head_commit, * We ignore errors in 'gc --auto', since the * user should see them. */ - close_all_packs(); + close_all_packs(the_repository->objects); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); } } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index e7e673266e..89f49bb5f6 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "attr.h" #include "object.h" @@ -28,6 +29,7 @@ #include "argv-array.h" #include "list.h" #include "packfile.h" +#include "object-store.h" static const char *pack_usage[] = { N_("git pack-objects --stdout [...] [< | < ]"), @@ -1023,8 +1025,7 @@ static int want_object_in_pack(const struct object_id *oid, if (want != -1) return want; } - - list_for_each(pos, &packed_git_mru) { + list_for_each(pos, get_packed_git_mru(the_repository)) { struct packed_git *p = list_entry(pos, struct packed_git, mru); off_t offset; @@ -1042,7 +1043,8 @@ static int want_object_in_pack(const struct object_id *oid, } want = want_found_object(exclude, p); if (!exclude && want > 0) - list_move(&p->mru, &packed_git_mru); + list_move(&p->mru, + get_packed_git_mru(the_repository)); if (want != -1) return want; } @@ -2669,7 +2671,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs) memset(&in_pack, 0, sizeof(in_pack)); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { struct object_id oid; struct object *o; @@ -2732,7 +2734,8 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid) static struct packed_git *last_found = (void *)1; struct packed_git *p; - p = (last_found != (void *)1) ? last_found : packed_git; + p = (last_found != (void *)1) ? last_found : + get_packed_git(the_repository); while (p) { if ((!p->pack_local || p->pack_keep) && @@ -2741,7 +2744,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid) return 1; } if (p == last_found) - p = packed_git; + p = get_packed_git(the_repository); else p = p->next; if (p == last_found) @@ -2777,7 +2780,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs) uint32_t i; struct object_id oid; - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local || p->pack_keep) continue; @@ -3148,7 +3151,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) prepare_packed_git(); if (ignore_packed_keep) { struct packed_git *p; - for (p = packed_git; p; p = p->next) + for (p = get_packed_git(the_repository); p; p = p->next) if (p->pack_local && p->pack_keep) break; if (!p) /* no keep-able packs found */ @@ -3161,7 +3164,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) * also covers non-local objects */ struct packed_git *p; - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) { have_non_local_packs = 1; break; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index 991e1bb76f..f060b941b5 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -7,7 +7,9 @@ */ #include "builtin.h" +#include "repository.h" #include "packfile.h" +#include "object-store.h" #define BLKSIZE 512 @@ -571,7 +573,7 @@ static struct pack_list * add_pack(struct packed_git *p) static struct pack_list * add_pack_file(const char *filename) { - struct packed_git *p = packed_git; + struct packed_git *p = get_packed_git(the_repository); if (strlen(filename) < 40) die("Bad pack filename: %s", filename); @@ -586,7 +588,7 @@ static struct pack_list * add_pack_file(const char *filename) static void load_all(void) { - struct packed_git *p = packed_git; + struct packed_git *p = get_packed_git(the_repository); while (p) { add_pack(p); diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 2bf7f2d1a3..19428ef97d 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -2027,7 +2027,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) proc.git_cmd = 1; proc.argv = argv_gc_auto; - close_all_packs(); + close_all_packs(the_repository->objects); if (!start_command(&proc)) { if (use_sideband) copy_to_sideband(proc.err, -1, NULL); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 6ba8587b6d..a2327c98b0 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -16,6 +16,7 @@ #include "revision.h" #include "diffcore.h" #include "diff.h" +#include "object-store.h" #define OPT_QUIET (1 << 0) #define OPT_CACHED (1 << 1) diff --git a/cache.h b/cache.h index 6e45c1b537..bbaf5c349a 100644 --- a/cache.h +++ b/cache.h @@ -940,12 +940,6 @@ extern void check_repository_format(void); #define DATA_CHANGED 0x0020 #define TYPE_CHANGED 0x0040 -/* - * Put in `buf` the name of the file in the local object database that - * would be used to store a loose object with the specified sha1. - */ -extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1); - /* * Return an abbreviated sha1 unique within this repository's object database. * The result will be at least `len` characters long, and will be NUL @@ -1236,7 +1230,6 @@ extern int force_object_loose(const struct object_id *oid, time_t mtime); extern int git_open_cloexec(const char *name, int flags); #define git_open(name) git_open_cloexec(name, O_RDONLY) -extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size); extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz); extern int parse_sha1_header(const char *hdr, unsigned long *sizep); @@ -1564,57 +1557,6 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len); extern void schedule_dir_for_removal(const char *name, int len); extern void remove_scheduled_dirs(void); -extern struct alternate_object_database { - struct alternate_object_database *next; - - /* see alt_scratch_buf() */ - struct strbuf scratch; - size_t base_len; - - /* - * Used to store the results of readdir(3) calls when searching - * for unique abbreviated hashes. This cache is never - * invalidated, thus it's racy and not necessarily accurate. - * That's fine for its purpose; don't use it for tasks requiring - * greater accuracy! - */ - char loose_objects_subdir_seen[256]; - struct oid_array loose_objects_cache; - - char path[FLEX_ARRAY]; -} *alt_odb_list; -extern void prepare_alt_odb(void); -extern char *compute_alternate_path(const char *path, struct strbuf *err); -typedef int alt_odb_fn(struct alternate_object_database *, void *); -extern int foreach_alt_odb(alt_odb_fn, void*); - -/* - * Allocate a "struct alternate_object_database" but do _not_ actually - * add it to the list of alternates. - */ -struct alternate_object_database *alloc_alt_odb(const char *dir); - -/* - * Add the directory to the on-disk alternates file; the new entry will also - * take effect in the current process. - */ -extern void add_to_alternates_file(const char *dir); - -/* - * Add the directory to the in-memory list of alternates (along with any - * recursive alternates it points to), but do not modify the on-disk alternates - * file. - */ -extern void add_to_alternates_memory(const char *dir); - -/* - * Returns a scratch strbuf pre-filled with the alternate object directory, - * including a trailing slash, which can be used to access paths in the - * alternate. Always use this over direct access to alt->scratch, as it - * cleans up any previous use of the scratch buffer. - */ -extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt); - struct pack_window { struct pack_window *next; unsigned char *base; @@ -1624,35 +1566,6 @@ struct pack_window { unsigned int inuse_cnt; }; -extern struct packed_git { - struct packed_git *next; - struct list_head mru; - struct pack_window *windows; - off_t pack_size; - const void *index_data; - size_t index_size; - uint32_t num_objects; - uint32_t num_bad_objects; - unsigned char *bad_object_sha1; - int index_version; - time_t mtime; - int pack_fd; - unsigned pack_local:1, - pack_keep:1, - freshened:1, - do_not_close:1, - pack_promisor:1; - unsigned char sha1[20]; - struct revindex_entry *revindex; - /* something like ".git/objects/pack/xxxxx.pack" */ - char pack_name[FLEX_ARRAY]; /* more */ -} *packed_git; - -/* - * A most-recently-used ordered version of the packed_git list. - */ -extern struct list_head packed_git_mru; - struct pack_entry { off_t offset; unsigned char sha1[20]; diff --git a/environment.c b/environment.c index 21565c3c52..39b3d906c8 100644 --- a/environment.c +++ b/environment.c @@ -14,6 +14,7 @@ #include "fmt-merge-msg.h" #include "commit.h" #include "argv-array.h" +#include "object-store.h" int trust_executable_bit = 1; int trust_ctime = 1; @@ -270,9 +271,9 @@ const char *get_git_work_tree(void) char *get_object_directory(void) { - if (!the_repository->objectdir) + if (!the_repository->objects->objectdir) BUG("git environment hasn't been setup"); - return the_repository->objectdir; + return the_repository->objects->objectdir; } int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) diff --git a/fast-import.c b/fast-import.c index a2e8b1d763..b2f6d6d583 100644 --- a/fast-import.c +++ b/fast-import.c @@ -154,6 +154,7 @@ Format of STDIN stream: #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "lockfile.h" #include "object.h" @@ -168,6 +169,7 @@ Format of STDIN stream: #include "dir.h" #include "run-command.h" #include "packfile.h" +#include "object-store.h" #define PACK_ID_BITS 16 #define MAX_PACK_ID ((1<idx.offset) { duplicate_count_by_type[type]++; return 1; - } else if (find_sha1_pack(oid.hash, packed_git)) { + } else if (find_sha1_pack(oid.hash, + get_packed_git(the_repository))) { e->type = type; e->pack_id = MAX_PACK_ID; e->idx.offset = 1; /* just not zero! */ @@ -1307,7 +1310,8 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) duplicate_count_by_type[OBJ_BLOB]++; truncate_pack(&checkpoint); - } else if (find_sha1_pack(oid.hash, packed_git)) { + } else if (find_sha1_pack(oid.hash, + get_packed_git(the_repository))) { e->type = OBJ_BLOB; e->pack_id = MAX_PACK_ID; e->idx.offset = 1; /* just not zero! */ diff --git a/http-backend.c b/http-backend.c index f3dc218b2a..64dde78c1b 100644 --- a/http-backend.c +++ b/http-backend.c @@ -1,5 +1,6 @@ #include "cache.h" #include "config.h" +#include "repository.h" #include "refs.h" #include "pkt-line.h" #include "object.h" @@ -10,6 +11,7 @@ #include "url.h" #include "argv-array.h" #include "packfile.h" +#include "object-store.h" static const char content_type[] = "Content-Type"; static const char content_length[] = "Content-Length"; @@ -518,13 +520,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg) select_getanyfile(hdr); prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (p->pack_local) cnt++; } strbuf_grow(&buf, cnt * 53 + 2); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (p->pack_local) strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6); } diff --git a/http-push.c b/http-push.c index ff82b63133..c0998fd763 100644 --- a/http-push.c +++ b/http-push.c @@ -12,6 +12,7 @@ #include "sigchain.h" #include "argv-array.h" #include "packfile.h" +#include "object-store.h" #ifdef EXPAT_NEEDS_XMLPARSE_H #include diff --git a/http-walker.c b/http-walker.c index f506f394ac..7cdfb2f24c 100644 --- a/http-walker.c +++ b/http-walker.c @@ -1,10 +1,12 @@ #include "cache.h" +#include "repository.h" #include "commit.h" #include "walker.h" #include "http.h" #include "list.h" #include "transport.h" #include "packfile.h" +#include "object-store.h" struct alt_base { char *base; @@ -545,7 +547,7 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) ret = error("File %s has bad hash", hex); } else if (req->rename < 0) { struct strbuf buf = STRBUF_INIT; - sha1_file_name(&buf, req->sha1); + sha1_file_name(the_repository, &buf, req->sha1); ret = error("unable to write sha1 filename %s", buf.buf); strbuf_release(&buf); } diff --git a/http.c b/http.c index a5bd5d62c2..9304045b6c 100644 --- a/http.c +++ b/http.c @@ -14,6 +14,7 @@ #include "packfile.h" #include "protocol.h" #include "string-list.h" +#include "object-store.h" static struct trace_key trace_curl = TRACE_KEY_INIT(CURL); static int trace_curl_data = 1; @@ -2248,7 +2249,7 @@ struct http_object_request *new_http_object_request(const char *base_url, hashcpy(freq->sha1, sha1); freq->localfile = -1; - sha1_file_name(&filename, sha1); + sha1_file_name(the_repository, &filename, sha1); snprintf(freq->tmpfile, sizeof(freq->tmpfile), "%s.temp", filename.buf); @@ -2397,8 +2398,7 @@ int finish_http_object_request(struct http_object_request *freq) unlink_or_warn(freq->tmpfile); return -1; } - - sha1_file_name(&filename, freq->sha1); + sha1_file_name(the_repository, &filename, freq->sha1); freq->rename = finalize_object_file(freq->tmpfile, filename.buf); strbuf_release(&filename); diff --git a/object-store.h b/object-store.h new file mode 100644 index 0000000000..fef33f345f --- /dev/null +++ b/object-store.h @@ -0,0 +1,132 @@ +#ifndef OBJECT_STORE_H +#define OBJECT_STORE_H + +struct alternate_object_database { + struct alternate_object_database *next; + + /* see alt_scratch_buf() */ + struct strbuf scratch; + size_t base_len; + + /* + * Used to store the results of readdir(3) calls when searching + * for unique abbreviated hashes. This cache is never + * invalidated, thus it's racy and not necessarily accurate. + * That's fine for its purpose; don't use it for tasks requiring + * greater accuracy! + */ + char loose_objects_subdir_seen[256]; + struct oid_array loose_objects_cache; + + /* + * Path to the alternative object store. If this is a relative path, + * it is relative to the current working directory. + */ + char path[FLEX_ARRAY]; +}; +void prepare_alt_odb(struct repository *r); +char *compute_alternate_path(const char *path, struct strbuf *err); +typedef int alt_odb_fn(struct alternate_object_database *, void *); +int foreach_alt_odb(alt_odb_fn, void*); + +/* + * Allocate a "struct alternate_object_database" but do _not_ actually + * add it to the list of alternates. + */ +struct alternate_object_database *alloc_alt_odb(const char *dir); + +/* + * Add the directory to the on-disk alternates file; the new entry will also + * take effect in the current process. + */ +void add_to_alternates_file(const char *dir); + +/* + * Add the directory to the in-memory list of alternates (along with any + * recursive alternates it points to), but do not modify the on-disk alternates + * file. + */ +void add_to_alternates_memory(const char *dir); + +/* + * Returns a scratch strbuf pre-filled with the alternate object directory, + * including a trailing slash, which can be used to access paths in the + * alternate. Always use this over direct access to alt->scratch, as it + * cleans up any previous use of the scratch buffer. + */ +struct strbuf *alt_scratch_buf(struct alternate_object_database *alt); + +struct packed_git { + struct packed_git *next; + struct list_head mru; + struct pack_window *windows; + off_t pack_size; + const void *index_data; + size_t index_size; + uint32_t num_objects; + uint32_t num_bad_objects; + unsigned char *bad_object_sha1; + int index_version; + time_t mtime; + int pack_fd; + unsigned pack_local:1, + pack_keep:1, + freshened:1, + do_not_close:1, + pack_promisor:1; + unsigned char sha1[20]; + struct revindex_entry *revindex; + /* something like ".git/objects/pack/xxxxx.pack" */ + char pack_name[FLEX_ARRAY]; /* more */ +}; + +struct raw_object_store { + /* + * Path to the repository's object store. + * Cannot be NULL after initialization. + */ + char *objectdir; + + /* Path to extra alternate object database if not NULL */ + char *alternate_db; + + struct alternate_object_database *alt_odb_list; + struct alternate_object_database **alt_odb_tail; + + /* + * private data + * + * should only be accessed directly by packfile.c + */ + + struct packed_git *packed_git; + /* A most-recently-used ordered version of the packed_git list. */ + struct list_head packed_git_mru; + + /* + * A fast, rough count of the number of objects in the repository. + * These two fields are not meant for direct access. Use + * approximate_object_count() instead. + */ + unsigned long approximate_object_count; + unsigned approximate_object_count_valid : 1; + + /* + * Whether packed_git has already been populated with this repository's + * packs. + */ + unsigned packed_git_initialized : 1; +}; + +struct raw_object_store *raw_object_store_new(void); +void raw_object_store_clear(struct raw_object_store *o); + +/* + * Put in `buf` the name of the file in the local object database that + * would be used to store a loose object with the specified sha1. + */ +void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1); + +void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size); + +#endif /* OBJECT_STORE_H */ diff --git a/object.c b/object.c index 2c909385a7..a0a756f24f 100644 --- a/object.c +++ b/object.c @@ -4,6 +4,8 @@ #include "tree.h" #include "commit.h" #include "tag.h" +#include "object-store.h" +#include "packfile.h" static struct object **obj_hash; static int nr_objs, obj_hash_size; @@ -445,3 +447,43 @@ void clear_commit_marks_all(unsigned int flags) obj->flags &= ~flags; } } + +struct raw_object_store *raw_object_store_new(void) +{ + struct raw_object_store *o = xmalloc(sizeof(*o)); + + memset(o, 0, sizeof(*o)); + INIT_LIST_HEAD(&o->packed_git_mru); + return o; +} + +static void free_alt_odb(struct alternate_object_database *alt) +{ + strbuf_release(&alt->scratch); + oid_array_clear(&alt->loose_objects_cache); + free(alt); +} + +static void free_alt_odbs(struct raw_object_store *o) +{ + while (o->alt_odb_list) { + struct alternate_object_database *next; + + next = o->alt_odb_list->next; + free_alt_odb(o->alt_odb_list); + o->alt_odb_list = next; + } +} + +void raw_object_store_clear(struct raw_object_store *o) +{ + FREE_AND_NULL(o->objectdir); + FREE_AND_NULL(o->alternate_db); + + free_alt_odbs(o); + o->alt_odb_tail = NULL; + + INIT_LIST_HEAD(&o->packed_git_mru); + close_all_packs(o); + o->packed_git = NULL; +} diff --git a/pack-bitmap.c b/pack-bitmap.c index 9270983e5f..22cd425788 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -10,6 +10,8 @@ #include "pack-revindex.h" #include "pack-objects.h" #include "packfile.h" +#include "repository.h" +#include "object-store.h" /* * An entry on the bitmap index, representing the bitmap for a given @@ -335,7 +337,7 @@ static int open_pack_bitmap(void) assert(!bitmap_git.map && !bitmap_git.loaded); prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (open_pack_bitmap_1(p) == 0) ret = 0; } diff --git a/pack-check.c b/pack-check.c index d0591dd5e8..385d964bdd 100644 --- a/pack-check.c +++ b/pack-check.c @@ -3,6 +3,7 @@ #include "pack-revindex.h" #include "progress.h" #include "packfile.h" +#include "object-store.h" struct idx_entry { off_t offset; diff --git a/pack-revindex.c b/pack-revindex.c index ff5f62c033..bb521cf7fb 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -1,5 +1,6 @@ #include "cache.h" #include "pack-revindex.h" +#include "object-store.h" /* * Pack index for existing packs give us easy access to the offsets into diff --git a/packfile.c b/packfile.c index 69d3afda6c..8e8b743910 100644 --- a/packfile.c +++ b/packfile.c @@ -1,6 +1,7 @@ #include "cache.h" #include "list.h" #include "pack.h" +#include "repository.h" #include "dir.h" #include "mergesort.h" #include "packfile.h" @@ -13,6 +14,7 @@ #include "tag.h" #include "tree-walk.h" #include "tree.h" +#include "object-store.h" char *odb_pack_name(struct strbuf *buf, const unsigned char *sha1, @@ -44,8 +46,6 @@ static unsigned int pack_open_fds; static unsigned int pack_max_fds; static size_t peak_pack_mapped; static size_t pack_mapped; -struct packed_git *packed_git; -LIST_HEAD(packed_git_mru); #define SZ_FMT PRIuMAX static inline uintmax_t sz_fmt(size_t s) { return s; } @@ -245,7 +245,7 @@ static int unuse_one_window(struct packed_git *current) if (current) scan_windows(current, &lru_p, &lru_w, &lru_l); - for (p = packed_git; p; p = p->next) + for (p = the_repository->objects->packed_git; p; p = p->next) scan_windows(p, &lru_p, &lru_w, &lru_l); if (lru_p) { munmap(lru_w->base, lru_w->len); @@ -311,11 +311,11 @@ static void close_pack(struct packed_git *p) close_pack_index(p); } -void close_all_packs(void) +void close_all_packs(struct raw_object_store *o) { struct packed_git *p; - for (p = packed_git; p; p = p->next) + for (p = o->packed_git; p; p = p->next) if (p->do_not_close) die("BUG: want to close pack marked 'do-not-close'"); else @@ -383,7 +383,7 @@ static int close_one_pack(void) struct pack_window *mru_w = NULL; int accept_windows_inuse = 1; - for (p = packed_git; p; p = p->next) { + for (p = the_repository->objects->packed_git; p; p = p->next) { if (p->pack_fd == -1) continue; find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse); @@ -685,8 +685,8 @@ void install_packed_git(struct packed_git *pack) if (pack->pack_fd != -1) pack_open_fds++; - pack->next = packed_git; - packed_git = pack; + pack->next = the_repository->objects->packed_git; + the_repository->objects->packed_git = pack; } void (*report_garbage)(unsigned seen_bits, const char *path); @@ -768,7 +768,8 @@ static void prepare_packed_git_one(char *objdir, int local) base_len = path.len; if (strip_suffix_mem(path.buf, &base_len, ".idx")) { /* Don't reopen a pack we already have. */ - for (p = packed_git; p; p = p->next) { + for (p = the_repository->objects->packed_git; p; + p = p->next) { size_t len; if (strip_suffix(p->pack_name, ".pack", &len) && len == base_len && @@ -802,8 +803,6 @@ static void prepare_packed_git_one(char *objdir, int local) strbuf_release(&path); } -static int approximate_object_count_valid; - /* * Give a fast, rough count of the number of objects in the repository. This * ignores loose objects completely. If you have a lot of them, then either @@ -813,19 +812,20 @@ static int approximate_object_count_valid; */ unsigned long approximate_object_count(void) { - static unsigned long count; - if (!approximate_object_count_valid) { + if (!the_repository->objects->approximate_object_count_valid) { + unsigned long count; struct packed_git *p; prepare_packed_git(); count = 0; - for (p = packed_git; p; p = p->next) { + for (p = the_repository->objects->packed_git; p; p = p->next) { if (open_pack_index(p)) continue; count += p->num_objects; } + the_repository->objects->approximate_object_count = count; } - return count; + return the_repository->objects->approximate_object_count; } static void *get_next_packed_git(const void *p) @@ -868,43 +868,53 @@ static int sort_pack(const void *a_, const void *b_) static void rearrange_packed_git(void) { - packed_git = llist_mergesort(packed_git, get_next_packed_git, - set_next_packed_git, sort_pack); + the_repository->objects->packed_git = llist_mergesort( + the_repository->objects->packed_git, get_next_packed_git, + set_next_packed_git, sort_pack); } static void prepare_packed_git_mru(void) { struct packed_git *p; - INIT_LIST_HEAD(&packed_git_mru); + INIT_LIST_HEAD(&the_repository->objects->packed_git_mru); - for (p = packed_git; p; p = p->next) - list_add_tail(&p->mru, &packed_git_mru); + for (p = the_repository->objects->packed_git; p; p = p->next) + list_add_tail(&p->mru, &the_repository->objects->packed_git_mru); } -static int prepare_packed_git_run_once = 0; void prepare_packed_git(void) { struct alternate_object_database *alt; - if (prepare_packed_git_run_once) + if (the_repository->objects->packed_git_initialized) return; prepare_packed_git_one(get_object_directory(), 1); - prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) + prepare_alt_odb(the_repository); + for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) prepare_packed_git_one(alt->path, 0); rearrange_packed_git(); prepare_packed_git_mru(); - prepare_packed_git_run_once = 1; + the_repository->objects->packed_git_initialized = 1; } void reprepare_packed_git(void) { - approximate_object_count_valid = 0; - prepare_packed_git_run_once = 0; + the_repository->objects->approximate_object_count_valid = 0; + the_repository->objects->packed_git_initialized = 0; prepare_packed_git(); } +struct packed_git *get_packed_git(struct repository *r) +{ + return r->objects->packed_git; +} + +struct list_head *get_packed_git_mru(struct repository *r) +{ + return &r->objects->packed_git_mru; +} + unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep) { @@ -1013,7 +1023,7 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1) struct packed_git *p; unsigned i; - for (p = packed_git; p; p = p->next) + for (p = the_repository->objects->packed_git; p; p = p->next) for (i = 0; i < p->num_bad_objects; i++) if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i)) return p; @@ -1833,13 +1843,14 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e) struct list_head *pos; prepare_packed_git(); - if (!packed_git) + if (!the_repository->objects->packed_git) return 0; - list_for_each(pos, &packed_git_mru) { + list_for_each(pos, &the_repository->objects->packed_git_mru) { struct packed_git *p = list_entry(pos, struct packed_git, mru); if (fill_pack_entry(sha1, e, p)) { - list_move(&p->mru, &packed_git_mru); + list_move(&p->mru, + &the_repository->objects->packed_git_mru); return 1; } } @@ -1886,7 +1897,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags) int pack_errors = 0; prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = the_repository->objects->packed_git; p; p = p->next) { if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local) continue; if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) && @@ -1917,7 +1928,7 @@ static int add_promisor_object(const struct object_id *oid, /* * If this is a tree, commit, or tag, the objects it refers - * to are also promisor objects. (Blobs refer to no objects.) + * to are also promisor objects. (Blobs refer to no objects->) */ if (obj->type == OBJ_TREE) { struct tree *tree = (struct tree *)obj; diff --git a/packfile.h b/packfile.h index ec08cb2bb0..a7abd602da 100644 --- a/packfile.h +++ b/packfile.h @@ -38,6 +38,9 @@ extern void prepare_packed_git(void); extern void reprepare_packed_git(void); extern void install_packed_git(struct packed_git *pack); +struct packed_git *get_packed_git(struct repository *r); +struct list_head *get_packed_git_mru(struct repository *r); + /* * Give a rough count of objects in the repository. This sacrifices accuracy * for speed. @@ -63,7 +66,7 @@ extern void close_pack_index(struct packed_git *); extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *); extern void close_pack_windows(struct packed_git *); -extern void close_all_packs(void); +extern void close_all_packs(struct raw_object_store *o); extern void unuse_pack(struct pack_window **); extern void clear_delta_base_cache(void); extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local); diff --git a/path.c b/path.c index da8b655730..3308b7b958 100644 --- a/path.c +++ b/path.c @@ -10,6 +10,7 @@ #include "submodule-config.h" #include "path.h" #include "packfile.h" +#include "object-store.h" static int get_st_mode_bits(const char *path, int *mode) { @@ -382,7 +383,7 @@ static void adjust_git_path(const struct repository *repo, strbuf_splice(buf, 0, buf->len, repo->index_file, strlen(repo->index_file)); else if (dir_prefix(base, "objects")) - replace_dir(buf, git_dir_len + 7, repo->objectdir); + replace_dir(buf, git_dir_len + 7, repo->objects->objectdir); else if (git_hooks_path && dir_prefix(base, "hooks")) replace_dir(buf, git_dir_len + 5, git_hooks_path); else if (repo->different_commondir) diff --git a/reachable.c b/reachable.c index 404e1440e9..a6ea33a5db 100644 --- a/reachable.c +++ b/reachable.c @@ -11,6 +11,7 @@ #include "list-objects.h" #include "packfile.h" #include "worktree.h" +#include "object-store.h" struct connectivity_progress { struct progress *progress; diff --git a/repository.c b/repository.c index 62f52f47fc..a4848c1bd0 100644 --- a/repository.c +++ b/repository.c @@ -1,5 +1,6 @@ #include "cache.h" #include "repository.h" +#include "object-store.h" #include "config.h" #include "submodule-config.h" @@ -12,6 +13,7 @@ void initialize_the_repository(void) the_repository = &the_repo; the_repo.index = &the_index; + the_repo.objects = raw_object_store_new(); repo_set_hash_algo(&the_repo, GIT_HASH_SHA1); } @@ -58,10 +60,10 @@ void repo_set_gitdir(struct repository *repo, free(old_gitdir); repo_set_commondir(repo, o->commondir); - expand_base_dir(&repo->objectdir, o->object_dir, + expand_base_dir(&repo->objects->objectdir, o->object_dir, repo->commondir, "objects"); - free(repo->alternate_db); - repo->alternate_db = xstrdup_or_null(o->alternate_db); + free(repo->objects->alternate_db); + repo->objects->alternate_db = xstrdup_or_null(o->alternate_db); expand_base_dir(&repo->graft_file, o->graft_file, repo->commondir, "info/grafts"); expand_base_dir(&repo->index_file, o->index_file, @@ -140,6 +142,8 @@ static int repo_init(struct repository *repo, struct repository_format format; memset(repo, 0, sizeof(*repo)); + repo->objects = raw_object_store_new(); + if (repo_init_gitdir(repo, gitdir)) goto error; @@ -214,13 +218,14 @@ void repo_clear(struct repository *repo) { FREE_AND_NULL(repo->gitdir); FREE_AND_NULL(repo->commondir); - FREE_AND_NULL(repo->objectdir); - FREE_AND_NULL(repo->alternate_db); FREE_AND_NULL(repo->graft_file); FREE_AND_NULL(repo->index_file); FREE_AND_NULL(repo->worktree); FREE_AND_NULL(repo->submodule_prefix); + raw_object_store_clear(repo->objects); + FREE_AND_NULL(repo->objects); + if (repo->config) { git_configset_clear(repo->config); FREE_AND_NULL(repo->config); diff --git a/repository.h b/repository.h index f21fd93f72..09df94a472 100644 --- a/repository.h +++ b/repository.h @@ -2,9 +2,10 @@ #define REPOSITORY_H struct config_set; -struct index_state; -struct submodule_cache; struct git_hash_algo; +struct index_state; +struct raw_object_store; +struct submodule_cache; struct repository { /* Environment */ @@ -21,13 +22,9 @@ struct repository { char *commondir; /* - * Path to the repository's object store. - * Cannot be NULL after initialization. + * Holds any information related to accessing the raw object content. */ - char *objectdir; - - /* Path to extra alternate object database if not NULL */ - char *alternate_db; + struct raw_object_store *objects; /* * Path to the repository's graft file. diff --git a/server-info.c b/server-info.c index 26a6c20b7d..75a8b65e47 100644 --- a/server-info.c +++ b/server-info.c @@ -1,9 +1,11 @@ #include "cache.h" +#include "repository.h" #include "refs.h" #include "object.h" #include "commit.h" #include "tag.h" #include "packfile.h" +#include "object-store.h" /* * Create the file "path" by writing to a temporary file and renaming @@ -200,7 +202,7 @@ static void init_pack_info(const char *infofile, int force) objdirlen = strlen(objdir); prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { /* we ignore things on alternate path since they are * not available to the pullers in general. */ @@ -210,7 +212,7 @@ static void init_pack_info(const char *infofile, int force) } num_pack = i; info = xcalloc(num_pack, sizeof(struct pack_info *)); - for (i = 0, p = packed_git; p; p = p->next) { + for (i = 0, p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; info[i] = xcalloc(1, sizeof(struct pack_info)); diff --git a/sha1_file.c b/sha1_file.c index aea9124a78..aab3b58e03 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -22,6 +22,7 @@ #include "pack-revindex.h" #include "sha1-lookup.h" #include "bulk-checkin.h" +#include "repository.h" #include "streaming.h" #include "dir.h" #include "list.h" @@ -29,6 +30,7 @@ #include "quote.h" #include "packfile.h" #include "fetch-object.h" +#include "object-store.h" /* The maximum size for an object header. */ #define MAX_HEADER_LEN 32 @@ -322,9 +324,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1) } } -void sha1_file_name(struct strbuf *buf, const unsigned char *sha1) +void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1) { - strbuf_addstr(buf, get_object_directory()); + strbuf_addstr(buf, r->objects->objectdir); strbuf_addch(buf, '/'); fill_sha1_path(buf, sha1); } @@ -343,13 +345,12 @@ static const char *alt_sha1_path(struct alternate_object_database *alt, return buf->buf; } -struct alternate_object_database *alt_odb_list; -static struct alternate_object_database **alt_odb_tail; - /* * Return non-zero iff the path is usable as an alternate object database. */ -static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir) +static int alt_odb_usable(struct raw_object_store *o, + struct strbuf *path, + const char *normalized_objdir) { struct alternate_object_database *alt; @@ -365,7 +366,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir) * Prevent the common mistake of listing the same * thing twice, or object directory itself. */ - for (alt = alt_odb_list; alt; alt = alt->next) { + for (alt = o->alt_odb_list; alt; alt = alt->next) { if (!fspathcmp(path->buf, alt->path)) return 0; } @@ -390,9 +391,11 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir) * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -static void read_info_alternates(const char * relative_base, int depth); -static int link_alt_odb_entry(const char *entry, const char *relative_base, - int depth, const char *normalized_objdir) +static void read_info_alternates(struct repository *r, + const char *relative_base, + int depth); +static int link_alt_odb_entry(struct repository *r, const char *entry, + const char *relative_base, int depth, const char *normalized_objdir) { struct alternate_object_database *ent; struct strbuf pathbuf = STRBUF_INIT; @@ -417,7 +420,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base, while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') strbuf_setlen(&pathbuf, pathbuf.len - 1); - if (!alt_odb_usable(&pathbuf, normalized_objdir)) { + if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir)) { strbuf_release(&pathbuf); return -1; } @@ -425,12 +428,12 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base, ent = alloc_alt_odb(pathbuf.buf); /* add the alternate entry */ - *alt_odb_tail = ent; - alt_odb_tail = &(ent->next); + *r->objects->alt_odb_tail = ent; + r->objects->alt_odb_tail = &(ent->next); ent->next = NULL; /* recursively add alternates */ - read_info_alternates(pathbuf.buf, depth + 1); + read_info_alternates(r, pathbuf.buf, depth + 1); strbuf_release(&pathbuf); return 0; @@ -465,8 +468,8 @@ static const char *parse_alt_odb_entry(const char *string, return end; } -static void link_alt_odb_entries(const char *alt, int sep, - const char *relative_base, int depth) +static void link_alt_odb_entries(struct repository *r, const char *alt, + int sep, const char *relative_base, int depth) { struct strbuf objdirbuf = STRBUF_INIT; struct strbuf entry = STRBUF_INIT; @@ -480,7 +483,7 @@ static void link_alt_odb_entries(const char *alt, int sep, return; } - strbuf_add_absolute_path(&objdirbuf, get_object_directory()); + strbuf_add_absolute_path(&objdirbuf, r->objects->objectdir); if (strbuf_normalize_path(&objdirbuf) < 0) die("unable to normalize object directory: %s", objdirbuf.buf); @@ -489,13 +492,16 @@ static void link_alt_odb_entries(const char *alt, int sep, alt = parse_alt_odb_entry(alt, sep, &entry); if (!entry.len) continue; - link_alt_odb_entry(entry.buf, relative_base, depth, objdirbuf.buf); + link_alt_odb_entry(r, entry.buf, + relative_base, depth, objdirbuf.buf); } strbuf_release(&entry); strbuf_release(&objdirbuf); } -static void read_info_alternates(const char * relative_base, int depth) +static void read_info_alternates(struct repository *r, + const char *relative_base, + int depth) { char *path; struct strbuf buf = STRBUF_INIT; @@ -507,7 +513,7 @@ static void read_info_alternates(const char * relative_base, int depth) return; } - link_alt_odb_entries(buf.buf, '\n', relative_base, depth); + link_alt_odb_entries(r, buf.buf, '\n', relative_base, depth); strbuf_release(&buf); free(path); } @@ -560,8 +566,9 @@ void add_to_alternates_file(const char *reference) fprintf_or_die(out, "%s\n", reference); if (commit_lock_file(&lock)) die_errno("unable to move new alternates file into place"); - if (alt_odb_tail) - link_alt_odb_entries(reference, '\n', NULL, 0); + if (the_repository->objects->alt_odb_tail) + link_alt_odb_entries(the_repository, reference, + '\n', NULL, 0); } free(alts); } @@ -572,9 +579,10 @@ void add_to_alternates_memory(const char *reference) * Make sure alternates are initialized, or else our entry may be * overwritten when they are. */ - prepare_alt_odb(); + prepare_alt_odb(the_repository); - link_alt_odb_entries(reference, '\n', NULL, 0); + link_alt_odb_entries(the_repository, reference, + '\n', NULL, 0); } /* @@ -657,8 +665,8 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) struct alternate_object_database *ent; int r = 0; - prepare_alt_odb(); - for (ent = alt_odb_list; ent; ent = ent->next) { + prepare_alt_odb(the_repository); + for (ent = the_repository->objects->alt_odb_list; ent; ent = ent->next) { r = fn(ent, cb); if (r) break; @@ -666,15 +674,15 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) return r; } -void prepare_alt_odb(void) +void prepare_alt_odb(struct repository *r) { - if (alt_odb_tail) + if (r->objects->alt_odb_tail) return; - alt_odb_tail = &alt_odb_list; - link_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0); + r->objects->alt_odb_tail = &r->objects->alt_odb_list; + link_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0); - read_info_alternates(get_object_directory(), 0); + read_info_alternates(r, r->objects->objectdir, 0); } /* Returns 1 if we have successfully freshened the file, 0 otherwise. */ @@ -706,7 +714,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen) static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - sha1_file_name(&buf, sha1); + sha1_file_name(the_repository, &buf, sha1); return check_and_freshen_file(buf.buf, freshen); } @@ -714,8 +722,8 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen) static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen) { struct alternate_object_database *alt; - prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) { + prepare_alt_odb(the_repository); + for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) { const char *path = alt_sha1_path(alt, sha1); if (check_and_freshen_file(path, freshen)) return 1; @@ -860,22 +868,22 @@ int git_open_cloexec(const char *name, int flags) * Note that it may point to static storage and is only valid until another * call to sha1_file_name(), etc. */ -static int stat_sha1_file(const unsigned char *sha1, struct stat *st, - const char **path) +static int stat_sha1_file(struct repository *r, const unsigned char *sha1, + struct stat *st, const char **path) { struct alternate_object_database *alt; static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - sha1_file_name(&buf, sha1); + sha1_file_name(r, &buf, sha1); *path = buf.buf; if (!lstat(*path, st)) return 0; - prepare_alt_odb(); + prepare_alt_odb(r); errno = ENOENT; - for (alt = alt_odb_list; alt; alt = alt->next) { + for (alt = r->objects->alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); if (!lstat(*path, st)) return 0; @@ -888,7 +896,8 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, * Like stat_sha1_file(), but actually open the object and return the * descriptor. See the caveats on the "path" parameter above. */ -static int open_sha1_file(const unsigned char *sha1, const char **path) +static int open_sha1_file(struct repository *r, + const unsigned char *sha1, const char **path) { int fd; struct alternate_object_database *alt; @@ -896,7 +905,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - sha1_file_name(&buf, sha1); + sha1_file_name(r, &buf, sha1); *path = buf.buf; fd = git_open(*path); @@ -904,8 +913,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) return fd; most_interesting_errno = errno; - prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) { + prepare_alt_odb(r); + for (alt = r->objects->alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); fd = git_open(*path); if (fd >= 0) @@ -921,9 +930,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) * Map the loose object at "path" if it is not NULL, or the path found by * searching for a loose object named "sha1". */ -static void *map_sha1_file_1(const char *path, - const unsigned char *sha1, - unsigned long *size) +static void *map_sha1_file_1(struct repository *r, const char *path, + const unsigned char *sha1, unsigned long *size) { void *map; int fd; @@ -931,7 +939,7 @@ static void *map_sha1_file_1(const char *path, if (path) fd = git_open(path); else - fd = open_sha1_file(sha1, &path); + fd = open_sha1_file(r, sha1, &path); map = NULL; if (fd >= 0) { struct stat st; @@ -950,9 +958,10 @@ static void *map_sha1_file_1(const char *path, return map; } -void *map_sha1_file(const unsigned char *sha1, unsigned long *size) +void *map_sha1_file(struct repository *r, + const unsigned char *sha1, unsigned long *size) { - return map_sha1_file_1(NULL, sha1, size); + return map_sha1_file_1(r, NULL, sha1, size); } static int unpack_sha1_short_header(git_zstream *stream, @@ -1141,9 +1150,9 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep) return parse_sha1_header_extended(hdr, &oi, 0); } -static int sha1_loose_object_info(const unsigned char *sha1, - struct object_info *oi, - int flags) +static int sha1_loose_object_info(struct repository *r, + const unsigned char *sha1, + struct object_info *oi, int flags) { int status = 0; unsigned long mapsize; @@ -1167,14 +1176,14 @@ static int sha1_loose_object_info(const unsigned char *sha1, if (!oi->typep && !oi->type_name && !oi->sizep && !oi->contentp) { const char *path; struct stat st; - if (stat_sha1_file(sha1, &st, &path) < 0) + if (stat_sha1_file(r, sha1, &st, &path) < 0) return -1; if (oi->disk_sizep) *oi->disk_sizep = st.st_size; return 0; } - map = map_sha1_file(sha1, &mapsize); + map = map_sha1_file(r, sha1, &mapsize); if (!map) return -1; @@ -1266,7 +1275,7 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi return -1; /* Most likely it's a loose object. */ - if (!sha1_loose_object_info(real->hash, oi, flags)) + if (!sha1_loose_object_info(the_repository, real->hash, oi, flags)) return 0; /* Not a loose object; someone else may have just packed it. */ @@ -1390,7 +1399,7 @@ void *read_object_file_extended(const struct object_id *oid, die("replacement %s not found for %s", oid_to_hex(repl), oid_to_hex(oid)); - if (!stat_sha1_file(repl->hash, &st, &path)) + if (!stat_sha1_file(the_repository, repl->hash, &st, &path)) die("loose object %s (stored in %s) is corrupt", oid_to_hex(repl), path); @@ -1591,7 +1600,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr, static struct strbuf filename = STRBUF_INIT; strbuf_reset(&filename); - sha1_file_name(&filename, oid->hash); + sha1_file_name(the_repository, &filename, oid->hash); fd = create_tmpfile(&tmp_file, filename.buf); if (fd < 0) { @@ -2199,7 +2208,7 @@ int read_loose_object(const char *path, *contents = NULL; - map = map_sha1_file_1(path, NULL, &mapsize); + map = map_sha1_file_1(the_repository, path, NULL, &mapsize); if (!map) { error_errno("unable to mmap %s", path); goto out; diff --git a/sha1_name.c b/sha1_name.c index 0185c6081a..509a95f0cf 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -10,6 +10,8 @@ #include "dir.h" #include "sha1-array.h" #include "packfile.h" +#include "object-store.h" +#include "repository.h" static int get_oid_oneline(const char *, struct object_id *, struct commit_list *); @@ -104,7 +106,7 @@ static void find_short_object_filename(struct disambiguate_state *ds) */ fakeent = alloc_alt_odb(get_object_directory()); } - fakeent->next = alt_odb_list; + fakeent->next = the_repository->objects->alt_odb_list; for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) { int pos; @@ -178,7 +180,8 @@ static void find_short_packed_object(struct disambiguate_state *ds) struct packed_git *p; prepare_packed_git(); - for (p = packed_git; p && !ds->ambiguous; p = p->next) + for (p = get_packed_git(the_repository); p && !ds->ambiguous; + p = p->next) unique_in_pack(p, ds); } @@ -334,7 +337,7 @@ static int init_object_disambiguation(const char *name, int len, ds->len = len; ds->hex_pfx[len] = '\0'; - prepare_alt_odb(); + prepare_alt_odb(the_repository); return 0; } @@ -532,7 +535,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad) struct packed_git *p; prepare_packed_git(); - for (p = packed_git; p; p = p->next) + for (p = get_packed_git(the_repository); p; p = p->next) find_abbrev_len_for_pack(p, mad); } diff --git a/streaming.c b/streaming.c index 46fabee3aa..7d55ba64c7 100644 --- a/streaming.c +++ b/streaming.c @@ -3,6 +3,8 @@ */ #include "cache.h" #include "streaming.h" +#include "repository.h" +#include "object-store.h" #include "packfile.h" enum input_source { @@ -335,7 +337,8 @@ static struct stream_vtbl loose_vtbl = { static open_method_decl(loose) { - st->u.loose.mapped = map_sha1_file(oid->hash, &st->u.loose.mapsize); + st->u.loose.mapped = map_sha1_file(the_repository, + oid->hash, &st->u.loose.mapsize); if (!st->u.loose.mapped) return -1; if ((unpack_sha1_header(&st->z, diff --git a/submodule.c b/submodule.c index a05c544e8d..9a50168b23 100644 --- a/submodule.c +++ b/submodule.c @@ -21,6 +21,7 @@ #include "remote.h" #include "worktree.h" #include "parse-options.h" +#include "object-store.h" static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF; static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP; diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 7120634b04..7314b5943e 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -1,6 +1,7 @@ #include "cache.h" #include "refs.h" #include "worktree.h" +#include "object-store.h" static const char *notnull(const char *arg, const char *name) { diff --git a/tmp-objdir.c b/tmp-objdir.c index b2d9280f10..fea3f55545 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -6,6 +6,7 @@ #include "strbuf.h" #include "argv-array.h" #include "quote.h" +#include "object-store.h" struct tmp_objdir { struct strbuf path; diff --git a/transport.c b/transport.c index b9dfa11bd2..94eccf29aa 100644 --- a/transport.c +++ b/transport.c @@ -18,6 +18,7 @@ #include "sha1-array.h" #include "sigchain.h" #include "transport-internal.h" +#include "object-store.h" static void set_upstreams(struct transport *transport, struct ref *refs, int pretend)