From 90c62155d65a6bec5c2c293c8ece0b22173f63a3 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:20:55 +0100 Subject: [PATCH 01/27] repository: introduce raw object store field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The raw object store field will contain any objects needed for access to objects in a given repository. This patch introduces the raw object store and populates it with the `objectdir`, which used to be part of the repository struct. As the struct gains members, we'll also populate the function to clear the memory for these members. In a later step, we'll introduce a struct object_parser, that will complement the object parsing in a repository struct: The raw object parser is the layer that will provide access to raw object content, while the higher level object parser code will parse raw objects and keeps track of parenthood and other object relationships using 'struct object'. For now only add the lower level to the repository struct. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/grep.c | 3 ++- environment.c | 5 +++-- object-store.h | 18 ++++++++++++++++++ object.c | 14 ++++++++++++++ path.c | 3 ++- repository.c | 15 ++++++++++----- repository.h | 13 +++++-------- sha1_file.c | 4 +++- 8 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 object-store.h diff --git a/builtin/grep.c b/builtin/grep.c index 3ca4ac80d8..1e9cdbdf78 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] [...] [[--] ...]"), @@ -432,7 +433,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/environment.c b/environment.c index a5eaa97fb1..93c9fbb0ba 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 *template, const char *pattern) diff --git a/object-store.h b/object-store.h new file mode 100644 index 0000000000..abfaae059b --- /dev/null +++ b/object-store.h @@ -0,0 +1,18 @@ +#ifndef OBJECT_STORE_H +#define OBJECT_STORE_H + +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 raw_object_store *raw_object_store_new(void); +void raw_object_store_clear(struct raw_object_store *o); + +#endif /* OBJECT_STORE_H */ diff --git a/object.c b/object.c index 9e6f9ff20b..6ddd61242c 100644 --- a/object.c +++ b/object.c @@ -4,6 +4,7 @@ #include "tree.h" #include "commit.h" #include "tag.h" +#include "object-store.h" static struct object **obj_hash; static int nr_objs, obj_hash_size; @@ -445,3 +446,16 @@ 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)); + return o; +} +void raw_object_store_clear(struct raw_object_store *o) +{ + FREE_AND_NULL(o->objectdir); + FREE_AND_NULL(o->alternate_db); +} 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/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/sha1_file.c b/sha1_file.c index 4af422e3cf..af5aa83db5 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -29,6 +29,7 @@ #include "quote.h" #include "packfile.h" #include "fetch-object.h" +#include "object-store.h" const unsigned char null_sha1[GIT_MAX_RAWSZ]; const struct object_id null_oid; @@ -671,7 +672,8 @@ void prepare_alt_odb(void) return; alt_odb_tail = &alt_odb_list; - link_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0); + link_alt_odb_entries(the_repository->objects->alternate_db, + PATH_SEP, NULL, 0); read_info_alternates(get_object_directory(), 0); } From 0d4a132144a14ae6801523960cbc1939a9bab6c1 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:20:56 +0100 Subject: [PATCH 02/27] object-store: migrate alternates struct and functions from cache.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrate the struct alternate_object_database and all its related functions to the object store as these functions are easier found in that header. The migration is just a verbatim copy, no need to include the object store header at any C file, because cache.h includes repository.h which in turn includes the object-store.h Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/clone.c | 1 + builtin/count-objects.c | 1 + builtin/fsck.c | 1 + builtin/submodule--helper.c | 1 + cache.h | 51 ------------------------------------- object-store.h | 51 +++++++++++++++++++++++++++++++++++++ packfile.c | 1 + sha1_name.c | 1 + submodule.c | 1 + t/helper/test-ref-store.c | 1 + tmp-objdir.c | 1 + transport.c | 1 + 12 files changed, 61 insertions(+), 51 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 101c27a593..855947f1ab 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: diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 33343818c8..ced8958e43 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -11,6 +11,7 @@ #include "parse-options.h" #include "quote.h" #include "packfile.h" +#include "object-store.h" static unsigned long garbage; static off_t size_garbage; diff --git a/builtin/fsck.c b/builtin/fsck.c index 7a8a679d4f..b0eba4c3c9 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -16,6 +16,7 @@ #include "streaming.h" #include "decorate.h" #include "packfile.h" +#include "object-store.h" #define REACHABLE 0x0001 #define SEEN 0x0002 diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index b1daca995f..6d8e002be7 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 41ba67cc16..41530d5d16 100644 --- a/cache.h +++ b/cache.h @@ -1576,57 +1576,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; diff --git a/object-store.h b/object-store.h index abfaae059b..5002e373cd 100644 --- a/object-store.h +++ b/object-store.h @@ -1,6 +1,57 @@ #ifndef OBJECT_STORE_H #define OBJECT_STORE_H +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; +void prepare_alt_odb(void); +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 raw_object_store { /* * Path to the repository's object store. diff --git a/packfile.c b/packfile.c index 7dbe8739d1..c6651682a7 100644 --- a/packfile.c +++ b/packfile.c @@ -13,6 +13,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, diff --git a/sha1_name.c b/sha1_name.c index 611c7d24dd..434025bf03 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -10,6 +10,7 @@ #include "dir.h" #include "sha1-array.h" #include "packfile.h" +#include "object-store.h" static int get_oid_oneline(const char *, struct object_id *, struct commit_list *); diff --git a/submodule.c b/submodule.c index 47ddc9b273..b03e5f5045 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 00d48b5b56..3afc632472 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) From 031dc927f443fa5274e794c12ac34f19a0e0d318 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:20:57 +0100 Subject: [PATCH 03/27] object-store: move alt_odb_list and alt_odb_tail to object store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a process with multiple repositories open, alternates should be associated to a single repository and not shared globally. Move alt_odb_list and alt_odb_tail into the_repository and adjust callers to reflect this. Now that the alternative object data base is per repository, we're leaking its memory upon freeing a repository. The next patch plugs this hole. No functional change intended. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/fsck.c | 4 ++++ object-store.h | 7 +++++-- packfile.c | 3 ++- sha1_file.c | 25 ++++++++++++------------- sha1_name.c | 3 ++- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index b0eba4c3c9..c736a10a11 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" @@ -714,9 +715,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(); + alt_odb_list = the_repository->objects->alt_odb_list; for (alt = alt_odb_list; alt; alt = alt->next) fsck_object_dir(alt->path); diff --git a/object-store.h b/object-store.h index 5002e373cd..0b4db5867d 100644 --- a/object-store.h +++ b/object-store.h @@ -1,7 +1,7 @@ #ifndef OBJECT_STORE_H #define OBJECT_STORE_H -extern struct alternate_object_database { +struct alternate_object_database { struct alternate_object_database *next; /* see alt_scratch_buf() */ @@ -19,7 +19,7 @@ extern struct alternate_object_database { struct oid_array loose_objects_cache; char path[FLEX_ARRAY]; -} *alt_odb_list; +}; void prepare_alt_odb(void); char *compute_alternate_path(const char *path, struct strbuf *err); typedef int alt_odb_fn(struct alternate_object_database *, void *); @@ -61,6 +61,9 @@ struct raw_object_store { /* 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; }; struct raw_object_store *raw_object_store_new(void); diff --git a/packfile.c b/packfile.c index c6651682a7..fdbf240f81 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" @@ -892,7 +893,7 @@ void prepare_packed_git(void) return; prepare_packed_git_one(get_object_directory(), 1); prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) + 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(); diff --git a/sha1_file.c b/sha1_file.c index af5aa83db5..84b361c125 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" @@ -343,9 +344,6 @@ 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. */ @@ -365,7 +363,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 = the_repository->objects->alt_odb_list; alt; alt = alt->next) { if (!fspathcmp(path->buf, alt->path)) return 0; } @@ -425,8 +423,8 @@ 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); + *the_repository->objects->alt_odb_tail = ent; + the_repository->objects->alt_odb_tail = &(ent->next); ent->next = NULL; /* recursively add alternates */ @@ -560,7 +558,7 @@ 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) + if (the_repository->objects->alt_odb_tail) link_alt_odb_entries(reference, '\n', NULL, 0); } free(alts); @@ -658,7 +656,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) int r = 0; prepare_alt_odb(); - for (ent = alt_odb_list; ent; ent = ent->next) { + for (ent = the_repository->objects->alt_odb_list; ent; ent = ent->next) { r = fn(ent, cb); if (r) break; @@ -668,10 +666,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) void prepare_alt_odb(void) { - if (alt_odb_tail) + if (the_repository->objects->alt_odb_tail) return; - alt_odb_tail = &alt_odb_list; + the_repository->objects->alt_odb_tail = + &the_repository->objects->alt_odb_list; link_alt_odb_entries(the_repository->objects->alternate_db, PATH_SEP, NULL, 0); @@ -716,7 +715,7 @@ 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) { + 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; @@ -876,7 +875,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, prepare_alt_odb(); errno = ENOENT; - for (alt = alt_odb_list; alt; alt = alt->next) { + for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); if (!lstat(*path, st)) return 0; @@ -906,7 +905,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) most_interesting_errno = errno; prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) { + for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); fd = git_open(*path); if (fd >= 0) diff --git a/sha1_name.c b/sha1_name.c index 434025bf03..a22a29cda0 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -11,6 +11,7 @@ #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 *); @@ -105,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; From 97501e933a6d4d5a8567dbbb44fa3b4bff2ea298 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:20:58 +0100 Subject: [PATCH 04/27] object-store: free alt_odb_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Free the memory and reset alt_odb_{list, tail} to NULL. Signed-off-by: Stefan Beller Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- object.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/object.c b/object.c index 6ddd61242c..581347b535 100644 --- a/object.c +++ b/object.c @@ -454,8 +454,30 @@ struct raw_object_store *raw_object_store_new(void) memset(o, 0, sizeof(*o)); 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; } From a80d72db2a73174b3f22142eb2014b33696fd795 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:20:59 +0100 Subject: [PATCH 05/27] object-store: move packed_git and packed_git_mru to object store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a process with multiple repositories open, packfile accessors should be associated to a single repository and not shared globally. Move packed_git and packed_git_mru into the_repository and adjust callers to reflect this. [nd: while at there, wrap access to these two fields in get_packed_git() and get_packed_git_mru(). This allows us to lazily initialize these fields without caller doing that explicitly] Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/count-objects.c | 5 ++-- builtin/fsck.c | 6 +++-- builtin/gc.c | 4 +++- builtin/index-pack.c | 1 + builtin/pack-objects.c | 21 ++++++++++------- builtin/pack-redundant.c | 6 +++-- cache.h | 29 ----------------------- fast-import.c | 8 +++++-- http-backend.c | 6 +++-- http-push.c | 1 + http-walker.c | 1 + http.c | 1 + object-store.h | 34 +++++++++++++++++++++++++++ object.c | 7 ++++++ pack-bitmap.c | 4 +++- pack-check.c | 1 + pack-revindex.c | 1 + packfile.c | 51 ++++++++++++++++++++++++---------------- packfile.h | 3 +++ reachable.c | 1 + server-info.c | 6 +++-- sha1_name.c | 5 ++-- 22 files changed, 128 insertions(+), 74 deletions(-) diff --git a/builtin/count-objects.c b/builtin/count-objects.c index ced8958e43..b28ff00be2 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -7,6 +7,7 @@ #include "cache.h" #include "config.h" #include "dir.h" +#include "repository.h" #include "builtin.h" #include "parse-options.h" #include "quote.h" @@ -121,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/fsck.c b/builtin/fsck.c index c736a10a11..7707407275 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -732,7 +732,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; @@ -740,7 +741,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 77fa720bd0..b00238cd5d 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/index-pack.c b/builtin/index-pack.c index 5ebd370c56..1d6bc87b76 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/pack-objects.c b/builtin/pack-objects.c index 83dcbc9773..223f2d9fc0 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 [...] [< | < ]"), @@ -1025,8 +1027,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; @@ -1044,7 +1045,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; } @@ -2673,7 +2675,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; @@ -2736,7 +2738,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) && @@ -2745,7 +2748,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) @@ -2781,7 +2784,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; @@ -3152,7 +3155,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 */ @@ -3165,7 +3168,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 aaa8136322..b5b007e706 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/cache.h b/cache.h index 41530d5d16..d3429a0d48 100644 --- a/cache.h +++ b/cache.h @@ -1585,35 +1585,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/fast-import.c b/fast-import.c index b70ac025e0..b3492fce5c 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! */ @@ -1305,7 +1308,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 0913f8ab86..97fe22a705 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 07c2b1af82..d850408d18 100644 --- a/http-walker.c +++ b/http-walker.c @@ -5,6 +5,7 @@ #include "list.h" #include "transport.h" #include "packfile.h" +#include "object-store.h" struct alt_base { char *base; diff --git a/http.c b/http.c index 31755023a4..efa977112a 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; diff --git a/object-store.h b/object-store.h index 0b4db5867d..c687ab7587 100644 --- a/object-store.h +++ b/object-store.h @@ -52,6 +52,30 @@ void add_to_alternates_memory(const char *dir); */ 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. @@ -64,6 +88,16 @@ struct raw_object_store { 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; }; struct raw_object_store *raw_object_store_new(void); diff --git a/object.c b/object.c index 581347b535..04631ee841 100644 --- a/object.c +++ b/object.c @@ -452,6 +452,7 @@ 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; } @@ -480,4 +481,10 @@ void raw_object_store_clear(struct raw_object_store *o) free_alt_odbs(o); o->alt_odb_tail = NULL; + + INIT_LIST_HEAD(&o->packed_git_mru); + /* + * TODO: call close_all_packs once migrated to + * take an object store argument + */ } 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 073c1fbd46..2378f25999 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 fdbf240f81..b56ed10b68 100644 --- a/packfile.c +++ b/packfile.c @@ -46,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; } @@ -247,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); @@ -317,7 +315,7 @@ void close_all_packs(void) { struct packed_git *p; - for (p = packed_git; p; p = p->next) + for (p = the_repository->objects->packed_git; p; p = p->next) if (p->do_not_close) die("BUG: want to close pack marked 'do-not-close'"); else @@ -385,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); @@ -687,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); @@ -770,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 && @@ -821,7 +820,7 @@ unsigned long approximate_object_count(void) 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; @@ -870,18 +869,19 @@ 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; @@ -907,6 +907,16 @@ void reprepare_packed_git(void) 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) { @@ -1015,7 +1025,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; @@ -1846,13 +1856,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; } } @@ -1899,7 +1910,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) && @@ -1930,7 +1941,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 a7fca598d6..76496226bb 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. diff --git a/reachable.c b/reachable.c index 88d7d679da..25cfd99d1c 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/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_name.c b/sha1_name.c index a22a29cda0..ffff7d8710 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -197,7 +197,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); } @@ -567,7 +568,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); } From d0b59866223f7ef0dcd07bff857f651cd921bc02 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:00 +0100 Subject: [PATCH 06/27] object-store: close all packs upon clearing the object store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/am.c | 2 +- builtin/clone.c | 2 +- builtin/fetch.c | 2 +- builtin/merge.c | 2 +- builtin/receive-pack.c | 2 +- object.c | 7 +++---- packfile.c | 4 ++-- packfile.h | 2 +- 8 files changed, 11 insertions(+), 12 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 5bdd2d7578..47beddbe24 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1859,7 +1859,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 855947f1ab..7df5932b85 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1218,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/fetch.c b/builtin/fetch.c index 8ee998ea2e..a39e9d7b15 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1478,7 +1478,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/merge.c b/builtin/merge.c index 30264cfd7c..96d56cbdd2 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -411,7 +411,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/receive-pack.c b/builtin/receive-pack.c index b7ce7c7f52..1a298a6711 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -2026,7 +2026,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/object.c b/object.c index 04631ee841..4c2cf7ff5d 100644 --- a/object.c +++ b/object.c @@ -5,6 +5,7 @@ #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; @@ -483,8 +484,6 @@ void raw_object_store_clear(struct raw_object_store *o) o->alt_odb_tail = NULL; INIT_LIST_HEAD(&o->packed_git_mru); - /* - * TODO: call close_all_packs once migrated to - * take an object store argument - */ + close_all_packs(o); + o->packed_git = NULL; } diff --git a/packfile.c b/packfile.c index b56ed10b68..8b27b69bff 100644 --- a/packfile.c +++ b/packfile.c @@ -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 = the_repository->objects->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 diff --git a/packfile.h b/packfile.h index 76496226bb..5b1ce00f84 100644 --- a/packfile.h +++ b/packfile.h @@ -66,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); From 5508f69348ee1073666d3611a4a62ecdb0849e4e Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:01 +0100 Subject: [PATCH 07/27] pack: move prepare_packed_git_run_once to object store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each repository's object store can be initialized independently, so they must not share a run_once variable. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- object-store.h | 6 ++++++ packfile.c | 7 +++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/object-store.h b/object-store.h index c687ab7587..6a07a14d63 100644 --- a/object-store.h +++ b/object-store.h @@ -98,6 +98,12 @@ struct raw_object_store { struct packed_git *packed_git; /* A most-recently-used ordered version of the packed_git list. */ struct list_head packed_git_mru; + + /* + * 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); diff --git a/packfile.c b/packfile.c index 8b27b69bff..98162a0513 100644 --- a/packfile.c +++ b/packfile.c @@ -884,12 +884,11 @@ static void prepare_packed_git_mru(void) 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(); @@ -897,13 +896,13 @@ void prepare_packed_git(void) 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->packed_git_initialized = 0; prepare_packed_git(); } From 9a00580d0383fe60c70e966e66584e626ca3a846 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:02 +0100 Subject: [PATCH 08/27] pack: move approximate object count to object store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The approximate_object_count() function maintains a rough count of objects in a repository to estimate how long object name abbreviates should be. Object names are scoped to a repository and the appropriate length may differ by repository, so the object count should not be global. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- object-store.h | 8 ++++++++ packfile.c | 11 +++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/object-store.h b/object-store.h index 6a07a14d63..b53e125902 100644 --- a/object-store.h +++ b/object-store.h @@ -99,6 +99,14 @@ struct raw_object_store { /* 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. diff --git a/packfile.c b/packfile.c index 98162a0513..36922b5872 100644 --- a/packfile.c +++ b/packfile.c @@ -803,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 @@ -814,8 +812,8 @@ 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(); @@ -825,8 +823,9 @@ unsigned long approximate_object_count(void) 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) @@ -901,7 +900,7 @@ void prepare_packed_git(void) void reprepare_packed_git(void) { - approximate_object_count_valid = 0; + the_repository->objects->approximate_object_count_valid = 0; the_repository->objects->packed_git_initialized = 0; prepare_packed_git(); } From 13313fc333ef509465df6b681169e9842a99ae5d Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:03 +0100 Subject: [PATCH 09/27] sha1_file: add raw_object_store argument to alt_odb_usable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a raw_object_store to alt_odb_usable to be more specific about which repository to act on. The choice of the repository is delegated to its only caller link_alt_odb_entry. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 84b361c125..097c372d03 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -347,7 +347,9 @@ static const char *alt_sha1_path(struct alternate_object_database *alt, /* * 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; @@ -363,7 +365,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 = the_repository->objects->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; } @@ -415,7 +417,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(the_repository->objects, &pathbuf, normalized_objdir)) { strbuf_release(&pathbuf); return -1; } From cfc62fc98c0510e9ea0eeedd473411415fd33fac Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:04 +0100 Subject: [PATCH 10/27] sha1_file: add repository argument to link_alt_odb_entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a repository argument to allow the link_alt_odb_entry caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. Since the implementation does not yet work with other repositories, use a wrapper macro to enforce that the caller passes in the_repository as the first argument. It would be more appealing to use BUILD_ASSERT_OR_ZERO to enforce this, but that doesn't work because it requires a compile-time constant and common compilers like gcc 4.8.4 do not consider "r == the_repository" a compile-time constant. This and the following three patches add repository arguments to link_alt_odb_entry, read_info_alternates, link_alt_odb_entries and prepare_alt_odb. Three out of the four functions are found in a recursive call chain, calling each other, and one of them accesses the repositories `objectdir` (which was migrated; it was an obvious choice) and `ignore_env` (which we need to keep in the repository struct for clarify); hence we will pass through the repository unlike just the object store object + the ignore_env flag. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 097c372d03..7c0ace646a 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -391,8 +391,9 @@ static int alt_odb_usable(struct raw_object_store *o, * 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) +#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n) +static int link_alt_odb_entry_the_repository(const char *entry, + const char *relative_base, int depth, const char *normalized_objdir) { struct alternate_object_database *ent; struct strbuf pathbuf = STRBUF_INIT; @@ -489,7 +490,8 @@ 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(the_repository, entry.buf, + relative_base, depth, objdirbuf.buf); } strbuf_release(&entry); strbuf_release(&objdirbuf); From ca5e6d26400af12cd938d468f2c21a1c895b612f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:05 +0100 Subject: [PATCH 11/27] sha1_file: add repository argument to read_info_alternates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See previous patch for explanation. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 7c0ace646a..81ad2a84f2 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -390,7 +390,9 @@ static int alt_odb_usable(struct raw_object_store *o, * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -static void read_info_alternates(const char * relative_base, int depth); +#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d) +static void read_info_alternates_the_repository(const char *relative_base, + int depth); #define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n) static int link_alt_odb_entry_the_repository(const char *entry, const char *relative_base, int depth, const char *normalized_objdir) @@ -431,7 +433,7 @@ static int link_alt_odb_entry_the_repository(const char *entry, ent->next = NULL; /* recursively add alternates */ - read_info_alternates(pathbuf.buf, depth + 1); + read_info_alternates(the_repository, pathbuf.buf, depth + 1); strbuf_release(&pathbuf); return 0; @@ -497,7 +499,8 @@ static void link_alt_odb_entries(const char *alt, int sep, strbuf_release(&objdirbuf); } -static void read_info_alternates(const char * relative_base, int depth) +static void read_info_alternates_the_repository(const char *relative_base, + int depth) { char *path; struct strbuf buf = STRBUF_INIT; @@ -678,7 +681,7 @@ void prepare_alt_odb(void) link_alt_odb_entries(the_repository->objects->alternate_db, PATH_SEP, NULL, 0); - read_info_alternates(get_object_directory(), 0); + read_info_alternates(the_repository, get_object_directory(), 0); } /* Returns 1 if we have successfully freshened the file, 0 otherwise. */ From 93d8d1e29d635741cc1a95c337d2a51dee0dcdf1 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:06 +0100 Subject: [PATCH 12/27] sha1_file: add repository argument to link_alt_odb_entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See previous patch for explanation. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 81ad2a84f2..ba4fc9103b 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -468,8 +468,12 @@ 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) +#define link_alt_odb_entries(r, a, s, rb, d) \ + link_alt_odb_entries_##r(a, s, rb, d) +static void link_alt_odb_entries_the_repository(const char *alt, + int sep, + const char *relative_base, + int depth) { struct strbuf objdirbuf = STRBUF_INIT; struct strbuf entry = STRBUF_INIT; @@ -512,7 +516,7 @@ static void read_info_alternates_the_repository(const char *relative_base, return; } - link_alt_odb_entries(buf.buf, '\n', relative_base, depth); + link_alt_odb_entries(the_repository, buf.buf, '\n', relative_base, depth); strbuf_release(&buf); free(path); } @@ -566,7 +570,8 @@ void add_to_alternates_file(const char *reference) if (commit_lock_file(&lock)) die_errno("unable to move new alternates file into place"); if (the_repository->objects->alt_odb_tail) - link_alt_odb_entries(reference, '\n', NULL, 0); + link_alt_odb_entries(the_repository, reference, + '\n', NULL, 0); } free(alts); } @@ -579,7 +584,8 @@ void add_to_alternates_memory(const char *reference) */ prepare_alt_odb(); - link_alt_odb_entries(reference, '\n', NULL, 0); + link_alt_odb_entries(the_repository, reference, + '\n', NULL, 0); } /* @@ -678,7 +684,8 @@ void prepare_alt_odb(void) the_repository->objects->alt_odb_tail = &the_repository->objects->alt_odb_list; - link_alt_odb_entries(the_repository->objects->alternate_db, + link_alt_odb_entries(the_repository, + the_repository->objects->alternate_db, PATH_SEP, NULL, 0); read_info_alternates(the_repository, get_object_directory(), 0); From 0b2090340544caaabb378706a6ed3853dd617a6f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:07 +0100 Subject: [PATCH 13/27] sha1_file: add repository argument to prepare_alt_odb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See previous patch for explanation. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/fsck.c | 2 +- object-store.h | 3 ++- packfile.c | 2 +- sha1_file.c | 12 ++++++------ sha1_name.c | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index 7707407275..3ef25fab97 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -719,7 +719,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) 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); diff --git a/object-store.h b/object-store.h index b53e125902..79de470639 100644 --- a/object-store.h +++ b/object-store.h @@ -20,7 +20,8 @@ struct alternate_object_database { char path[FLEX_ARRAY]; }; -void prepare_alt_odb(void); +#define prepare_alt_odb(r) prepare_alt_odb_##r() +void prepare_alt_odb_the_repository(void); 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*); diff --git a/packfile.c b/packfile.c index 36922b5872..d087eacc06 100644 --- a/packfile.c +++ b/packfile.c @@ -890,7 +890,7 @@ void prepare_packed_git(void) if (the_repository->objects->packed_git_initialized) return; prepare_packed_git_one(get_object_directory(), 1); - prepare_alt_odb(); + 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(); diff --git a/sha1_file.c b/sha1_file.c index ba4fc9103b..0fac75bd31 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -582,7 +582,7 @@ 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(the_repository, reference, '\n', NULL, 0); @@ -668,7 +668,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) struct alternate_object_database *ent; int r = 0; - prepare_alt_odb(); + prepare_alt_odb(the_repository); for (ent = the_repository->objects->alt_odb_list; ent; ent = ent->next) { r = fn(ent, cb); if (r) @@ -677,7 +677,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) return r; } -void prepare_alt_odb(void) +void prepare_alt_odb_the_repository(void) { if (the_repository->objects->alt_odb_tail) return; @@ -728,7 +728,7 @@ 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(); + 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)) @@ -887,7 +887,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, if (!lstat(*path, st)) return 0; - prepare_alt_odb(); + prepare_alt_odb(the_repository); errno = ENOENT; for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); @@ -918,7 +918,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) return fd; most_interesting_errno = errno; - prepare_alt_odb(); + prepare_alt_odb(the_repository); for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); fd = git_open(*path); diff --git a/sha1_name.c b/sha1_name.c index ffff7d8710..4325f74e0c 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -354,7 +354,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; } From 77f012e876d5845856cb939c6435e839d5f9d027 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:08 +0100 Subject: [PATCH 14/27] sha1_file: allow link_alt_odb_entries to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actually this also allows read_info_alternates and link_alt_odb_entry to handle arbitrary repositories, but link_alt_odb_entries is the most interesting function in this set of functions, hence the commit subject. These functions span a strongly connected component in the function graph, i.e. the recursive call chain might look like -> link_alt_odb_entries -> link_alt_odb_entry -> read_info_alternates -> link_alt_odb_entries That is why we need to convert all these functions at the same time. Signed-off-by: Jonathan Nieder Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- object-store.h | 4 ++++ sha1_file.c | 36 ++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/object-store.h b/object-store.h index 79de470639..3fc461a463 100644 --- a/object-store.h +++ b/object-store.h @@ -18,6 +18,10 @@ struct alternate_object_database { 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]; }; #define prepare_alt_odb(r) prepare_alt_odb_##r() diff --git a/sha1_file.c b/sha1_file.c index 0fac75bd31..d38f5cdb0e 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -390,11 +390,10 @@ static int alt_odb_usable(struct raw_object_store *o, * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d) -static void read_info_alternates_the_repository(const char *relative_base, - int depth); -#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n) -static int link_alt_odb_entry_the_repository(const char *entry, +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; @@ -420,7 +419,7 @@ static int link_alt_odb_entry_the_repository(const char *entry, while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') strbuf_setlen(&pathbuf, pathbuf.len - 1); - if (!alt_odb_usable(the_repository->objects, &pathbuf, normalized_objdir)) { + if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir)) { strbuf_release(&pathbuf); return -1; } @@ -428,12 +427,12 @@ static int link_alt_odb_entry_the_repository(const char *entry, ent = alloc_alt_odb(pathbuf.buf); /* add the alternate entry */ - *the_repository->objects->alt_odb_tail = ent; - the_repository->objects->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(the_repository, pathbuf.buf, depth + 1); + read_info_alternates(r, pathbuf.buf, depth + 1); strbuf_release(&pathbuf); return 0; @@ -468,12 +467,8 @@ static const char *parse_alt_odb_entry(const char *string, return end; } -#define link_alt_odb_entries(r, a, s, rb, d) \ - link_alt_odb_entries_##r(a, s, rb, d) -static void link_alt_odb_entries_the_repository(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; @@ -487,7 +482,7 @@ static void link_alt_odb_entries_the_repository(const char *alt, 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); @@ -496,15 +491,16 @@ static void link_alt_odb_entries_the_repository(const char *alt, alt = parse_alt_odb_entry(alt, sep, &entry); if (!entry.len) continue; - link_alt_odb_entry(the_repository, entry.buf, + link_alt_odb_entry(r, entry.buf, relative_base, depth, objdirbuf.buf); } strbuf_release(&entry); strbuf_release(&objdirbuf); } -static void read_info_alternates_the_repository(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; @@ -516,7 +512,7 @@ static void read_info_alternates_the_repository(const char *relative_base, return; } - link_alt_odb_entries(the_repository, buf.buf, '\n', relative_base, depth); + link_alt_odb_entries(r, buf.buf, '\n', relative_base, depth); strbuf_release(&buf); free(path); } From 13068bf0a04c4c3cfc177f1aabc61037e319d595 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:09 +0100 Subject: [PATCH 15/27] sha1_file: allow prepare_alt_odb to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- object-store.h | 3 +-- sha1_file.c | 13 +++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/object-store.h b/object-store.h index 3fc461a463..f54bc0b951 100644 --- a/object-store.h +++ b/object-store.h @@ -24,8 +24,7 @@ struct alternate_object_database { */ char path[FLEX_ARRAY]; }; -#define prepare_alt_odb(r) prepare_alt_odb_##r() -void prepare_alt_odb_the_repository(void); +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*); diff --git a/sha1_file.c b/sha1_file.c index d38f5cdb0e..04118f331c 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -673,18 +673,15 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) return r; } -void prepare_alt_odb_the_repository(void) +void prepare_alt_odb(struct repository *r) { - if (the_repository->objects->alt_odb_tail) + if (r->objects->alt_odb_tail) return; - the_repository->objects->alt_odb_tail = - &the_repository->objects->alt_odb_list; - link_alt_odb_entries(the_repository, - the_repository->objects->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(the_repository, get_object_directory(), 0); + read_info_alternates(r, r->objects->objectdir, 0); } /* Returns 1 if we have successfully freshened the file, 0 otherwise. */ From cf78ae4f3dcd1cf509a053023cc048f34f72140e Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:10 +0100 Subject: [PATCH 16/27] sha1_file: add repository argument to sha1_file_name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a repository argument to allow sha1_file_name callers to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. While at it, move the declaration to object-store.h, where it should be easier to find. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- cache.h | 6 ------ http-walker.c | 3 ++- http.c | 5 ++--- object-store.h | 7 +++++++ sha1_file.c | 10 +++++----- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/cache.h b/cache.h index d3429a0d48..cbec0ecd23 100644 --- a/cache.h +++ b/cache.h @@ -961,12 +961,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 diff --git a/http-walker.c b/http-walker.c index d850408d18..75d55d42a9 100644 --- a/http-walker.c +++ b/http-walker.c @@ -1,4 +1,5 @@ #include "cache.h" +#include "repository.h" #include "commit.h" #include "walker.h" #include "http.h" @@ -546,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 efa977112a..4d613d5f6b 100644 --- a/http.c +++ b/http.c @@ -2247,7 +2247,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); @@ -2396,8 +2396,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 index f54bc0b951..3707f3c495 100644 --- a/object-store.h +++ b/object-store.h @@ -121,4 +121,11 @@ struct raw_object_store { 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. + */ +#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s) +void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1); + #endif /* OBJECT_STORE_H */ diff --git a/sha1_file.c b/sha1_file.c index 04118f331c..fe16d30f66 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -323,7 +323,7 @@ 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_the_repository(struct strbuf *buf, const unsigned char *sha1) { strbuf_addstr(buf, get_object_directory()); strbuf_addch(buf, '/'); @@ -713,7 +713,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); } @@ -874,7 +874,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - sha1_file_name(&buf, sha1); + sha1_file_name(the_repository, &buf, sha1); *path = buf.buf; if (!lstat(*path, st)) @@ -903,7 +903,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(the_repository, &buf, sha1); *path = buf.buf; fd = git_open(*path); @@ -1588,7 +1588,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen, static struct strbuf filename = STRBUF_INIT; strbuf_reset(&filename); - sha1_file_name(&filename, sha1); + sha1_file_name(the_repository, &filename, sha1); fd = create_tmpfile(&tmp_file, filename.buf); if (fd < 0) { From fbe33e2798fdbd7feac2d19c68e1a9c447e337c0 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:11 +0100 Subject: [PATCH 17/27] sha1_file: add repository argument to stat_sha1_file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a repository argument to allow the stat_sha1_file caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index fe16d30f66..80bac89014 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -867,8 +867,9 @@ 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) +#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p) +static int stat_sha1_file_the_repository(const unsigned char *sha1, + struct stat *st, const char **path) { struct alternate_object_database *alt; static struct strbuf buf = STRBUF_INIT; @@ -1174,7 +1175,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) { const char *path; struct stat st; - if (stat_sha1_file(sha1, &st, &path) < 0) + if (stat_sha1_file(the_repository, sha1, &st, &path) < 0) return -1; if (oi->disk_sizep) *oi->disk_sizep = st.st_size; @@ -1388,7 +1389,7 @@ void *read_sha1_file_extended(const unsigned char *sha1, die("replacement %s not found for %s", sha1_to_hex(repl), sha1_to_hex(sha1)); - if (!stat_sha1_file(repl, &st, &path)) + if (!stat_sha1_file(the_repository, repl, &st, &path)) die("loose object %s (stored in %s) is corrupt", sha1_to_hex(repl), path); From 2ba0bfd67f3a5b6b5e26436d899e7fd02b578bb6 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:12 +0100 Subject: [PATCH 18/27] sha1_file: add repository argument to open_sha1_file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a repository argument to allow the open_sha1_file caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 80bac89014..a2ab2b82c3 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -896,7 +896,9 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1, * 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) +#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p) +static int open_sha1_file_the_repository(const unsigned char *sha1, + const char **path) { int fd; struct alternate_object_database *alt; @@ -939,7 +941,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(the_repository, sha1, &path); map = NULL; if (fd >= 0) { struct stat st; From 332295d7e4292d78c92ac36e4c794ab634ab9399 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:13 +0100 Subject: [PATCH 19/27] sha1_file: add repository argument to map_sha1_file_1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a repository argument to allow the map_sha1_file_1 caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index a2ab2b82c3..4b6144b7cd 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -931,9 +931,10 @@ static int open_sha1_file_the_repository(const unsigned char *sha1, * 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) +#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si) +static void *map_sha1_file_1_the_repository(const char *path, + const unsigned char *sha1, + unsigned long *size) { void *map; int fd; @@ -962,7 +963,7 @@ static void *map_sha1_file_1(const char *path, void *map_sha1_file(const unsigned char *sha1, unsigned long *size) { - return map_sha1_file_1(NULL, sha1, size); + return map_sha1_file_1(the_repository, NULL, sha1, size); } static int unpack_sha1_short_header(git_zstream *stream, @@ -2192,7 +2193,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; From e35454fa622dc5978100ad0aa5fa85dc02aa6a43 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:14 +0100 Subject: [PATCH 20/27] sha1_file: add repository argument to map_sha1_file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a repository argument to allow map_sha1_file callers to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. While at it, move the declaration to object-store.h, where it should be easier to find. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- cache.h | 1 - object-store.h | 3 +++ sha1_file.c | 4 ++-- streaming.c | 5 ++++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cache.h b/cache.h index cbec0ecd23..720664e394 100644 --- a/cache.h +++ b/cache.h @@ -1242,7 +1242,6 @@ extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned c extern int force_object_loose(const unsigned char *sha1, 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); diff --git a/object-store.h b/object-store.h index 3707f3c495..03671745f4 100644 --- a/object-store.h +++ b/object-store.h @@ -128,4 +128,7 @@ void raw_object_store_clear(struct raw_object_store *o); #define sha1_file_name(r, b, s) sha1_file_name_##r(b, s) void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1); +#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz) +void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size); + #endif /* OBJECT_STORE_H */ diff --git a/sha1_file.c b/sha1_file.c index 4b6144b7cd..f968f67a14 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -961,7 +961,7 @@ static void *map_sha1_file_1_the_repository(const char *path, return map; } -void *map_sha1_file(const unsigned char *sha1, unsigned long *size) +void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size) { return map_sha1_file_1(the_repository, NULL, sha1, size); } @@ -1185,7 +1185,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, return 0; } - map = map_sha1_file(sha1, &mapsize); + map = map_sha1_file(the_repository, sha1, &mapsize); if (!map) return -1; diff --git a/streaming.c b/streaming.c index 5892b50bd8..22d27df55e 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(sha1, &st->u.loose.mapsize); + st->u.loose.mapped = map_sha1_file(the_repository, + sha1, &st->u.loose.mapsize); if (!st->u.loose.mapped) return -1; if ((unpack_sha1_header(&st->z, From e977fc7469d0524b31eea22431b7c6ef6616741f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:15 +0100 Subject: [PATCH 21/27] sha1_file: add repository argument to sha1_loose_object_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a repository argument to allow the sha1_loose_object_info caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index f968f67a14..74c68ea776 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1152,9 +1152,10 @@ 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) +#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f) +static int sha1_loose_object_info_the_repository(const unsigned char *sha1, + struct object_info *oi, + int flags) { int status = 0; unsigned long mapsize; @@ -1273,7 +1274,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, break; /* Most likely it's a loose object. */ - if (!sha1_loose_object_info(real, oi, flags)) + if (!sha1_loose_object_info(the_repository, real, oi, flags)) return 0; /* Not a loose object; someone else may have just packed it. */ From a68377b5dedbe7e5230901577eac9b9a00cb26b4 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:16 +0100 Subject: [PATCH 22/27] sha1_file: allow sha1_file_name to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- object-store.h | 3 +-- sha1_file.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/object-store.h b/object-store.h index 03671745f4..d9cc875153 100644 --- a/object-store.h +++ b/object-store.h @@ -125,8 +125,7 @@ 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. */ -#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s) -void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1); +void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1); #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz) void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size); diff --git a/sha1_file.c b/sha1_file.c index 74c68ea776..aed9a558c5 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -323,9 +323,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1) } } -void sha1_file_name_the_repository(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); } From d2607fa053441827446b57c17a3605840d638f15 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:17 +0100 Subject: [PATCH 23/27] sha1_file: allow stat_sha1_file to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index aed9a558c5..fc4f209981 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -867,23 +867,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. */ -#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p) -static int stat_sha1_file_the_repository(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(the_repository, &buf, sha1); + sha1_file_name(r, &buf, sha1); *path = buf.buf; if (!lstat(*path, st)) return 0; - prepare_alt_odb(the_repository); + prepare_alt_odb(r); errno = ENOENT; - for (alt = the_repository->objects->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; From ec7283e586f034404a31087c52749a6e15bb0318 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:18 +0100 Subject: [PATCH 24/27] sha1_file: allow open_sha1_file to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index fc4f209981..1fa32c8a06 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -895,9 +895,8 @@ static int stat_sha1_file(struct repository *r, const unsigned char *sha1, * Like stat_sha1_file(), but actually open the object and return the * descriptor. See the caveats on the "path" parameter above. */ -#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p) -static int open_sha1_file_the_repository(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; @@ -905,7 +904,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1, static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - sha1_file_name(the_repository, &buf, sha1); + sha1_file_name(r, &buf, sha1); *path = buf.buf; fd = git_open(*path); @@ -913,8 +912,8 @@ static int open_sha1_file_the_repository(const unsigned char *sha1, return fd; most_interesting_errno = errno; - prepare_alt_odb(the_repository); - for (alt = the_repository->objects->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) From 1fea63e1da74b875790e8f2c63119c79fc5b52a6 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Fri, 23 Mar 2018 18:21:19 +0100 Subject: [PATCH 25/27] sha1_file: allow map_sha1_file_1 to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 1fa32c8a06..1d5d23dfe2 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -929,10 +929,8 @@ static int open_sha1_file(struct repository *r, * Map the loose object at "path" if it is not NULL, or the path found by * searching for a loose object named "sha1". */ -#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si) -static void *map_sha1_file_1_the_repository(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; @@ -940,7 +938,7 @@ static void *map_sha1_file_1_the_repository(const char *path, if (path) fd = git_open(path); else - fd = open_sha1_file(the_repository, sha1, &path); + fd = open_sha1_file(r, sha1, &path); map = NULL; if (fd >= 0) { struct stat st; From bd27f50c801410433542a31122985b7d808b0a7f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 23 Mar 2018 18:21:20 +0100 Subject: [PATCH 26/27] sha1_file: allow map_sha1_file to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- object-store.h | 3 +-- sha1_file.c | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/object-store.h b/object-store.h index d9cc875153..fef33f345f 100644 --- a/object-store.h +++ b/object-store.h @@ -127,7 +127,6 @@ void raw_object_store_clear(struct raw_object_store *o); */ void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1); -#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz) -void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size); +void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size); #endif /* OBJECT_STORE_H */ diff --git a/sha1_file.c b/sha1_file.c index 1d5d23dfe2..9addad6887 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -957,9 +957,10 @@ static void *map_sha1_file_1(struct repository *r, const char *path, return map; } -void *map_sha1_file_the_repository(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(the_repository, NULL, sha1, size); + return map_sha1_file_1(r, NULL, sha1, size); } static int unpack_sha1_short_header(git_zstream *stream, From 4a7c05f7d7f17cd7a42fa944e79c2ef294cb17b6 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Fri, 23 Mar 2018 18:21:21 +0100 Subject: [PATCH 27/27] sha1_file: allow sha1_loose_object_info to handle arbitrary repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- sha1_file.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 9addad6887..0989bbd948 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1149,10 +1149,9 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep) return parse_sha1_header_extended(hdr, &oi, 0); } -#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f) -static int sha1_loose_object_info_the_repository(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; @@ -1176,14 +1175,14 @@ static int sha1_loose_object_info_the_repository(const unsigned char *sha1, if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) { const char *path; struct stat st; - if (stat_sha1_file(the_repository, 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(the_repository, sha1, &mapsize); + map = map_sha1_file(r, sha1, &mapsize); if (!map) return -1;