{"thread":{"id":"46683","subject":"[PATCH 00/39] per-repository object store, part 1","startedAt":"2017-08-30T06:47:12Z","lastAt":"2017-09-06T22:00:07Z","messageCount":46,"participants":["Jonathan Nieder","Jeff King","Brandon Williams","Junio C Hamano","Stefan Beller"],"isPatch":true,"patchVersion":1,"patchTotal":39},"messages":[{"id":"327351","messageId":"20170830064634.GA153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":null,"subject":"[PATCH 00/39] per-repository object store, part 1","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:46:34Z","receivedAt":"2017-08-30T06:47:12Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nMost of the credit for this series should go to Stefan Beller.  I just\ndecided to pull the trigger on sending out what we have so far.\n\nThis series is about API.  It makes no functional change yet.\n\nToday, when a git command wants to operate on some objects from another\nrepository (e.g., a submodule), it has two choices:\n\n A. Use run_command to operate on that repository in a separate process.\n\n B. Use add_to_alternates_memory to pretend the repository is an\n    alternate.  This has a number of downsides.  Aside from aesthetics,\n    one particularly painful consequence is that as alternates\n    accumulate, the number of packs git has to check for objects\n    increases, which can cause significant slowdowns.\n\nBrandon Williams's recent work to introduce \"struct repository\" points\nto a better way.  Encapsulating object access in struct repository\nwould mean:\n\n  i. The API for accessing objects in another repository becomes more\n     simple and familiar (instead of using the CLI or abusing alternates).\n\n  ii. Operations on one repository do not interfere with another,\n      neither in semantics (e.g. replace objects do not work correctly\n      with the approach (B) above) nor performance (already described\n      above).\n\n iii. Resources associated with access to a repository could be freed\n      when done with that repo.\n\n  iv. Thread-safe multiple readers to a single repository also become\n      straightforward, by using multiple repository objects for the same\n      repo.\n\nThis series is a small step in that direction.\n\nAt the end of this series, sha1_loose_object_info takes a repository\nargument and can be independently called for multiple repositories.\nNot incredibly useful on its own, but a future series will do the same\nfor sha1_object_info, which will be enough to migrate a caller in\nsubmodule.c (which uses the object store for commit existence checks).\n\nThis series has a few phases:\n\n 1. Patch 1 is a cleanup that made some of the later patches easier.\n\n 2. Patches 2-6 create a struct object_store field inside struct\n    repository and move some globals to it.\n\n 3. Patches 7-24 are mechanical changes that update some functions to\n    accept a repository argument. The only goal is to make the later\n    patches that teach these functions to actual handle a repository\n    other than the_repository easier to review.  The patches enforce\n    at compile time that no caller passes a repository other than\n    the_repository --- see patch 7 in particular for details on how\n    that works.\n\n 4. Patches 25-39 update the implementations of those functions to\n    handle a repository other than the_repository.  This means the\n    safety check introduced in phase 3 goes away completely --- all\n    functions that gained a repository argument are safe to use with\n    a repository argument other than the_repository.\n\nPatches 2-6 and 25-39 should be the most interesting to review.  I'd\nparticularly appreciate if people can look over 25-39 carefully.  We\nwere careful not to leave any calls to functions that assume they are\noperating on the_repository, but a triple-check is always welcome.\n\nThanks as well to brian m. carlson, who showed us how such a long and\npotentially tedius series can be made bearable for reviewers.\n\nThoughts of all kinds welcome, as always.\n\nThanks,\nJonathan Nieder (24):\n  pack: make packed_git_mru global a value instead of a pointer\n  object-store: move packed_git and packed_git_mru to object store\n    struct\n  pack: move prepare_packed_git_run_once to object store struct\n  pack: move approximate object count to object store struct\n  pack: add repository argument to install_packed_git\n  pack: add repository argument to prepare_packed_git_one\n  pack: add repository argument to rearrange_packed_git\n  pack: add repository argument to prepare_packed_git_mru\n  pack: add repository argument to prepare_packed_git\n  pack: add repository argument to reprepare_packed_git\n  pack: add repository argument to sha1_file_name\n  pack: add repository argument to map_sha1_file\n  pack: allow install_packed_git to handle arbitrary repositories\n  pack: allow rearrange_packed_git to handle arbitrary repositories\n  pack: allow prepare_packed_git_mru to handle arbitrary repositories\n  pack: allow prepare_packed_git_one to handle arbitrary repositories\n  pack: allow prepare_packed_git to handle arbitrary repositories\n  pack: allow reprepare_packed_git to handle arbitrary repositories\n  pack: allow sha1_file_name to handle arbitrary repositories\n  pack: allow stat_sha1_file to handle arbitrary repositories\n  pack: allow open_sha1_file to handle arbitrary repositories\n  pack: allow map_sha1_file_1 to handle arbitrary repositories\n  pack: allow map_sha1_file to handle arbitrary repositories\n  pack: allow sha1_loose_object_info to handle arbitrary repositories\n\nStefan Beller (15):\n  repository: introduce object store field\n  object-store: move alt_odb_list and alt_odb_tail to object store\n    struct\n  sha1_file: add repository argument to alt_odb_usable\n  sha1_file: add repository argument to link_alt_odb_entry\n  sha1_file: add repository argument to read_info_alternates\n  sha1_file: add repository argument to link_alt_odb_entries\n  sha1_file: add repository argument to stat_sha1_file\n  sha1_file: add repository argument to open_sha1_file\n  sha1_file: add repository argument to map_sha1_file_1\n  sha1_file: add repository argument to sha1_loose_object_info\n  object-store: add repository argument to prepare_alt_odb\n  object-store: add repository argument to foreach_alt_odb\n  sha1_file: allow alt_odb_usable to handle arbitrary repositories\n  object-store: allow prepare_alt_odb to handle arbitrary repositories\n  object-store: allow foreach_alt_odb to handle arbitrary repositories\n\n builtin/count-objects.c             |  10 ++-\n builtin/fsck.c                      |  15 ++--\n builtin/gc.c                        |   8 +-\n builtin/index-pack.c                |   1 +\n builtin/pack-objects.c              |  23 +++--\n builtin/pack-redundant.c            |   8 +-\n builtin/receive-pack.c              |   4 +-\n builtin/submodule--helper.c         |   4 +-\n bulk-checkin.c                      |   3 +-\n cache.h                             |  50 ++---------\n contrib/coccinelle/packed_git.cocci |  15 ++++\n fast-import.c                       |  10 ++-\n fetch-pack.c                        |   3 +-\n http-backend.c                      |   8 +-\n http-push.c                         |   1 +\n http-walker.c                       |   4 +-\n http.c                              |   9 +-\n mru.h                               |   1 +\n object-store.h                      |  71 ++++++++++++++++\n pack-bitmap.c                       |   6 +-\n pack-check.c                        |   1 +\n pack-revindex.c                     |   1 +\n packfile.c                          |  94 ++++++++++----------\n packfile.h                          |   6 +-\n reachable.c                         |   1 +\n repository.c                        |   4 +-\n repository.h                        |   7 ++\n server-info.c                       |   8 +-\n sha1_file.c                         | 165 ++++++++++++++++++++----------------\n sha1_name.c                         |  11 ++-\n streaming.c                         |   5 +-\n transport.c                         |   4 +-\n 32 files changed, 344 insertions(+), 217 deletions(-)\n create mode 100644 contrib/coccinelle/packed_git.cocci\n create mode 100644 object-store.h\n\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327352","messageId":"20170830064827.GB153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:48:27Z","receivedAt":"2017-08-30T06:48:34Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The MRU cache that keeps track of recently used packs is represented\nusing two global variables:\n\n\tstruct mru packed_git_mru_storage;\n\tstruct mru *packed_git_mru = &packed_git_mru_storage;\n\nCallers never assign to the packed_git_mru pointer, though, so we can\nsimplify by eliminating it and using &packed_git_mru_storage (renamed\nto &packed_git_mru) directly.  This variable is only used by the\npackfile subsystem, making this a relatively uninvasive change (and\nany new unadapted callers would trigger a compile error).\n\nNoticed while moving these globals to the object_store struct.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/pack-objects.c |  4 ++--\n cache.h                |  4 ++--\n packfile.c             | 12 +++++-------\n 3 files changed, 9 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 82ad6e0c81..ad53d4fa72 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -1012,7 +1012,7 @@ static int want_object_in_pack(const unsigned char *sha1,\n \t\t\treturn want;\n \t}\n \n-\tfor (entry = packed_git_mru->head; entry; entry = entry->next) {\n+\tfor (entry = packed_git_mru.head; entry; entry = entry->next) {\n \t\tstruct packed_git *p = entry->item;\n \t\toff_t offset;\n \n@@ -1030,7 +1030,7 @@ static int want_object_in_pack(const unsigned char *sha1,\n \t\t\t}\n \t\t\twant = want_found_object(exclude, p);\n \t\t\tif (!exclude && want > 0)\n-\t\t\t\tmru_mark(packed_git_mru, entry);\n+\t\t\t\tmru_mark(&packed_git_mru, entry);\n \t\t\tif (want != -1)\n \t\t\t\treturn want;\n \t\t}\ndiff --git a/cache.h b/cache.h\nindex a916bc79e3..49b083ee0a 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -4,6 +4,7 @@\n #include \"git-compat-util.h\"\n #include \"strbuf.h\"\n #include \"hashmap.h\"\n+#include \"mru.h\"\n #include \"advice.h\"\n #include \"gettext.h\"\n #include \"convert.h\"\n@@ -1589,8 +1590,7 @@ extern struct packed_git {\n  * A most-recently-used ordered version of the packed_git list, which can\n  * be iterated instead of packed_git (and marked via mru_mark).\n  */\n-struct mru;\n-extern struct mru *packed_git_mru;\n+extern struct mru packed_git_mru;\n \n struct pack_entry {\n \toff_t offset;\ndiff --git a/packfile.c b/packfile.c\nindex f86fa051c9..f69a5c8d60 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -40,9 +40,7 @@ static unsigned int pack_max_fds;\n static size_t peak_pack_mapped;\n static size_t pack_mapped;\n struct packed_git *packed_git;\n-\n-static struct mru packed_git_mru_storage;\n-struct mru *packed_git_mru = &packed_git_mru_storage;\n+struct mru packed_git_mru;\n \n #define SZ_FMT PRIuMAX\n static inline uintmax_t sz_fmt(size_t s) { return s; }\n@@ -861,9 +859,9 @@ static void prepare_packed_git_mru(void)\n {\n \tstruct packed_git *p;\n \n-\tmru_clear(packed_git_mru);\n+\tmru_clear(&packed_git_mru);\n \tfor (p = packed_git; p; p = p->next)\n-\t\tmru_append(packed_git_mru, p);\n+\t\tmru_append(&packed_git_mru, p);\n }\n \n static int prepare_packed_git_run_once = 0;\n@@ -1832,9 +1830,9 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n \tif (!packed_git)\n \t\treturn 0;\n \n-\tfor (p = packed_git_mru->head; p; p = p->next) {\n+\tfor (p = packed_git_mru.head; p; p = p->next) {\n \t\tif (fill_pack_entry(sha1, e, p->item)) {\n-\t\t\tmru_mark(packed_git_mru, p);\n+\t\t\tmru_mark(&packed_git_mru, p);\n \t\t\treturn 1;\n \t\t}\n \t}\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327353","messageId":"20170830065219.GC153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 02/39] repository: introduce object store field","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:52:19Z","receivedAt":"2017-08-30T06:52:26Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThe object store field will contain any objects needed for access to\nobjects in a given repository.\n\nThis patch introduces the object store but for now it is empty.  C99\nforbids empty structs, but common C compilers cope well with them and\nthis struct will gain members very soon (starting with the next\npatch).\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nAre there any straightforward ways to avoid the empty struct?  Should\nthe struct have a placeholder member to avoid language issues with an\nobject that would have size 0?\n\n object-store.h | 8 ++++++++\n repository.c   | 4 +++-\n repository.h   | 7 +++++++\n 3 files changed, 18 insertions(+), 1 deletion(-)\n create mode 100644 object-store.h\n\ndiff --git a/object-store.h b/object-store.h\nnew file mode 100644\nindex 0000000000..05722cdde0\n--- /dev/null\n+++ b/object-store.h\n@@ -0,0 +1,8 @@\n+#ifndef OBJECT_STORE_H\n+#define OBJECT_STORE_H\n+\n+struct object_store {\n+};\n+#define OBJECT_STORE_INIT {}\n+\n+#endif /* OBJECT_STORE_H */\ndiff --git a/repository.c b/repository.c\nindex f107af7d76..566753ed4b 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -1,11 +1,13 @@\n #include \"cache.h\"\n #include \"repository.h\"\n+#include \"object-store.h\"\n #include \"config.h\"\n #include \"submodule-config.h\"\n \n /* The main repository */\n static struct repository the_repo = {\n-\tNULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &the_index, 0, 0\n+\tNULL, NULL, NULL, OBJECT_STORE_INIT,\n+\tNULL, NULL, NULL, NULL, NULL, NULL, &the_index, 0, 0\n };\n struct repository *the_repository = &the_repo;\n \ndiff --git a/repository.h b/repository.h\nindex 7f5e24a0a2..9633ad10f5 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -1,6 +1,8 @@\n #ifndef REPOSITORY_H\n #define REPOSITORY_H\n \n+#include \"object-store.h\"\n+\n struct config_set;\n struct index_state;\n struct submodule_cache;\n@@ -25,6 +27,11 @@ struct repository {\n \t */\n \tchar *objectdir;\n \n+\t/*\n+\t * Holds any information related to the object store.\n+\t */\n+\tstruct object_store objects;\n+\n \t/*\n \t * Path to the repository's graft file.\n \t * Cannot be NULL after initialization.\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327354","messageId":"20170830065321.GD153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 03/39] object-store: move alt_odb_list and alt_odb_tail to object store","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:53:21Z","receivedAt":"2017-08-30T06:53:28Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nIn a process with multiple repositories open, alternates should be\nassociated to a single repository and not shared globally. Move\nalt_odb_list and alt_odb_tail into the_repository and adjust callers\nto reflect this.\n\nNo functional change intended.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/fsck.c |  4 +++-\n cache.h        |  4 ++--\n object-store.h |  6 +++++-\n packfile.c     |  3 ++-\n sha1_file.c    | 25 ++++++++++++-------------\n sha1_name.c    |  3 ++-\n 6 files changed, 26 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 1e4c471b41..188e32acd6 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -1,5 +1,6 @@\n #include \"builtin.h\"\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"commit.h\"\n #include \"tree.h\"\n@@ -699,7 +700,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \t\tfsck_object_dir(get_object_directory());\n \n \t\tprepare_alt_odb();\n-\t\tfor (alt = alt_odb_list; alt; alt = alt->next)\n+\t\tfor (alt = the_repository->objects.alt_odb_list;\n+\t\t\t\talt; alt = alt->next)\n \t\t\tfsck_object_dir(alt->path);\n \n \t\tif (check_full) {\ndiff --git a/cache.h b/cache.h\nindex 49b083ee0a..8d0d34f78b 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1504,7 +1504,7 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len);\n extern void schedule_dir_for_removal(const char *name, int len);\n extern void remove_scheduled_dirs(void);\n \n-extern struct alternate_object_database {\n+struct alternate_object_database {\n \tstruct alternate_object_database *next;\n \n \t/* see alt_scratch_buf() */\n@@ -1522,7 +1522,7 @@ extern struct alternate_object_database {\n \tstruct oid_array loose_objects_cache;\n \n \tchar path[FLEX_ARRAY];\n-} *alt_odb_list;\n+};\n extern void prepare_alt_odb(void);\n extern char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\ndiff --git a/object-store.h b/object-store.h\nindex 05722cdde0..ace3efbfab 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -1,8 +1,12 @@\n #ifndef OBJECT_STORE_H\n #define OBJECT_STORE_H\n \n+#include \"cache.h\"\n+\n struct object_store {\n+\tstruct alternate_object_database *alt_odb_list;\n+\tstruct alternate_object_database **alt_odb_tail;\n };\n-#define OBJECT_STORE_INIT {}\n+#define OBJECT_STORE_INIT { NULL, NULL }\n \n #endif /* OBJECT_STORE_H */\ndiff --git a/packfile.c b/packfile.c\nindex f69a5c8d60..5040c9f137 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1,6 +1,7 @@\n #include \"cache.h\"\n #include \"mru.h\"\n #include \"pack.h\"\n+#include \"repository.h\"\n #include \"dir.h\"\n #include \"mergesort.h\"\n #include \"packfile.h\"\n@@ -873,7 +874,7 @@ void prepare_packed_git(void)\n \t\treturn;\n \tprepare_packed_git_one(get_object_directory(), 1);\n \tprepare_alt_odb();\n-\tfor (alt = alt_odb_list; alt; alt = alt->next)\n+\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)\n \t\tprepare_packed_git_one(alt->path, 0);\n \trearrange_packed_git();\n \tprepare_packed_git_mru();\ndiff --git a/sha1_file.c b/sha1_file.c\nindex f56bb5cae7..7c6ffd205a 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -22,6 +22,7 @@\n #include \"pack-revindex.h\"\n #include \"sha1-lookup.h\"\n #include \"bulk-checkin.h\"\n+#include \"repository.h\"\n #include \"streaming.h\"\n #include \"dir.h\"\n #include \"mru.h\"\n@@ -276,9 +277,6 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,\n \treturn buf->buf;\n }\n \n-struct alternate_object_database *alt_odb_list;\n-static struct alternate_object_database **alt_odb_tail;\n-\n /*\n  * Return non-zero iff the path is usable as an alternate object database.\n  */\n@@ -298,7 +296,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)\n \t * Prevent the common mistake of listing the same\n \t * thing twice, or object directory itself.\n \t */\n-\tfor (alt = alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n \t\tif (!fspathcmp(path->buf, alt->path))\n \t\t\treturn 0;\n \t}\n@@ -358,8 +356,8 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,\n \tent = alloc_alt_odb(pathbuf.buf);\n \n \t/* add the alternate entry */\n-\t*alt_odb_tail = ent;\n-\talt_odb_tail = &(ent->next);\n+\t*the_repository->objects.alt_odb_tail = ent;\n+\tthe_repository->objects.alt_odb_tail = &(ent->next);\n \tent->next = NULL;\n \n \t/* recursively add alternates */\n@@ -502,7 +500,7 @@ void add_to_alternates_file(const char *reference)\n \t\tfprintf_or_die(out, \"%s\\n\", reference);\n \t\tif (commit_lock_file(lock))\n \t\t\tdie_errno(\"unable to move new alternates file into place\");\n-\t\tif (alt_odb_tail)\n+\t\tif (the_repository->objects.alt_odb_tail)\n \t\t\tlink_alt_odb_entries(reference, strlen(reference), '\\n', NULL, 0);\n \t}\n \tfree(alts);\n@@ -600,7 +598,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \tint r = 0;\n \n \tprepare_alt_odb();\n-\tfor (ent = alt_odb_list; ent; ent = ent->next) {\n+\tfor (ent = the_repository->objects.alt_odb_list; ent; ent = ent->next) {\n \t\tr = fn(ent, cb);\n \t\tif (r)\n \t\t\tbreak;\n@@ -612,13 +610,14 @@ void prepare_alt_odb(void)\n {\n \tconst char *alt;\n \n-\tif (alt_odb_tail)\n+\tif (the_repository->objects.alt_odb_tail)\n \t\treturn;\n \n \talt = getenv(ALTERNATE_DB_ENVIRONMENT);\n \tif (!alt) alt = \"\";\n \n-\talt_odb_tail = &alt_odb_list;\n+\tthe_repository->objects.alt_odb_tail =\n+\t\t\t&the_repository->objects.alt_odb_list;\n \tlink_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);\n \n \tread_info_alternates(get_object_directory(), 0);\n@@ -657,7 +656,7 @@ static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)\n {\n \tstruct alternate_object_database *alt;\n \tprepare_alt_odb();\n-\tfor (alt = alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n \t\tconst char *path = alt_sha1_path(alt, sha1);\n \t\tif (check_and_freshen_file(path, freshen))\n \t\t\treturn 1;\n@@ -813,7 +812,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,\n \n \tprepare_alt_odb();\n \terrno = ENOENT;\n-\tfor (alt = alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n \t\t*path = alt_sha1_path(alt, sha1);\n \t\tif (!lstat(*path, st))\n \t\t\treturn 0;\n@@ -839,7 +838,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)\n \tmost_interesting_errno = errno;\n \n \tprepare_alt_odb();\n-\tfor (alt = alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n \t\t*path = alt_sha1_path(alt, sha1);\n \t\tfd = git_open(*path);\n \t\tif (fd >= 0)\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 134ac9742f..5b8ce1c42c 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -10,6 +10,7 @@\n #include \"dir.h\"\n #include \"sha1-array.h\"\n #include \"packfile.h\"\n+#include \"repository.h\"\n \n static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);\n \n@@ -104,7 +105,7 @@ static void find_short_object_filename(struct disambiguate_state *ds)\n \t\t */\n \t\tfakeent = alloc_alt_odb(get_object_directory());\n \t}\n-\tfakeent->next = alt_odb_list;\n+\tfakeent->next = the_repository->objects.alt_odb_list;\n \n \tfor (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {\n \t\tint pos;\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327355","messageId":"20170830065416.GE153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 04/39] object-store: move packed_git and packed_git_mru to object store","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:54:16Z","receivedAt":"2017-08-30T06:54:25Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"In a process with multiple repositories open, packfile accessors\nshould be associated to a single repository and not shared globally.\nMove packed_git and packed_git_mru into the_repository and adjust\ncallers to reflect this.\n\nPatch generated by\n\n 1. Moving the struct packed_git declaration to object-store.h\n    and packed_git, packed_git_mru globals to struct object_store.\n\n 2. Applying the semantic patch contrib/coccinelle/packed_git.cocci\n    to adjust callers.\n\n 3. Applying line wrapping fixes from \"make style\" to break the\n    resulting long lines.\n\n 4. Adding missing #includes of repository.h and object-store.h\n    where needed.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/count-objects.c             |  6 ++++--\n builtin/fsck.c                      |  7 +++++--\n builtin/gc.c                        |  4 +++-\n builtin/index-pack.c                |  1 +\n builtin/pack-objects.c              | 21 ++++++++++++--------\n builtin/pack-redundant.c            |  6 ++++--\n builtin/receive-pack.c              |  1 +\n cache.h                             | 28 --------------------------\n contrib/coccinelle/packed_git.cocci |  7 +++++++\n fast-import.c                       |  6 ++++--\n http-backend.c                      |  6 ++++--\n http-push.c                         |  1 +\n http-walker.c                       |  1 +\n http.c                              |  1 +\n mru.h                               |  1 +\n object-store.h                      | 33 ++++++++++++++++++++++++++++++-\n pack-bitmap.c                       |  4 +++-\n pack-check.c                        |  1 +\n pack-revindex.c                     |  1 +\n packfile.c                          | 39 +++++++++++++++++++------------------\n reachable.c                         |  1 +\n server-info.c                       |  6 ++++--\n sha1_name.c                         |  3 ++-\n 23 files changed, 114 insertions(+), 71 deletions(-)\n create mode 100644 contrib/coccinelle/packed_git.cocci\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 33343818c8..9334648dcc 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -7,6 +7,8 @@\n #include \"cache.h\"\n #include \"config.h\"\n #include \"dir.h\"\n+#include \"repository.h\"\n+#include \"object-store.h\"\n #include \"builtin.h\"\n #include \"parse-options.h\"\n #include \"quote.h\"\n@@ -120,9 +122,9 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)\n \t\tstruct strbuf loose_buf = STRBUF_INIT;\n \t\tstruct strbuf pack_buf = STRBUF_INIT;\n \t\tstruct strbuf garbage_buf = STRBUF_INIT;\n-\t\tif (!packed_git)\n+\t\tif (!the_repository->objects.packed_git)\n \t\t\tprepare_packed_git();\n-\t\tfor (p = packed_git; p; p = p->next) {\n+\t\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\t\tif (!p->pack_local)\n \t\t\t\tcontinue;\n \t\t\tif (open_pack_index(p))\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 188e32acd6..20bbcdcf4a 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -2,6 +2,7 @@\n #include \"cache.h\"\n #include \"repository.h\"\n #include \"config.h\"\n+#include \"object-store.h\"\n #include \"commit.h\"\n #include \"tree.h\"\n #include \"blob.h\"\n@@ -712,7 +713,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \t\t\tprepare_packed_git();\n \n \t\t\tif (show_progress) {\n-\t\t\t\tfor (p = packed_git; p; p = p->next) {\n+\t\t\t\tfor (p = the_repository->objects.packed_git; p;\n+\t\t\t\t     p = p->next) {\n \t\t\t\t\tif (open_pack_index(p))\n \t\t\t\t\t\tcontinue;\n \t\t\t\t\ttotal += p->num_objects;\n@@ -720,7 +722,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \n \t\t\t\tprogress = start_progress(_(\"Checking objects\"), total);\n \t\t\t}\n-\t\t\tfor (p = packed_git; p; p = p->next) {\n+\t\t\tfor (p = the_repository->objects.packed_git; p;\n+\t\t\t     p = p->next) {\n \t\t\t\t/* verify gives error messages itself */\n \t\t\t\tif (verify_pack(p, fsck_obj_buffer,\n \t\t\t\t\t\tprogress, count))\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 3c78fcb9b1..73f727332c 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -11,6 +11,7 @@\n  */\n \n #include \"builtin.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"tempfile.h\"\n #include \"lockfile.h\"\n@@ -18,6 +19,7 @@\n #include \"run-command.h\"\n #include \"sigchain.h\"\n #include \"argv-array.h\"\n+#include \"object-store.h\"\n #include \"commit.h\"\n #include \"packfile.h\"\n \n@@ -173,7 +175,7 @@ static int too_many_packs(void)\n \t\treturn 0;\n \n \tprepare_packed_git();\n-\tfor (cnt = 0, p = packed_git; p; p = p->next) {\n+\tfor (cnt = 0, p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (!p->pack_local)\n \t\t\tcontinue;\n \t\tif (p->pack_keep)\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex f2be145e12..82f98b56ed 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -12,6 +12,7 @@\n #include \"exec_cmd.h\"\n #include \"streaming.h\"\n #include \"thread-utils.h\"\n+#include \"object-store.h\"\n #include \"packfile.h\"\n \n static const char index_pack_usage[] =\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex ad53d4fa72..b135fb3fb9 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -1,6 +1,8 @@\n #include \"builtin.h\"\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n+#include \"object-store.h\"\n #include \"attr.h\"\n #include \"object.h\"\n #include \"blob.h\"\n@@ -1012,7 +1014,8 @@ static int want_object_in_pack(const unsigned char *sha1,\n \t\t\treturn want;\n \t}\n \n-\tfor (entry = packed_git_mru.head; entry; entry = entry->next) {\n+\tfor (entry = the_repository->objects.packed_git_mru.head; entry;\n+\t     entry = entry->next) {\n \t\tstruct packed_git *p = entry->item;\n \t\toff_t offset;\n \n@@ -1030,7 +1033,8 @@ static int want_object_in_pack(const unsigned char *sha1,\n \t\t\t}\n \t\t\twant = want_found_object(exclude, p);\n \t\t\tif (!exclude && want > 0)\n-\t\t\t\tmru_mark(&packed_git_mru, entry);\n+\t\t\t\tmru_mark(&the_repository->objects.packed_git_mru,\n+\t\t\t\t\t entry);\n \t\t\tif (want != -1)\n \t\t\t\treturn want;\n \t\t}\n@@ -2594,7 +2598,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)\n \n \tmemset(&in_pack, 0, sizeof(in_pack));\n \n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tconst unsigned char *sha1;\n \t\tstruct object *o;\n \n@@ -2657,7 +2661,8 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)\n \tstatic struct packed_git *last_found = (void *)1;\n \tstruct packed_git *p;\n \n-\tp = (last_found != (void *)1) ? last_found : packed_git;\n+\tp = (last_found != (void *)1) ? last_found :\n+\t\t\t\t\tthe_repository->objects.packed_git;\n \n \twhile (p) {\n \t\tif ((!p->pack_local || p->pack_keep) &&\n@@ -2666,7 +2671,7 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)\n \t\t\treturn 1;\n \t\t}\n \t\tif (p == last_found)\n-\t\t\tp = packed_git;\n+\t\t\tp = the_repository->objects.packed_git;\n \t\telse\n \t\t\tp = p->next;\n \t\tif (p == last_found)\n@@ -2702,7 +2707,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)\n \tuint32_t i;\n \tstruct object_id oid;\n \n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (!p->pack_local || p->pack_keep)\n \t\t\tcontinue;\n \n@@ -3050,7 +3055,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)\n \tprepare_packed_git();\n \tif (ignore_packed_keep) {\n \t\tstruct packed_git *p;\n-\t\tfor (p = packed_git; p; p = p->next)\n+\t\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n \t\t\tif (p->pack_local && p->pack_keep)\n \t\t\t\tbreak;\n \t\tif (!p) /* no keep-able packs found */\n@@ -3063,7 +3068,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)\n \t\t * also covers non-local objects\n \t\t */\n \t\tstruct packed_git *p;\n-\t\tfor (p = packed_git; p; p = p->next) {\n+\t\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\t\tif (!p->pack_local) {\n \t\t\t\thave_non_local_packs = 1;\n \t\t\t\tbreak;\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex aaa8136322..55462bc826 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -7,6 +7,8 @@\n */\n \n #include \"builtin.h\"\n+#include \"repository.h\"\n+#include \"object-store.h\"\n #include \"packfile.h\"\n \n #define BLKSIZE 512\n@@ -571,7 +573,7 @@ static struct pack_list * add_pack(struct packed_git *p)\n \n static struct pack_list * add_pack_file(const char *filename)\n {\n-\tstruct packed_git *p = packed_git;\n+\tstruct packed_git *p = the_repository->objects.packed_git;\n \n \tif (strlen(filename) < 40)\n \t\tdie(\"Bad pack filename: %s\", filename);\n@@ -586,7 +588,7 @@ static struct pack_list * add_pack_file(const char *filename)\n \n static void load_all(void)\n {\n-\tstruct packed_git *p = packed_git;\n+\tstruct packed_git *p = the_repository->objects.packed_git;\n \n \twhile (p) {\n \t\tadd_pack(p);\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 52c63ebfdc..6657ba1375 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -7,6 +7,7 @@\n #include \"sideband.h\"\n #include \"run-command.h\"\n #include \"exec_cmd.h\"\n+#include \"object-store.h\"\n #include \"commit.h\"\n #include \"object.h\"\n #include \"remote.h\"\ndiff --git a/cache.h b/cache.h\nindex 8d0d34f78b..cd59c2fdb7 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1564,34 +1564,6 @@ struct pack_window {\n \tunsigned int inuse_cnt;\n };\n \n-extern struct packed_git {\n-\tstruct packed_git *next;\n-\tstruct pack_window *windows;\n-\toff_t pack_size;\n-\tconst void *index_data;\n-\tsize_t index_size;\n-\tuint32_t num_objects;\n-\tuint32_t num_bad_objects;\n-\tunsigned char *bad_object_sha1;\n-\tint index_version;\n-\ttime_t mtime;\n-\tint pack_fd;\n-\tunsigned pack_local:1,\n-\t\t pack_keep:1,\n-\t\t freshened:1,\n-\t\t do_not_close:1;\n-\tunsigned char sha1[20];\n-\tstruct revindex_entry *revindex;\n-\t/* something like \".git/objects/pack/xxxxx.pack\" */\n-\tchar pack_name[FLEX_ARRAY]; /* more */\n-} *packed_git;\n-\n-/*\n- * A most-recently-used ordered version of the packed_git list, which can\n- * be iterated instead of packed_git (and marked via mru_mark).\n- */\n-extern struct mru packed_git_mru;\n-\n struct pack_entry {\n \toff_t offset;\n \tunsigned char sha1[20];\ndiff --git a/contrib/coccinelle/packed_git.cocci b/contrib/coccinelle/packed_git.cocci\nnew file mode 100644\nindex 0000000000..da317a51a9\n--- /dev/null\n+++ b/contrib/coccinelle/packed_git.cocci\n@@ -0,0 +1,7 @@\n+@@ @@\n+- packed_git\n++ the_repository->objects.packed_git\n+\n+@@ @@\n+- packed_git_mru\n++ the_repository->objects.packed_git_mru\ndiff --git a/fast-import.c b/fast-import.c\nindex 49516d60e6..9a725ebf4f 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -154,8 +154,10 @@ Format of STDIN stream:\n \n #include \"builtin.h\"\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n+#include \"object-store.h\"\n #include \"object.h\"\n #include \"blob.h\"\n #include \"tree.h\"\n@@ -1110,7 +1112,7 @@ static int store_object(\n \tif (e->idx.offset) {\n \t\tduplicate_count_by_type[type]++;\n \t\treturn 1;\n-\t} else if (find_sha1_pack(oid.hash, packed_git)) {\n+\t} else if (find_sha1_pack(oid.hash, the_repository->objects.packed_git)) {\n \t\te->type = type;\n \t\te->pack_id = MAX_PACK_ID;\n \t\te->idx.offset = 1; /* just not zero! */\n@@ -1305,7 +1307,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)\n \t\tduplicate_count_by_type[OBJ_BLOB]++;\n \t\ttruncate_pack(&checkpoint);\n \n-\t} else if (find_sha1_pack(oid.hash, packed_git)) {\n+\t} else if (find_sha1_pack(oid.hash, the_repository->objects.packed_git)) {\n \t\te->type = OBJ_BLOB;\n \t\te->pack_id = MAX_PACK_ID;\n \t\te->idx.offset = 1; /* just not zero! */\ndiff --git a/http-backend.c b/http-backend.c\nindex 8076b1d5e5..681515aefd 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -1,7 +1,9 @@\n #include \"cache.h\"\n #include \"config.h\"\n+#include \"repository.h\"\n #include \"refs.h\"\n #include \"pkt-line.h\"\n+#include \"object-store.h\"\n #include \"object.h\"\n #include \"tag.h\"\n #include \"exec_cmd.h\"\n@@ -519,13 +521,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg)\n \n \tselect_getanyfile(hdr);\n \tprepare_packed_git();\n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (p->pack_local)\n \t\t\tcnt++;\n \t}\n \n \tstrbuf_grow(&buf, cnt * 53 + 2);\n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (p->pack_local)\n \t\t\tstrbuf_addf(&buf, \"P %s\\n\", p->pack_name + objdirlen + 6);\n \t}\ndiff --git a/http-push.c b/http-push.c\nindex e4c9b065ce..dfd83c4769 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1,4 +1,5 @@\n #include \"cache.h\"\n+#include \"object-store.h\"\n #include \"commit.h\"\n #include \"tag.h\"\n #include \"blob.h\"\ndiff --git a/http-walker.c b/http-walker.c\nindex 1ae8363de2..a1c6f2639b 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -4,6 +4,7 @@\n #include \"http.h\"\n #include \"list.h\"\n #include \"transport.h\"\n+#include \"object-store.h\"\n #include \"packfile.h\"\n \n struct alt_base {\ndiff --git a/http.c b/http.c\nindex 9e40a465fd..3186de107b 100644\n--- a/http.c\n+++ b/http.c\n@@ -1,6 +1,7 @@\n #include \"git-compat-util.h\"\n #include \"http.h\"\n #include \"config.h\"\n+#include \"object-store.h\"\n #include \"pack.h\"\n #include \"sideband.h\"\n #include \"run-command.h\"\ndiff --git a/mru.h b/mru.h\nindex 42e4aeaa10..d7de81efb9 100644\n--- a/mru.h\n+++ b/mru.h\n@@ -37,6 +37,7 @@ struct mru_entry {\n struct mru {\n \tstruct mru_entry *head, *tail;\n };\n+#define MRU_INIT { NULL, NULL }\n \n void mru_append(struct mru *mru, void *item);\n void mru_mark(struct mru *mru, struct mru_entry *entry);\ndiff --git a/object-store.h b/object-store.h\nindex ace3efbfab..e2a59a0611 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -2,11 +2,42 @@\n #define OBJECT_STORE_H\n \n #include \"cache.h\"\n+#include \"mru.h\"\n \n struct object_store {\n+\tstruct packed_git *packed_git;\n+\n+\t/*\n+\t * A most-recently-used ordered version of the packed_git list, which can\n+\t * be iterated instead of packed_git (and marked via mru_mark).\n+\t */\n+\tstruct mru packed_git_mru;\n+\n \tstruct alternate_object_database *alt_odb_list;\n \tstruct alternate_object_database **alt_odb_tail;\n };\n-#define OBJECT_STORE_INIT { NULL, NULL }\n+#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL }\n+\n+struct packed_git {\n+\tstruct packed_git *next;\n+\tstruct pack_window *windows;\n+\toff_t pack_size;\n+\tconst void *index_data;\n+\tsize_t index_size;\n+\tuint32_t num_objects;\n+\tuint32_t num_bad_objects;\n+\tunsigned char *bad_object_sha1;\n+\tint index_version;\n+\ttime_t mtime;\n+\tint pack_fd;\n+\tunsigned pack_local:1,\n+\t\t pack_keep:1,\n+\t\t freshened:1,\n+\t\t do_not_close:1;\n+\tunsigned char sha1[20];\n+\tstruct revindex_entry *revindex;\n+\t/* something like \".git/objects/pack/xxxxx.pack\" */\n+\tchar pack_name[FLEX_ARRAY]; /* more */\n+};\n \n #endif /* OBJECT_STORE_H */\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex cb3d14ba45..396abb75bd 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -5,11 +5,13 @@\n #include \"revision.h\"\n #include \"progress.h\"\n #include \"list-objects.h\"\n+#include \"object-store.h\"\n #include \"pack.h\"\n #include \"pack-bitmap.h\"\n #include \"pack-revindex.h\"\n #include \"pack-objects.h\"\n #include \"packfile.h\"\n+#include \"repository.h\"\n \n /*\n  * An entry on the bitmap index, representing the bitmap for a given\n@@ -335,7 +337,7 @@ static int open_pack_bitmap(void)\n \tassert(!bitmap_git.map && !bitmap_git.loaded);\n \n \tprepare_packed_git();\n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (open_pack_bitmap_1(p) == 0)\n \t\t\tret = 0;\n \t}\ndiff --git a/pack-check.c b/pack-check.c\nindex 073c1fbd46..c80c3ed8fd 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"pack.h\"\n+#include \"object-store.h\"\n #include \"pack-revindex.h\"\n #include \"progress.h\"\n #include \"packfile.h\"\ndiff --git a/pack-revindex.c b/pack-revindex.c\nindex 1b7ebd8d7e..82c3119652 100644\n--- a/pack-revindex.c\n+++ b/pack-revindex.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"pack-revindex.h\"\n+#include \"object-store.h\"\n \n /*\n  * Pack index for existing packs give us easy access to the offsets into\ndiff --git a/packfile.c b/packfile.c\nindex 5040c9f137..57260a9b34 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -7,6 +7,7 @@\n #include \"packfile.h\"\n #include \"delta.h\"\n #include \"list.h\"\n+#include \"object-store.h\"\n #include \"streaming.h\"\n #include \"sha1-lookup.h\"\n \n@@ -40,8 +41,6 @@ static unsigned int pack_open_fds;\n static unsigned int pack_max_fds;\n static size_t peak_pack_mapped;\n static size_t pack_mapped;\n-struct packed_git *packed_git;\n-struct mru packed_git_mru;\n \n #define SZ_FMT PRIuMAX\n static inline uintmax_t sz_fmt(size_t s) { return s; }\n@@ -241,7 +240,7 @@ static int unuse_one_window(struct packed_git *current)\n \n \tif (current)\n \t\tscan_windows(current, &lru_p, &lru_w, &lru_l);\n-\tfor (p = packed_git; p; p = p->next)\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n \t\tscan_windows(p, &lru_p, &lru_w, &lru_l);\n \tif (lru_p) {\n \t\tmunmap(lru_w->base, lru_w->len);\n@@ -311,7 +310,7 @@ void close_all_packs(void)\n {\n \tstruct packed_git *p;\n \n-\tfor (p = packed_git; p; p = p->next)\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n \t\tif (p->do_not_close)\n \t\t\tdie(\"BUG: want to close pack marked 'do-not-close'\");\n \t\telse\n@@ -379,7 +378,7 @@ static int close_one_pack(void)\n \tstruct pack_window *mru_w = NULL;\n \tint accept_windows_inuse = 1;\n \n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (p->pack_fd == -1)\n \t\t\tcontinue;\n \t\tfind_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);\n@@ -670,8 +669,8 @@ void install_packed_git(struct packed_git *pack)\n \tif (pack->pack_fd != -1)\n \t\tpack_open_fds++;\n \n-\tpack->next = packed_git;\n-\tpacked_git = pack;\n+\tpack->next = the_repository->objects.packed_git;\n+\tthe_repository->objects.packed_git = pack;\n }\n \n void (*report_garbage)(unsigned seen_bits, const char *path);\n@@ -753,7 +752,8 @@ static void prepare_packed_git_one(char *objdir, int local)\n \t\tbase_len = path.len;\n \t\tif (strip_suffix_mem(path.buf, &base_len, \".idx\")) {\n \t\t\t/* Don't reopen a pack we already have. */\n-\t\t\tfor (p = packed_git; p; p = p->next) {\n+\t\t\tfor (p = the_repository->objects.packed_git; p;\n+\t\t\t     p = p->next) {\n \t\t\t\tsize_t len;\n \t\t\t\tif (strip_suffix(p->pack_name, \".pack\", &len) &&\n \t\t\t\t    len == base_len &&\n@@ -803,7 +803,7 @@ unsigned long approximate_object_count(void)\n \n \t\tprepare_packed_git();\n \t\tcount = 0;\n-\t\tfor (p = packed_git; p; p = p->next) {\n+\t\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\t\tif (open_pack_index(p))\n \t\t\t\tcontinue;\n \t\t\tcount += p->num_objects;\n@@ -852,17 +852,18 @@ static int sort_pack(const void *a_, const void *b_)\n \n static void rearrange_packed_git(void)\n {\n-\tpacked_git = llist_mergesort(packed_git, get_next_packed_git,\n-\t\t\t\t     set_next_packed_git, sort_pack);\n+\tthe_repository->objects.packed_git = llist_mergesort(\n+\t\tthe_repository->objects.packed_git, get_next_packed_git,\n+\t\tset_next_packed_git, sort_pack);\n }\n \n static void prepare_packed_git_mru(void)\n {\n \tstruct packed_git *p;\n \n-\tmru_clear(&packed_git_mru);\n-\tfor (p = packed_git; p; p = p->next)\n-\t\tmru_append(&packed_git_mru, p);\n+\tmru_clear(&the_repository->objects.packed_git_mru);\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n+\t\tmru_append(&the_repository->objects.packed_git_mru, p);\n }\n \n static int prepare_packed_git_run_once = 0;\n@@ -996,7 +997,7 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1)\n \tstruct packed_git *p;\n \tunsigned i;\n \n-\tfor (p = packed_git; p; p = p->next)\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n \t\tfor (i = 0; i < p->num_bad_objects; i++)\n \t\t\tif (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))\n \t\t\t\treturn p;\n@@ -1828,12 +1829,12 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n \tstruct mru_entry *p;\n \n \tprepare_packed_git();\n-\tif (!packed_git)\n+\tif (!the_repository->objects.packed_git)\n \t\treturn 0;\n \n-\tfor (p = packed_git_mru.head; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git_mru.head; p; p = p->next) {\n \t\tif (fill_pack_entry(sha1, e, p->item)) {\n-\t\t\tmru_mark(&packed_git_mru, p);\n+\t\t\tmru_mark(&the_repository->objects.packed_git_mru, p);\n \t\t\treturn 1;\n \t\t}\n \t}\n@@ -1880,7 +1881,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)\n \tint pack_errors = 0;\n \n \tprepare_packed_git();\n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)\n \t\t\tcontinue;\n \t\tif (open_pack_index(p)) {\ndiff --git a/reachable.c b/reachable.c\nindex d1ac5d97ef..efd1224f97 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"refs.h\"\n+#include \"object-store.h\"\n #include \"tag.h\"\n #include \"commit.h\"\n #include \"blob.h\"\ndiff --git a/server-info.c b/server-info.c\nindex 26a6c20b7d..96885c45f6 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -1,5 +1,7 @@\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"refs.h\"\n+#include \"object-store.h\"\n #include \"object.h\"\n #include \"commit.h\"\n #include \"tag.h\"\n@@ -200,7 +202,7 @@ static void init_pack_info(const char *infofile, int force)\n \tobjdirlen = strlen(objdir);\n \n \tprepare_packed_git();\n-\tfor (p = packed_git; p; p = p->next) {\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\t/* we ignore things on alternate path since they are\n \t\t * not available to the pullers in general.\n \t\t */\n@@ -210,7 +212,7 @@ static void init_pack_info(const char *infofile, int force)\n \t}\n \tnum_pack = i;\n \tinfo = xcalloc(num_pack, sizeof(struct pack_info *));\n-\tfor (i = 0, p = packed_git; p; p = p->next) {\n+\tfor (i = 0, p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (!p->pack_local)\n \t\t\tcontinue;\n \t\tinfo[i] = xcalloc(1, sizeof(struct pack_info));\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 5b8ce1c42c..153bcd83b9 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -194,7 +194,8 @@ static void find_short_packed_object(struct disambiguate_state *ds)\n \tstruct packed_git *p;\n \n \tprepare_packed_git();\n-\tfor (p = packed_git; p && !ds->ambiguous; p = p->next)\n+\tfor (p = the_repository->objects.packed_git; p && !ds->ambiguous;\n+\t     p = p->next)\n \t\tunique_in_pack(p, ds);\n }\n \n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327356","messageId":"20170830065453.GF153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 05/39] pack: move prepare_packed_git_run_once to object store","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:54:53Z","receivedAt":"2017-08-30T06:55:00Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Each repository's object store can be initialized independently, so\nthey must not share a run_once variable.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n object-store.h | 8 +++++++-\n packfile.c     | 7 +++----\n 2 files changed, 10 insertions(+), 5 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex e2a59a0611..14129fbba1 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -15,8 +15,14 @@ struct object_store {\n \n \tstruct alternate_object_database *alt_odb_list;\n \tstruct alternate_object_database **alt_odb_tail;\n+\n+\t/*\n+\t * Whether packed_git has already been populated with this repository's\n+\t * packs.\n+\t */\n+\tunsigned packed_git_initialized : 1;\n };\n-#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL }\n+#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL, 0 }\n \n struct packed_git {\n \tstruct packed_git *next;\ndiff --git a/packfile.c b/packfile.c\nindex 57260a9b34..c54fe0ac1c 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -866,12 +866,11 @@ static void prepare_packed_git_mru(void)\n \t\tmru_append(&the_repository->objects.packed_git_mru, p);\n }\n \n-static int prepare_packed_git_run_once = 0;\n void prepare_packed_git(void)\n {\n \tstruct alternate_object_database *alt;\n \n-\tif (prepare_packed_git_run_once)\n+\tif (the_repository->objects.packed_git_initialized)\n \t\treturn;\n \tprepare_packed_git_one(get_object_directory(), 1);\n \tprepare_alt_odb();\n@@ -879,13 +878,13 @@ void prepare_packed_git(void)\n \t\tprepare_packed_git_one(alt->path, 0);\n \trearrange_packed_git();\n \tprepare_packed_git_mru();\n-\tprepare_packed_git_run_once = 1;\n+\tthe_repository->objects.packed_git_initialized = 1;\n }\n \n void reprepare_packed_git(void)\n {\n \tapproximate_object_count_valid = 0;\n-\tprepare_packed_git_run_once = 0;\n+\tthe_repository->objects.packed_git_initialized = 0;\n \tprepare_packed_git();\n }\n \n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327358","messageId":"20170830065550.GG153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 06/39] pack: move approximate object count to object store","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:55:50Z","receivedAt":"2017-08-30T06:55:57Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The approximate_object_count() function maintains a rough count of\nobjects in a repository to estimate how long object name abbreviates\nshould be.  Object names are scoped to a repository and the\nappropriate length may differ by repository, so the object count\nshould not be global.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n object-store.h | 10 +++++++++-\n packfile.c     | 11 +++++------\n 2 files changed, 14 insertions(+), 7 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 14129fbba1..99f77d10cd 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -16,13 +16,21 @@ struct object_store {\n \tstruct alternate_object_database *alt_odb_list;\n \tstruct alternate_object_database **alt_odb_tail;\n \n+\t/*\n+\t * A fast, rough count of the number of objects in the repository.\n+\t * These two fields are not meant for direct access. Use\n+\t * approximate_object_count() instead.\n+\t */\n+\tunsigned long approximate_object_count;\n+\tunsigned approximate_object_count_valid : 1;\n+\n \t/*\n \t * Whether packed_git has already been populated with this repository's\n \t * packs.\n \t */\n \tunsigned packed_git_initialized : 1;\n };\n-#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL, 0 }\n+#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL, 0, 0, 0 }\n \n struct packed_git {\n \tstruct packed_git *next;\ndiff --git a/packfile.c b/packfile.c\nindex c54fe0ac1c..98267f014f 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -786,8 +786,6 @@ static void prepare_packed_git_one(char *objdir, int local)\n \tstrbuf_release(&path);\n }\n \n-static int approximate_object_count_valid;\n-\n /*\n  * Give a fast, rough count of the number of objects in the repository. This\n  * ignores loose objects completely. If you have a lot of them, then either\n@@ -797,8 +795,8 @@ static int approximate_object_count_valid;\n  */\n unsigned long approximate_object_count(void)\n {\n-\tstatic unsigned long count;\n-\tif (!approximate_object_count_valid) {\n+\tif (!the_repository->objects.approximate_object_count_valid) {\n+\t\tunsigned long count;\n \t\tstruct packed_git *p;\n \n \t\tprepare_packed_git();\n@@ -808,8 +806,9 @@ unsigned long approximate_object_count(void)\n \t\t\t\tcontinue;\n \t\t\tcount += p->num_objects;\n \t\t}\n+\t\tthe_repository->objects.approximate_object_count = count;\n \t}\n-\treturn count;\n+\treturn the_repository->objects.approximate_object_count;\n }\n \n static void *get_next_packed_git(const void *p)\n@@ -883,7 +882,7 @@ void prepare_packed_git(void)\n \n void reprepare_packed_git(void)\n {\n-\tapproximate_object_count_valid = 0;\n+\tthe_repository->objects.approximate_object_count_valid = 0;\n \tthe_repository->objects.packed_git_initialized = 0;\n \tprepare_packed_git();\n }\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327359","messageId":"20170830065631.GH153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 07/39] sha1_file: add repository argument to alt_odb_usable","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:56:31Z","receivedAt":"2017-08-30T06:56:38Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the alt_odb_usable caller to be\nmore specific about which repository to act on. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nSince the implementation does not yet work with other repositories,\nuse a wrapper macro to enforce that the caller passes in\nthe_repository as the first argument. It would be more appealing to\nuse BUILD_ASSERT_OR_ZERO to enforce this, but that doesn't work\nbecause it requires a compile-time constant and common compilers like\ngcc 4.8.4 do not consider \"r == the_repository\" a compile-time\nconstant.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 7c6ffd205a..1c757b44a3 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -280,7 +280,9 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,\n /*\n  * Return non-zero iff the path is usable as an alternate object database.\n  */\n-static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)\n+#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)\n+static int alt_odb_usable_the_repository(struct strbuf *path,\n+\t\t\t\t\t const char *normalized_objdir)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -348,7 +350,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,\n \twhile (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')\n \t\tstrbuf_setlen(&pathbuf, pathbuf.len - 1);\n \n-\tif (!alt_odb_usable(&pathbuf, normalized_objdir)) {\n+\tif (!alt_odb_usable(the_repository, &pathbuf, normalized_objdir)) {\n \t\tstrbuf_release(&pathbuf);\n \t\treturn -1;\n \t}\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327360","messageId":"20170830065717.GI153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 08/39] sha1_file: add repository argument to link_alt_odb_entry","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:57:17Z","receivedAt":"2017-08-30T06:57:25Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the link_alt_odb_entry caller to be\nmore specific about which repository to act on. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commit, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 8 +++++---\n 1 file changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 1c757b44a3..c63b52f6fa 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -324,8 +324,9 @@ static int alt_odb_usable_the_repository(struct strbuf *path,\n  * terminating NUL.\n  */\n static void read_info_alternates(const char * relative_base, int depth);\n-static int link_alt_odb_entry(const char *entry, const char *relative_base,\n-\tint depth, const char *normalized_objdir)\n+#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n)\n+static int link_alt_odb_entry_the_repository(const char *entry,\n+\tconst char *relative_base, int depth, const char *normalized_objdir)\n {\n \tstruct alternate_object_database *ent;\n \tstruct strbuf pathbuf = STRBUF_INIT;\n@@ -419,7 +420,8 @@ static void link_alt_odb_entries(const char *alt, int len, int sep,\n \t\talt = parse_alt_odb_entry(alt, sep, &entry);\n \t\tif (!entry.len)\n \t\t\tcontinue;\n-\t\tlink_alt_odb_entry(entry.buf, relative_base, depth, objdirbuf.buf);\n+\t\tlink_alt_odb_entry(the_repository, entry.buf,\n+\t\t\t\t   relative_base, depth, objdirbuf.buf);\n \t}\n \tstrbuf_release(&entry);\n \tstrbuf_release(&objdirbuf);\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327361","messageId":"20170830065802.GJ153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 09/39] sha1_file: add repository argument to read_info_alternates","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:58:02Z","receivedAt":"2017-08-30T06:58:09Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the read_info_alternates caller to\nbe more specific about which repository to read from. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commit, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 11 +++++++----\n 1 file changed, 7 insertions(+), 4 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex c63b52f6fa..29cead6d2c 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -323,7 +323,9 @@ static int alt_odb_usable_the_repository(struct strbuf *path,\n  * SHA1, an extra slash for the first level indirection, and the\n  * terminating NUL.\n  */\n-static void read_info_alternates(const char * relative_base, int depth);\n+#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d)\n+static void read_info_alternates_the_repository(const char *relative_base,\n+\t\t\t\t\t\tint depth);\n #define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n)\n static int link_alt_odb_entry_the_repository(const char *entry,\n \tconst char *relative_base, int depth, const char *normalized_objdir)\n@@ -364,7 +366,7 @@ static int link_alt_odb_entry_the_repository(const char *entry,\n \tent->next = NULL;\n \n \t/* recursively add alternates */\n-\tread_info_alternates(pathbuf.buf, depth + 1);\n+\tread_info_alternates(the_repository, pathbuf.buf, depth + 1);\n \n \tstrbuf_release(&pathbuf);\n \treturn 0;\n@@ -427,7 +429,8 @@ static void link_alt_odb_entries(const char *alt, int len, int sep,\n \tstrbuf_release(&objdirbuf);\n }\n \n-static void read_info_alternates(const char * relative_base, int depth)\n+static void read_info_alternates_the_repository(const char *relative_base,\n+\t\t\t\t\t\tint depth)\n {\n \tchar *map;\n \tsize_t mapsz;\n@@ -624,7 +627,7 @@ void prepare_alt_odb(void)\n \t\t\t&the_repository->objects.alt_odb_list;\n \tlink_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);\n \n-\tread_info_alternates(get_object_directory(), 0);\n+\tread_info_alternates(the_repository, get_object_directory(), 0);\n }\n \n /* Returns 1 if we have successfully freshened the file, 0 otherwise. */\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327362","messageId":"20170830065841.GK153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 10/39] sha1_file: add repository argument to link_alt_odb_entries","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:58:41Z","receivedAt":"2017-08-30T06:58:48Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the link_alt_odb_entries caller to\nbe more specific about which repository to act on. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 19 +++++++++++++------\n 1 file changed, 13 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 29cead6d2c..7938bd2a6f 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -401,8 +401,12 @@ static const char *parse_alt_odb_entry(const char *string,\n \treturn end;\n }\n \n-static void link_alt_odb_entries(const char *alt, int len, int sep,\n-\t\t\t\t const char *relative_base, int depth)\n+#define link_alt_odb_entries(r, a, l, s, rb, d) \\\n+\tlink_alt_odb_entries_##r(a, l, s, rb, d)\n+static void link_alt_odb_entries_the_repository(const char *alt, int len,\n+\t\t\t\t\t\tint sep,\n+\t\t\t\t\t\tconst char *relative_base,\n+\t\t\t\t\t\tint depth)\n {\n \tstruct strbuf objdirbuf = STRBUF_INIT;\n \tstruct strbuf entry = STRBUF_INIT;\n@@ -451,7 +455,7 @@ static void read_info_alternates_the_repository(const char *relative_base,\n \tmap = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);\n \tclose(fd);\n \n-\tlink_alt_odb_entries(map, mapsz, '\\n', relative_base, depth);\n+\tlink_alt_odb_entries(the_repository, map, mapsz, '\\n', relative_base, depth);\n \n \tmunmap(map, mapsz);\n }\n@@ -508,7 +512,8 @@ void add_to_alternates_file(const char *reference)\n \t\tif (commit_lock_file(lock))\n \t\t\tdie_errno(\"unable to move new alternates file into place\");\n \t\tif (the_repository->objects.alt_odb_tail)\n-\t\t\tlink_alt_odb_entries(reference, strlen(reference), '\\n', NULL, 0);\n+\t\t\tlink_alt_odb_entries(the_repository, reference,\n+\t\t\t\t\t     strlen(reference), '\\n', NULL, 0);\n \t}\n \tfree(alts);\n }\n@@ -521,7 +526,8 @@ void add_to_alternates_memory(const char *reference)\n \t */\n \tprepare_alt_odb();\n \n-\tlink_alt_odb_entries(reference, strlen(reference), '\\n', NULL, 0);\n+\tlink_alt_odb_entries(the_repository, reference, strlen(reference),\n+\t\t\t     '\\n', NULL, 0);\n }\n \n /*\n@@ -625,7 +631,8 @@ void prepare_alt_odb(void)\n \n \tthe_repository->objects.alt_odb_tail =\n \t\t\t&the_repository->objects.alt_odb_list;\n-\tlink_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);\n+\tlink_alt_odb_entries(the_repository, alt, strlen(alt),\n+\t\t\t     PATH_SEP, NULL, 0);\n \n \tread_info_alternates(the_repository, get_object_directory(), 0);\n }\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327363","messageId":"20170830065926.GL153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 11/39] sha1_file: add repository argument to stat_sha1_file","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:59:26Z","receivedAt":"2017-08-30T06:59:33Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the stat_sha1_file caller to be\nmore specific about which repository to act on. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 9 +++++----\n 1 file changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 7938bd2a6f..d3573cec62 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -815,8 +815,9 @@ int git_open_cloexec(const char *name, int flags)\n  * Note that it may point to static storage and is only valid until another\n  * call to sha1_file_name(), etc.\n  */\n-static int stat_sha1_file(const unsigned char *sha1, struct stat *st,\n-\t\t\t  const char **path)\n+#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p)\n+static int stat_sha1_file_the_repository(const unsigned char *sha1,\n+\t\t\t\t\t struct stat *st, const char **path)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -1114,7 +1115,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,\n \tif (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) {\n \t\tconst char *path;\n \t\tstruct stat st;\n-\t\tif (stat_sha1_file(sha1, &st, &path) < 0)\n+\t\tif (stat_sha1_file(the_repository, sha1, &st, &path) < 0)\n \t\t\treturn -1;\n \t\tif (oi->disk_sizep)\n \t\t\t*oi->disk_sizep = st.st_size;\n@@ -1306,7 +1307,7 @@ void *read_sha1_file_extended(const unsigned char *sha1,\n \t\tdie(\"replacement %s not found for %s\",\n \t\t    sha1_to_hex(repl), sha1_to_hex(sha1));\n \n-\tif (!stat_sha1_file(repl, &st, &path))\n+\tif (!stat_sha1_file(the_repository, repl, &st, &path))\n \t\tdie(\"loose object %s (stored in %s) is corrupt\",\n \t\t    sha1_to_hex(repl), path);\n \n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327364","messageId":"20170830065955.GM153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 12/39] sha1_file: add repository argument to open_sha1_file","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T06:59:55Z","receivedAt":"2017-08-30T07:00:07Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the open_sha1_file caller to be\nmore specific about which repository to act on. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex d3573cec62..893e37afec 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -840,7 +840,9 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1,\n  * Like stat_sha1_file(), but actually open the object and return the\n  * descriptor. See the caveats on the \"path\" parameter above.\n  */\n-static int open_sha1_file(const unsigned char *sha1, const char **path)\n+#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p)\n+static int open_sha1_file_the_repository(const unsigned char *sha1,\n+\t\t\t\t\t const char **path)\n {\n \tint fd;\n \tstruct alternate_object_database *alt;\n@@ -879,7 +881,7 @@ static void *map_sha1_file_1(const char *path,\n \tif (path)\n \t\tfd = git_open(path);\n \telse\n-\t\tfd = open_sha1_file(sha1, &path);\n+\t\tfd = open_sha1_file(the_repository, sha1, &path);\n \tmap = NULL;\n \tif (fd >= 0) {\n \t\tstruct stat st;\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327365","messageId":"20170830070029.GN153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 13/39] sha1_file: add repository argument to map_sha1_file_1","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:00:29Z","receivedAt":"2017-08-30T07:00:36Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the map_sha1_file_1 caller to be\nmore specific about which repository to act on. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 11 ++++++-----\n 1 file changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 893e37afec..3adae104c6 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -871,9 +871,10 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,\n  * Map the loose object at \"path\" if it is not NULL, or the path found by\n  * searching for a loose object named \"sha1\".\n  */\n-static void *map_sha1_file_1(const char *path,\n-\t\t\t     const unsigned char *sha1,\n-\t\t\t     unsigned long *size)\n+#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si)\n+static void *map_sha1_file_1_the_repository(const char *path,\n+\t\t\t\t\t    const unsigned char *sha1,\n+\t\t\t\t\t    unsigned long *size)\n {\n \tvoid *map;\n \tint fd;\n@@ -902,7 +903,7 @@ static void *map_sha1_file_1(const char *path,\n \n void *map_sha1_file(const unsigned char *sha1, unsigned long *size)\n {\n-\treturn map_sha1_file_1(NULL, sha1, size);\n+\treturn map_sha1_file_1(the_repository, NULL, sha1, size);\n }\n \n static int unpack_sha1_short_header(git_zstream *stream,\n@@ -2102,7 +2103,7 @@ int read_loose_object(const char *path,\n \n \t*contents = NULL;\n \n-\tmap = map_sha1_file_1(path, NULL, &mapsize);\n+\tmap = map_sha1_file_1(the_repository, path, NULL, &mapsize);\n \tif (!map) {\n \t\terror_errno(\"unable to mmap %s\", path);\n \t\tgoto out;\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327366","messageId":"20170830070103.GO153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 14/39] sha1_file: add repository argument to sha1_loose_object_info","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:01:03Z","receivedAt":"2017-08-30T07:01:10Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow the sha1_loose_object_info caller\nto be more specific about which repository to act on. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 9 +++++----\n 1 file changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 3adae104c6..d1c8dbcfa5 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1092,9 +1092,10 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)\n \treturn parse_sha1_header_extended(hdr, &oi, 0);\n }\n \n-static int sha1_loose_object_info(const unsigned char *sha1,\n-\t\t\t\t  struct object_info *oi,\n-\t\t\t\t  int flags)\n+#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f)\n+static int sha1_loose_object_info_the_repository(const unsigned char *sha1,\n+\t\t\t\t\t\t struct object_info *oi,\n+\t\t\t\t\t\t int flags)\n {\n \tint status = 0;\n \tunsigned long mapsize;\n@@ -1200,7 +1201,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \n \tif (!find_pack_entry(real, &e)) {\n \t\t/* Most likely it's a loose object. */\n-\t\tif (!sha1_loose_object_info(real, oi, flags))\n+\t\tif (!sha1_loose_object_info(the_repository, real, oi, flags))\n \t\t\treturn 0;\n \n \t\t/* Not a loose object; someone else may have just packed it. */\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327367","messageId":"20170830070139.GP153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 15/39] object-store: add repository argument to prepare_alt_odb","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:01:39Z","receivedAt":"2017-08-30T07:01:46Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow prepare_alt_odb callers to be more\nspecific about which repository to handle. This is a small mechanical\nchange; it doesn't change the implementation to handle repositories\nother than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nWhile at it, move the declaration to object-store.h, where it should\nbe easier to find.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/fsck.c |  2 +-\n cache.h        |  1 -\n object-store.h |  3 +++\n packfile.c     |  2 +-\n sha1_file.c    | 13 +++++++------\n sha1_name.c    |  3 ++-\n 6 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 20bbcdcf4a..35972fe2be 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -700,7 +700,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \t} else {\n \t\tfsck_object_dir(get_object_directory());\n \n-\t\tprepare_alt_odb();\n+\t\tprepare_alt_odb(the_repository);\n \t\tfor (alt = the_repository->objects.alt_odb_list;\n \t\t\t\talt; alt = alt->next)\n \t\t\tfsck_object_dir(alt->path);\ndiff --git a/cache.h b/cache.h\nindex cd59c2fdb7..5770224167 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1523,7 +1523,6 @@ struct alternate_object_database {\n \n \tchar path[FLEX_ARRAY];\n };\n-extern void prepare_alt_odb(void);\n extern char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n extern int foreach_alt_odb(alt_odb_fn, void*);\ndiff --git a/object-store.h b/object-store.h\nindex 99f77d10cd..e749c952d5 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -54,4 +54,7 @@ struct packed_git {\n \tchar pack_name[FLEX_ARRAY]; /* more */\n };\n \n+#define prepare_alt_odb(r) prepare_alt_odb_##r()\n+extern void prepare_alt_odb_the_repository(void);\n+\n #endif /* OBJECT_STORE_H */\ndiff --git a/packfile.c b/packfile.c\nindex 98267f014f..2cd61b32a3 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -872,7 +872,7 @@ void prepare_packed_git(void)\n \tif (the_repository->objects.packed_git_initialized)\n \t\treturn;\n \tprepare_packed_git_one(get_object_directory(), 1);\n-\tprepare_alt_odb();\n+\tprepare_alt_odb(the_repository);\n \tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)\n \t\tprepare_packed_git_one(alt->path, 0);\n \trearrange_packed_git();\ndiff --git a/sha1_file.c b/sha1_file.c\nindex d1c8dbcfa5..9211c73920 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -23,6 +23,7 @@\n #include \"sha1-lookup.h\"\n #include \"bulk-checkin.h\"\n #include \"repository.h\"\n+#include \"object-store.h\"\n #include \"streaming.h\"\n #include \"dir.h\"\n #include \"mru.h\"\n@@ -524,7 +525,7 @@ void add_to_alternates_memory(const char *reference)\n \t * Make sure alternates are initialized, or else our entry may be\n \t * overwritten when they are.\n \t */\n-\tprepare_alt_odb();\n+\tprepare_alt_odb(the_repository);\n \n \tlink_alt_odb_entries(the_repository, reference, strlen(reference),\n \t\t\t     '\\n', NULL, 0);\n@@ -610,7 +611,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \tstruct alternate_object_database *ent;\n \tint r = 0;\n \n-\tprepare_alt_odb();\n+\tprepare_alt_odb(the_repository);\n \tfor (ent = the_repository->objects.alt_odb_list; ent; ent = ent->next) {\n \t\tr = fn(ent, cb);\n \t\tif (r)\n@@ -619,7 +620,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \treturn r;\n }\n \n-void prepare_alt_odb(void)\n+void prepare_alt_odb_the_repository(void)\n {\n \tconst char *alt;\n \n@@ -669,7 +670,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)\n static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)\n {\n \tstruct alternate_object_database *alt;\n-\tprepare_alt_odb();\n+\tprepare_alt_odb(the_repository);\n \tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n \t\tconst char *path = alt_sha1_path(alt, sha1);\n \t\tif (check_and_freshen_file(path, freshen))\n@@ -825,7 +826,7 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1,\n \tif (!lstat(*path, st))\n \t\treturn 0;\n \n-\tprepare_alt_odb();\n+\tprepare_alt_odb(the_repository);\n \terrno = ENOENT;\n \tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n \t\t*path = alt_sha1_path(alt, sha1);\n@@ -854,7 +855,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,\n \t\treturn fd;\n \tmost_interesting_errno = errno;\n \n-\tprepare_alt_odb();\n+\tprepare_alt_odb(the_repository);\n \tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n \t\t*path = alt_sha1_path(alt, sha1);\n \t\tfd = git_open(*path);\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 153bcd83b9..952eb64711 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -11,6 +11,7 @@\n #include \"sha1-array.h\"\n #include \"packfile.h\"\n #include \"repository.h\"\n+#include \"object-store.h\"\n \n static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);\n \n@@ -351,7 +352,7 @@ static int init_object_disambiguation(const char *name, int len,\n \n \tds->len = len;\n \tds->hex_pfx[len] = '\\0';\n-\tprepare_alt_odb();\n+\tprepare_alt_odb(the_repository);\n \treturn 0;\n }\n \n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327368","messageId":"20170830070216.GQ153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 16/39] object-store: add repository argument to foreach_alt_odb","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:02:16Z","receivedAt":"2017-08-30T07:02:23Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow foreach_alt_odb callers to be more\nspecific about which repository to handle. This is a small mechanical\nchange; it doesn't change the implementation to handle repositories\nother than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nWhile at it, move the declaration to object-store.h, where it should\nbe easier to find.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/count-objects.c     | 2 +-\n builtin/submodule--helper.c | 4 +++-\n cache.h                     | 2 --\n object-store.h              | 4 ++++\n sha1_file.c                 | 4 ++--\n transport.c                 | 4 +++-\n 6 files changed, 13 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 9334648dcc..843a7d7d7e 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -155,7 +155,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)\n \t\tprintf(\"prune-packable: %lu\\n\", packed_loose);\n \t\tprintf(\"garbage: %lu\\n\", garbage);\n \t\tprintf(\"size-garbage: %s\\n\", garbage_buf.buf);\n-\t\tforeach_alt_odb(print_alternate, NULL);\n+\t\tforeach_alt_odb(the_repository, print_alternate, NULL);\n \t\tstrbuf_release(&loose_buf);\n \t\tstrbuf_release(&pack_buf);\n \t\tstrbuf_release(&garbage_buf);\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 818fe74f0a..299a71b90c 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -6,6 +6,7 @@\n #include \"quote.h\"\n #include \"pathspec.h\"\n #include \"dir.h\"\n+#include \"object-store.h\"\n #include \"submodule.h\"\n #include \"submodule-config.h\"\n #include \"string-list.h\"\n@@ -598,7 +599,8 @@ static void prepare_possible_alternates(const char *sm_name,\n \t\tdie(_(\"Value '%s' for submodule.alternateErrorStrategy is not recognized\"), error_strategy);\n \n \tif (!strcmp(sm_alternate, \"superproject\"))\n-\t\tforeach_alt_odb(add_possible_reference_from_superproject, &sas);\n+\t\tforeach_alt_odb(the_repository,\n+\t\t\t\tadd_possible_reference_from_superproject, &sas);\n \telse if (!strcmp(sm_alternate, \"no\"))\n \t\t; /* do nothing */\n \telse\ndiff --git a/cache.h b/cache.h\nindex 5770224167..abec62dc9b 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1524,8 +1524,6 @@ struct alternate_object_database {\n \tchar path[FLEX_ARRAY];\n };\n extern char *compute_alternate_path(const char *path, struct strbuf *err);\n-typedef int alt_odb_fn(struct alternate_object_database *, void *);\n-extern int foreach_alt_odb(alt_odb_fn, void*);\n \n /*\n  * Allocate a \"struct alternate_object_database\" but do _not_ actually\ndiff --git a/object-store.h b/object-store.h\nindex e749c952d5..eef8d3b653 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -57,4 +57,8 @@ struct packed_git {\n #define prepare_alt_odb(r) prepare_alt_odb_##r()\n extern void prepare_alt_odb_the_repository(void);\n \n+typedef int alt_odb_fn(struct alternate_object_database *, void *);\n+#define foreach_alt_odb(r, fn, cb) foreach_alt_odb_##r(fn, cb)\n+extern int foreach_alt_odb_the_repository(alt_odb_fn, void*);\n+\n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 9211c73920..8c599dbfc2 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -606,7 +606,7 @@ char *compute_alternate_path(const char *path, struct strbuf *err)\n \treturn ref_git;\n }\n \n-int foreach_alt_odb(alt_odb_fn fn, void *cb)\n+int foreach_alt_odb_the_repository(alt_odb_fn fn, void *cb)\n {\n \tstruct alternate_object_database *ent;\n \tint r = 0;\n@@ -2031,7 +2031,7 @@ int for_each_loose_object(each_loose_object_fn cb, void *data, unsigned flags)\n \n \talt.cb = cb;\n \talt.data = data;\n-\treturn foreach_alt_odb(loose_from_alt_odb, &alt);\n+\treturn foreach_alt_odb(the_repository, loose_from_alt_odb, &alt);\n }\n \n static int check_stream_sha1(git_zstream *stream,\ndiff --git a/transport.c b/transport.c\nindex d75ff0514d..426a3a3a80 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -1,6 +1,7 @@\n #include \"cache.h\"\n #include \"config.h\"\n #include \"transport.h\"\n+#include \"repository.h\"\n #include \"run-command.h\"\n #include \"pkt-line.h\"\n #include \"fetch-pack.h\"\n@@ -11,6 +12,7 @@\n #include \"bundle.h\"\n #include \"dir.h\"\n #include \"refs.h\"\n+#include \"object-store.h\"\n #include \"branch.h\"\n #include \"url.h\"\n #include \"submodule.h\"\n@@ -1286,5 +1288,5 @@ void for_each_alternate_ref(alternate_ref_fn fn, void *data)\n \tstruct alternate_refs_data cb;\n \tcb.fn = fn;\n \tcb.data = data;\n-\tforeach_alt_odb(refs_from_alternate_cb, &cb);\n+\tforeach_alt_odb(the_repository, refs_from_alternate_cb, &cb);\n }\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327369","messageId":"20170830070250.GR153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 17/39] pack: add repository argument to install_packed_git","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:02:50Z","receivedAt":"2017-08-30T07:02:56Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow install_packed_git callers to be\nmore specific about which repository to handle. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n fast-import.c | 2 +-\n http.c        | 3 ++-\n packfile.c    | 4 ++--\n packfile.h    | 3 ++-\n 4 files changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/fast-import.c b/fast-import.c\nindex 9a725ebf4f..4c3b3d9df6 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -1038,7 +1038,7 @@ static void end_packfile(void)\n \t\tif (!new_p)\n \t\t\tdie(\"core git rejected index %s\", idx_name);\n \t\tall_packs[pack_id] = new_p;\n-\t\tinstall_packed_git(new_p);\n+\t\tinstall_packed_git(the_repository, new_p);\n \t\tfree(idx_name);\n \n \t\t/* Print the boundary */\ndiff --git a/http.c b/http.c\nindex 3186de107b..0979053272 100644\n--- a/http.c\n+++ b/http.c\n@@ -1,5 +1,6 @@\n #include \"git-compat-util.h\"\n #include \"http.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"object-store.h\"\n #include \"pack.h\"\n@@ -2049,7 +2050,7 @@ int finish_http_pack_request(struct http_pack_request *preq)\n \t\treturn -1;\n \t}\n \n-\tinstall_packed_git(p);\n+\tinstall_packed_git(the_repository, p);\n \tfree(tmp_idx);\n \treturn 0;\n }\ndiff --git a/packfile.c b/packfile.c\nindex 2cd61b32a3..cea3698af5 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -664,7 +664,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n \treturn p;\n }\n \n-void install_packed_git(struct packed_git *pack)\n+void install_packed_git_the_repository(struct packed_git *pack)\n {\n \tif (pack->pack_fd != -1)\n \t\tpack_open_fds++;\n@@ -766,7 +766,7 @@ static void prepare_packed_git_one(char *objdir, int local)\n \t\t\t     * corresponding .pack file that we can map.\n \t\t\t     */\n \t\t\t    (p = add_packed_git(path.buf, path.len, local)) != NULL)\n-\t\t\t\tinstall_packed_git(p);\n+\t\t\t\tinstall_packed_git(the_repository, p);\n \t\t}\n \n \t\tif (!report_garbage)\ndiff --git a/packfile.h b/packfile.h\nindex 0cdeb54dcd..7e6959d440 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,7 +34,8 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path);\n \n extern void prepare_packed_git(void);\n extern void reprepare_packed_git(void);\n-extern void install_packed_git(struct packed_git *pack);\n+#define install_packed_git(r, p) install_packed_git_##r(p)\n+extern void install_packed_git_the_repository(struct packed_git *pack);\n \n /*\n  * Give a rough count of objects in the repository. This sacrifices accuracy\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327370","messageId":"20170830070329.GS153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 18/39] pack: add repository argument to prepare_packed_git_one","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:03:29Z","receivedAt":"2017-08-30T07:03:36Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow the prepare_packed_git_one caller\nto be more specific about which repository to handle. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex cea3698af5..3a841c0f69 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -719,7 +719,8 @@ static void report_pack_garbage(struct string_list *list)\n \treport_helper(list, seen_bits, first, list->nr);\n }\n \n-static void prepare_packed_git_one(char *objdir, int local)\n+#define prepare_packed_git_one(r, o, l) prepare_packed_git_one_##r(o, l)\n+static void prepare_packed_git_one_the_repository(char *objdir, int local)\n {\n \tstruct strbuf path = STRBUF_INIT;\n \tsize_t dirnamelen;\n@@ -871,10 +872,10 @@ void prepare_packed_git(void)\n \n \tif (the_repository->objects.packed_git_initialized)\n \t\treturn;\n-\tprepare_packed_git_one(get_object_directory(), 1);\n+\tprepare_packed_git_one(the_repository, get_object_directory(), 1);\n \tprepare_alt_odb(the_repository);\n \tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)\n-\t\tprepare_packed_git_one(alt->path, 0);\n+\t\tprepare_packed_git_one(the_repository, alt->path, 0);\n \trearrange_packed_git();\n \tprepare_packed_git_mru();\n \tthe_repository->objects.packed_git_initialized = 1;\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327371","messageId":"20170830070354.GT153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 19/39] pack: add repository argument to rearrange_packed_git","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:03:54Z","receivedAt":"2017-08-30T07:04:00Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow the rearrange_packed_git caller to\nbe more specific about which repository to handle. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 3a841c0f69..1d03bf48b4 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -850,7 +850,8 @@ static int sort_pack(const void *a_, const void *b_)\n \treturn -1;\n }\n \n-static void rearrange_packed_git(void)\n+#define rearrange_packed_git(r) rearrange_packed_git_##r()\n+static void rearrange_packed_git_the_repository(void)\n {\n \tthe_repository->objects.packed_git = llist_mergesort(\n \t\tthe_repository->objects.packed_git, get_next_packed_git,\n@@ -876,7 +877,7 @@ void prepare_packed_git(void)\n \tprepare_alt_odb(the_repository);\n \tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)\n \t\tprepare_packed_git_one(the_repository, alt->path, 0);\n-\trearrange_packed_git();\n+\trearrange_packed_git(the_repository);\n \tprepare_packed_git_mru();\n \tthe_repository->objects.packed_git_initialized = 1;\n }\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327372","messageId":"20170830070427.GU153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 20/39] pack: add repository argument to prepare_packed_git_mru","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:04:27Z","receivedAt":"2017-08-30T07:04:35Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow the prepare_packed_git_mru caller\nto be more specific about which repository to handle. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 1d03bf48b4..6a04e4bb1b 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -858,7 +858,8 @@ static void rearrange_packed_git_the_repository(void)\n \t\tset_next_packed_git, sort_pack);\n }\n \n-static void prepare_packed_git_mru(void)\n+#define prepare_packed_git_mru(r) prepare_packed_git_mru_##r()\n+static void prepare_packed_git_mru_the_repository(void)\n {\n \tstruct packed_git *p;\n \n@@ -878,7 +879,7 @@ void prepare_packed_git(void)\n \tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)\n \t\tprepare_packed_git_one(the_repository, alt->path, 0);\n \trearrange_packed_git(the_repository);\n-\tprepare_packed_git_mru();\n+\tprepare_packed_git_mru(the_repository);\n \tthe_repository->objects.packed_git_initialized = 1;\n }\n \n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327373","messageId":"20170830070521.GV153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 21/39] pack: add repository argument to prepare_packed_git","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:05:21Z","receivedAt":"2017-08-30T07:05:28Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow prepare_packed_git_mru callers to\nbe more specific about which repository to handle. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nCallers adapted using contrib/coccinelle/packed_git.cocci.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/count-objects.c             |  2 +-\n builtin/fsck.c                      |  2 +-\n builtin/gc.c                        |  2 +-\n builtin/pack-objects.c              |  2 +-\n builtin/pack-redundant.c            |  2 +-\n contrib/coccinelle/packed_git.cocci |  4 ++++\n fast-import.c                       |  2 +-\n http-backend.c                      |  2 +-\n pack-bitmap.c                       |  2 +-\n packfile.c                          | 10 +++++-----\n packfile.h                          |  3 ++-\n server-info.c                       |  2 +-\n sha1_name.c                         |  2 +-\n 13 files changed, 21 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 843a7d7d7e..e340b3e3c3 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -123,7 +123,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)\n \t\tstruct strbuf pack_buf = STRBUF_INIT;\n \t\tstruct strbuf garbage_buf = STRBUF_INIT;\n \t\tif (!the_repository->objects.packed_git)\n-\t\t\tprepare_packed_git();\n+\t\t\tprepare_packed_git(the_repository);\n \t\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\t\tif (!p->pack_local)\n \t\t\t\tcontinue;\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 35972fe2be..9ed210b377 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -710,7 +710,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \t\t\tuint32_t total = 0, count = 0;\n \t\t\tstruct progress *progress = NULL;\n \n-\t\t\tprepare_packed_git();\n+\t\t\tprepare_packed_git(the_repository);\n \n \t\t\tif (show_progress) {\n \t\t\t\tfor (p = the_repository->objects.packed_git; p;\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 73f727332c..11312529c8 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -174,7 +174,7 @@ static int too_many_packs(void)\n \tif (gc_auto_pack_limit <= 0)\n \t\treturn 0;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (cnt = 0, p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (!p->pack_local)\n \t\t\tcontinue;\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex b135fb3fb9..cf2941e68f 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -3052,7 +3052,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)\n \tif (progress && all_progress_implied)\n \t\tprogress = 2;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tif (ignore_packed_keep) {\n \t\tstruct packed_git *p;\n \t\tfor (p = the_repository->objects.packed_git; p; p = p->next)\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 55462bc826..83d2395dae 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -631,7 +631,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)\n \t\t\tbreak;\n \t}\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \n \tif (load_all_packs)\n \t\tload_all();\ndiff --git a/contrib/coccinelle/packed_git.cocci b/contrib/coccinelle/packed_git.cocci\nindex da317a51a9..7554f4773c 100644\n--- a/contrib/coccinelle/packed_git.cocci\n+++ b/contrib/coccinelle/packed_git.cocci\n@@ -5,3 +5,7 @@\n @@ @@\n - packed_git_mru\n + the_repository->objects.packed_git_mru\n+\n+@@ @@\n+- prepare_packed_git()\n++ prepare_packed_git(the_repository)\ndiff --git a/fast-import.c b/fast-import.c\nindex 4c3b3d9df6..0024a5e132 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -3471,7 +3471,7 @@ int cmd_main(int argc, const char **argv)\n \t\trc_free[i].next = &rc_free[i + 1];\n \trc_free[cmd_save - 1].next = NULL;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tstart_packfile();\n \tset_die_routine(die_nicely);\n \tset_checkpoint_signal();\ndiff --git a/http-backend.c b/http-backend.c\nindex 681515aefd..c62796a131 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -520,7 +520,7 @@ static void get_info_packs(struct strbuf *hdr, char *arg)\n \tsize_t cnt = 0;\n \n \tselect_getanyfile(hdr);\n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (p->pack_local)\n \t\t\tcnt++;\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 396abb75bd..39ec1eaf05 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -336,7 +336,7 @@ static int open_pack_bitmap(void)\n \n \tassert(!bitmap_git.map && !bitmap_git.loaded);\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif (open_pack_bitmap_1(p) == 0)\n \t\t\tret = 0;\ndiff --git a/packfile.c b/packfile.c\nindex 6a04e4bb1b..34b887e7e5 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -800,7 +800,7 @@ unsigned long approximate_object_count(void)\n \t\tunsigned long count;\n \t\tstruct packed_git *p;\n \n-\t\tprepare_packed_git();\n+\t\tprepare_packed_git(the_repository);\n \t\tcount = 0;\n \t\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\t\tif (open_pack_index(p))\n@@ -868,7 +868,7 @@ static void prepare_packed_git_mru_the_repository(void)\n \t\tmru_append(&the_repository->objects.packed_git_mru, p);\n }\n \n-void prepare_packed_git(void)\n+void prepare_packed_git_the_repository(void)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -887,7 +887,7 @@ void reprepare_packed_git(void)\n {\n \tthe_repository->objects.approximate_object_count_valid = 0;\n \tthe_repository->objects.packed_git_initialized = 0;\n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n }\n \n unsigned long unpack_object_header_buffer(const unsigned char *buf,\n@@ -1829,7 +1829,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n {\n \tstruct mru_entry *p;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tif (!the_repository->objects.packed_git)\n \t\treturn 0;\n \n@@ -1881,7 +1881,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)\n \tint r = 0;\n \tint pack_errors = 0;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\tif ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)\n \t\t\tcontinue;\ndiff --git a/packfile.h b/packfile.h\nindex 7e6959d440..e543a98b23 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -32,7 +32,8 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_\n #define PACKDIR_FILE_GARBAGE 4\n extern void (*report_garbage)(unsigned seen_bits, const char *path);\n \n-extern void prepare_packed_git(void);\n+#define prepare_packed_git(r) prepare_packed_git_##r()\n+extern void prepare_packed_git_the_repository(void);\n extern void reprepare_packed_git(void);\n #define install_packed_git(r, p) install_packed_git_##r(p)\n extern void install_packed_git_the_repository(struct packed_git *pack);\ndiff --git a/server-info.c b/server-info.c\nindex 96885c45f6..6cd1506e5e 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -201,7 +201,7 @@ static void init_pack_info(const char *infofile, int force)\n \tobjdir = get_object_directory();\n \tobjdirlen = strlen(objdir);\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n \t\t/* we ignore things on alternate path since they are\n \t\t * not available to the pullers in general.\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 952eb64711..387836e717 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -194,7 +194,7 @@ static void find_short_packed_object(struct disambiguate_state *ds)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (p = the_repository->objects.packed_git; p && !ds->ambiguous;\n \t     p = p->next)\n \t\tunique_in_pack(p, ds);\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327374","messageId":"20170830070610.GW153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 22/39] pack: add repository argument to reprepare_packed_git","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:06:10Z","receivedAt":"2017-08-30T07:06:17Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow reprepare_packed_git_mru callers to\nbe more specific about which repository to handle. This is a small\nmechanical change; it doesn't change the implementation to handle\nrepositories other than the_repository yet.\n\nCallers adapted using contrib/coccinelle/packed_git.cocci.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/gc.c                        | 2 +-\n builtin/receive-pack.c              | 3 ++-\n bulk-checkin.c                      | 3 ++-\n contrib/coccinelle/packed_git.cocci | 4 ++++\n fetch-pack.c                        | 3 ++-\n packfile.c                          | 2 +-\n packfile.h                          | 3 ++-\n sha1_file.c                         | 2 +-\n 8 files changed, 15 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 11312529c8..d0da9e5403 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -475,7 +475,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)\n \t\treturn error(FAILED_RUN, rerere.argv[0]);\n \n \treport_garbage = report_pack_garbage;\n-\treprepare_packed_git();\n+\treprepare_packed_git(the_repository);\n \tif (pack_garbage.nr > 0)\n \t\tclean_pack_garbage();\n \ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 6657ba1375..97750d0d4e 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -1,4 +1,5 @@\n #include \"builtin.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n #include \"pack.h\"\n@@ -1779,7 +1780,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)\n \t\tstatus = finish_command(&child);\n \t\tif (status)\n \t\t\treturn \"index-pack abnormal exit\";\n-\t\treprepare_packed_git();\n+\t\treprepare_packed_git(the_repository);\n \t}\n \treturn NULL;\n }\ndiff --git a/bulk-checkin.c b/bulk-checkin.c\nindex 9a1f6c49ab..96f37100fc 100644\n--- a/bulk-checkin.c\n+++ b/bulk-checkin.c\n@@ -3,6 +3,7 @@\n  */\n #include \"cache.h\"\n #include \"bulk-checkin.h\"\n+#include \"repository.h\"\n #include \"csum-file.h\"\n #include \"pack.h\"\n #include \"strbuf.h\"\n@@ -57,7 +58,7 @@ static void finish_bulk_checkin(struct bulk_checkin_state *state)\n \n \tstrbuf_release(&packname);\n \t/* Make objects we just wrote available to ourselves */\n-\treprepare_packed_git();\n+\treprepare_packed_git(the_repository);\n }\n \n static int already_written(struct bulk_checkin_state *state, unsigned char sha1[])\ndiff --git a/contrib/coccinelle/packed_git.cocci b/contrib/coccinelle/packed_git.cocci\nindex 7554f4773c..0cb0e95f82 100644\n--- a/contrib/coccinelle/packed_git.cocci\n+++ b/contrib/coccinelle/packed_git.cocci\n@@ -9,3 +9,7 @@\n @@ @@\n - prepare_packed_git()\n + prepare_packed_git(the_repository)\n+\n+@@ @@\n+- reprepare_packed_git()\n++ reprepare_packed_git(the_repository)\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex 105506e9aa..e9a6683437 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1,4 +1,5 @@\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n #include \"refs.h\"\n@@ -1168,7 +1169,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,\n \tprepare_shallow_info(&si, shallow);\n \tref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,\n \t\t\t\t&si, pack_lockfile);\n-\treprepare_packed_git();\n+\treprepare_packed_git(the_repository);\n \tupdate_shallow(args, sought, nr_sought, &si);\n \tclear_shallow_info(&si);\n \treturn ref_cpy;\ndiff --git a/packfile.c b/packfile.c\nindex 34b887e7e5..86c3964018 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -883,7 +883,7 @@ void prepare_packed_git_the_repository(void)\n \tthe_repository->objects.packed_git_initialized = 1;\n }\n \n-void reprepare_packed_git(void)\n+void reprepare_packed_git_the_repository(void)\n {\n \tthe_repository->objects.approximate_object_count_valid = 0;\n \tthe_repository->objects.packed_git_initialized = 0;\ndiff --git a/packfile.h b/packfile.h\nindex e543a98b23..74f293c439 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,7 +34,8 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path);\n \n #define prepare_packed_git(r) prepare_packed_git_##r()\n extern void prepare_packed_git_the_repository(void);\n-extern void reprepare_packed_git(void);\n+#define reprepare_packed_git(r) reprepare_packed_git_##r()\n+extern void reprepare_packed_git_the_repository(void);\n #define install_packed_git(r, p) install_packed_git_##r(p)\n extern void install_packed_git_the_repository(struct packed_git *pack);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex 8c599dbfc2..6af88e5b04 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1209,7 +1209,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \t\tif (flags & OBJECT_INFO_QUICK) {\n \t\t\treturn -1;\n \t\t} else {\n-\t\t\treprepare_packed_git();\n+\t\t\treprepare_packed_git(the_repository);\n \t\t\tif (!find_pack_entry(real, &e))\n \t\t\t\treturn -1;\n \t\t}\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327375","messageId":"20170830070638.GX153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 23/39] pack: add repository argument to sha1_file_name","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:06:38Z","receivedAt":"2017-08-30T07:06:46Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow sha1_file_name callers to be more\nspecific about which repository to handle. This is a small mechanical\nchange; it doesn't change the implementation to handle repositories\nother than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nWhile at it, move the declaration to object-store.h, where it should\nbe easier to find.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n cache.h        |  8 --------\n http-walker.c  |  3 ++-\n http.c         |  5 +++--\n object-store.h |  9 +++++++++\n sha1_file.c    | 11 ++++++-----\n 5 files changed, 20 insertions(+), 16 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex abec62dc9b..0d120b9327 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -895,14 +895,6 @@ extern void check_repository_format(void);\n #define DATA_CHANGED    0x0020\n #define TYPE_CHANGED    0x0040\n \n-/*\n- * Return the name of the file in the local object database that would\n- * be used to store a loose object with the specified sha1.  The\n- * return value is a pointer to a statically allocated buffer that is\n- * overwritten each time the function is called.\n- */\n-extern const char *sha1_file_name(const unsigned char *sha1);\n-\n /*\n  * Return an abbreviated sha1 unique within this repository's object database.\n  * The result will be at least `len` characters long, and will be NUL\ndiff --git a/http-walker.c b/http-walker.c\nindex a1c6f2639b..96873bdfed 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -1,4 +1,5 @@\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"commit.h\"\n #include \"walker.h\"\n #include \"http.h\"\n@@ -546,7 +547,7 @@ static int fetch_object(struct walker *walker, unsigned char *sha1)\n \t\tret = error(\"File %s has bad hash\", hex);\n \t} else if (req->rename < 0) {\n \t\tret = error(\"unable to write sha1 filename %s\",\n-\t\t\t    sha1_file_name(req->sha1));\n+\t\t\t    sha1_file_name(the_repository, req->sha1));\n \t}\n \n \trelease_http_object_request(req);\ndiff --git a/http.c b/http.c\nindex 0979053272..2c86e6e76e 100644\n--- a/http.c\n+++ b/http.c\n@@ -2163,7 +2163,7 @@ struct http_object_request *new_http_object_request(const char *base_url,\n \thashcpy(freq->sha1, sha1);\n \tfreq->localfile = -1;\n \n-\tfilename = sha1_file_name(sha1);\n+\tfilename = sha1_file_name(the_repository, sha1);\n \tsnprintf(freq->tmpfile, sizeof(freq->tmpfile),\n \t\t \"%s.temp\", filename);\n \n@@ -2311,7 +2311,8 @@ int finish_http_object_request(struct http_object_request *freq)\n \t\treturn -1;\n \t}\n \tfreq->rename =\n-\t\tfinalize_object_file(freq->tmpfile, sha1_file_name(freq->sha1));\n+\t\tfinalize_object_file(freq->tmpfile,\n+\t\t\t\t     sha1_file_name(the_repository, freq->sha1));\n \n \treturn freq->rename;\n }\ndiff --git a/object-store.h b/object-store.h\nindex eef8d3b653..228c2ce8ae 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -54,6 +54,15 @@ struct packed_git {\n \tchar pack_name[FLEX_ARRAY]; /* more */\n };\n \n+/*\n+ * Return the name of the file in a repository's local object database\n+ * that would be used to store a loose object with the specified sha1.\n+ * The return value is a pointer to a statically allocated buffer that\n+ * is overwritten each time the function is called.\n+ */\n+#define sha1_file_name(r, s) sha1_file_name_##r(s)\n+extern const char *sha1_file_name_the_repository(const unsigned char *sha1);\n+\n #define prepare_alt_odb(r) prepare_alt_odb_##r()\n extern void prepare_alt_odb_the_repository(void);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex 6af88e5b04..8ab26fb3b3 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -253,7 +253,7 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)\n \t}\n }\n \n-const char *sha1_file_name(const unsigned char *sha1)\n+const char *sha1_file_name_the_repository(const unsigned char *sha1)\n {\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n@@ -664,7 +664,8 @@ int check_and_freshen_file(const char *fn, int freshen)\n \n static int check_and_freshen_local(const unsigned char *sha1, int freshen)\n {\n-\treturn check_and_freshen_file(sha1_file_name(sha1), freshen);\n+\treturn check_and_freshen_file(sha1_file_name(the_repository, sha1),\n+\t\t\t\t      freshen);\n }\n \n static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)\n@@ -822,7 +823,7 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1,\n {\n \tstruct alternate_object_database *alt;\n \n-\t*path = sha1_file_name(sha1);\n+\t*path = sha1_file_name(the_repository, sha1);\n \tif (!lstat(*path, st))\n \t\treturn 0;\n \n@@ -849,7 +850,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,\n \tstruct alternate_object_database *alt;\n \tint most_interesting_errno;\n \n-\t*path = sha1_file_name(sha1);\n+\t*path = sha1_file_name(the_repository, sha1);\n \tfd = git_open(*path);\n \tif (fd >= 0)\n \t\treturn fd;\n@@ -1509,7 +1510,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,\n \tgit_SHA_CTX c;\n \tunsigned char parano_sha1[20];\n \tstatic struct strbuf tmp_file = STRBUF_INIT;\n-\tconst char *filename = sha1_file_name(sha1);\n+\tconst char *filename = sha1_file_name(the_repository, sha1);\n \n \tfd = create_tmpfile(&tmp_file, filename);\n \tif (fd < 0) {\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327376","messageId":"20170830070709.GY153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 24/39] pack: add repository argument to map_sha1_file","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:07:09Z","receivedAt":"2017-08-30T07:07:16Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add a repository argument to allow map_sha1_file callers to be more\nspecific about which repository to handle. This is a small mechanical\nchange; it doesn't change the implementation to handle repositories\nother than the_repository yet.\n\nAs with the previous commits, use a macro to catch callers passing a\nrepository other than the_repository at compile time.\n\nWhile at it, move the declaration to object-store.h, where it should\nbe easier to find.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n cache.h        | 1 -\n object-store.h | 2 ++\n sha1_file.c    | 4 ++--\n streaming.c    | 5 ++++-\n 4 files changed, 8 insertions(+), 4 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 0d120b9327..454cfb50c4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1176,7 +1176,6 @@ extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned c\n extern int force_object_loose(const unsigned char *sha1, time_t mtime);\n extern int git_open_cloexec(const char *name, int flags);\n #define git_open(name) git_open_cloexec(name, O_RDONLY)\n-extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);\n extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);\n extern int parse_sha1_header(const char *hdr, unsigned long *sizep);\n \ndiff --git a/object-store.h b/object-store.h\nindex 228c2ce8ae..92fbf4a9ca 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -62,6 +62,8 @@ struct packed_git {\n  */\n #define sha1_file_name(r, s) sha1_file_name_##r(s)\n extern const char *sha1_file_name_the_repository(const unsigned char *sha1);\n+#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n+extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n \n #define prepare_alt_odb(r) prepare_alt_odb_##r()\n extern void prepare_alt_odb_the_repository(void);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 8ab26fb3b3..e7c86e5363 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -903,7 +903,7 @@ static void *map_sha1_file_1_the_repository(const char *path,\n \treturn map;\n }\n \n-void *map_sha1_file(const unsigned char *sha1, unsigned long *size)\n+void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size)\n {\n \treturn map_sha1_file_1(the_repository, NULL, sha1, size);\n }\n@@ -1128,7 +1128,7 @@ static int sha1_loose_object_info_the_repository(const unsigned char *sha1,\n \t\treturn 0;\n \t}\n \n-\tmap = map_sha1_file(sha1, &mapsize);\n+\tmap = map_sha1_file(the_repository, sha1, &mapsize);\n \tif (!map)\n \t\treturn -1;\n \ndiff --git a/streaming.c b/streaming.c\nindex 6f1c60f12b..86808a6d99 100644\n--- a/streaming.c\n+++ b/streaming.c\n@@ -3,6 +3,8 @@\n  */\n #include \"cache.h\"\n #include \"streaming.h\"\n+#include \"repository.h\"\n+#include \"object-store.h\"\n #include \"packfile.h\"\n \n enum input_source {\n@@ -335,7 +337,8 @@ static struct stream_vtbl loose_vtbl = {\n \n static open_method_decl(loose)\n {\n-\tst->u.loose.mapped = map_sha1_file(sha1, &st->u.loose.mapsize);\n+\tst->u.loose.mapped = map_sha1_file(the_repository,\n+\t\t\t\t\t   sha1, &st->u.loose.mapsize);\n \tif (!st->u.loose.mapped)\n \t\treturn -1;\n \tif ((unpack_sha1_header(&st->z,\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327378","messageId":"20170830070812.GZ153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:08:12Z","receivedAt":"2017-08-30T07:08:18Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n sha1_file.c | 16 +++++++++-------\n 1 file changed, 9 insertions(+), 7 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex e7c86e5363..b854cad970 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -25,6 +25,7 @@\n #include \"repository.h\"\n #include \"object-store.h\"\n #include \"streaming.h\"\n+#include \"path.h\"\n #include \"dir.h\"\n #include \"mru.h\"\n #include \"list.h\"\n@@ -281,17 +282,18 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,\n /*\n  * Return non-zero iff the path is usable as an alternate object database.\n  */\n-#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)\n-static int alt_odb_usable_the_repository(struct strbuf *path,\n-\t\t\t\t\t const char *normalized_objdir)\n+static int alt_odb_usable(struct repository *r, struct strbuf *path,\n+\t\t\t  const char *normalized_objdir)\n {\n \tstruct alternate_object_database *alt;\n \n \t/* Detect cases where alternate disappeared */\n \tif (!is_directory(path->buf)) {\n-\t\terror(\"object directory %s does not exist; \"\n-\t\t      \"check .git/objects/info/alternates.\",\n-\t\t      path->buf);\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\tstrbuf_repo_git_path(&sb, r, \"objects/info/alternates\");\n+\t\terror(\"object directory %s does not exist; check %s\",\n+\t\t      path->buf, sb.buf);\n+\t\tstrbuf_release(&sb);\n \t\treturn 0;\n \t}\n \n@@ -299,7 +301,7 @@ static int alt_odb_usable_the_repository(struct strbuf *path,\n \t * Prevent the common mistake of listing the same\n \t * thing twice, or object directory itself.\n \t */\n-\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = r->objects.alt_odb_list; alt; alt = alt->next) {\n \t\tif (!fspathcmp(path->buf, alt->path))\n \t\t\treturn 0;\n \t}\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327379","messageId":"20170830071036.GA153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 26/39] object-store: allow prepare_alt_odb to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:10:36Z","receivedAt":"2017-08-30T07:10:43Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n cache.h        |  4 ++++\n object-store.h |  3 +--\n sha1_file.c    | 65 ++++++++++++++++++++++++++++++----------------------------\n 3 files changed, 39 insertions(+), 33 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 454cfb50c4..d204048d3d 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1512,6 +1512,10 @@ struct alternate_object_database {\n \tchar loose_objects_subdir_seen[256];\n \tstruct oid_array loose_objects_cache;\n \n+\t/*\n+\t * Path to the alternate object database, relative to the\n+\t * current working directory.\n+\t */\n \tchar path[FLEX_ARRAY];\n };\n extern char *compute_alternate_path(const char *path, struct strbuf *err);\ndiff --git a/object-store.h b/object-store.h\nindex 92fbf4a9ca..fcf36c7370 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -65,8 +65,7 @@ extern const char *sha1_file_name_the_repository(const unsigned char *sha1);\n #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n \n-#define prepare_alt_odb(r) prepare_alt_odb_##r()\n-extern void prepare_alt_odb_the_repository(void);\n+extern void prepare_alt_odb(struct repository *r);\n \n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n #define foreach_alt_odb(r, fn, cb) foreach_alt_odb_##r(fn, cb)\ndiff --git a/sha1_file.c b/sha1_file.c\nindex b854cad970..452c8f0bbd 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -326,11 +326,10 @@ static int alt_odb_usable(struct repository *r, struct strbuf *path,\n  * SHA1, an extra slash for the first level indirection, and the\n  * terminating NUL.\n  */\n-#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d)\n-static void read_info_alternates_the_repository(const char *relative_base,\n-\t\t\t\t\t\tint depth);\n-#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n)\n-static int link_alt_odb_entry_the_repository(const char *entry,\n+static void read_info_alternates(struct repository *r,\n+\t\t\t\t const char *relative_base,\n+\t\t\t\t int depth);\n+static int link_alt_odb_entry(struct repository *r, const char *entry,\n \tconst char *relative_base, int depth, const char *normalized_objdir)\n {\n \tstruct alternate_object_database *ent;\n@@ -356,7 +355,7 @@ static int link_alt_odb_entry_the_repository(const char *entry,\n \twhile (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')\n \t\tstrbuf_setlen(&pathbuf, pathbuf.len - 1);\n \n-\tif (!alt_odb_usable(the_repository, &pathbuf, normalized_objdir)) {\n+\tif (!alt_odb_usable(r, &pathbuf, normalized_objdir)) {\n \t\tstrbuf_release(&pathbuf);\n \t\treturn -1;\n \t}\n@@ -364,12 +363,12 @@ static int link_alt_odb_entry_the_repository(const char *entry,\n \tent = alloc_alt_odb(pathbuf.buf);\n \n \t/* add the alternate entry */\n-\t*the_repository->objects.alt_odb_tail = ent;\n-\tthe_repository->objects.alt_odb_tail = &(ent->next);\n+\t*r->objects.alt_odb_tail = ent;\n+\tr->objects.alt_odb_tail = &(ent->next);\n \tent->next = NULL;\n \n \t/* recursively add alternates */\n-\tread_info_alternates(the_repository, pathbuf.buf, depth + 1);\n+\tread_info_alternates(r, pathbuf.buf, depth + 1);\n \n \tstrbuf_release(&pathbuf);\n \treturn 0;\n@@ -404,12 +403,8 @@ static const char *parse_alt_odb_entry(const char *string,\n \treturn end;\n }\n \n-#define link_alt_odb_entries(r, a, l, s, rb, d) \\\n-\tlink_alt_odb_entries_##r(a, l, s, rb, d)\n-static void link_alt_odb_entries_the_repository(const char *alt, int len,\n-\t\t\t\t\t\tint sep,\n-\t\t\t\t\t\tconst char *relative_base,\n-\t\t\t\t\t\tint depth)\n+static void link_alt_odb_entries(struct repository *r, const char *alt, int len,\n+\t\t\t\t int sep, const char *relative_base, int depth)\n {\n \tstruct strbuf objdirbuf = STRBUF_INIT;\n \tstruct strbuf entry = STRBUF_INIT;\n@@ -420,7 +415,7 @@ static void link_alt_odb_entries_the_repository(const char *alt, int len,\n \t\treturn;\n \t}\n \n-\tstrbuf_add_absolute_path(&objdirbuf, get_object_directory());\n+\tstrbuf_add_absolute_path(&objdirbuf, r->objectdir);\n \tif (strbuf_normalize_path(&objdirbuf) < 0)\n \t\tdie(\"unable to normalize object directory: %s\",\n \t\t    objdirbuf.buf);\n@@ -429,15 +424,16 @@ static void link_alt_odb_entries_the_repository(const char *alt, int len,\n \t\talt = parse_alt_odb_entry(alt, sep, &entry);\n \t\tif (!entry.len)\n \t\t\tcontinue;\n-\t\tlink_alt_odb_entry(the_repository, entry.buf,\n+\t\tlink_alt_odb_entry(r, entry.buf,\n \t\t\t\t   relative_base, depth, objdirbuf.buf);\n \t}\n \tstrbuf_release(&entry);\n \tstrbuf_release(&objdirbuf);\n }\n \n-static void read_info_alternates_the_repository(const char *relative_base,\n-\t\t\t\t\t\tint depth)\n+static void read_info_alternates(struct repository *r,\n+\t\t\t\t const char *relative_base,\n+\t\t\t\t int depth)\n {\n \tchar *map;\n \tsize_t mapsz;\n@@ -458,7 +454,7 @@ static void read_info_alternates_the_repository(const char *relative_base,\n \tmap = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);\n \tclose(fd);\n \n-\tlink_alt_odb_entries(the_repository, map, mapsz, '\\n', relative_base, depth);\n+\tlink_alt_odb_entries(r, map, mapsz, '\\n', relative_base, depth);\n \n \tmunmap(map, mapsz);\n }\n@@ -622,22 +618,29 @@ int foreach_alt_odb_the_repository(alt_odb_fn fn, void *cb)\n \treturn r;\n }\n \n-void prepare_alt_odb_the_repository(void)\n+void prepare_alt_odb(struct repository *r)\n {\n-\tconst char *alt;\n-\n-\tif (the_repository->objects.alt_odb_tail)\n+\tif (r->objects.alt_odb_tail)\n \t\treturn;\n \n+\tr->objects.alt_odb_tail = &r->objects.alt_odb_list;\n+\n-\talt = getenv(ALTERNATE_DB_ENVIRONMENT);\n-\tif (!alt) alt = \"\";\n-\n-\tthe_repository->objects.alt_odb_tail =\n-\t\t\t&the_repository->objects.alt_odb_list;\n-\tlink_alt_odb_entries(the_repository, alt, strlen(alt),\n-\t\t\t     PATH_SEP, NULL, 0);\n+\tif (!r->ignore_env) {\n+\t\tconst char *alt = getenv(ALTERNATE_DB_ENVIRONMENT);\n+\t\tif (!alt)\n+\t\t\talt = \"\";\n+\n+\t\t/*\n+\t\t * Paths in alt are relative to the cwd. We ignore environment\n+\t\t * settings like this for all repositories except for\n+\t\t * the_repository, so we don't have to worry about transforming\n+\t\t * the path to be relative to another repository.\n+\t\t */\n+\t\tlink_alt_odb_entries(r, alt, strlen(alt),\n+\t\t\t\t     PATH_SEP, NULL, 0);\n+\t}\n \n-\tread_info_alternates(the_repository, get_object_directory(), 0);\n+\tread_info_alternates(r, r->objectdir, 0);\n }\n \n /* Returns 1 if we have successfully freshened the file, 0 otherwise. */\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327380","messageId":"20170830071118.GB153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 27/39] object-store: allow foreach_alt_odb to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:11:18Z","receivedAt":"2017-08-30T07:11:24Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n object-store.h |  3 +--\n sha1_file.c    | 14 +++++++-------\n 2 files changed, 8 insertions(+), 9 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex fcf36c7370..518da80367 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -68,7 +68,6 @@ extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned lo\n extern void prepare_alt_odb(struct repository *r);\n \n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n-#define foreach_alt_odb(r, fn, cb) foreach_alt_odb_##r(fn, cb)\n-extern int foreach_alt_odb_the_repository(alt_odb_fn, void*);\n+extern int foreach_alt_odb(struct repository *r, alt_odb_fn, void*);\n \n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 452c8f0bbd..81bc1ab309 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -604,18 +604,18 @@ char *compute_alternate_path(const char *path, struct strbuf *err)\n \treturn ref_git;\n }\n \n-int foreach_alt_odb_the_repository(alt_odb_fn fn, void *cb)\n+int foreach_alt_odb(struct repository *r, alt_odb_fn fn, void *cb)\n {\n \tstruct alternate_object_database *ent;\n-\tint r = 0;\n+\tint ret = 0;\n \n-\tprepare_alt_odb(the_repository);\n-\tfor (ent = the_repository->objects.alt_odb_list; ent; ent = ent->next) {\n-\t\tr = fn(ent, cb);\n-\t\tif (r)\n+\tprepare_alt_odb(r);\n+\tfor (ent = r->objects.alt_odb_list; ent; ent = ent->next) {\n+\t\tret = fn(ent, cb);\n+\t\tif (ret)\n \t\t\tbreak;\n \t}\n-\treturn r;\n+\treturn ret;\n }\n \n void prepare_alt_odb(struct repository *r)\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327381","messageId":"20170830071156.GC153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 28/39] pack: allow install_packed_git to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:11:56Z","receivedAt":"2017-08-30T07:12:03Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 6 +++---\n packfile.h | 3 +--\n 2 files changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 86c3964018..51af035965 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -664,13 +664,13 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n \treturn p;\n }\n \n-void install_packed_git_the_repository(struct packed_git *pack)\n+void install_packed_git(struct repository *r, struct packed_git *pack)\n {\n \tif (pack->pack_fd != -1)\n \t\tpack_open_fds++;\n \n-\tpack->next = the_repository->objects.packed_git;\n-\tthe_repository->objects.packed_git = pack;\n+\tpack->next = r->objects.packed_git;\n+\tr->objects.packed_git = pack;\n }\n \n void (*report_garbage)(unsigned seen_bits, const char *path);\ndiff --git a/packfile.h b/packfile.h\nindex 74f293c439..ba6f08be99 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -36,8 +36,7 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path);\n extern void prepare_packed_git_the_repository(void);\n #define reprepare_packed_git(r) reprepare_packed_git_##r()\n extern void reprepare_packed_git_the_repository(void);\n-#define install_packed_git(r, p) install_packed_git_##r(p)\n-extern void install_packed_git_the_repository(struct packed_git *pack);\n+extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \n /*\n  * Give a rough count of objects in the repository. This sacrifices accuracy\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327382","messageId":"20170830071223.GD153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 29/39] pack: allow rearrange_packed_git to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:12:23Z","receivedAt":"2017-08-30T07:12:30Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 7 +++----\n 1 file changed, 3 insertions(+), 4 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 51af035965..977e714d9a 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -850,11 +850,10 @@ static int sort_pack(const void *a_, const void *b_)\n \treturn -1;\n }\n \n-#define rearrange_packed_git(r) rearrange_packed_git_##r()\n-static void rearrange_packed_git_the_repository(void)\n+static void rearrange_packed_git(struct repository *r)\n {\n-\tthe_repository->objects.packed_git = llist_mergesort(\n-\t\tthe_repository->objects.packed_git, get_next_packed_git,\n+\tr->objects.packed_git = llist_mergesort(\n+\t\tr->objects.packed_git, get_next_packed_git,\n \t\tset_next_packed_git, sort_pack);\n }\n \n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327383","messageId":"20170830071247.GE153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 30/39] pack: allow prepare_packed_git_mru to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:12:47Z","receivedAt":"2017-08-30T07:12:54Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 9 ++++-----\n 1 file changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 977e714d9a..9bb93ce256 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -857,14 +857,13 @@ static void rearrange_packed_git(struct repository *r)\n \t\tset_next_packed_git, sort_pack);\n }\n \n-#define prepare_packed_git_mru(r) prepare_packed_git_mru_##r()\n-static void prepare_packed_git_mru_the_repository(void)\n+static void prepare_packed_git_mru(struct repository *r)\n {\n \tstruct packed_git *p;\n \n-\tmru_clear(&the_repository->objects.packed_git_mru);\n-\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n-\t\tmru_append(&the_repository->objects.packed_git_mru, p);\n+\tmru_clear(&r->objects.packed_git_mru);\n+\tfor (p = r->objects.packed_git; p; p = p->next)\n+\t\tmru_append(&r->objects.packed_git_mru, p);\n }\n \n void prepare_packed_git_the_repository(void)\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327384","messageId":"20170830071313.GF153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 31/39] pack: allow prepare_packed_git_one to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:13:13Z","receivedAt":"2017-08-30T07:13:20Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 9 ++++-----\n 1 file changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 9bb93ce256..4652be0b6e 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -719,8 +719,8 @@ static void report_pack_garbage(struct string_list *list)\n \treport_helper(list, seen_bits, first, list->nr);\n }\n \n-#define prepare_packed_git_one(r, o, l) prepare_packed_git_one_##r(o, l)\n-static void prepare_packed_git_one_the_repository(char *objdir, int local)\n+static void prepare_packed_git_one(struct repository *r,\n+\t\t\t\t   char *objdir, int local)\n {\n \tstruct strbuf path = STRBUF_INIT;\n \tsize_t dirnamelen;\n@@ -753,8 +753,7 @@ static void prepare_packed_git_one_the_repository(char *objdir, int local)\n \t\tbase_len = path.len;\n \t\tif (strip_suffix_mem(path.buf, &base_len, \".idx\")) {\n \t\t\t/* Don't reopen a pack we already have. */\n-\t\t\tfor (p = the_repository->objects.packed_git; p;\n-\t\t\t     p = p->next) {\n+\t\t\tfor (p = r->objects.packed_git; p; p = p->next) {\n \t\t\t\tsize_t len;\n \t\t\t\tif (strip_suffix(p->pack_name, \".pack\", &len) &&\n \t\t\t\t    len == base_len &&\n@@ -767,7 +766,7 @@ static void prepare_packed_git_one_the_repository(char *objdir, int local)\n \t\t\t     * corresponding .pack file that we can map.\n \t\t\t     */\n \t\t\t    (p = add_packed_git(path.buf, path.len, local)) != NULL)\n-\t\t\t\tinstall_packed_git(the_repository, p);\n+\t\t\t\tinstall_packed_git(r, p);\n \t\t}\n \n \t\tif (!report_garbage)\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327385","messageId":"20170830071349.GG153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 32/39] pack: allow prepare_packed_git to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:13:49Z","receivedAt":"2017-08-30T07:13:57Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 18 +++++++++---------\n packfile.h |  3 +--\n 2 files changed, 10 insertions(+), 11 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 4652be0b6e..23a835f7fb 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -865,19 +865,19 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tmru_append(&r->objects.packed_git_mru, p);\n }\n \n-void prepare_packed_git_the_repository(void)\n+void prepare_packed_git(struct repository *r)\n {\n \tstruct alternate_object_database *alt;\n \n-\tif (the_repository->objects.packed_git_initialized)\n+\tif (r->objects.packed_git_initialized)\n \t\treturn;\n-\tprepare_packed_git_one(the_repository, get_object_directory(), 1);\n-\tprepare_alt_odb(the_repository);\n-\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)\n-\t\tprepare_packed_git_one(the_repository, alt->path, 0);\n-\trearrange_packed_git(the_repository);\n-\tprepare_packed_git_mru(the_repository);\n-\tthe_repository->objects.packed_git_initialized = 1;\n+\tprepare_packed_git_one(r, r->objectdir, 1);\n+\tprepare_alt_odb(r);\n+\tfor (alt = r->objects.alt_odb_list; alt; alt = alt->next)\n+\t\tprepare_packed_git_one(r, alt->path, 0);\n+\trearrange_packed_git(r);\n+\tprepare_packed_git_mru(r);\n+\tr->objects.packed_git_initialized = 1;\n }\n \n void reprepare_packed_git_the_repository(void)\ndiff --git a/packfile.h b/packfile.h\nindex ba6f08be99..75be3cb877 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -32,8 +32,7 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_\n #define PACKDIR_FILE_GARBAGE 4\n extern void (*report_garbage)(unsigned seen_bits, const char *path);\n \n-#define prepare_packed_git(r) prepare_packed_git_##r()\n-extern void prepare_packed_git_the_repository(void);\n+extern void prepare_packed_git(struct repository *r);\n #define reprepare_packed_git(r) reprepare_packed_git_##r()\n extern void reprepare_packed_git_the_repository(void);\n extern void install_packed_git(struct repository *r, struct packed_git *pack);\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327386","messageId":"20170830071425.GH153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 33/39] pack: allow reprepare_packed_git to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:14:25Z","receivedAt":"2017-08-30T07:14:32Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n packfile.c | 8 ++++----\n packfile.h | 3 +--\n 2 files changed, 5 insertions(+), 6 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 23a835f7fb..67274d01fd 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -880,11 +880,11 @@ void prepare_packed_git(struct repository *r)\n \tr->objects.packed_git_initialized = 1;\n }\n \n-void reprepare_packed_git_the_repository(void)\n+void reprepare_packed_git(struct repository *r)\n {\n-\tthe_repository->objects.approximate_object_count_valid = 0;\n-\tthe_repository->objects.packed_git_initialized = 0;\n-\tprepare_packed_git(the_repository);\n+\tr->objects.approximate_object_count_valid = 0;\n+\tr->objects.packed_git_initialized = 0;\n+\tprepare_packed_git(r);\n }\n \n unsigned long unpack_object_header_buffer(const unsigned char *buf,\ndiff --git a/packfile.h b/packfile.h\nindex 75be3cb877..b3138816e7 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -33,8 +33,7 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_\n extern void (*report_garbage)(unsigned seen_bits, const char *path);\n \n extern void prepare_packed_git(struct repository *r);\n-#define reprepare_packed_git(r) reprepare_packed_git_##r()\n-extern void reprepare_packed_git_the_repository(void);\n+extern void reprepare_packed_git(struct repository *r);\n extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \n /*\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327387","messageId":"20170830071450.GI153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 34/39] pack: allow sha1_file_name to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:14:50Z","receivedAt":"2017-08-30T07:14:57Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n object-store.h | 3 +--\n sha1_file.c    | 4 ++--\n 2 files changed, 3 insertions(+), 4 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 518da80367..fe2187fd65 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -60,8 +60,7 @@ struct packed_git {\n  * The return value is a pointer to a statically allocated buffer that\n  * is overwritten each time the function is called.\n  */\n-#define sha1_file_name(r, s) sha1_file_name_##r(s)\n-extern const char *sha1_file_name_the_repository(const unsigned char *sha1);\n+extern const char *sha1_file_name(struct repository *r, const unsigned char *sha1);\n #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex 81bc1ab309..ac57eea0f2 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -254,12 +254,12 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)\n \t}\n }\n \n-const char *sha1_file_name_the_repository(const unsigned char *sha1)\n+const char *sha1_file_name(struct repository *r, const unsigned char *sha1)\n {\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tstrbuf_addf(&buf, \"%s/\", get_object_directory());\n+\tstrbuf_addf(&buf, \"%s/\", r->objectdir);\n \n \tfill_sha1_path(&buf, sha1);\n \treturn buf.buf;\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327388","messageId":"20170830071513.GJ153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 35/39] pack: allow stat_sha1_file to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:15:13Z","receivedAt":"2017-08-30T07:15:20Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 11 +++++------\n 1 file changed, 5 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex ac57eea0f2..282ed7bd1b 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -822,19 +822,18 @@ int git_open_cloexec(const char *name, int flags)\n  * Note that it may point to static storage and is only valid until another\n  * call to sha1_file_name(), etc.\n  */\n-#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p)\n-static int stat_sha1_file_the_repository(const unsigned char *sha1,\n-\t\t\t\t\t struct stat *st, const char **path)\n+static int stat_sha1_file(struct repository *r, const unsigned char *sha1,\n+\t\t\t  struct stat *st, const char **path)\n {\n \tstruct alternate_object_database *alt;\n \n-\t*path = sha1_file_name(the_repository, sha1);\n+\t*path = sha1_file_name(r, sha1);\n \tif (!lstat(*path, st))\n \t\treturn 0;\n \n-\tprepare_alt_odb(the_repository);\n+\tprepare_alt_odb(r);\n \terrno = ENOENT;\n-\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = r->objects.alt_odb_list; alt; alt = alt->next) {\n \t\t*path = alt_sha1_path(alt, sha1);\n \t\tif (!lstat(*path, st))\n \t\t\treturn 0;\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327389","messageId":"20170830071606.GK153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 36/39] pack: allow open_sha1_file to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:16:06Z","receivedAt":"2017-08-30T07:16:13Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 11 +++++------\n 1 file changed, 5 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 282ed7bd1b..930705f59b 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -846,22 +846,21 @@ static int stat_sha1_file(struct repository *r, const unsigned char *sha1,\n  * Like stat_sha1_file(), but actually open the object and return the\n  * descriptor. See the caveats on the \"path\" parameter above.\n  */\n-#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p)\n-static int open_sha1_file_the_repository(const unsigned char *sha1,\n-\t\t\t\t\t const char **path)\n+static int open_sha1_file(struct repository *r,\n+\t\t\t  const unsigned char *sha1, const char **path)\n {\n \tint fd;\n \tstruct alternate_object_database *alt;\n \tint most_interesting_errno;\n \n-\t*path = sha1_file_name(the_repository, sha1);\n+\t*path = sha1_file_name(r, sha1);\n \tfd = git_open(*path);\n \tif (fd >= 0)\n \t\treturn fd;\n \tmost_interesting_errno = errno;\n \n-\tprepare_alt_odb(the_repository);\n-\tfor (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n+\tprepare_alt_odb(r);\n+\tfor (alt = r->objects.alt_odb_list; alt; alt = alt->next) {\n \t\t*path = alt_sha1_path(alt, sha1);\n \t\tfd = git_open(*path);\n \t\tif (fd >= 0)\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327390","messageId":"20170830071632.GL153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 37/39] pack: allow map_sha1_file_1 to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:16:32Z","receivedAt":"2017-08-30T07:16:39Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c | 8 +++-----\n 1 file changed, 3 insertions(+), 5 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 930705f59b..7fc5ebf2af 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -876,10 +876,8 @@ static int open_sha1_file(struct repository *r,\n  * Map the loose object at \"path\" if it is not NULL, or the path found by\n  * searching for a loose object named \"sha1\".\n  */\n-#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si)\n-static void *map_sha1_file_1_the_repository(const char *path,\n-\t\t\t\t\t    const unsigned char *sha1,\n-\t\t\t\t\t    unsigned long *size)\n+static void *map_sha1_file_1(struct repository *r, const char *path,\n+\t\t\t     const unsigned char *sha1, unsigned long *size)\n {\n \tvoid *map;\n \tint fd;\n@@ -887,7 +885,7 @@ static void *map_sha1_file_1_the_repository(const char *path,\n \tif (path)\n \t\tfd = git_open(path);\n \telse\n-\t\tfd = open_sha1_file(the_repository, sha1, &path);\n+\t\tfd = open_sha1_file(r, sha1, &path);\n \tmap = NULL;\n \tif (fd >= 0) {\n \t\tstruct stat st;\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327391","messageId":"20170830071656.GM153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 38/39] pack: allow map_sha1_file to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:16:56Z","receivedAt":"2017-08-30T07:17:03Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n object-store.h | 3 +--\n sha1_file.c    | 5 +++--\n 2 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex fe2187fd65..57b8d89738 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -61,8 +61,7 @@ struct packed_git {\n  * is overwritten each time the function is called.\n  */\n extern const char *sha1_file_name(struct repository *r, const unsigned char *sha1);\n-#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n-extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n+extern void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);\n \n extern void prepare_alt_odb(struct repository *r);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex 7fc5ebf2af..dc3c0b07ea 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -904,9 +904,10 @@ static void *map_sha1_file_1(struct repository *r, const char *path,\n \treturn map;\n }\n \n-void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size)\n+void *map_sha1_file(struct repository *r,\n+\t\t    const unsigned char *sha1, unsigned long *size)\n {\n-\treturn map_sha1_file_1(the_repository, NULL, sha1, size);\n+\treturn map_sha1_file_1(r, NULL, sha1, size);\n }\n \n static int unpack_sha1_short_header(git_zstream *stream,\n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327392","messageId":"20170830071805.GN153983@aiede.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"[PATCH 39/39] pack: allow sha1_loose_object_info to handle arbitrary repositories","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2017-08-30T07:18:05Z","receivedAt":"2017-08-30T07:18:11Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nThat's the end of the series.  Thanks for reading.\n\n sha1_file.c | 11 +++++------\n 1 file changed, 5 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex dc3c0b07ea..0f302a8c48 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1096,10 +1096,9 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)\n \treturn parse_sha1_header_extended(hdr, &oi, 0);\n }\n \n-#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f)\n-static int sha1_loose_object_info_the_repository(const unsigned char *sha1,\n-\t\t\t\t\t\t struct object_info *oi,\n-\t\t\t\t\t\t int flags)\n+static int sha1_loose_object_info(struct repository *r,\n+\t\t\t\t  const unsigned char *sha1,\n+\t\t\t\t  struct object_info *oi, int flags)\n {\n \tint status = 0;\n \tunsigned long mapsize;\n@@ -1123,14 +1122,14 @@ static int sha1_loose_object_info_the_repository(const unsigned char *sha1,\n \tif (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) {\n \t\tconst char *path;\n \t\tstruct stat st;\n-\t\tif (stat_sha1_file(the_repository, sha1, &st, &path) < 0)\n+\t\tif (stat_sha1_file(r, sha1, &st, &path) < 0)\n \t\t\treturn -1;\n \t\tif (oi->disk_sizep)\n \t\t\t*oi->disk_sizep = st.st_size;\n \t\treturn 0;\n \t}\n \n-\tmap = map_sha1_file(the_repository, sha1, &mapsize);\n+\tmap = map_sha1_file(r, sha1, &mapsize);\n \tif (!map)\n \t\treturn -1;\n \n-- \n2.14.1.581.gf28d330327\n\n"},{"id":"327461","messageId":"20170830194448.u653vadhgzmkru3y@sigill.intra.peff.net","threadId":"46683","inReplyTo":"20170830064827.GB153983@aiede.mtv.corp.google.com","subject":"Re: [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-08-30T19:44:48Z","receivedAt":"2017-08-30T19:45:00Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Aug 29, 2017 at 11:48:27PM -0700, Jonathan Nieder wrote:\n\n> The MRU cache that keeps track of recently used packs is represented\n> using two global variables:\n> \n> \tstruct mru packed_git_mru_storage;\n> \tstruct mru *packed_git_mru = &packed_git_mru_storage;\n> \n> Callers never assign to the packed_git_mru pointer, though, so we can\n> simplify by eliminating it and using &packed_git_mru_storage (renamed\n> to &packed_git_mru) directly.  This variable is only used by the\n> packfile subsystem, making this a relatively uninvasive change (and\n> any new unadapted callers would trigger a compile error).\n> \n> Noticed while moving these globals to the object_store struct.\n\nSounds reasonable. I think I had originally wanted to hide the\nimplementation and make the MRU more opaque, hence exposing only the\npointer. But since I ended up just letting people directly walk over the\nstruct pointers to do iteration, it needs to expose the struct internals\nanyway, and this layer of indirection isn't useful.\n\n> ---\n>  builtin/pack-objects.c |  4 ++--\n>  cache.h                |  4 ++--\n>  packfile.c             | 12 +++++-------\n>  3 files changed, 9 insertions(+), 11 deletions(-)\n\nThe patch looks good to me.\n\nAs an aside, the mru code could probably be simplified a bit by reusing\nthe list implementation from list.h (both were added around the same\ntime, and it wasn't worth creating a dependency then, but I think list.h\nis useful and here to stay at this point).\n\nIt's definitely not critical to put that into this already-large series,\nthough.  Maybe we can use Junio's #leftoverbits tag. :)\n\n-Peff\n"},{"id":"327473","messageId":"20170830224028.GE50018@google.com","threadId":"46683","inReplyTo":"20170830065631.GH153983@aiede.mtv.corp.google.com","subject":"Re: [PATCH 07/39] sha1_file: add repository argument to alt_odb_usable","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-08-30T22:40:28Z","receivedAt":"2017-08-30T22:40:36Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 08/29, Jonathan Nieder wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> Add a repository argument to allow the alt_odb_usable caller to be\n> more specific about which repository to act on. This is a small\n> mechanical change; it doesn't change the implementation to handle\n> repositories other than the_repository yet.\n> \n> Since the implementation does not yet work with other repositories,\n> use a wrapper macro to enforce that the caller passes in\n> the_repository as the first argument. It would be more appealing to\n> use BUILD_ASSERT_OR_ZERO to enforce this, but that doesn't work\n> because it requires a compile-time constant and common compilers like\n> gcc 4.8.4 do not consider \"r == the_repository\" a compile-time\n> constant.\n\nVery clever trick :)\n\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> ---\n>  sha1_file.c | 6 ++++--\n>  1 file changed, 4 insertions(+), 2 deletions(-)\n> \n> diff --git a/sha1_file.c b/sha1_file.c\n> index 7c6ffd205a..1c757b44a3 100644\n> --- a/sha1_file.c\n> +++ b/sha1_file.c\n> @@ -280,7 +280,9 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,\n>  /*\n>   * Return non-zero iff the path is usable as an alternate object database.\n>   */\n> -static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)\n> +#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)\n> +static int alt_odb_usable_the_repository(struct strbuf *path,\n> +\t\t\t\t\t const char *normalized_objdir)\n>  {\n>  \tstruct alternate_object_database *alt;\n>  \n> @@ -348,7 +350,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,\n>  \twhile (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')\n>  \t\tstrbuf_setlen(&pathbuf, pathbuf.len - 1);\n>  \n> -\tif (!alt_odb_usable(&pathbuf, normalized_objdir)) {\n> +\tif (!alt_odb_usable(the_repository, &pathbuf, normalized_objdir)) {\n>  \t\tstrbuf_release(&pathbuf);\n>  \t\treturn -1;\n>  \t}\n> -- \n> 2.14.1.581.gf28d330327\n> \n\n-- \nBrandon Williams\n"},{"id":"327474","messageId":"20170830230755.GF50018@google.com","threadId":"46683","inReplyTo":"20170830064634.GA153983@aiede.mtv.corp.google.com","subject":"Re: [PATCH 00/39] per-repository object store, part 1","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-08-30T23:07:55Z","receivedAt":"2017-08-30T23:08:04Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 08/29, Jonathan Nieder wrote:\n> Hi,\n> \n> Most of the credit for this series should go to Stefan Beller.  I just\n> decided to pull the trigger on sending out what we have so far.\n> \n> This series is about API.  It makes no functional change yet.\n> \n> Today, when a git command wants to operate on some objects from another\n> repository (e.g., a submodule), it has two choices:\n> \n>  A. Use run_command to operate on that repository in a separate process.\n> \n>  B. Use add_to_alternates_memory to pretend the repository is an\n>     alternate.  This has a number of downsides.  Aside from aesthetics,\n>     one particularly painful consequence is that as alternates\n>     accumulate, the number of packs git has to check for objects\n>     increases, which can cause significant slowdowns.\n> \n> Brandon Williams's recent work to introduce \"struct repository\" points\n> to a better way.  Encapsulating object access in struct repository\n> would mean:\n> \n>   i. The API for accessing objects in another repository becomes more\n>      simple and familiar (instead of using the CLI or abusing alternates).\n> \n>   ii. Operations on one repository do not interfere with another,\n>       neither in semantics (e.g. replace objects do not work correctly\n>       with the approach (B) above) nor performance (already described\n>       above).\n> \n>  iii. Resources associated with access to a repository could be freed\n>       when done with that repo.\n> \n>   iv. Thread-safe multiple readers to a single repository also become\n>       straightforward, by using multiple repository objects for the same\n>       repo.\n> \n> This series is a small step in that direction.\n> \n> At the end of this series, sha1_loose_object_info takes a repository\n> argument and can be independently called for multiple repositories.\n> Not incredibly useful on its own, but a future series will do the same\n> for sha1_object_info, which will be enough to migrate a caller in\n> submodule.c (which uses the object store for commit existence checks).\n> \n> This series has a few phases:\n> \n>  1. Patch 1 is a cleanup that made some of the later patches easier.\n> \n>  2. Patches 2-6 create a struct object_store field inside struct\n>     repository and move some globals to it.\n> \n>  3. Patches 7-24 are mechanical changes that update some functions to\n>     accept a repository argument. The only goal is to make the later\n>     patches that teach these functions to actual handle a repository\n>     other than the_repository easier to review.  The patches enforce\n>     at compile time that no caller passes a repository other than\n>     the_repository --- see patch 7 in particular for details on how\n>     that works.\n> \n>  4. Patches 25-39 update the implementations of those functions to\n>     handle a repository other than the_repository.  This means the\n>     safety check introduced in phase 3 goes away completely --- all\n>     functions that gained a repository argument are safe to use with\n>     a repository argument other than the_repository.\n> \n> Patches 2-6 and 25-39 should be the most interesting to review.  I'd\n> particularly appreciate if people can look over 25-39 carefully.  We\n> were careful not to leave any calls to functions that assume they are\n> operating on the_repository, but a triple-check is always welcome.\n> \n> Thanks as well to brian m. carlson, who showed us how such a long and\n> potentially tedius series can be made bearable for reviewers.\n> \n> Thoughts of all kinds welcome, as always.\n\nJust finished looking through the series.  Thanks for keeping each\ncommit very short and to the point, it made reviewing it much easier.  I\ncouldn't see anything wrong these transformations and I am very happy to\nsee this work getting done.\n\nOne thing that needs to be noted is that currently the object_store is\nonly really being used by the_repository so this series didn't need to\ncreate any object_store_init() or object_store_clear() type functions.\nSo these types of functions will need to be added once submodules are\nusing their own object store, in their own struct repository.\n\n> \n> Thanks,\n> Jonathan Nieder (24):\n>   pack: make packed_git_mru global a value instead of a pointer\n>   object-store: move packed_git and packed_git_mru to object store\n>     struct\n>   pack: move prepare_packed_git_run_once to object store struct\n>   pack: move approximate object count to object store struct\n>   pack: add repository argument to install_packed_git\n>   pack: add repository argument to prepare_packed_git_one\n>   pack: add repository argument to rearrange_packed_git\n>   pack: add repository argument to prepare_packed_git_mru\n>   pack: add repository argument to prepare_packed_git\n>   pack: add repository argument to reprepare_packed_git\n>   pack: add repository argument to sha1_file_name\n>   pack: add repository argument to map_sha1_file\n>   pack: allow install_packed_git to handle arbitrary repositories\n>   pack: allow rearrange_packed_git to handle arbitrary repositories\n>   pack: allow prepare_packed_git_mru to handle arbitrary repositories\n>   pack: allow prepare_packed_git_one to handle arbitrary repositories\n>   pack: allow prepare_packed_git to handle arbitrary repositories\n>   pack: allow reprepare_packed_git to handle arbitrary repositories\n>   pack: allow sha1_file_name to handle arbitrary repositories\n>   pack: allow stat_sha1_file to handle arbitrary repositories\n>   pack: allow open_sha1_file to handle arbitrary repositories\n>   pack: allow map_sha1_file_1 to handle arbitrary repositories\n>   pack: allow map_sha1_file to handle arbitrary repositories\n>   pack: allow sha1_loose_object_info to handle arbitrary repositories\n> \n> Stefan Beller (15):\n>   repository: introduce object store field\n>   object-store: move alt_odb_list and alt_odb_tail to object store\n>     struct\n>   sha1_file: add repository argument to alt_odb_usable\n>   sha1_file: add repository argument to link_alt_odb_entry\n>   sha1_file: add repository argument to read_info_alternates\n>   sha1_file: add repository argument to link_alt_odb_entries\n>   sha1_file: add repository argument to stat_sha1_file\n>   sha1_file: add repository argument to open_sha1_file\n>   sha1_file: add repository argument to map_sha1_file_1\n>   sha1_file: add repository argument to sha1_loose_object_info\n>   object-store: add repository argument to prepare_alt_odb\n>   object-store: add repository argument to foreach_alt_odb\n>   sha1_file: allow alt_odb_usable to handle arbitrary repositories\n>   object-store: allow prepare_alt_odb to handle arbitrary repositories\n>   object-store: allow foreach_alt_odb to handle arbitrary repositories\n> \n>  builtin/count-objects.c             |  10 ++-\n>  builtin/fsck.c                      |  15 ++--\n>  builtin/gc.c                        |   8 +-\n>  builtin/index-pack.c                |   1 +\n>  builtin/pack-objects.c              |  23 +++--\n>  builtin/pack-redundant.c            |   8 +-\n>  builtin/receive-pack.c              |   4 +-\n>  builtin/submodule--helper.c         |   4 +-\n>  bulk-checkin.c                      |   3 +-\n>  cache.h                             |  50 ++---------\n>  contrib/coccinelle/packed_git.cocci |  15 ++++\n>  fast-import.c                       |  10 ++-\n>  fetch-pack.c                        |   3 +-\n>  http-backend.c                      |   8 +-\n>  http-push.c                         |   1 +\n>  http-walker.c                       |   4 +-\n>  http.c                              |   9 +-\n>  mru.h                               |   1 +\n>  object-store.h                      |  71 ++++++++++++++++\n>  pack-bitmap.c                       |   6 +-\n>  pack-check.c                        |   1 +\n>  pack-revindex.c                     |   1 +\n>  packfile.c                          |  94 ++++++++++----------\n>  packfile.h                          |   6 +-\n>  reachable.c                         |   1 +\n>  repository.c                        |   4 +-\n>  repository.h                        |   7 ++\n>  server-info.c                       |   8 +-\n>  sha1_file.c                         | 165 ++++++++++++++++++++----------------\n>  sha1_name.c                         |  11 ++-\n>  streaming.c                         |   5 +-\n>  transport.c                         |   4 +-\n>  32 files changed, 344 insertions(+), 217 deletions(-)\n>  create mode 100644 contrib/coccinelle/packed_git.cocci\n>  create mode 100644 object-store.h\n> \n> -- \n> 2.14.1.581.gf28d330327\n> \n\n-- \nBrandon Williams\n"},{"id":"327666","messageId":"xmqqfubz61x8.fsf@gitster.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830194448.u653vadhgzmkru3y@sigill.intra.peff.net","subject":"Re: [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-09-06T19:51:31Z","receivedAt":"2017-09-06T19:51:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> As an aside, the mru code could probably be simplified a bit by reusing\n> the list implementation from list.h (both were added around the same\n> time, and it wasn't worth creating a dependency then, but I think list.h\n> is useful and here to stay at this point).\n>\n> It's definitely not critical to put that into this already-large series,\n> though.  Maybe we can use Junio's #leftoverbits tag. :)\n\nI had the same reaction while reading it; perhaps I should read the\nresponses from trusted reviewers first before reading the patches\nmyself ;-)\n\nThanks.\n"},{"id":"327671","messageId":"xmqqd1734mvg.fsf@gitster.mtv.corp.google.com","threadId":"46683","inReplyTo":"20170830070812.GZ153983@aiede.mtv.corp.google.com","subject":"Re: [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-09-06T20:01:55Z","receivedAt":"2017-09-06T20:02:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> ---\n>  sha1_file.c | 16 +++++++++-------\n>  1 file changed, 9 insertions(+), 7 deletions(-)\n>\n> diff --git a/sha1_file.c b/sha1_file.c\n> index e7c86e5363..b854cad970 100644\n> --- a/sha1_file.c\n> +++ b/sha1_file.c\n> @@ -25,6 +25,7 @@\n>  #include \"repository.h\"\n>  #include \"object-store.h\"\n>  #include \"streaming.h\"\n> +#include \"path.h\"\n>  #include \"dir.h\"\n>  #include \"mru.h\"\n>  #include \"list.h\"\n> @@ -281,17 +282,18 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,\n>  /*\n>   * Return non-zero iff the path is usable as an alternate object database.\n>   */\n> -#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)\n> -static int alt_odb_usable_the_repository(struct strbuf *path,\n> -\t\t\t\t\t const char *normalized_objdir)\n> +static int alt_odb_usable(struct repository *r, struct strbuf *path,\n> +\t\t\t  const char *normalized_objdir)\n\nThese token-pasting macros introduced in 07-24/39 were certainly\ncute but they may be rather misleading and useless.  e.g. a natural\nexpectaion would be\n\n\tstruct repository *r = &the_repository;\n\tprepare_alt_odb(r);\n\nto work, but obviously it wouldn't.  And this step and later in\n25-39/39 corrects them one by one.\n\nI suspect that you used the token-pasting cuteness because you\nthought that the callsite would not have to change in the later step\nlike 25/39 that removes the trick.  I also suspect that you thought\nthat it may be a good thing that prepare_alt_odb(r) does not work\nimmediately after 07/39, as the callee is not prepared.  But both of\nthese are misguided.\n\nIf you have two functions, A and B, that we want to update to\neventually take a \"struct repository *\" argument, and if A uses B in\nits implementation, the endgame would be\n\n\tA(struct repository *r, ...)\n\t{\n\t\t...\n\t\tB(r, ...);\n\t\t...\n\t}\n\nbut with the ##r approach, the call to B in A in the initial\ntoken-pasting phase would say B(the_repository, ...) so the call\nwill need to be changed in the step you update A's implementation to\ntake a caller-supplied respotory object anyway.  And the fact that a\nfunction's first parameter is not the_repository (i.e. leaving B()'s\nsignature unchanged while it is not ready to take a repository) is\nsufficient to mark that a function is not yet prepared to take a\ncaller-supplied repository object.\n\nI found that this aspect of the structure of the series was somewhat\nirritating in that (1) combining the earlier ##r thing with its fix\nwould have made the code that needs to be reviewed much cleaner, (2)\nit wouldn't have made the patch that longer, and most importantly\n(3) it is unclear why 24-7 != 39-25, i.e. it is hard to answer \"is\nthere any ##r hack still remaining after this series?  if so why?\"\n\nThe end-result of the whole series makes me think that it is going\nin the right direction, though.\n\nThanks.\n"},{"id":"327676","messageId":"CAGZ79kb+GDvh8+HZ6Hu8ydj6BUNY4YckvyXtvZbsxaME9zyWYQ@mail.gmail.com","threadId":"46683","inReplyTo":"xmqqd1734mvg.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-09-06T21:59:58Z","receivedAt":"2017-09-06T22:00:07Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Sep 6, 2017 at 1:01 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jonathan Nieder <jrnieder@gmail.com> writes:\n>\n>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n>> Signed-off-by: Stefan Beller <sbeller@google.com>\n>> ---\n>>  sha1_file.c | 16 +++++++++-------\n>>  1 file changed, 9 insertions(+), 7 deletions(-)\n>>\n>> diff --git a/sha1_file.c b/sha1_file.c\n>> index e7c86e5363..b854cad970 100644\n>> --- a/sha1_file.c\n>> +++ b/sha1_file.c\n>> @@ -25,6 +25,7 @@\n>>  #include \"repository.h\"\n>>  #include \"object-store.h\"\n>>  #include \"streaming.h\"\n>> +#include \"path.h\"\n>>  #include \"dir.h\"\n>>  #include \"mru.h\"\n>>  #include \"list.h\"\n>> @@ -281,17 +282,18 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,\n>>  /*\n>>   * Return non-zero iff the path is usable as an alternate object database.\n>>   */\n>> -#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)\n>> -static int alt_odb_usable_the_repository(struct strbuf *path,\n>> -                                      const char *normalized_objdir)\n>> +static int alt_odb_usable(struct repository *r, struct strbuf *path,\n>> +                       const char *normalized_objdir)\n>\n> These token-pasting macros introduced in 07-24/39 were certainly\n> cute but they may be rather misleading and useless.  e.g. a natural\n> expectaion would be\n>\n>         struct repository *r = &the_repository;\n>         prepare_alt_odb(r);\n>\n> to work, but obviously it wouldn't.  And this step and later in\n> 25-39/39 corrects them one by one.\n\nYes. The intent was to deliver patches that are easiest to review as\nthat is usually the crux with long series. To do that we came up with this\nway:\n* patches  07-24 can be reviewed easily by only looking at\n   the textual replacement, no need to think about implications.\n   It should be boring(in a good way) to review these.\n* patches 25-39, that allow arbitrary repositories to be handled\n   only need to be reviewed inside its function bounds, because\n   each function call that takes a repository argument will be verified\n   by the compiler, precisely because the above won't work!\n   That way the reviewer can rely on the compile output\n   that the conversion was done in the correct order and no\n   small function was missed. All review attention can go into\n   just looking at the one function that is converted in such a\n   patch. no need to double check with other parts of the code.\n   We discussed we'd send the patches 25-39 with --function-context.\n   The follow ups will do so.\n\n> I suspect that you used the token-pasting cuteness because you\n> thought that the callsite would not have to change in the later step\n> like 25/39 that removes the trick.\n\nNo. We did these two different phases to ease review specifically.\n\nNote how the call site is the function itself, ( --function-context would\nhave been really neat here)\n\n\n>  I also suspect that you thought\n> that it may be a good thing that prepare_alt_odb(r) does not work\n> immediately after 07/39, as the callee is not prepared.  But both of\n> these are misguided.\n>\n> If you have two functions, A and B, that we want to update to\n> eventually take a \"struct repository *\" argument, and if A uses B in\n> its implementation, the endgame would be\n>\n>         A(struct repository *r, ...)\n>         {\n>                 ...\n>                 B(r, ...);\n>                 ...\n>         }\n>\n> but with the ##r approach, the call to B in A in the initial\n> token-pasting phase would say B(the_repository, ...) so the call\n> will need to be changed in the step you update A's implementation to\n> take a caller-supplied respotory object anyway.  And the fact that a\n> function's first parameter is not the_repository (i.e. leaving B()'s\n> signature unchanged while it is not ready to take a repository) is\n> sufficient to mark that a function is not yet prepared to take a\n> caller-supplied repository object.\n\nThe absence of a repository argument is not sufficient that a function\n(or any function called by it) does not rely on some global state, which\nneeds to be put into the repository struct.\n\nSo when converting function A (above), the careful reviewer needs to\ninspect B, C, D... if they touch global state. Using the current approach,\nmost functions (maybe just B and C here) would take a repository struct\nalready, and the compiler would yell if these were not ready for anything\nexcept the_repository. So the reviewer only has to worry about D.\n\n> I found that this aspect of the structure of the series was somewhat\n> irritating in that (1) combining the earlier ##r thing with its fix\n> would have made the code that needs to be reviewed much cleaner,\n\nagreed.\n\n> (2) it wouldn't have made the patch that longer,\n\nbut more complicated to review (and write actually; as it was easy\nto reason about functions to be ready for conversion, not using\nglobal state)\n\n> and most importantly\n> (3) it is unclear why 24-7 != 39-25, i.e. it is hard to answer \"is\n> there any ##r hack still remaining after this series?  if so why?\"\n\nJonathan is currently OOO, but last week we continued developing this\nseries and ended up with ca. 90 patches in the series.\n\n> The end-result of the whole series makes me think that it is going\n> in the right direction, though.\n\nWe'll revisit if we can squash commits before sending out.\n\nThanks for the feedback,\nStefan\n"}]}