{"thread":{"id":"47963","subject":"Re: [PATCH 00/11] Moving global state into the repository object (part 2)","startedAt":"2018-03-03T02:54:51Z","lastAt":"2018-03-26T21:05:27Z","messageCount":135,"participants":["Duy Nguyen","Nguyễn Thái Ngọc Duy","Eric Sunshine","Junio C Hamano","Jonathan Tan","Brandon Williams","Stefan Beller"],"isPatch":true,"patchVersion":1,"patchTotal":11},"messages":[{"id":"340858","messageId":"CACsJy8DWrNzZM1K2vkx2XiETdAR5WhwXEdPijsxd0ZD4Lj=tZw@mail.gmail.com","threadId":"47963","inReplyTo":null,"subject":"Re: [PATCH 00/11] Moving global state into the repository object (part 2)","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T02:54:15Z","receivedAt":"2018-03-03T02:54:51Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Mar 1, 2018 at 2:09 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Stefan Beller <sbeller@google.com> writes:\n>\n>> On Wed, Feb 28, 2018 at 9:59 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Duy Nguyen <pclouds@gmail.com> writes:\n>>>\n>>>> Looking at the full-series diff though, it makes me wonder if we\n>>>> should keep prepare_packed_git() private (i.e. how we initialize the\n>>>> object store, packfile included, is a private matter). How about\n>>>> something like this on top?\n>>>\n>>> Yup, that looks cleaner.\n>>\n>> I agree that it looks cleaner. So we plan on just putting\n>> it on top of that series?\n>\n> We tend to avoid \"oops, that was wrong and here is a band aid on\n> top\" for things that are still mushy, so it would be preferrable to\n> get it fixed inline, especially if there are more changes to the\n> other parts of the series coming.\n\nI agree with this. Stefan, if you're getting bored with rerolling\nrefactor patches, I can update this series and send out v2.\n-- \nDuy\n"},{"id":"340892","messageId":"20180303113637.26518-1-pclouds@gmail.com","threadId":"47963","inReplyTo":"CACsJy8DWrNzZM1K2vkx2XiETdAR5WhwXEdPijsxd0ZD4Lj=tZw@mail.gmail.com","subject":"[PATCH 00/44] reroll nd/remove-ignore-env.. sb/object-store and sb/packfiles..","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:35:53Z","receivedAt":"2018-03-03T11:36:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Mar 3, 2018 at 9:54 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Thu, Mar 1, 2018 at 2:09 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Stefan Beller <sbeller@google.com> writes:\n>>\n>>> On Wed, Feb 28, 2018 at 9:59 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>>> Duy Nguyen <pclouds@gmail.com> writes:\n>>>>\n>>>>> Looking at the full-series diff though, it makes me wonder if we\n>>>>> should keep prepare_packed_git() private (i.e. how we initialize the\n>>>>> object store, packfile included, is a private matter). How about\n>>>>> something like this on top?\n>>>>\n>>>> Yup, that looks cleaner.\n>>>\n>>> I agree that it looks cleaner. So we plan on just putting\n>>> it on top of that series?\n>>\n>> We tend to avoid \"oops, that was wrong and here is a band aid on\n>> top\" for things that are still mushy, so it would be preferrable to\n>> get it fixed inline, especially if there are more changes to the\n>> other parts of the series coming.\n>\n> I agree with this. Stefan, if you're getting bored with rerolling\n> refactor patches, I can update this series and send out v2.\n\nSince Stefan is traveling, I take this opportunity to reroll it.\nUnfortunately, I think the fix should go in 46cd557bd9 (object-store:\nmove packed_git and packed_git_mru to object store - 2018-02-23) where\nwe start removing the global \"packed_git\". But that's in\nsb/object-store, so.. I'm rerolling all three\n\n01/44 - 05/44: nd/remove-ignore-env-field\n\n  This series is moved up top. After this the patch that touch\n  alternate-db in sha1_file.c looks natural because no env is involved\n  anymore\n\n  I also take this opportunity to introduce a new patch 01/44 to avoid\n  struct initialization that makes it hard to read and update. Later\n  patches are also simplified thanks to this.\n\n06/44 - 32/44: sb/object-store\n\n  06/44 is updated to introduce raw_object_store_init() instead of\n  RAW_OBJECT_STORE_INIT macro. This function is now used to initialize\n  both main repo and submodule ones.\n\n  10/44 (moving \"packed_git\") also introduces two new access wrapper\n  get_packed_git() and get_packed_git_mru()\n\n33/44 - 44/44: sb/packfiles-in-repository\n\n  The only thing new here is 44/44 which makes prepare_packed_git()\n  internal. get_packed_git() and get_packed_git_mru() introduced\n  earlier will call prepare_packed_git() automatically.\n\nThe whole thing is also available at\n\nhttps://github.com/pclouds/git/tree/ignore-env-object-store-packfiles\n\nAnd interdiff of all three, compared to what is currently in 'pu'.\nLooks pretty good in my opinon:\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex d480301763..ee6ae35244 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -121,9 +121,8 @@ 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 (!the_repository->objects.packed_git)\n-\t\t\tprepare_packed_git(the_repository);\n-\t\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n+\n+\t\tfor (p = get_packed_git(the_repository); 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 030c7fb7a0..9911c52bc8 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -726,10 +726,8 @@ 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(the_repository);\n-\n \t\t\tif (show_progress) {\n-\t\t\t\tfor (p = the_repository->objects.packed_git; p;\n+\t\t\t\tfor (p = get_packed_git(the_repository); 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@@ -738,7 +736,7 @@ 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 = the_repository->objects.packed_git; p;\n+\t\t\tfor (p = get_packed_git(the_repository); 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,\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 80d19c54d5..be63bec09c 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -173,8 +173,7 @@ static int too_many_packs(void)\n \tif (gc_auto_pack_limit <= 0)\n \t\treturn 0;\n \n-\tprepare_packed_git(the_repository);\n-\tfor (cnt = 0, p = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {\n \t\tif (!p->pack_local)\n \t\t\tcontinue;\n \t\tif (p->pack_keep)\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 142ec223cb..435f091a69 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -1026,7 +1026,7 @@ static int want_object_in_pack(const struct object_id *oid,\n \t\tif (want != -1)\n \t\t\treturn want;\n \t}\n-\tlist_for_each(pos, &the_repository->objects.packed_git_mru) {\n+\tlist_for_each(pos, get_packed_git_mru(the_repository)) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\toff_t offset;\n \n@@ -1045,7 +1045,7 @@ static int want_object_in_pack(const struct object_id *oid,\n \t\t\twant = want_found_object(exclude, p);\n \t\t\tif (!exclude && want > 0)\n \t\t\t\tlist_move(&p->mru,\n-\t\t\t\t\t  &the_repository->objects.packed_git_mru);\n+\t\t\t\t\t  get_packed_git_mru(the_repository));\n \t\t\tif (want != -1)\n \t\t\t\treturn want;\n \t\t}\n@@ -2674,7 +2674,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 = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (p = get_packed_git(the_repository); p; p = p->next) {\n \t\tstruct object_id oid;\n \t\tstruct object *o;\n \n@@ -2738,7 +2738,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\n \tstruct packed_git *p;\n \n \tp = (last_found != (void *)1) ? last_found :\n-\t\t\t\t\tthe_repository->objects.packed_git;\n+\t\t\t\t\tget_packed_git(the_repository);\n \n \twhile (p) {\n \t\tif ((!p->pack_local || p->pack_keep) &&\n@@ -2747,7 +2747,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\n \t\t\treturn 1;\n \t\t}\n \t\tif (p == last_found)\n-\t\t\tp = the_repository->objects.packed_git;\n+\t\t\tp = get_packed_git(the_repository);\n \t\telse\n \t\t\tp = p->next;\n \t\tif (p == last_found)\n@@ -2783,7 +2783,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)\n \tuint32_t i;\n \tstruct object_id oid;\n \n-\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (p = get_packed_git(the_repository); p; p = p->next) {\n \t\tif (!p->pack_local || p->pack_keep)\n \t\t\tcontinue;\n \n@@ -3151,10 +3151,9 @@ 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(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)\n+\t\tfor (p = get_packed_git(the_repository); 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@@ -3167,7 +3166,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 = the_repository->objects.packed_git; p; p = p->next) {\n+\t\tfor (p = get_packed_git(the_repository); 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 3b02f94248..02b5f0becc 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -572,7 +572,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 = the_repository->objects.packed_git;\n+\tstruct packed_git *p = get_packed_git(the_repository);\n \n \tif (strlen(filename) < 40)\n \t\tdie(\"Bad pack filename: %s\", filename);\n@@ -587,7 +587,7 @@ static struct pack_list * add_pack_file(const char *filename)\n \n static void load_all(void)\n {\n-\tstruct packed_git *p = the_repository->objects.packed_git;\n+\tstruct packed_git *p = get_packed_git(the_repository);\n \n \twhile (p) {\n \t\tadd_pack(p);\n@@ -630,8 +630,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)\n \t\t\tbreak;\n \t}\n \n-\tprepare_packed_git(the_repository);\n-\n \tif (load_all_packs)\n \t\tload_all();\n \telse\ndiff --git a/common-main.c b/common-main.c\nindex 6a689007e7..7d716d5a54 100644\n--- a/common-main.c\n+++ b/common-main.c\n@@ -34,6 +34,8 @@ int main(int argc, const char **argv)\n \n \tgit_setup_gettext();\n \n+\tinitialize_the_repository();\n+\n \tattr_start();\n \n \tgit_extract_argv0_path(argv[0]);\ndiff --git a/environment.c b/environment.c\nindex b2128c1188..c05705e384 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -13,8 +13,8 @@\n #include \"refs.h\"\n #include \"fmt-merge-msg.h\"\n #include \"commit.h\"\n-#include \"object-store.h\"\n #include \"argv-array.h\"\n+#include \"object-store.h\"\n \n int trust_executable_bit = 1;\n int trust_ctime = 1;\ndiff --git a/fast-import.c b/fast-import.c\nindex d2032e4ade..2298bfcdfd 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -1112,7 +1112,7 @@ static int store_object(\n \t\tduplicate_count_by_type[type]++;\n \t\treturn 1;\n \t} else if (find_sha1_pack(oid.hash,\n-\t\t\t\t  the_repository->objects.packed_git)) {\n+\t\t\t\t  get_packed_git(the_repository))) {\n \t\te->type = type;\n \t\te->pack_id = MAX_PACK_ID;\n \t\te->idx.offset = 1; /* just not zero! */\n@@ -1308,7 +1308,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)\n \t\ttruncate_pack(&checkpoint);\n \n \t} else if (find_sha1_pack(oid.hash,\n-\t\t\t\t  the_repository->objects.packed_git)) {\n+\t\t\t\t  get_packed_git(the_repository))) {\n \t\te->type = OBJ_BLOB;\n \t\te->pack_id = MAX_PACK_ID;\n \t\te->idx.offset = 1; /* just not zero! */\n@@ -3472,7 +3472,6 @@ 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(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 defa6ba350..22d2e1668e 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -518,14 +518,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg)\n \tsize_t cnt = 0;\n \n \tselect_getanyfile(hdr);\n-\tprepare_packed_git(the_repository);\n-\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (p = get_packed_git(the_repository); 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 = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (p = get_packed_git(the_repository); 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/object-store.h b/object-store.h\nindex 9b1303549b..521f5a1755 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -90,9 +90,9 @@ struct raw_object_store {\n \t/* Path to extra alternate object database if not NULL */\n \tchar *alternate_db;\n \n-\tstruct packed_git *packed_git;\n+\tstruct packed_git *packed_git; /* private */\n \t/* A most-recently-used ordered version of the packed_git list. */\n-\tstruct list_head packed_git_mru;\n+\tstruct list_head packed_git_mru; /* private */\n \n \tstruct alternate_object_database *alt_odb_list;\n \tstruct alternate_object_database **alt_odb_tail;\n@@ -112,8 +112,7 @@ struct raw_object_store {\n \tunsigned packed_git_initialized : 1;\n };\n \n-#define RAW_OBJECT_STORE_INIT(o) { NULL, NULL, NULL, LIST_HEAD_INIT(o.packed_git_mru), NULL, NULL, 0, 0, 0 }\n-\n+void raw_object_store_init(struct raw_object_store *o);\n void raw_object_store_clear(struct raw_object_store *o);\n \n /*\ndiff --git a/object.c b/object.c\nindex 5317cfc390..60ca76b285 100644\n--- a/object.c\n+++ b/object.c\n@@ -447,6 +447,12 @@ void clear_commit_marks_all(unsigned int flags)\n \t}\n }\n \n+void raw_object_store_init(struct raw_object_store *o)\n+{\n+\tmemset(o, 0, sizeof(*o));\n+\tINIT_LIST_HEAD(&o->packed_git_mru);\n+}\n+\n static void free_alt_odb(struct alternate_object_database *alt)\n {\n \tstrbuf_release(&alt->scratch);\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex bcc04bc45e..2a007b5539 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -335,8 +335,7 @@ static int open_pack_bitmap(void)\n \n \tassert(!bitmap_git.map && !bitmap_git.loaded);\n \n-\tprepare_packed_git(the_repository);\n-\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (p = get_packed_git(the_repository); p; p = p->next) {\n \t\tif (open_pack_bitmap_1(p) == 0)\n \t\t\tret = 0;\n \t}\ndiff --git a/packfile.c b/packfile.c\nindex 1a045157d0..773cd99a13 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -802,6 +802,7 @@ static void prepare_packed_git_one(struct repository *r, char *objdir, int local\n \tstrbuf_release(&path);\n }\n \n+static void prepare_packed_git(struct repository *r);\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@@ -882,7 +883,7 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\n }\n \n-void prepare_packed_git(struct repository *r)\n+static void prepare_packed_git(struct repository *r)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -904,6 +905,18 @@ void reprepare_packed_git(struct repository *r)\n \tprepare_packed_git(r);\n }\n \n+struct packed_git *get_packed_git(struct repository *r)\n+{\n+\tprepare_packed_git(r);\n+\treturn r->objects.packed_git;\n+}\n+\n+struct list_head *get_packed_git_mru(struct repository *r)\n+{\n+\tprepare_packed_git(r);\n+\treturn &r->objects.packed_git_mru;\n+}\n+\n unsigned long unpack_object_header_buffer(const unsigned char *buf,\n \t\tunsigned long len, enum object_type *type, unsigned long *sizep)\n {\ndiff --git a/packfile.h b/packfile.h\nindex 6f7b9e91d6..efda10329c 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,10 +34,12 @@ 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(struct repository *r);\n extern void reprepare_packed_git(struct repository *r);\n extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \n+struct packed_git *get_packed_git(struct repository *r);\n+struct list_head *get_packed_git_mru(struct repository *r);\n+\n /*\n  * Give a rough count of objects in the repository. This sacrifices accuracy\n  * for speed.\ndiff --git a/repository.c b/repository.c\nindex 4f44384dde..34c0a7f180 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -5,16 +5,17 @@\n #include \"submodule-config.h\"\n \n /* The main repository */\n-static struct repository the_repo = {\n-\tNULL, NULL,\n-\tRAW_OBJECT_STORE_INIT(the_repo.objects),\n-\tNULL, NULL, NULL,\n-\tNULL, NULL, NULL,\n-\t&the_index,\n-\t&hash_algos[GIT_HASH_SHA1],\n-\t0\n-};\n-struct repository *the_repository = &the_repo;\n+static struct repository the_repo;\n+struct repository *the_repository;\n+\n+void initialize_the_repository(void)\n+{\n+\tthe_repository = &the_repo;\n+\n+\tthe_repo.index = &the_index;\n+\traw_object_store_init(&the_repo.objects);\n+\trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n+}\n \n static void expand_base_dir(char **out, const char *in,\n \t\t\t    const char *base_dir, const char *def_in)\n@@ -134,12 +135,14 @@ static int read_and_verify_repository_format(struct repository_format *format,\n  * Initialize 'repo' based on the provided 'gitdir'.\n  * Return 0 upon success and a non-zero value upon failure.\n  */\n-int repo_init(struct repository *repo, const char *gitdir, const char *worktree)\n+static int repo_init(struct repository *repo,\n+\t\t     const char *gitdir,\n+\t\t     const char *worktree)\n {\n \tstruct repository_format format;\n \tmemset(repo, 0, sizeof(*repo));\n \n-\tINIT_LIST_HEAD(&repo->objects.packed_git_mru);\n+\traw_object_store_init(&repo->objects);\n \n \tif (repo_init_gitdir(repo, gitdir))\n \t\tgoto error;\ndiff --git a/repository.h b/repository.h\nindex e05a77a099..6c383c05c6 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -93,7 +93,7 @@ extern void repo_set_gitdir(struct repository *repo,\n \t\t\t    const struct set_gitdir_args *optional);\n extern void repo_set_worktree(struct repository *repo, const char *path);\n extern void repo_set_hash_algo(struct repository *repo, int algo);\n-extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree);\n+extern void initialize_the_repository(void);\n extern int repo_submodule_init(struct repository *submodule,\n \t\t\t       struct repository *superproject,\n \t\t\t       const char *path);\ndiff --git a/server-info.c b/server-info.c\nindex f5e4d1cc89..af737acd24 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -200,8 +200,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(the_repository);\n-\tfor (p = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (p = get_packed_git(the_repository); 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@@ -211,7 +210,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 = the_repository->objects.packed_git; p; p = p->next) {\n+\tfor (i = 0, p = get_packed_git(the_repository); 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 773322ac81..f25a0970ca 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -195,8 +195,7 @@ static void find_short_packed_object(struct disambiguate_state *ds)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git(the_repository);\n-\tfor (p = the_repository->objects.packed_git; p && !ds->ambiguous;\n+\tfor (p = get_packed_git(the_repository); p && !ds->ambiguous;\n \t     p = p->next)\n \t\tunique_in_pack(p, ds);\n }\n@@ -566,8 +565,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git(the_repository);\n-\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n+\tfor (p = get_packed_git(the_repository); p; p = p->next)\n \t\tfind_abbrev_len_for_pack(p, mad);\n }\n \n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340893","messageId":"20180303113637.26518-2-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 01/44] repository: initialize the_repository in main()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:35:54Z","receivedAt":"2018-03-03T11:36:58Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This simplifies initialization of struct repository and anything\ninside. Easier to read. Easier to add/remove fields.\n\nEverything will go through main() common-main.c so this should cover all\nprograms, including t/helper.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n common-main.c |  2 ++\n repository.c  | 18 +++++++++++++-----\n repository.h  |  2 +-\n 3 files changed, 16 insertions(+), 6 deletions(-)\n\ndiff --git a/common-main.c b/common-main.c\nindex 6a689007e7..7d716d5a54 100644\n--- a/common-main.c\n+++ b/common-main.c\n@@ -34,6 +34,8 @@ int main(int argc, const char **argv)\n \n \tgit_setup_gettext();\n \n+\tinitialize_the_repository();\n+\n \tattr_start();\n \n \tgit_extract_argv0_path(argv[0]);\ndiff --git a/repository.c b/repository.c\nindex 4ffbe9bc94..0eddf28fcd 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -4,10 +4,16 @@\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, &hash_algos[GIT_HASH_SHA1], 0, 0\n-};\n-struct repository *the_repository = &the_repo;\n+static struct repository the_repo;\n+struct repository *the_repository;\n+\n+void initialize_the_repository(void)\n+{\n+\tthe_repository = &the_repo;\n+\n+\tthe_repo.index = &the_index;\n+\trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n+}\n \n static char *git_path_from_env(const char *envvar, const char *git_dir,\n \t\t\t       const char *path, int fromenv)\n@@ -128,7 +134,9 @@ static int read_and_verify_repository_format(struct repository_format *format,\n  * Initialize 'repo' based on the provided 'gitdir'.\n  * Return 0 upon success and a non-zero value upon failure.\n  */\n-int repo_init(struct repository *repo, const char *gitdir, const char *worktree)\n+static int repo_init(struct repository *repo,\n+\t\t     const char *gitdir,\n+\t\t     const char *worktree)\n {\n \tstruct repository_format format;\n \tmemset(repo, 0, sizeof(*repo));\ndiff --git a/repository.h b/repository.h\nindex 0329e40c7f..40c1c81bdc 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -91,7 +91,7 @@ extern struct repository *the_repository;\n extern void repo_set_gitdir(struct repository *repo, const char *path);\n extern void repo_set_worktree(struct repository *repo, const char *path);\n extern void repo_set_hash_algo(struct repository *repo, int algo);\n-extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree);\n+extern void initialize_the_repository(void);\n extern int repo_submodule_init(struct repository *submodule,\n \t\t\t       struct repository *superproject,\n \t\t\t       const char *path);\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340894","messageId":"20180303113637.26518-3-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 02/44] repository.c: move env-related setup code back to environment.c","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:35:55Z","receivedAt":"2018-03-03T11:37:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"It does not make sense that generic repository code contains handling\nof environment variables, which are specific for the main repository\nonly. Refactor repo_set_gitdir() function to take $GIT_DIR and\noptionally _all_ other customizable paths. These optional paths can be\nNULL and will be calculated according to the default directory layout.\n\nNote that some dead functions are left behind to reduce diff\nnoise. They will be deleted in the next patch.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h       |  2 +-\n environment.c | 30 +++++++++++++++++++++++---\n repository.c  | 58 +++++++++++++++++++++++++++++++++++----------------\n repository.h  | 11 +++++++++-\n setup.c       |  3 +--\n 5 files changed, 79 insertions(+), 25 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 9cac7bb518..41ba67cc16 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -484,7 +484,7 @@ static inline enum object_type object_type(unsigned int mode)\n  */\n extern const char * const local_repo_env[];\n \n-extern void setup_git_env(void);\n+extern void setup_git_env(const char *git_dir);\n \n /*\n  * Returns true iff we have a configured git repository (either via\ndiff --git a/environment.c b/environment.c\nindex de8431e01e..da3f7daa09 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -13,6 +13,7 @@\n #include \"refs.h\"\n #include \"fmt-merge-msg.h\"\n #include \"commit.h\"\n+#include \"argv-array.h\"\n \n int trust_executable_bit = 1;\n int trust_ctime = 1;\n@@ -147,10 +148,34 @@ static char *expand_namespace(const char *raw_namespace)\n \treturn strbuf_detach(&buf, NULL);\n }\n \n-void setup_git_env(void)\n+/*\n+ * Wrapper of getenv() that returns a strdup value. This value is kept\n+ * in argv to be freed later.\n+ */\n+static const char *getenv_safe(struct argv_array *argv, const char *name)\n+{\n+\tconst char *value = getenv(name);\n+\n+\tif (!value)\n+\t\treturn NULL;\n+\n+\targv_array_push(argv, value);\n+\treturn argv->argv[argv->argc - 1];\n+}\n+\n+void setup_git_env(const char *git_dir)\n {\n \tconst char *shallow_file;\n \tconst char *replace_ref_base;\n+\tstruct set_gitdir_args args = { NULL };\n+\tstruct argv_array to_free = ARGV_ARRAY_INIT;\n+\n+\targs.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);\n+\targs.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);\n+\targs.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);\n+\targs.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);\n+\trepo_set_gitdir(the_repository, git_dir, &args);\n+\targv_array_clear(&to_free);\n \n \tif (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))\n \t\tcheck_replace_refs = 0;\n@@ -300,8 +325,7 @@ int set_git_dir(const char *path)\n {\n \tif (setenv(GIT_DIR_ENVIRONMENT, path, 1))\n \t\treturn error(\"Could not set GIT_DIR to '%s'\", path);\n-\trepo_set_gitdir(the_repository, path);\n-\tsetup_git_env();\n+\tsetup_git_env(path);\n \treturn 0;\n }\n \ndiff --git a/repository.c b/repository.c\nindex 0eddf28fcd..bb53b54b6d 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -40,34 +40,55 @@ static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)\n \treturn get_common_dir_noenv(sb, gitdir);\n }\n \n-static void repo_setup_env(struct repository *repo)\n+static void expand_base_dir(char **out, const char *in,\n+\t\t\t    const char *base_dir, const char *def_in)\n+{\n+\tfree(*out);\n+\tif (in)\n+\t\t*out = xstrdup(in);\n+\telse\n+\t\t*out = xstrfmt(\"%s/%s\", base_dir, def_in);\n+}\n+\n+static void repo_set_commondir(struct repository *repo,\n+\t\t\t       const char *commondir)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \n-\trepo->different_commondir = find_common_dir(&sb, repo->gitdir,\n-\t\t\t\t\t\t    !repo->ignore_env);\n \tfree(repo->commondir);\n+\n+\tif (commondir) {\n+\t\trepo->different_commondir = 1;\n+\t\trepo->commondir = xstrdup(commondir);\n+\t\treturn;\n+\t}\n+\n+\trepo->different_commondir = get_common_dir_noenv(&sb, repo->gitdir);\n \trepo->commondir = strbuf_detach(&sb, NULL);\n-\tfree(repo->objectdir);\n-\trepo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir,\n-\t\t\t\t\t    \"objects\", !repo->ignore_env);\n-\tfree(repo->graft_file);\n-\trepo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir,\n-\t\t\t\t\t     \"info/grafts\", !repo->ignore_env);\n-\tfree(repo->index_file);\n-\trepo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir,\n-\t\t\t\t\t     \"index\", !repo->ignore_env);\n }\n \n-void repo_set_gitdir(struct repository *repo, const char *path)\n+void repo_set_gitdir(struct repository *repo,\n+\t\t     const char *root,\n+\t\t     const struct set_gitdir_args *o)\n {\n-\tconst char *gitfile = read_gitfile(path);\n+\tconst char *gitfile = read_gitfile(root);\n+\t/*\n+\t * repo->gitdir is saved because the caller could pass \"root\"\n+\t * that also points to repo->gitdir. We want to keep it alive\n+\t * until after xstrdup(root). Then we can free it.\n+\t */\n \tchar *old_gitdir = repo->gitdir;\n \n-\trepo->gitdir = xstrdup(gitfile ? gitfile : path);\n-\trepo_setup_env(repo);\n-\n+\trepo->gitdir = xstrdup(gitfile ? gitfile : root);\n \tfree(old_gitdir);\n+\n+\trepo_set_commondir(repo, o->commondir);\n+\texpand_base_dir(&repo->objectdir, o->object_dir,\n+\t\t\trepo->commondir, \"objects\");\n+\texpand_base_dir(&repo->graft_file, o->graft_file,\n+\t\t\trepo->commondir, \"info/grafts\");\n+\texpand_base_dir(&repo->index_file, o->index_file,\n+\t\t\trepo->gitdir, \"index\");\n }\n \n void repo_set_hash_algo(struct repository *repo, int hash_algo)\n@@ -85,6 +106,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)\n \tint error = 0;\n \tchar *abspath = NULL;\n \tconst char *resolved_gitdir;\n+\tstruct set_gitdir_args args = { NULL };\n \n \tabspath = real_pathdup(gitdir, 0);\n \tif (!abspath) {\n@@ -99,7 +121,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)\n \t\tgoto out;\n \t}\n \n-\trepo_set_gitdir(repo, resolved_gitdir);\n+\trepo_set_gitdir(repo, resolved_gitdir, &args);\n \n out:\n \tfree(abspath);\ndiff --git a/repository.h b/repository.h\nindex 40c1c81bdc..84aeac2825 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -88,7 +88,16 @@ struct repository {\n \n extern struct repository *the_repository;\n \n-extern void repo_set_gitdir(struct repository *repo, const char *path);\n+struct set_gitdir_args {\n+\tconst char *commondir;\n+\tconst char *object_dir;\n+\tconst char *graft_file;\n+\tconst char *index_file;\n+};\n+\n+extern void repo_set_gitdir(struct repository *repo,\n+\t\t\t    const char *root,\n+\t\t\t    const struct set_gitdir_args *optional);\n extern void repo_set_worktree(struct repository *repo, const char *path);\n extern void repo_set_hash_algo(struct repository *repo, int algo);\n extern void initialize_the_repository(void);\ndiff --git a/setup.c b/setup.c\nindex c5d55dcee4..6fac1bb58a 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1116,8 +1116,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\tif (!gitdir)\n \t\t\t\tgitdir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\t\t\trepo_set_gitdir(the_repository, gitdir);\n-\t\t\tsetup_git_env();\n+\t\t\tsetup_git_env(gitdir);\n \t\t}\n \t\tif (startup_info->have_repository)\n \t\t\trepo_set_hash_algo(the_repository, repo_fmt.hash_algo);\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340895","messageId":"20180303113637.26518-4-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 03/44] repository.c: delete dead functions","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:35:56Z","receivedAt":"2018-03-03T11:37:06Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n repository.c | 25 -------------------------\n 1 file changed, 25 deletions(-)\n\ndiff --git a/repository.c b/repository.c\nindex bb53b54b6d..e65f4138a7 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -15,31 +15,6 @@ void initialize_the_repository(void)\n \trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n }\n \n-static char *git_path_from_env(const char *envvar, const char *git_dir,\n-\t\t\t       const char *path, int fromenv)\n-{\n-\tif (fromenv) {\n-\t\tconst char *value = getenv(envvar);\n-\t\tif (value)\n-\t\t\treturn xstrdup(value);\n-\t}\n-\n-\treturn xstrfmt(\"%s/%s\", git_dir, path);\n-}\n-\n-static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)\n-{\n-\tif (fromenv) {\n-\t\tconst char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT);\n-\t\tif (value) {\n-\t\t\tstrbuf_addstr(sb, value);\n-\t\t\treturn 1;\n-\t\t}\n-\t}\n-\n-\treturn get_common_dir_noenv(sb, gitdir);\n-}\n-\n static void expand_base_dir(char **out, const char *in,\n \t\t\t    const char *base_dir, const char *def_in)\n {\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340896","messageId":"20180303113637.26518-5-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 04/44] sha1_file.c: move delayed getenv(altdb) back to setup_git_env()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:35:57Z","receivedAt":"2018-03-03T11:37:13Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"getenv() is supposed to work on the main repository only. This delayed\ngetenv() code in sha1_file.c makes it more difficult to convert\nsha1_file.c to a generic object store that could be used by both\nsubmodule and main repositories.\n\nMove the getenv() back in setup_git_env() where other env vars are\nalso fetched.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n environment.c | 1 +\n repository.c  | 3 +++\n repository.h  | 4 ++++\n sha1_file.c   | 6 +-----\n 4 files changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/environment.c b/environment.c\nindex da3f7daa09..a5eaa97fb1 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -174,6 +174,7 @@ void setup_git_env(const char *git_dir)\n \targs.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);\n \targs.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);\n \targs.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);\n+\targs.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);\n \trepo_set_gitdir(the_repository, git_dir, &args);\n \targv_array_clear(&to_free);\n \ndiff --git a/repository.c b/repository.c\nindex e65f4138a7..04d85a2869 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -60,6 +60,8 @@ void repo_set_gitdir(struct repository *repo,\n \trepo_set_commondir(repo, o->commondir);\n \texpand_base_dir(&repo->objectdir, o->object_dir,\n \t\t\trepo->commondir, \"objects\");\n+\tfree(repo->alternate_db);\n+\trepo->alternate_db = xstrdup_or_null(o->alternate_db);\n \texpand_base_dir(&repo->graft_file, o->graft_file,\n \t\t\trepo->commondir, \"info/grafts\");\n \texpand_base_dir(&repo->index_file, o->index_file,\n@@ -215,6 +217,7 @@ void repo_clear(struct repository *repo)\n \tFREE_AND_NULL(repo->gitdir);\n \tFREE_AND_NULL(repo->commondir);\n \tFREE_AND_NULL(repo->objectdir);\n+\tFREE_AND_NULL(repo->alternate_db);\n \tFREE_AND_NULL(repo->graft_file);\n \tFREE_AND_NULL(repo->index_file);\n \tFREE_AND_NULL(repo->worktree);\ndiff --git a/repository.h b/repository.h\nindex 84aeac2825..2bfbf762f3 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -26,6 +26,9 @@ struct repository {\n \t */\n \tchar *objectdir;\n \n+\t/* Path to extra alternate object database if not NULL */\n+\tchar *alternate_db;\n+\n \t/*\n \t * Path to the repository's graft file.\n \t * Cannot be NULL after initialization.\n@@ -93,6 +96,7 @@ struct set_gitdir_args {\n \tconst char *object_dir;\n \tconst char *graft_file;\n \tconst char *index_file;\n+\tconst char *alternate_db;\n };\n \n extern void repo_set_gitdir(struct repository *repo,\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 831d9e7343..4af422e3cf 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -667,15 +667,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \n void prepare_alt_odb(void)\n {\n-\tconst char *alt;\n-\n \tif (alt_odb_tail)\n \t\treturn;\n \n-\talt = getenv(ALTERNATE_DB_ENVIRONMENT);\n-\n \talt_odb_tail = &alt_odb_list;\n-\tlink_alt_odb_entries(alt, PATH_SEP, NULL, 0);\n+\tlink_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);\n \n \tread_info_alternates(get_object_directory(), 0);\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340897","messageId":"20180303113637.26518-6-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 05/44] repository: delete ignore_env member","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:35:58Z","receivedAt":"2018-03-03T11:37:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This variable was added because the repo_set_gitdir() was created to\ncover both submodule and main repos, but these two are initialized a\nbit differently so ignore_env == 0 means main repo, while ignore_env\n!= 0 is submodules.\n\nSince the difference part (env variables) has been moved out of\nrepo_set_gitdir(), this function works the same way for both repo\ntypes and ignore_env is not needed anymore.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n repository.c | 2 --\n repository.h | 9 ---------\n 2 files changed, 11 deletions(-)\n\ndiff --git a/repository.c b/repository.c\nindex 04d85a2869..62f52f47fc 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -140,8 +140,6 @@ static int repo_init(struct repository *repo,\n \tstruct repository_format format;\n \tmemset(repo, 0, sizeof(*repo));\n \n-\trepo->ignore_env = 1;\n-\n \tif (repo_init_gitdir(repo, gitdir))\n \t\tgoto error;\n \ndiff --git a/repository.h b/repository.h\nindex 2bfbf762f3..e7127baffb 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -75,15 +75,6 @@ struct repository {\n \tconst struct git_hash_algo *hash_algo;\n \n \t/* Configurations */\n-\t/*\n-\t * Bit used during initialization to indicate if repository state (like\n-\t * the location of the 'objectdir') should be read from the\n-\t * environment.  By default this bit will be set at the begining of\n-\t * 'repo_init()' so that all repositories will ignore the environment.\n-\t * The exception to this is 'the_repository', which doesn't go through\n-\t * the normal 'repo_init()' process.\n-\t */\n-\tunsigned ignore_env:1;\n \n \t/* Indicate if a repository has a different 'commondir' from 'gitdir' */\n \tunsigned different_commondir:1;\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340898","messageId":"20180303113637.26518-7-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 06/44] repository: introduce raw object store field","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:35:59Z","receivedAt":"2018-03-03T11:37:20Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThe raw object store field will contain any objects needed for\naccess to objects in a given repository.\n\nThis patch introduces the raw object store and populates it with the\n`objectdir`, which used to be part of the repository struct.\n\nAs the struct gains members, we'll also populate the function to clear\nthe memory for these members.\n\nIn a later we'll introduce a struct object_parser, that will complement\nthe object parsing in a repository struct: The raw object parser is the\nlayer that will provide access to raw object content, while the higher\nlevel object parser code will parse raw objects and keeps track of\nparenthood and other object relationships using 'struct object'.\nFor now only add the lower level to the repository struct.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/grep.c |  2 +-\n environment.c  |  5 +++--\n object-store.h | 18 ++++++++++++++++++\n object.c       | 10 ++++++++++\n path.c         |  2 +-\n repository.c   | 14 +++++++++-----\n repository.h   | 10 ++++------\n sha1_file.c    |  3 ++-\n 8 files changed, 48 insertions(+), 16 deletions(-)\n create mode 100644 object-store.h\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 3ca4ac80d8..0f0c195705 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -432,7 +432,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,\n \t * object.\n \t */\n \tgrep_read_lock();\n-\tadd_to_alternates_memory(submodule.objectdir);\n+\tadd_to_alternates_memory(submodule.objects.objectdir);\n \tgrep_read_unlock();\n \n \tif (oid) {\ndiff --git a/environment.c b/environment.c\nindex a5eaa97fb1..c05705e384 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -14,6 +14,7 @@\n #include \"fmt-merge-msg.h\"\n #include \"commit.h\"\n #include \"argv-array.h\"\n+#include \"object-store.h\"\n \n int trust_executable_bit = 1;\n int trust_ctime = 1;\n@@ -270,9 +271,9 @@ const char *get_git_work_tree(void)\n \n char *get_object_directory(void)\n {\n-\tif (!the_repository->objectdir)\n+\tif (!the_repository->objects.objectdir)\n \t\tBUG(\"git environment hasn't been setup\");\n-\treturn the_repository->objectdir;\n+\treturn the_repository->objects.objectdir;\n }\n \n int odb_mkstemp(struct strbuf *template, const char *pattern)\ndiff --git a/object-store.h b/object-store.h\nnew file mode 100644\nindex 0000000000..69bb5ac065\n--- /dev/null\n+++ b/object-store.h\n@@ -0,0 +1,18 @@\n+#ifndef OBJECT_STORE_H\n+#define OBJECT_STORE_H\n+\n+struct raw_object_store {\n+\t/*\n+\t * Path to the repository's object store.\n+\t * Cannot be NULL after initialization.\n+\t */\n+\tchar *objectdir;\n+\n+\t/* Path to extra alternate object database if not NULL */\n+\tchar *alternate_db;\n+};\n+\n+void raw_object_store_init(struct raw_object_store *o);\n+void raw_object_store_clear(struct raw_object_store *o);\n+\n+#endif /* OBJECT_STORE_H */\ndiff --git a/object.c b/object.c\nindex 9e6f9ff20b..e91711dd56 100644\n--- a/object.c\n+++ b/object.c\n@@ -445,3 +445,13 @@ void clear_commit_marks_all(unsigned int flags)\n \t\t\tobj->flags &= ~flags;\n \t}\n }\n+\n+void raw_object_store_init(struct raw_object_store *o)\n+{\n+\tmemset(o, 0, sizeof(*o));\n+}\n+void raw_object_store_clear(struct raw_object_store *o)\n+{\n+\tFREE_AND_NULL(o->objectdir);\n+\tFREE_AND_NULL(o->alternate_db);\n+}\ndiff --git a/path.c b/path.c\nindex da8b655730..81a42d9115 100644\n--- a/path.c\n+++ b/path.c\n@@ -382,7 +382,7 @@ static void adjust_git_path(const struct repository *repo,\n \t\tstrbuf_splice(buf, 0, buf->len,\n \t\t\t      repo->index_file, strlen(repo->index_file));\n \telse if (dir_prefix(base, \"objects\"))\n-\t\treplace_dir(buf, git_dir_len + 7, repo->objectdir);\n+\t\treplace_dir(buf, git_dir_len + 7, repo->objects.objectdir);\n \telse if (git_hooks_path && dir_prefix(base, \"hooks\"))\n \t\treplace_dir(buf, git_dir_len + 5, git_hooks_path);\n \telse if (repo->different_commondir)\ndiff --git a/repository.c b/repository.c\nindex 62f52f47fc..34c0a7f180 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"repository.h\"\n+#include \"object-store.h\"\n #include \"config.h\"\n #include \"submodule-config.h\"\n \n@@ -12,6 +13,7 @@ void initialize_the_repository(void)\n \tthe_repository = &the_repo;\n \n \tthe_repo.index = &the_index;\n+\traw_object_store_init(&the_repo.objects);\n \trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n }\n \n@@ -58,10 +60,10 @@ void repo_set_gitdir(struct repository *repo,\n \tfree(old_gitdir);\n \n \trepo_set_commondir(repo, o->commondir);\n-\texpand_base_dir(&repo->objectdir, o->object_dir,\n+\texpand_base_dir(&repo->objects.objectdir, o->object_dir,\n \t\t\trepo->commondir, \"objects\");\n-\tfree(repo->alternate_db);\n-\trepo->alternate_db = xstrdup_or_null(o->alternate_db);\n+\tfree(repo->objects.alternate_db);\n+\trepo->objects.alternate_db = xstrdup_or_null(o->alternate_db);\n \texpand_base_dir(&repo->graft_file, o->graft_file,\n \t\t\trepo->commondir, \"info/grafts\");\n \texpand_base_dir(&repo->index_file, o->index_file,\n@@ -140,6 +142,8 @@ static int repo_init(struct repository *repo,\n \tstruct repository_format format;\n \tmemset(repo, 0, sizeof(*repo));\n \n+\traw_object_store_init(&repo->objects);\n+\n \tif (repo_init_gitdir(repo, gitdir))\n \t\tgoto error;\n \n@@ -214,13 +218,13 @@ void repo_clear(struct repository *repo)\n {\n \tFREE_AND_NULL(repo->gitdir);\n \tFREE_AND_NULL(repo->commondir);\n-\tFREE_AND_NULL(repo->objectdir);\n-\tFREE_AND_NULL(repo->alternate_db);\n \tFREE_AND_NULL(repo->graft_file);\n \tFREE_AND_NULL(repo->index_file);\n \tFREE_AND_NULL(repo->worktree);\n \tFREE_AND_NULL(repo->submodule_prefix);\n \n+\traw_object_store_clear(&repo->objects);\n+\n \tif (repo->config) {\n \t\tgit_configset_clear(repo->config);\n \t\tFREE_AND_NULL(repo->config);\ndiff --git a/repository.h b/repository.h\nindex e7127baffb..6c383c05c6 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@@ -21,13 +23,9 @@ struct repository {\n \tchar *commondir;\n \n \t/*\n-\t * Path to the repository's object store.\n-\t * Cannot be NULL after initialization.\n+\t * Holds any information related to accessing the raw object content.\n \t */\n-\tchar *objectdir;\n-\n-\t/* Path to extra alternate object database if not NULL */\n-\tchar *alternate_db;\n+\tstruct raw_object_store objects;\n \n \t/*\n \t * Path to the repository's graft file.\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 4af422e3cf..792bb21c15 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -671,7 +671,8 @@ void prepare_alt_odb(void)\n \t\treturn;\n \n \talt_odb_tail = &alt_odb_list;\n-\tlink_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);\n+\tlink_alt_odb_entries(the_repository->objects.alternate_db,\n+\t\t\t     PATH_SEP, NULL, 0);\n \n \tread_info_alternates(get_object_directory(), 0);\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340899","messageId":"20180303113637.26518-8-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 07/44] object-store: migrate alternates struct and functions from cache.h","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:00Z","receivedAt":"2018-03-03T11:37:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nMigrate the struct alternate_object_database and all its related\nfunctions to the object store as these functions are easier found in\nthat header. The migration is just a verbatim copy, no need to\ninclude the object store header at any C file, because cache.h includes\nrepository.h which in turn includes the object-store.h\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h        | 51 --------------------------------------------------\n object-store.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 51 insertions(+), 51 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 41ba67cc16..41530d5d16 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1576,57 +1576,6 @@ 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-\tstruct alternate_object_database *next;\n-\n-\t/* see alt_scratch_buf() */\n-\tstruct strbuf scratch;\n-\tsize_t base_len;\n-\n-\t/*\n-\t * Used to store the results of readdir(3) calls when searching\n-\t * for unique abbreviated hashes.  This cache is never\n-\t * invalidated, thus it's racy and not necessarily accurate.\n-\t * That's fine for its purpose; don't use it for tasks requiring\n-\t * greater accuracy!\n-\t */\n-\tchar loose_objects_subdir_seen[256];\n-\tstruct oid_array loose_objects_cache;\n-\n-\tchar path[FLEX_ARRAY];\n-} *alt_odb_list;\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*);\n-\n-/*\n- * Allocate a \"struct alternate_object_database\" but do _not_ actually\n- * add it to the list of alternates.\n- */\n-struct alternate_object_database *alloc_alt_odb(const char *dir);\n-\n-/*\n- * Add the directory to the on-disk alternates file; the new entry will also\n- * take effect in the current process.\n- */\n-extern void add_to_alternates_file(const char *dir);\n-\n-/*\n- * Add the directory to the in-memory list of alternates (along with any\n- * recursive alternates it points to), but do not modify the on-disk alternates\n- * file.\n- */\n-extern void add_to_alternates_memory(const char *dir);\n-\n-/*\n- * Returns a scratch strbuf pre-filled with the alternate object directory,\n- * including a trailing slash, which can be used to access paths in the\n- * alternate. Always use this over direct access to alt->scratch, as it\n- * cleans up any previous use of the scratch buffer.\n- */\n-extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);\n-\n struct pack_window {\n \tstruct pack_window *next;\n \tunsigned char *base;\ndiff --git a/object-store.h b/object-store.h\nindex 69bb5ac065..505f123976 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -1,6 +1,57 @@\n #ifndef OBJECT_STORE_H\n #define OBJECT_STORE_H\n \n+extern struct alternate_object_database {\n+\tstruct alternate_object_database *next;\n+\n+\t/* see alt_scratch_buf() */\n+\tstruct strbuf scratch;\n+\tsize_t base_len;\n+\n+\t/*\n+\t * Used to store the results of readdir(3) calls when searching\n+\t * for unique abbreviated hashes.  This cache is never\n+\t * invalidated, thus it's racy and not necessarily accurate.\n+\t * That's fine for its purpose; don't use it for tasks requiring\n+\t * greater accuracy!\n+\t */\n+\tchar loose_objects_subdir_seen[256];\n+\tstruct oid_array loose_objects_cache;\n+\n+\tchar path[FLEX_ARRAY];\n+} *alt_odb_list;\n+void prepare_alt_odb(void);\n+char *compute_alternate_path(const char *path, struct strbuf *err);\n+typedef int alt_odb_fn(struct alternate_object_database *, void *);\n+int foreach_alt_odb(alt_odb_fn, void*);\n+\n+/*\n+ * Allocate a \"struct alternate_object_database\" but do _not_ actually\n+ * add it to the list of alternates.\n+ */\n+struct alternate_object_database *alloc_alt_odb(const char *dir);\n+\n+/*\n+ * Add the directory to the on-disk alternates file; the new entry will also\n+ * take effect in the current process.\n+ */\n+void add_to_alternates_file(const char *dir);\n+\n+/*\n+ * Add the directory to the in-memory list of alternates (along with any\n+ * recursive alternates it points to), but do not modify the on-disk alternates\n+ * file.\n+ */\n+void add_to_alternates_memory(const char *dir);\n+\n+/*\n+ * Returns a scratch strbuf pre-filled with the alternate object directory,\n+ * including a trailing slash, which can be used to access paths in the\n+ * alternate. Always use this over direct access to alt->scratch, as it\n+ * cleans up any previous use of the scratch buffer.\n+ */\n+struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);\n+\n struct raw_object_store {\n \t/*\n \t * Path to the repository's object store.\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340900","messageId":"20180303113637.26518-9-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 08/44] object-store: move alt_odb_list and alt_odb_tail to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:01Z","receivedAt":"2018-03-03T11:37:30Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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\nNow that the alternative object data base is per repository, we're\nleaking its memory upon freeing a repository. The next patch plugs\nthis hole.\n\nNo functional change intended.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/fsck.c |  4 +++-\n object-store.h |  7 +++++--\n packfile.c     |  3 ++-\n sha1_file.c    | 25 ++++++++++++-------------\n sha1_name.c    |  3 ++-\n 5 files changed, 24 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 7a8a679d4f..b284a3a74e 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@@ -716,7 +717,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     alt; alt = alt->next)\n \t\t\tfsck_object_dir(alt->path);\n \n \t\tif (check_full) {\ndiff --git a/object-store.h b/object-store.h\nindex 505f123976..0ca9233a85 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -1,7 +1,7 @@\n #ifndef OBJECT_STORE_H\n #define OBJECT_STORE_H\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@@ -19,7 +19,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 void prepare_alt_odb(void);\n char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n@@ -61,6 +61,9 @@ struct raw_object_store {\n \n \t/* Path to extra alternate object database if not NULL */\n \tchar *alternate_db;\n+\n+\tstruct alternate_object_database *alt_odb_list;\n+\tstruct alternate_object_database **alt_odb_tail;\n };\n \n void raw_object_store_init(struct raw_object_store *o);\ndiff --git a/packfile.c b/packfile.c\nindex 7dbe8739d1..216ea836ee 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1,6 +1,7 @@\n #include \"cache.h\"\n #include \"list.h\"\n #include \"pack.h\"\n+#include \"repository.h\"\n #include \"dir.h\"\n #include \"mergesort.h\"\n #include \"packfile.h\"\n@@ -891,7 +892,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 792bb21c15..4c9635dada 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 \"list.h\"\n@@ -342,9 +343,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@@ -364,7 +362,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@@ -424,8 +422,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@@ -559,7 +557,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, '\\n', NULL, 0);\n \t}\n \tfree(alts);\n@@ -657,7 +655,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@@ -667,10 +665,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \n void prepare_alt_odb(void)\n {\n-\tif (alt_odb_tail)\n+\tif (the_repository->objects.alt_odb_tail)\n \t\treturn;\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(the_repository->objects.alternate_db,\n \t\t\t     PATH_SEP, NULL, 0);\n \n@@ -715,7 +714,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@@ -875,7 +874,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@@ -905,7 +904,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 611c7d24dd..957ce25680 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.16.1.435.g8f24da2e1a\n\n"},{"id":"340901","messageId":"20180303113637.26518-10-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 09/44] object-store: free alt_odb_list","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:02Z","receivedAt":"2018-03-03T11:37:35Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nFree the memory and reset alt_odb_{list, tail} to NULL.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object.c | 18 ++++++++++++++++++\n 1 file changed, 18 insertions(+)\n\ndiff --git a/object.c b/object.c\nindex e91711dd56..a71ab34e69 100644\n--- a/object.c\n+++ b/object.c\n@@ -450,8 +450,26 @@ void raw_object_store_init(struct raw_object_store *o)\n {\n \tmemset(o, 0, sizeof(*o));\n }\n+\n+static void free_alt_odb(struct alternate_object_database *alt)\n+{\n+\tstrbuf_release(&alt->scratch);\n+\toid_array_clear(&alt->loose_objects_cache);\n+}\n+\n+static void free_alt_odbs(struct raw_object_store *o)\n+{\n+\twhile (o->alt_odb_list) {\n+\t\tfree_alt_odb(o->alt_odb_list);\n+\t\to->alt_odb_list = o->alt_odb_list->next;\n+\t}\n+}\n+\n void raw_object_store_clear(struct raw_object_store *o)\n {\n \tFREE_AND_NULL(o->objectdir);\n \tFREE_AND_NULL(o->alternate_db);\n+\n+\tfree_alt_odbs(o);\n+\to->alt_odb_tail = NULL;\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340902","messageId":"20180303113637.26518-11-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 10/44] object-store: move packed_git and packed_git_mru to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:03Z","receivedAt":"2018-03-03T11:37:41Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nIn 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\n[nd: while at there, wrap access to these two fields in get_packed_git()\nand get_packed_git_mru(). This allows us to lazily initialize these\nfields without caller doing that explicitly]\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. Apply the following semantic patch to adjust callers:\n    @@ @@\n    - packed_git\n    + the_repository->objects.packed_git\n\n    @@ @@\n    - packed_git_mru\n    + the_repository->objects.packed_git_mru\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 where needed.\n\n 5. As the packfiles are now owned by an objectstore, which is ephemeral\n    unlike globals, we introduce memory leaks. So address them in\n    raw_object_store_clear(). Defer freeing packed_git to the next\n    patch due to the size of this patch.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/count-objects.c  |  5 ++--\n builtin/fsck.c           |  6 +++--\n builtin/gc.c             |  3 ++-\n builtin/pack-objects.c   | 20 ++++++++--------\n builtin/pack-redundant.c |  5 ++--\n cache.h                  | 29 ------------------------\n fast-import.c            |  7 ++++--\n http-backend.c           |  5 ++--\n object-store.h           | 28 +++++++++++++++++++++++\n object.c                 |  7 ++++++\n pack-bitmap.c            |  3 ++-\n packfile.c               | 49 ++++++++++++++++++++++++----------------\n packfile.h               |  3 +++\n server-info.c            |  5 ++--\n sha1_name.c              |  5 ++--\n 15 files changed, 107 insertions(+), 73 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 33343818c8..5c7c3c6ae3 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -7,6 +7,7 @@\n #include \"cache.h\"\n #include \"config.h\"\n #include \"dir.h\"\n+#include \"repository.h\"\n #include \"builtin.h\"\n #include \"parse-options.h\"\n #include \"quote.h\"\n@@ -120,9 +121,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 (!get_packed_git(the_repository))\n \t\t\tprepare_packed_git();\n-\t\tfor (p = packed_git; p; p = p->next) {\n+\t\tfor (p = get_packed_git(the_repository); 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 b284a3a74e..7aca9699f6 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -729,7 +729,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 = get_packed_git(the_repository); 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@@ -737,7 +738,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 = get_packed_git(the_repository); 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 77fa720bd0..dd30067ac1 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@@ -173,7 +174,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 = get_packed_git(the_repository); p; p = p->next) {\n \t\tif (!p->pack_local)\n \t\t\tcontinue;\n \t\tif (p->pack_keep)\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 83dcbc9773..0e5fde1d6b 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -1,5 +1,6 @@\n #include \"builtin.h\"\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"attr.h\"\n #include \"object.h\"\n@@ -1025,8 +1026,7 @@ static int want_object_in_pack(const struct object_id *oid,\n \t\tif (want != -1)\n \t\t\treturn want;\n \t}\n-\n-\tlist_for_each(pos, &packed_git_mru) {\n+\tlist_for_each(pos, get_packed_git_mru(the_repository)) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\toff_t offset;\n \n@@ -1044,7 +1044,8 @@ static int want_object_in_pack(const struct object_id *oid,\n \t\t\t}\n \t\t\twant = want_found_object(exclude, p);\n \t\t\tif (!exclude && want > 0)\n-\t\t\t\tlist_move(&p->mru, &packed_git_mru);\n+\t\t\t\tlist_move(&p->mru,\n+\t\t\t\t\t  get_packed_git_mru(the_repository));\n \t\t\tif (want != -1)\n \t\t\t\treturn want;\n \t\t}\n@@ -2673,7 +2674,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 = get_packed_git(the_repository); p; p = p->next) {\n \t\tstruct object_id oid;\n \t\tstruct object *o;\n \n@@ -2736,7 +2737,8 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\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\tget_packed_git(the_repository);\n \n \twhile (p) {\n \t\tif ((!p->pack_local || p->pack_keep) &&\n@@ -2745,7 +2747,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\n \t\t\treturn 1;\n \t\t}\n \t\tif (p == last_found)\n-\t\t\tp = packed_git;\n+\t\t\tp = get_packed_git(the_repository);\n \t\telse\n \t\t\tp = p->next;\n \t\tif (p == last_found)\n@@ -2781,7 +2783,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 = get_packed_git(the_repository); p; p = p->next) {\n \t\tif (!p->pack_local || p->pack_keep)\n \t\t\tcontinue;\n \n@@ -3152,7 +3154,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 = get_packed_git(the_repository); 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@@ -3165,7 +3167,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 = get_packed_git(the_repository); 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..d6d8a44959 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -7,6 +7,7 @@\n */\n \n #include \"builtin.h\"\n+#include \"repository.h\"\n #include \"packfile.h\"\n \n #define BLKSIZE 512\n@@ -571,7 +572,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 = get_packed_git(the_repository);\n \n \tif (strlen(filename) < 40)\n \t\tdie(\"Bad pack filename: %s\", filename);\n@@ -586,7 +587,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 = get_packed_git(the_repository);\n \n \twhile (p) {\n \t\tadd_pack(p);\ndiff --git a/cache.h b/cache.h\nindex 41530d5d16..d3429a0d48 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1585,35 +1585,6 @@ struct pack_window {\n \tunsigned int inuse_cnt;\n };\n \n-extern struct packed_git {\n-\tstruct packed_git *next;\n-\tstruct list_head mru;\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-\t\t pack_promisor: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.\n- */\n-extern struct list_head packed_git_mru;\n-\n struct pack_entry {\n \toff_t offset;\n \tunsigned char sha1[20];\ndiff --git a/fast-import.c b/fast-import.c\nindex b70ac025e0..0dba555478 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -154,6 +154,7 @@ 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.h\"\n@@ -1110,7 +1111,8 @@ 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,\n+\t\t\t\t  get_packed_git(the_repository))) {\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,8 @@ 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,\n+\t\t\t\t  get_packed_git(the_repository))) {\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 f3dc218b2a..22921d169a 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"config.h\"\n+#include \"repository.h\"\n #include \"refs.h\"\n #include \"pkt-line.h\"\n #include \"object.h\"\n@@ -518,13 +519,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 = get_packed_git(the_repository); 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 = get_packed_git(the_repository); 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/object-store.h b/object-store.h\nindex 0ca9233a85..1f3e66a3b8 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -52,6 +52,30 @@ void add_to_alternates_memory(const char *dir);\n  */\n struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);\n \n+struct packed_git {\n+\tstruct packed_git *next;\n+\tstruct list_head mru;\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+\t\t pack_promisor: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 struct raw_object_store {\n \t/*\n \t * Path to the repository's object store.\n@@ -62,6 +86,10 @@ struct raw_object_store {\n \t/* Path to extra alternate object database if not NULL */\n \tchar *alternate_db;\n \n+\tstruct packed_git *packed_git; /* private */\n+\t/* A most-recently-used ordered version of the packed_git list. */\n+\tstruct list_head packed_git_mru; /* private */\n+\n \tstruct alternate_object_database *alt_odb_list;\n \tstruct alternate_object_database **alt_odb_tail;\n };\ndiff --git a/object.c b/object.c\nindex a71ab34e69..83be6b1ecb 100644\n--- a/object.c\n+++ b/object.c\n@@ -449,6 +449,7 @@ void clear_commit_marks_all(unsigned int flags)\n void raw_object_store_init(struct raw_object_store *o)\n {\n \tmemset(o, 0, sizeof(*o));\n+\tINIT_LIST_HEAD(&o->packed_git_mru);\n }\n \n static void free_alt_odb(struct alternate_object_database *alt)\n@@ -472,4 +473,10 @@ void raw_object_store_clear(struct raw_object_store *o)\n \n \tfree_alt_odbs(o);\n \to->alt_odb_tail = NULL;\n+\n+\tINIT_LIST_HEAD(&o->packed_git_mru);\n+\t/*\n+\t * TODO: call close_all_packs once migrated to\n+\t * take an object store argument\n+\t */\n }\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 9270983e5f..abed43cdb5 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -10,6 +10,7 @@\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 +336,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 = get_packed_git(the_repository); p; p = p->next) {\n \t\tif (open_pack_bitmap_1(p) == 0)\n \t\t\tret = 0;\n \t}\ndiff --git a/packfile.c b/packfile.c\nindex 216ea836ee..d3c4a12ae0 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -45,8 +45,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-LIST_HEAD(packed_git_mru);\n \n #define SZ_FMT PRIuMAX\n static inline uintmax_t sz_fmt(size_t s) { return s; }\n@@ -246,7 +244,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@@ -316,7 +314,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@@ -384,7 +382,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@@ -686,8 +684,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@@ -769,7 +767,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@@ -820,7 +819,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@@ -869,18 +868,19 @@ 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-\tINIT_LIST_HEAD(&packed_git_mru);\n+\tINIT_LIST_HEAD(&the_repository->objects.packed_git_mru);\n \n-\tfor (p = packed_git; p; p = p->next)\n-\t\tlist_add_tail(&p->mru, &packed_git_mru);\n+\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n+\t\tlist_add_tail(&p->mru, &the_repository->objects.packed_git_mru);\n }\n \n static int prepare_packed_git_run_once = 0;\n@@ -906,6 +906,16 @@ void reprepare_packed_git(void)\n \tprepare_packed_git();\n }\n \n+struct packed_git *get_packed_git(struct repository *r)\n+{\n+\treturn r->objects.packed_git;\n+}\n+\n+struct list_head *get_packed_git_mru(struct repository *r)\n+{\n+\treturn &r->objects.packed_git_mru;\n+}\n+\n unsigned long unpack_object_header_buffer(const unsigned char *buf,\n \t\tunsigned long len, enum object_type *type, unsigned long *sizep)\n {\n@@ -1014,7 +1024,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@@ -1845,13 +1855,14 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n \tstruct list_head *pos;\n \n \tprepare_packed_git();\n-\tif (!packed_git)\n+\tif (!the_repository->objects.packed_git)\n \t\treturn 0;\n \n-\tlist_for_each(pos, &packed_git_mru) {\n+\tlist_for_each(pos, &the_repository->objects.packed_git_mru) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\tif (fill_pack_entry(sha1, e, p)) {\n-\t\t\tlist_move(&p->mru, &packed_git_mru);\n+\t\t\tlist_move(&p->mru,\n+\t\t\t\t  &the_repository->objects.packed_git_mru);\n \t\t\treturn 1;\n \t\t}\n \t}\n@@ -1898,7 +1909,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 ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&\ndiff --git a/packfile.h b/packfile.h\nindex a7fca598d6..76496226bb 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -38,6 +38,9 @@ extern void prepare_packed_git(void);\n extern void reprepare_packed_git(void);\n extern void install_packed_git(struct packed_git *pack);\n \n+struct packed_git *get_packed_git(struct repository *r);\n+struct list_head *get_packed_git_mru(struct repository *r);\n+\n /*\n  * Give a rough count of objects in the repository. This sacrifices accuracy\n  * for speed.\ndiff --git a/server-info.c b/server-info.c\nindex 26a6c20b7d..6fe64ede17 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -1,4 +1,5 @@\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"refs.h\"\n #include \"object.h\"\n #include \"commit.h\"\n@@ -200,7 +201,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 = get_packed_git(the_repository); 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 +211,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 = get_packed_git(the_repository); 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 957ce25680..bd4d7352ce 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -196,7 +196,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 = get_packed_git(the_repository); p && !ds->ambiguous;\n+\t     p = p->next)\n \t\tunique_in_pack(p, ds);\n }\n \n@@ -566,7 +567,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n \tstruct packed_git *p;\n \n \tprepare_packed_git();\n-\tfor (p = packed_git; p; p = p->next)\n+\tfor (p = get_packed_git(the_repository); p; p = p->next)\n \t\tfind_abbrev_len_for_pack(p, mad);\n }\n \n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340903","messageId":"20180303113637.26518-12-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 11/44] object-store: close all packs upon clearing the object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:04Z","receivedAt":"2018-03-03T11:37:45Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/am.c           | 2 +-\n builtin/clone.c        | 2 +-\n builtin/fetch.c        | 2 +-\n builtin/merge.c        | 2 +-\n builtin/receive-pack.c | 2 +-\n object.c               | 7 +++----\n packfile.c             | 4 ++--\n packfile.h             | 2 +-\n 8 files changed, 11 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 5bdd2d7578..4762a702e3 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1859,7 +1859,7 @@ static void am_run(struct am_state *state, int resume)\n \t */\n \tif (!state->rebasing) {\n \t\tam_destroy(state);\n-\t\tclose_all_packs();\n+\t\tclose_all_packs(&the_repository->objects);\n \t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n \t}\n }\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 101c27a593..13cfaa6488 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1217,7 +1217,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \ttransport_disconnect(transport);\n \n \tif (option_dissociate) {\n-\t\tclose_all_packs();\n+\t\tclose_all_packs(&the_repository->objects);\n \t\tdissociate_from_references();\n \t}\n \ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 8ee998ea2e..4d72efca78 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -1478,7 +1478,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \n \tstring_list_clear(&list, 0);\n \n-\tclose_all_packs();\n+\tclose_all_packs(&the_repository->objects);\n \n \targv_array_pushl(&argv_gc_auto, \"gc\", \"--auto\", NULL);\n \tif (verbosity < 0)\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 30264cfd7c..907ae44ab5 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -411,7 +411,7 @@ static void finish(struct commit *head_commit,\n \t\t\t * We ignore errors in 'gc --auto', since the\n \t\t\t * user should see them.\n \t\t\t */\n-\t\t\tclose_all_packs();\n+\t\t\tclose_all_packs(&the_repository->objects);\n \t\t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n \t\t}\n \t}\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex b7ce7c7f52..ac478b7b99 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2026,7 +2026,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\t\tproc.git_cmd = 1;\n \t\t\tproc.argv = argv_gc_auto;\n \n-\t\t\tclose_all_packs();\n+\t\t\tclose_all_packs(&the_repository->objects);\n \t\t\tif (!start_command(&proc)) {\n \t\t\t\tif (use_sideband)\n \t\t\t\t\tcopy_to_sideband(proc.err, -1, NULL);\ndiff --git a/object.c b/object.c\nindex 83be6b1ecb..60ca76b285 100644\n--- a/object.c\n+++ b/object.c\n@@ -4,6 +4,7 @@\n #include \"tree.h\"\n #include \"commit.h\"\n #include \"tag.h\"\n+#include \"packfile.h\"\n \n static struct object **obj_hash;\n static int nr_objs, obj_hash_size;\n@@ -475,8 +476,6 @@ void raw_object_store_clear(struct raw_object_store *o)\n \to->alt_odb_tail = NULL;\n \n \tINIT_LIST_HEAD(&o->packed_git_mru);\n-\t/*\n-\t * TODO: call close_all_packs once migrated to\n-\t * take an object store argument\n-\t */\n+\tclose_all_packs(o);\n+\to->packed_git = NULL;\n }\ndiff --git a/packfile.c b/packfile.c\nindex d3c4a12ae0..1e38334ba2 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -310,11 +310,11 @@ static void close_pack(struct packed_git *p)\n \tclose_pack_index(p);\n }\n \n-void close_all_packs(void)\n+void close_all_packs(struct raw_object_store *o)\n {\n \tstruct packed_git *p;\n \n-\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n+\tfor (p = o->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\ndiff --git a/packfile.h b/packfile.h\nindex 76496226bb..5b1ce00f84 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -66,7 +66,7 @@ extern void close_pack_index(struct packed_git *);\n \n extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);\n extern void close_pack_windows(struct packed_git *);\n-extern void close_all_packs(void);\n+extern void close_all_packs(struct raw_object_store *o);\n extern void unuse_pack(struct pack_window **);\n extern void clear_delta_base_cache(void);\n extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340904","messageId":"20180303113637.26518-13-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 12/44] pack: move prepare_packed_git_run_once to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:05Z","receivedAt":"2018-03-03T11:37:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nEach 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>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h | 6 ++++++\n packfile.c     | 7 +++----\n 2 files changed, 9 insertions(+), 4 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 1f3e66a3b8..b954396615 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -92,6 +92,12 @@ struct raw_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 \n void raw_object_store_init(struct raw_object_store *o);\ndiff --git a/packfile.c b/packfile.c\nindex 1e38334ba2..caeab0f68c 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -883,12 +883,11 @@ static void prepare_packed_git_mru(void)\n \t\tlist_add_tail(&p->mru, &the_repository->objects.packed_git_mru);\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@@ -896,13 +895,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340905","messageId":"20180303113637.26518-14-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 13/44] pack: move approximate object count to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:06Z","receivedAt":"2018-03-03T11:37:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThe 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>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h |  8 ++++++++\n packfile.c     | 11 +++++------\n 2 files changed, 13 insertions(+), 6 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex b954396615..56ed4bd9e9 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -93,6 +93,14 @@ struct raw_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.\ndiff --git a/packfile.c b/packfile.c\nindex caeab0f68c..ce4cd7d5c9 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -802,8 +802,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@@ -813,8 +811,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@@ -824,8 +822,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@@ -900,7 +899,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340906","messageId":"20180303113637.26518-15-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 14/44] sha1_file: add raw_object_store argument to alt_odb_usable","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:07Z","receivedAt":"2018-03-03T11:38:00Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a raw_object_store to alt_odb_usable to be more specific about which\nrepository to act on. The choice of the repository is delegated to its\nonly caller link_alt_odb_entry.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 4c9635dada..77c099dadd 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -346,7 +346,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+static int alt_odb_usable(struct raw_object_store *o,\n+\t\t\t  struct strbuf *path,\n+\t\t\t  const char *normalized_objdir)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -362,7 +364,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 = the_repository->objects.alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = o->alt_odb_list; alt; alt = alt->next) {\n \t\tif (!fspathcmp(path->buf, alt->path))\n \t\t\treturn 0;\n \t}\n@@ -414,7 +416,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->objects, &pathbuf, normalized_objdir)) {\n \t\tstrbuf_release(&pathbuf);\n \t\treturn -1;\n \t}\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340907","messageId":"20180303113637.26518-16-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 15/44] sha1_file: add repository argument to link_alt_odb_entry","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:08Z","receivedAt":"2018-03-03T11:38:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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\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\nThis and the following three patches add repository arguments to\nlink_alt_odb_entry, read_info_alternates, link_alt_odb_entries\nand prepare_alt_odb. Three out of the four functions are found\nin a recursive call chain, calling each other, and one of them\naccesses the repositories `objectdir` (which was migrated; it\nwas an obvious choice) and `ignore_env` (which we need to keep in\nthe repository struct for clarify); hence we will pass through the\nrepository unlike just the object store object + the ignore_env flag.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 77c099dadd..2ee5fe6ba3 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -390,8 +390,9 @@ static int alt_odb_usable(struct raw_object_store *o,\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@@ -488,7 +489,8 @@ static void link_alt_odb_entries(const char *alt, 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.16.1.435.g8f24da2e1a\n\n"},{"id":"340908","messageId":"20180303113637.26518-17-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 16/44] sha1_file: add repository argument to read_info_alternates","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:09Z","receivedAt":"2018-03-03T11:38:09Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 2ee5fe6ba3..175ea58686 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -389,7 +389,9 @@ static int alt_odb_usable(struct raw_object_store *o,\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@@ -430,7 +432,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@@ -496,7 +498,8 @@ static void link_alt_odb_entries(const char *alt, 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 *path;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -677,7 +680,7 @@ void prepare_alt_odb(void)\n \tlink_alt_odb_entries(the_repository->objects.alternate_db,\n \t\t\t     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.16.1.435.g8f24da2e1a\n\n"},{"id":"340909","messageId":"20180303113637.26518-18-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 17/44] sha1_file: add repository argument to link_alt_odb_entries","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:10Z","receivedAt":"2018-03-03T11:38:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n sha1_file.c | 18 ++++++++++++------\n 1 file changed, 12 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 175ea58686..4f9c07b547 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -467,8 +467,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 sep,\n-\t\t\t\t const char *relative_base, int depth)\n+#define link_alt_odb_entries(r, a, s, rb, d) \\\n+\tlink_alt_odb_entries_##r(a, s, rb, d)\n+static void link_alt_odb_entries_the_repository(const char *alt,\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@@ -511,7 +515,7 @@ static void read_info_alternates_the_repository(const char *relative_base,\n \t\treturn;\n \t}\n \n-\tlink_alt_odb_entries(buf.buf, '\\n', relative_base, depth);\n+\tlink_alt_odb_entries(the_repository, buf.buf, '\\n', relative_base, depth);\n \tstrbuf_release(&buf);\n \tfree(path);\n }\n@@ -565,7 +569,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, '\\n', NULL, 0);\n+\t\t\tlink_alt_odb_entries(the_repository, reference,\n+\t\t\t\t\t     '\\n', NULL, 0);\n \t}\n \tfree(alts);\n }\n@@ -578,7 +583,8 @@ void add_to_alternates_memory(const char *reference)\n \t */\n \tprepare_alt_odb();\n \n-\tlink_alt_odb_entries(reference, '\\n', NULL, 0);\n+\tlink_alt_odb_entries(the_repository, reference,\n+\t\t\t     '\\n', NULL, 0);\n }\n \n /*\n@@ -677,7 +683,7 @@ 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(the_repository->objects.alternate_db,\n+\tlink_alt_odb_entries(the_repository, the_repository->objects.alternate_db,\n \t\t\t     PATH_SEP, NULL, 0);\n \n \tread_info_alternates(the_repository, get_object_directory(), 0);\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340910","messageId":"20180303113637.26518-19-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 18/44] sha1_file: add repository argument to prepare_alt_odb","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:11Z","receivedAt":"2018-03-03T11:38:20Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/fsck.c |  2 +-\n object-store.h |  3 ++-\n packfile.c     |  2 +-\n sha1_file.c    | 13 +++++++------\n sha1_name.c    |  2 +-\n 5 files changed, 12 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 7aca9699f6..b0abba6e04 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -716,7 +716,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     alt; alt = alt->next)\n \t\t\tfsck_object_dir(alt->path);\ndiff --git a/object-store.h b/object-store.h\nindex 56ed4bd9e9..3d0f8a87cb 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -20,7 +20,8 @@ struct alternate_object_database {\n \n \tchar path[FLEX_ARRAY];\n };\n-void prepare_alt_odb(void);\n+#define prepare_alt_odb(r) prepare_alt_odb_##r()\n+void prepare_alt_odb_the_repository(void);\n char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n int foreach_alt_odb(alt_odb_fn, void*);\ndiff --git a/packfile.c b/packfile.c\nindex ce4cd7d5c9..a0842521e5 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -889,7 +889,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 4f9c07b547..027e0f3741 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 \"list.h\"\n@@ -581,7 +582,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,\n \t\t\t     '\\n', NULL, 0);\n@@ -667,7 +668,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@@ -676,7 +677,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 \tif (the_repository->objects.alt_odb_tail)\n \t\treturn;\n@@ -726,7 +727,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@@ -885,7 +886,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,\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@@ -916,7 +917,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)\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 bd4d7352ce..2065be90d2 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -353,7 +353,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340911","messageId":"20180303113637.26518-20-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 19/44] sha1_file: allow link_alt_odb_entries to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:12Z","receivedAt":"2018-03-03T11:38:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nActually this also allows read_info_alternates and link_alt_odb_entry to\nhandle arbitrary repositories, but link_alt_odb_entries is the most\ninteresting function in this set of functions, hence the commit subject.\n\nThese functions span a strongly connected component in the function\ngraph, i.e. the recursive call chain might look like\n\n  -> link_alt_odb_entries\n    -> link_alt_odb_entry\n      -> read_info_alternates\n        -> link_alt_odb_entries\n\nThat is why we need to convert all these functions at the same time.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h |  4 ++++\n sha1_file.c    | 36 ++++++++++++++++--------------------\n 2 files changed, 20 insertions(+), 20 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 3d0f8a87cb..20ba136c1f 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -18,6 +18,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 alternative object store. If this is a relative path,\n+\t * it is relative to the current working directory.\n+\t */\n \tchar path[FLEX_ARRAY];\n };\n #define prepare_alt_odb(r) prepare_alt_odb_##r()\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 027e0f3741..f34eb69e39 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -390,11 +390,10 @@ static int alt_odb_usable(struct raw_object_store *o,\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@@ -420,7 +419,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->objects, &pathbuf, normalized_objdir)) {\n+\tif (!alt_odb_usable(&r->objects, &pathbuf, normalized_objdir)) {\n \t\tstrbuf_release(&pathbuf);\n \t\treturn -1;\n \t}\n@@ -428,12 +427,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@@ -468,12 +467,8 @@ static const char *parse_alt_odb_entry(const char *string,\n \treturn end;\n }\n \n-#define link_alt_odb_entries(r, a, s, rb, d) \\\n-\tlink_alt_odb_entries_##r(a, s, rb, d)\n-static void link_alt_odb_entries_the_repository(const char *alt,\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,\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@@ -487,7 +482,7 @@ static void link_alt_odb_entries_the_repository(const char *alt,\n \t\treturn;\n \t}\n \n-\tstrbuf_add_absolute_path(&objdirbuf, get_object_directory());\n+\tstrbuf_add_absolute_path(&objdirbuf, r->objects.objectdir);\n \tif (strbuf_normalize_path(&objdirbuf) < 0)\n \t\tdie(\"unable to normalize object directory: %s\",\n \t\t    objdirbuf.buf);\n@@ -496,15 +491,16 @@ static void link_alt_odb_entries_the_repository(const char *alt,\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 *path;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -516,7 +512,7 @@ static void read_info_alternates_the_repository(const char *relative_base,\n \t\treturn;\n \t}\n \n-\tlink_alt_odb_entries(the_repository, buf.buf, '\\n', relative_base, depth);\n+\tlink_alt_odb_entries(r, buf.buf, '\\n', relative_base, depth);\n \tstrbuf_release(&buf);\n \tfree(path);\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340912","messageId":"20180303113637.26518-21-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 20/44] sha1_file: allow prepare_alt_odb to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:13Z","receivedAt":"2018-03-03T11:38:29Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h |  3 +--\n sha1_file.c    | 12 +++++-------\n 2 files changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 20ba136c1f..141455b5b2 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -24,8 +24,7 @@ struct alternate_object_database {\n \t */\n \tchar path[FLEX_ARRAY];\n };\n-#define prepare_alt_odb(r) prepare_alt_odb_##r()\n-void prepare_alt_odb_the_repository(void);\n+void prepare_alt_odb(struct repository *r);\n char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n int foreach_alt_odb(alt_odb_fn, void*);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex f34eb69e39..a3e4ef4253 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -673,17 +673,15 @@ int foreach_alt_odb(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-\tif (the_repository->objects.alt_odb_tail)\n+\tif (r->objects.alt_odb_tail)\n \t\treturn;\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, the_repository->objects.alternate_db,\n-\t\t\t     PATH_SEP, NULL, 0);\n+\tr->objects.alt_odb_tail = &r->objects.alt_odb_list;\n+\tlink_alt_odb_entries(r, r->objects.alternate_db, PATH_SEP, NULL, 0);\n \n-\tread_info_alternates(the_repository, get_object_directory(), 0);\n+\tread_info_alternates(r, r->objects.objectdir, 0);\n }\n \n /* Returns 1 if we have successfully freshened the file, 0 otherwise. */\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340913","messageId":"20180303113637.26518-22-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 21/44] sha1_file: add repository argument to sha1_file_name","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:14Z","receivedAt":"2018-03-03T11:38:35Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd 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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h        |  6 ------\n http-walker.c  |  3 ++-\n http.c         |  5 ++---\n object-store.h |  7 +++++++\n sha1_file.c    | 10 +++++-----\n 5 files changed, 16 insertions(+), 15 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex d3429a0d48..cbec0ecd23 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -961,12 +961,6 @@ extern void check_repository_format(void);\n #define DATA_CHANGED    0x0020\n #define TYPE_CHANGED    0x0040\n \n-/*\n- * Put in `buf` the name of the file in the local object database that\n- * would be used to store a loose object with the specified sha1.\n- */\n-extern void sha1_file_name(struct strbuf *buf, 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 07c2b1af82..2c33969123 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@@ -545,7 +546,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\tstruct strbuf buf = STRBUF_INIT;\n-\t\tsha1_file_name(&buf, req->sha1);\n+\t\tsha1_file_name(the_repository, &buf, req->sha1);\n \t\tret = error(\"unable to write sha1 filename %s\", buf.buf);\n \t\tstrbuf_release(&buf);\n \t}\ndiff --git a/http.c b/http.c\nindex 31755023a4..df9dbea59c 100644\n--- a/http.c\n+++ b/http.c\n@@ -2246,7 +2246,7 @@ struct http_object_request *new_http_object_request(const char *base_url,\n \thashcpy(freq->sha1, sha1);\n \tfreq->localfile = -1;\n \n-\tsha1_file_name(&filename, sha1);\n+\tsha1_file_name(the_repository, &filename, sha1);\n \tsnprintf(freq->tmpfile, sizeof(freq->tmpfile),\n \t\t \"%s.temp\", filename.buf);\n \n@@ -2395,8 +2395,7 @@ int finish_http_object_request(struct http_object_request *freq)\n \t\tunlink_or_warn(freq->tmpfile);\n \t\treturn -1;\n \t}\n-\n-\tsha1_file_name(&filename, freq->sha1);\n+\tsha1_file_name(the_repository, &filename, freq->sha1);\n \tfreq->rename = finalize_object_file(freq->tmpfile, filename.buf);\n \tstrbuf_release(&filename);\n \ndiff --git a/object-store.h b/object-store.h\nindex 141455b5b2..f09acfbf5b 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -115,4 +115,11 @@ struct raw_object_store {\n void raw_object_store_init(struct raw_object_store *o);\n void raw_object_store_clear(struct raw_object_store *o);\n \n+/*\n+ * Put in `buf` the name of the file in the local object database that\n+ * would be used to store a loose object with the specified sha1.\n+ */\n+#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s)\n+void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1);\n+\n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex a3e4ef4253..e06d62a451 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -323,7 +323,7 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)\n \t}\n }\n \n-void sha1_file_name(struct strbuf *buf, const unsigned char *sha1)\n+void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1)\n {\n \tstrbuf_addstr(buf, get_object_directory());\n \tstrbuf_addch(buf, '/');\n@@ -713,7 +713,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(&buf, sha1);\n+\tsha1_file_name(the_repository, &buf, sha1);\n \n \treturn check_and_freshen_file(buf.buf, freshen);\n }\n@@ -874,7 +874,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(&buf, sha1);\n+\tsha1_file_name(the_repository, &buf, sha1);\n \t*path = buf.buf;\n \n \tif (!lstat(*path, st))\n@@ -903,7 +903,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(&buf, sha1);\n+\tsha1_file_name(the_repository, &buf, sha1);\n \t*path = buf.buf;\n \n \tfd = git_open(*path);\n@@ -1588,7 +1588,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,\n \tstatic struct strbuf filename = STRBUF_INIT;\n \n \tstrbuf_reset(&filename);\n-\tsha1_file_name(&filename, sha1);\n+\tsha1_file_name(the_repository, &filename, sha1);\n \n \tfd = create_tmpfile(&tmp_file, filename.buf);\n \tif (fd < 0) {\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340914","messageId":"20180303113637.26518-23-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 22/44] sha1_file: add repository argument to stat_sha1_file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:15Z","receivedAt":"2018-03-03T11:38:39Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 e06d62a451..7b640cca28 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -867,8 +867,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 \tstatic struct strbuf buf = STRBUF_INIT;\n@@ -1174,7 +1175,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@@ -1388,7 +1389,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340915","messageId":"20180303113637.26518-24-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 23/44] sha1_file: add repository argument to open_sha1_file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:16Z","receivedAt":"2018-03-03T11:38:43Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 7b640cca28..d4298805e3 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -896,7 +896,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@@ -939,7 +941,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340916","messageId":"20180303113637.26518-25-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 24/44] sha1_file: add repository argument to map_sha1_file_1","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:17Z","receivedAt":"2018-03-03T11:38:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 d4298805e3..78d5ffe876 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -931,9 +931,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@@ -962,7 +963,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@@ -2192,7 +2193,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340917","messageId":"20180303113637.26518-26-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 25/44] sha1_file: add repository argument to map_sha1_file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:18Z","receivedAt":"2018-03-03T11:38:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd 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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache.h        | 1 -\n object-store.h | 3 +++\n sha1_file.c    | 4 ++--\n streaming.c    | 5 ++++-\n 4 files changed, 9 insertions(+), 4 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex cbec0ecd23..720664e394 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1242,7 +1242,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 f09acfbf5b..ad4c7501d7 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -122,4 +122,7 @@ void raw_object_store_clear(struct raw_object_store *o);\n #define sha1_file_name(r, b, s) sha1_file_name_##r(b, s)\n void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1);\n \n+#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n+void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n+\n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 78d5ffe876..536c45589b 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -961,7 +961,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@@ -1185,7 +1185,7 @@ static int sha1_loose_object_info(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 5892b50bd8..22d27df55e 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.16.1.435.g8f24da2e1a\n\n"},{"id":"340918","messageId":"20180303113637.26518-27-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 26/44] sha1_file: add repository argument to sha1_loose_object_info","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:19Z","receivedAt":"2018-03-03T11:39:00Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 536c45589b..ecbf846f12 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1152,9 +1152,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@@ -1273,7 +1274,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \t\t\tbreak;\n \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.16.1.435.g8f24da2e1a\n\n"},{"id":"340919","messageId":"20180303113637.26518-28-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 27/44] sha1_file: allow sha1_file_name to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:20Z","receivedAt":"2018-03-03T11:39:05Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 ad4c7501d7..98622a2b98 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -119,8 +119,7 @@ void raw_object_store_clear(struct raw_object_store *o);\n  * Put in `buf` the name of the file in the local object database that\n  * would be used to store a loose object with the specified sha1.\n  */\n-#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s)\n-void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1);\n+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);\n \n #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex ecbf846f12..e04e0587c2 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -323,9 +323,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)\n \t}\n }\n \n-void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1)\n+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1)\n {\n-\tstrbuf_addstr(buf, get_object_directory());\n+\tstrbuf_addstr(buf, r->objects.objectdir);\n \tstrbuf_addch(buf, '/');\n \tfill_sha1_path(buf, sha1);\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340920","messageId":"20180303113637.26518-29-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 28/44] sha1_file: allow stat_sha1_file to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:21Z","receivedAt":"2018-03-03T11:39:10Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 e04e0587c2..f2533dd9e4 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -867,23 +867,22 @@ 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 \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(the_repository, &buf, sha1);\n+\tsha1_file_name(r, &buf, sha1);\n \t*path = buf.buf;\n \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.16.1.435.g8f24da2e1a\n\n"},{"id":"340921","messageId":"20180303113637.26518-30-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 29/44] sha1_file: allow open_sha1_file to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:22Z","receivedAt":"2018-03-03T11:39:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 f2533dd9e4..b3f7656c35 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -895,9 +895,8 @@ 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@@ -905,7 +904,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(the_repository, &buf, sha1);\n+\tsha1_file_name(r, &buf, sha1);\n \t*path = buf.buf;\n \n \tfd = git_open(*path);\n@@ -913,8 +912,8 @@ 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(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.16.1.435.g8f24da2e1a\n\n"},{"id":"340922","messageId":"20180303113637.26518-31-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 30/44] sha1_file: allow map_sha1_file_1 to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:23Z","receivedAt":"2018-03-03T11:39:20Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Jonathan Nieder <jrnieder@gmail.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 b3f7656c35..d4678f8162 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -929,10 +929,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@@ -940,7 +938,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340923","messageId":"20180303113637.26518-32-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 31/44] sha1_file: allow map_sha1_file to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:24Z","receivedAt":"2018-03-03T11:39:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 98622a2b98..521f5a1755 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -121,7 +121,6 @@ void raw_object_store_clear(struct raw_object_store *o);\n  */\n void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);\n \n-#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n-void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n+void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);\n \n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex d4678f8162..c5a8b00aed 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -957,9 +957,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340924","messageId":"20180303113637.26518-33-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 32/44] sha1_file: allow sha1_loose_object_info to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:25Z","receivedAt":"2018-03-03T11:39:30Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Jonathan Nieder <jrnieder@gmail.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 c5a8b00aed..7066d4c9ce 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1149,10 +1149,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@@ -1176,14 +1175,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340925","messageId":"20180303113637.26518-36-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 35/44] packfile: allow install_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:28Z","receivedAt":"2018-03-03T11:39:45Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThis conversion was done without the #define trick used in the earlier\nseries refactoring to have better repository access, because this function\nis easy to review, as it only has one caller and all lines but the first\ntwo are converted.\n\nWe must not convert 'pack_open_fds' to be a repository specific variable,\nas it is used to monitor resource usage of the machine that Git executes\non.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n fast-import.c | 2 +-\n http.c        | 2 +-\n packfile.c    | 8 ++++----\n packfile.h    | 2 +-\n 4 files changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/fast-import.c b/fast-import.c\nindex 0dba555478..ec78e8ff47 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -1037,7 +1037,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 df9dbea59c..649656b87c 100644\n--- a/http.c\n+++ b/http.c\n@@ -2133,7 +2133,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 5356712717..ba185daec2 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -679,13 +679,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(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);\n@@ -781,7 +781,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 5b1ce00f84..77442172f0 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -36,7 +36,7 @@ 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+extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \n struct packed_git *get_packed_git(struct repository *r);\n struct list_head *get_packed_git_mru(struct repository *r);\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340926","messageId":"20180303113637.26518-35-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 34/44] packfile: allow rearrange_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:27Z","receivedAt":"2018-03-03T11:39:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n packfile.c | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 0eaf5ee100..5356712717 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -865,10 +865,10 @@ static int sort_pack(const void *a_, const void *b_)\n \treturn -1;\n }\n \n-static void rearrange_packed_git(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@@ -892,7 +892,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(alt->path, 0);\n-\trearrange_packed_git();\n+\trearrange_packed_git(the_repository);\n \tprepare_packed_git_mru(the_repository);\n \tthe_repository->objects.packed_git_initialized = 1;\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340927","messageId":"20180303113637.26518-37-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 36/44] packfile: add repository argument to prepare_packed_git_one","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:29Z","receivedAt":"2018-03-03T11:39:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 ba185daec2..d7658e6c45 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -734,7 +734,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@@ -888,10 +889,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(the_repository);\n \tprepare_packed_git_mru(the_repository);\n \tthe_repository->objects.packed_git_initialized = 1;\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340928","messageId":"20180303113637.26518-38-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 37/44] packfile: add repository argument to prepare_packed_git","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:30Z","receivedAt":"2018-03-03T11:39:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow prepare_packed_git callers to\nbe more specific about which repository to handle. See c28d027a52c\n(sha1_file: add repository argument to link_alt_odb_entry, 2018-02-20)\nfor an explanation of the #define trick.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 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              |  4 ++--\n 12 files changed, 18 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 5c7c3c6ae3..2793c98ed3 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -122,7 +122,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 (!get_packed_git(the_repository))\n-\t\t\tprepare_packed_git();\n+\t\t\tprepare_packed_git(the_repository);\n \t\tfor (p = get_packed_git(the_repository); 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 b0abba6e04..7a3e323e9e 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -726,7 +726,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 = get_packed_git(the_repository); p;\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex dd30067ac1..526f06173e 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -173,7 +173,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 = get_packed_git(the_repository); 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 0e5fde1d6b..6020a7e230 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -3151,7 +3151,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 = get_packed_git(the_repository); p; p = p->next)\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex d6d8a44959..bf42e164eb 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -630,7 +630,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/fast-import.c b/fast-import.c\nindex ec78e8ff47..985eb2eccc 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -3472,7 +3472,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 22921d169a..659ddfb5f1 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -518,7 +518,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 = get_packed_git(the_repository); 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 abed43cdb5..01c9cd1642 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -335,7 +335,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 = get_packed_git(the_repository); 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 d7658e6c45..b5ad6838f8 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -816,7 +816,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@@ -883,7 +883,7 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\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@@ -902,7 +902,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 struct packed_git *get_packed_git(struct repository *r)\n@@ -1853,7 +1853,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n {\n \tstruct list_head *pos;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tif (!the_repository->objects.packed_git)\n \t\treturn 0;\n \n@@ -1907,7 +1907,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 77442172f0..3f59456e7e 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,7 +34,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 extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \ndiff --git a/server-info.c b/server-info.c\nindex 6fe64ede17..9604772522 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -200,7 +200,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 = get_packed_git(the_repository); 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 2065be90d2..cb42e398b2 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -195,7 +195,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 = get_packed_git(the_repository); p && !ds->ambiguous;\n \t     p = p->next)\n \t\tunique_in_pack(p, ds);\n@@ -566,7 +566,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); p; p = p->next)\n \t\tfind_abbrev_len_for_pack(p, mad);\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340929","messageId":"20180303113637.26518-39-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 38/44] packfile: add repository argument to reprepare_packed_git","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:31Z","receivedAt":"2018-03-03T11:40:02Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/gc.c           | 2 +-\n builtin/receive-pack.c | 3 ++-\n bulk-checkin.c         | 3 ++-\n fetch-pack.c           | 3 ++-\n packfile.c             | 2 +-\n packfile.h             | 3 ++-\n sha1_file.c            | 2 +-\n 7 files changed, 11 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 526f06173e..560d58daec 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -477,7 +477,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 ac478b7b99..dfc69be1a2 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@@ -1777,7 +1778,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 3310fd210a..eadc2d5172 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/fetch-pack.c b/fetch-pack.c\nindex 8253d746e0..eac5928a27 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@@ -1192,7 +1193,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 b5ad6838f8..53db240d0f 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -898,7 +898,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 3f59456e7e..ab5046938c 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -36,7 +36,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 extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \n struct packed_git *get_packed_git(struct repository *r);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 7066d4c9ce..be84f84373 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1274,7 +1274,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \t\t\treturn 0;\n \n \t\t/* Not a loose object; someone else may have just packed it. */\n-\t\treprepare_packed_git();\n+\t\treprepare_packed_git(the_repository);\n \t\tif (find_pack_entry(real, &e))\n \t\t\tbreak;\n \n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340930","messageId":"20180303113637.26518-40-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 39/44] packfile: allow prepare_packed_git_one to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:32Z","receivedAt":"2018-03-03T11:40:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 53db240d0f..52febba932 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -734,8 +734,7 @@ 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, char *objdir, int local)\n {\n \tstruct strbuf path = STRBUF_INIT;\n \tsize_t dirnamelen;\n@@ -768,7 +767,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\tfor (p = r->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@@ -782,7 +781,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340931","messageId":"20180303113637.26518-34-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 33/44] packfile: allow prepare_packed_git_mru to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:26Z","receivedAt":"2018-03-03T11:40:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThis conversion was done without the #define trick used in the earlier\nseries refactoring to have better repository access, because this function\nis easy to review, as all lines are converted and it has only one caller\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n packfile.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex a0842521e5..0eaf5ee100 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -872,14 +872,14 @@ static void rearrange_packed_git(void)\n \t\tset_next_packed_git, sort_pack);\n }\n \n-static void prepare_packed_git_mru(void)\n+static void prepare_packed_git_mru(struct repository *r)\n {\n \tstruct packed_git *p;\n \n-\tINIT_LIST_HEAD(&the_repository->objects.packed_git_mru);\n+\tINIT_LIST_HEAD(&r->objects.packed_git_mru);\n \n-\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n-\t\tlist_add_tail(&p->mru, &the_repository->objects.packed_git_mru);\n+\tfor (p = r->objects.packed_git; p; p = p->next)\n+\t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\n }\n \n void prepare_packed_git(void)\n@@ -893,7 +893,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(alt->path, 0);\n \trearrange_packed_git();\n-\tprepare_packed_git_mru();\n+\tprepare_packed_git_mru(the_repository);\n \tthe_repository->objects.packed_git_initialized = 1;\n }\n \n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340932","messageId":"20180303113637.26518-41-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 40/44] packfile: allow prepare_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:33Z","receivedAt":"2018-03-03T11:40:10Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 52febba932..2276e2ad26 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -882,19 +882,19 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\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, get_object_directory(), 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 ab5046938c..3fd9092472 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,8 +34,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.16.1.435.g8f24da2e1a\n\n"},{"id":"340933","messageId":"20180303113637.26518-42-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 41/44] packfile: allow reprepare_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:34Z","receivedAt":"2018-03-03T11:40:14Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 2276e2ad26..fbf5d56754 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -897,11 +897,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 struct packed_git *get_packed_git(struct repository *r)\ndiff --git a/packfile.h b/packfile.h\nindex 3fd9092472..ee6da3a9ae 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -35,8 +35,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 struct packed_git *get_packed_git(struct repository *r);\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340934","messageId":"20180303113637.26518-43-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 42/44] packfile: add repository argument to find_pack_entry","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:35Z","receivedAt":"2018-03-03T11:40:19Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nWhile at it move the documentation to the header and mention which pack\nfiles are searched.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n packfile.c  | 8 ++------\n packfile.h  | 7 ++++++-\n sha1_file.c | 6 +++---\n 3 files changed, 11 insertions(+), 10 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex fbf5d56754..7388debbb2 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1844,11 +1844,7 @@ static int fill_pack_entry(const unsigned char *sha1,\n \treturn 1;\n }\n \n-/*\n- * Iff a pack file contains the object named by sha1, return true and\n- * store its location to e.\n- */\n-int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n+int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e)\n {\n \tstruct list_head *pos;\n \n@@ -1870,7 +1866,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n int has_sha1_pack(const unsigned char *sha1)\n {\n \tstruct pack_entry e;\n-\treturn find_pack_entry(sha1, &e);\n+\treturn find_pack_entry(the_repository, sha1, &e);\n }\n \n int has_pack_index(const unsigned char *sha1)\ndiff --git a/packfile.h b/packfile.h\nindex ee6da3a9ae..e68f790ea7 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -123,7 +123,12 @@ extern int packed_object_info(struct packed_git *pack, off_t offset, struct obje\n extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);\n extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);\n \n-extern int find_pack_entry(const unsigned char *sha1, struct pack_entry *e);\n+/*\n+ * Iff a pack file in the given repository contains the object named by sha1,\n+ * return true and store its location to e.\n+ */\n+#define find_pack_entry(r, s, e) find_pack_entry_##r(s, e)\n+extern int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e);\n \n extern int has_sha1_pack(const unsigned char *sha1);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex be84f84373..ba47963e63 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1266,7 +1266,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \t}\n \n \twhile (1) {\n-\t\tif (find_pack_entry(real, &e))\n+\t\tif (find_pack_entry(the_repository, real, &e))\n \t\t\tbreak;\n \n \t\t/* Most likely it's a loose object. */\n@@ -1275,7 +1275,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \n \t\t/* Not a loose object; someone else may have just packed it. */\n \t\treprepare_packed_git(the_repository);\n-\t\tif (find_pack_entry(real, &e))\n+\t\tif (find_pack_entry(the_repository, real, &e))\n \t\t\tbreak;\n \n \t\t/* Check if it is a missing object */\n@@ -1655,7 +1655,7 @@ static int freshen_loose_object(const unsigned char *sha1)\n static int freshen_packed_object(const unsigned char *sha1)\n {\n \tstruct pack_entry e;\n-\tif (!find_pack_entry(sha1, &e))\n+\tif (!find_pack_entry(the_repository, sha1, &e))\n \t\treturn 0;\n \tif (e.p->freshened)\n \t\treturn 1;\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340935","messageId":"20180303113637.26518-44-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 43/44] packfile: allow find_pack_entry to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:36Z","receivedAt":"2018-03-03T11:40:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n packfile.c | 11 +++++------\n packfile.h |  3 +--\n 2 files changed, 6 insertions(+), 8 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 7388debbb2..bafe81544d 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1844,19 +1844,18 @@ static int fill_pack_entry(const unsigned char *sha1,\n \treturn 1;\n }\n \n-int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e)\n+int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e)\n {\n \tstruct list_head *pos;\n \n-\tprepare_packed_git(the_repository);\n-\tif (!the_repository->objects.packed_git)\n+\tprepare_packed_git(r);\n+\tif (!r->objects.packed_git)\n \t\treturn 0;\n \n-\tlist_for_each(pos, &the_repository->objects.packed_git_mru) {\n+\tlist_for_each(pos, &r->objects.packed_git_mru) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\tif (fill_pack_entry(sha1, e, p)) {\n-\t\t\tlist_move(&p->mru,\n-\t\t\t\t  &the_repository->objects.packed_git_mru);\n+\t\t\tlist_move(&p->mru, &r->objects.packed_git_mru);\n \t\t\treturn 1;\n \t\t}\n \t}\ndiff --git a/packfile.h b/packfile.h\nindex e68f790ea7..fe1a6380e6 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -127,8 +127,7 @@ extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);\n  * Iff a pack file in the given repository contains the object named by sha1,\n  * return true and store its location to e.\n  */\n-#define find_pack_entry(r, s, e) find_pack_entry_##r(s, e)\n-extern int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e);\n+extern int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e);\n \n extern int has_sha1_pack(const unsigned char *sha1);\n \n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340936","messageId":"20180303113637.26518-45-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 44/44] packfile: keep prepare_packed_git() private","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-03T11:36:37Z","receivedAt":"2018-03-03T11:40:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The reason callers have to call this is to make sure either packed_git\nor packed_git_mru pointers are initialized since we don't do that by\ndefault. Sometimes it's hard to see this connection between where the\nfunction is called and where packed_git pointer is used (sometimes in\nseparate functions).\n\nKeep this dependency internal because now all access to packed_git and\npacked_git_mru must go through get_xxx() wrappers.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/count-objects.c  | 3 +--\n builtin/fsck.c           | 2 --\n builtin/gc.c             | 1 -\n builtin/pack-objects.c   | 1 -\n builtin/pack-redundant.c | 2 --\n fast-import.c            | 1 -\n http-backend.c           | 1 -\n pack-bitmap.c            | 1 -\n packfile.c               | 5 ++++-\n packfile.h               | 1 -\n server-info.c            | 1 -\n sha1_name.c              | 2 --\n 12 files changed, 5 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 2793c98ed3..ee6ae35244 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -121,8 +121,7 @@ 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 (!get_packed_git(the_repository))\n-\t\t\tprepare_packed_git(the_repository);\n+\n \t\tfor (p = get_packed_git(the_repository); 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 7a3e323e9e..9911c52bc8 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -726,8 +726,6 @@ 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(the_repository);\n-\n \t\t\tif (show_progress) {\n \t\t\t\tfor (p = get_packed_git(the_repository); p;\n \t\t\t\t     p = p->next) {\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 560d58daec..be63bec09c 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -173,7 +173,6 @@ static int too_many_packs(void)\n \tif (gc_auto_pack_limit <= 0)\n \t\treturn 0;\n \n-\tprepare_packed_git(the_repository);\n \tfor (cnt = 0, p = get_packed_git(the_repository); 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 6020a7e230..435f091a69 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -3151,7 +3151,6 @@ 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(the_repository);\n \tif (ignore_packed_keep) {\n \t\tstruct packed_git *p;\n \t\tfor (p = get_packed_git(the_repository); p; p = p->next)\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex bf42e164eb..02b5f0becc 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -630,8 +630,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)\n \t\t\tbreak;\n \t}\n \n-\tprepare_packed_git(the_repository);\n-\n \tif (load_all_packs)\n \t\tload_all();\n \telse\ndiff --git a/fast-import.c b/fast-import.c\nindex 985eb2eccc..2298bfcdfd 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -3472,7 +3472,6 @@ 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(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 659ddfb5f1..22d2e1668e 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -518,7 +518,6 @@ static void get_info_packs(struct strbuf *hdr, char *arg)\n \tsize_t cnt = 0;\n \n \tselect_getanyfile(hdr);\n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); 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 01c9cd1642..2a007b5539 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -335,7 +335,6 @@ static int open_pack_bitmap(void)\n \n \tassert(!bitmap_git.map && !bitmap_git.loaded);\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); 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 bafe81544d..773cd99a13 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -802,6 +802,7 @@ static void prepare_packed_git_one(struct repository *r, char *objdir, int local\n \tstrbuf_release(&path);\n }\n \n+static void prepare_packed_git(struct repository *r);\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@@ -882,7 +883,7 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\n }\n \n-void prepare_packed_git(struct repository *r)\n+static void prepare_packed_git(struct repository *r)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -906,11 +907,13 @@ void reprepare_packed_git(struct repository *r)\n \n struct packed_git *get_packed_git(struct repository *r)\n {\n+\tprepare_packed_git(r);\n \treturn r->objects.packed_git;\n }\n \n struct list_head *get_packed_git_mru(struct repository *r)\n {\n+\tprepare_packed_git(r);\n \treturn &r->objects.packed_git_mru;\n }\n \ndiff --git a/packfile.h b/packfile.h\nindex fe1a6380e6..efda10329c 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,7 +34,6 @@ 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(struct repository *r);\n extern void reprepare_packed_git(struct repository *r);\n extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \ndiff --git a/server-info.c b/server-info.c\nindex 9604772522..af737acd24 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -200,7 +200,6 @@ static void init_pack_info(const char *infofile, int force)\n \tobjdir = get_object_directory();\n \tobjdirlen = strlen(objdir);\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); 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 cb42e398b2..f25a0970ca 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -195,7 +195,6 @@ static void find_short_packed_object(struct disambiguate_state *ds)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); p && !ds->ambiguous;\n \t     p = p->next)\n \t\tunique_in_pack(p, ds);\n@@ -566,7 +565,6 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); p; p = p->next)\n \t\tfind_abbrev_len_for_pack(p, mad);\n }\n-- \n2.16.1.435.g8f24da2e1a\n\n"},{"id":"340967","messageId":"CAPig+cRV7eRWMdONVNrFwF86Zbw=_hY-L354MNT54wwazjJRgA@mail.gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-7-pclouds@gmail.com","subject":"Re: [PATCH 06/44] repository: introduce raw object store field","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-03-04T02:19:09Z","receivedAt":"2018-03-04T02:19:15Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Mar 3, 2018 at 6:35 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> The raw object store field will contain any objects needed for\n> access to objects in a given repository.\n>\n> This patch introduces the raw object store and populates it with the\n> `objectdir`, which used to be part of the repository struct.\n>\n> As the struct gains members, we'll also populate the function to clear\n> the memory for these members.\n>\n> In a later we'll introduce a struct object_parser, that will complement\n\ns/In a later/Later,/\n\n> the object parsing in a repository struct: The raw object parser is the\n> layer that will provide access to raw object content, while the higher\n> level object parser code will parse raw objects and keeps track of\n> parenthood and other object relationships using 'struct object'.\n> For now only add the lower level to the repository struct.\n>\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n"},{"id":"340968","messageId":"CAPig+cSkU8j-NiNeMP-F3VygF1sAoXP3qzn4fx7C1qxTZoO5+g@mail.gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-10-pclouds@gmail.com","subject":"Re: [PATCH 09/44] object-store: free alt_odb_list","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-03-04T02:37:30Z","receivedAt":"2018-03-04T02:37:36Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> Free the memory and reset alt_odb_{list, tail} to NULL.\n>\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n> diff --git a/object.c b/object.c\n> @@ -450,8 +450,26 @@ void raw_object_store_init(struct raw_object_store *o)\n> +static void free_alt_odb(struct alternate_object_database *alt)\n> +{\n> +       strbuf_release(&alt->scratch);\n> +       oid_array_clear(&alt->loose_objects_cache);\n> +}\n\nThis doesn't free the 'struct alternate_object_database' entry itself, right?\n\nIs that intentional? Isn't the idea that this should free the entries too?\n\n> +static void free_alt_odbs(struct raw_object_store *o)\n> +{\n> +       while (o->alt_odb_list) {\n> +               free_alt_odb(o->alt_odb_list);\n> +               o->alt_odb_list = o->alt_odb_list->next;\n> +       }\n> +}\n\nAccessing an entry's 'next' member after invoking free_alt_odb() works\nbecause the entry itself hasn't been freed (as noted above).\n\nIs leaking the entries themselves intentional?\n\n>  void raw_object_store_clear(struct raw_object_store *o)\n>  {\n>         FREE_AND_NULL(o->objectdir);\n>         FREE_AND_NULL(o->alternate_db);\n> +\n> +       free_alt_odbs(o);\n> +       o->alt_odb_tail = NULL;\n>  }\n\nThe commit message talks about freeing memory and resetting\nalt_odb_list and alt_odb_tail, but this code only resets alt_odb_tail.\n"},{"id":"340969","messageId":"CAPig+cSE_x2f_8RG151MX3+FJhiofBPoVPXP+mxdJpoHXwjv9g@mail.gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-14-pclouds@gmail.com","subject":"Re: [PATCH 13/44] pack: move approximate object count to object store","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-03-04T02:47:20Z","receivedAt":"2018-03-04T02:47:26Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> The approximate_object_count() function maintains a rough count of\n> objects in a repository to estimate how long object name abbreviates\n> should be.  Object names are scoped to a repository and the\n> appropriate length may differ by repository, so the object count\n> should not be global.\n>\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n> diff --git a/packfile.c b/packfile.c\n> @@ -813,8 +811,8 @@ static int approximate_object_count_valid;\n>  unsigned long approximate_object_count(void)\n>  {\n> -       static unsigned long count;\n> -       if (!approximate_object_count_valid) {\n> +       if (!the_repository->objects.approximate_object_count_valid) {\n> +               unsigned long count;\n>                 struct packed_git *p;\n>\n>                 prepare_packed_git();\n> @@ -824,8 +822,9 @@ unsigned long approximate_object_count(void)\n>                                 continue;\n>                         count += p->num_objects;\n>                 }\n> +               the_repository->objects.approximate_object_count = count;\n>         }\n> -       return count;\n> +       return the_repository->objects.approximate_object_count;\n>  }\n> @@ -900,7 +899,7 @@ void prepare_packed_git(void)\n>  void reprepare_packed_git(void)\n>  {\n> -       approximate_object_count_valid = 0;\n> +       the_repository->objects.approximate_object_count_valid = 0;\n\nNot an issue specific to this patch, but where, how, when does\n'approximate_object_count_valid' ever get set to anything other than\n0? Even in the existing code (without this patch), there doesn't seem\nto be anyplace which sets this to a non-zero value. Am I missing\nsomething obvious (or subtle)?\n"},{"id":"340971","messageId":"CAPig+cQEZawtD+XR9KbSfyJNynh3M1pe4KMXWCc2FeyzgycvhA@mail.gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-38-pclouds@gmail.com","subject":"Re: [PATCH 37/44] packfile: add repository argument to prepare_packed_git","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-03-04T03:03:47Z","receivedAt":"2018-03-04T03:03:52Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> Add a repository argument to allow prepare_packed_git callers to\n> be more specific about which repository to handle. See c28d027a52c\n> (sha1_file: add repository argument to link_alt_odb_entry, 2018-02-20)\n> for an explanation of the #define trick.\n\nObject c28d027a52c doesn't exist. Most likely it was a reference to a\nchange existing only in 'pu' which got replaced by a later revision of\nthe series.\n\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n"},{"id":"340972","messageId":"CACsJy8CQxsTPH15jtvDUhc8DFdtPdLNDYtFe7HNn3ntUHAv=tg@mail.gmail.com","threadId":"47963","inReplyTo":"CAPig+cSE_x2f_8RG151MX3+FJhiofBPoVPXP+mxdJpoHXwjv9g@mail.gmail.com","subject":"Re: [PATCH 13/44] pack: move approximate object count to object store","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-04T03:41:11Z","receivedAt":"2018-03-04T03:43:19Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sun, Mar 4, 2018 at 9:47 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>> The approximate_object_count() function maintains a rough count of\n>> objects in a repository to estimate how long object name abbreviates\n>> should be.  Object names are scoped to a repository and the\n>> appropriate length may differ by repository, so the object count\n>> should not be global.\n>>\n>> Signed-off-by: Stefan Beller <sbeller@google.com>\n>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>> ---\n>> diff --git a/packfile.c b/packfile.c\n>> @@ -813,8 +811,8 @@ static int approximate_object_count_valid;\n>>  unsigned long approximate_object_count(void)\n>>  {\n>> -       static unsigned long count;\n>> -       if (!approximate_object_count_valid) {\n>> +       if (!the_repository->objects.approximate_object_count_valid) {\n>> +               unsigned long count;\n>>                 struct packed_git *p;\n>>\n>>                 prepare_packed_git();\n>> @@ -824,8 +822,9 @@ unsigned long approximate_object_count(void)\n>>                                 continue;\n>>                         count += p->num_objects;\n>>                 }\n>> +               the_repository->objects.approximate_object_count = count;\n>>         }\n>> -       return count;\n>> +       return the_repository->objects.approximate_object_count;\n>>  }\n>> @@ -900,7 +899,7 @@ void prepare_packed_git(void)\n>>  void reprepare_packed_git(void)\n>>  {\n>> -       approximate_object_count_valid = 0;\n>> +       the_repository->objects.approximate_object_count_valid = 0;\n>\n> Not an issue specific to this patch, but where, how, when does\n> 'approximate_object_count_valid' ever get set to anything other than\n> 0? Even in the existing code (without this patch), there doesn't seem\n> to be anyplace which sets this to a non-zero value. Am I missing\n> something obvious (or subtle)?\n\nProbably related to this\nhttps://public-inbox.org/git/20180226085508.GA30343@sigill.intra.peff.net/#t\n\n-- \nDuy\n"},{"id":"341003","messageId":"CACsJy8AH08k-=DATSn63T_4uVmjNoGn8m6k4=ZTq5RbO386k7A@mail.gmail.com","threadId":"47963","inReplyTo":"CAPig+cSkU8j-NiNeMP-F3VygF1sAoXP3qzn4fx7C1qxTZoO5+g@mail.gmail.com","subject":"Re: [PATCH 09/44] object-store: free alt_odb_list","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-05T09:54:48Z","receivedAt":"2018-03-05T09:55:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sun, Mar 4, 2018 at 9:37 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>> Free the memory and reset alt_odb_{list, tail} to NULL.\n>>\n>> Signed-off-by: Stefan Beller <sbeller@google.com>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>> ---\n>> diff --git a/object.c b/object.c\n>> @@ -450,8 +450,26 @@ void raw_object_store_init(struct raw_object_store *o)\n>> +static void free_alt_odb(struct alternate_object_database *alt)\n>> +{\n>> +       strbuf_release(&alt->scratch);\n>> +       oid_array_clear(&alt->loose_objects_cache);\n>> +}\n>\n> This doesn't free the 'struct alternate_object_database' entry itself, right?\n>\n> Is that intentional? Isn't the idea that this should free the entries too?\n\nI think \"alt\" should be freed too. But since this series is more about\nrefactoring, and we're still in the middle of converting to struct\nrepository/raw_object_store, I don't mind \"leaking a bit\" (the current\nstate is leaking freely when most things are global). Once the\nconversion is done, I think we could have some nice test that creates\nand destroys the object store gracefully, then tools like valgrind.\nasan... can help clean up these leaks.\n-- \nDuy\n"},{"id":"341053","messageId":"xmqq371e9vyk.fsf@gitster-ct.c.googlers.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"Re: [PATCH 00/44] reroll nd/remove-ignore-env.. sb/object-store and sb/packfiles..","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-03-05T19:13:55Z","receivedAt":"2018-03-05T19:14:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> 01/44 - 05/44: nd/remove-ignore-env-field\n>\n>   This series is moved up top. After this the patch that touch\n>   alternate-db in sha1_file.c looks natural because no env is involved\n>   anymore\n\nYes, I do like having this upfront and being able to merge it before\nhaving to wait for the rest of the huge pile.\n\n>   I also take this opportunity to introduce a new patch 01/44 to avoid\n>   struct initialization that makes it hard to read and update. Later\n>   patches are also simplified thanks to this.\n>\n> 06/44 - 32/44: sb/object-store\n>\n>   06/44 is updated to introduce raw_object_store_init() instead of\n>   RAW_OBJECT_STORE_INIT macro. This function is now used to initialize\n>   both main repo and submodule ones.\n>\n>   10/44 (moving \"packed_git\") also introduces two new access wrapper\n>   get_packed_git() and get_packed_git_mru()\n\nI haven't studied individual patches in this round for these, but\nthe interdiff you show below looks quite sensible.\n\nThanks, will take a bit deeper look at the rest.\n"},{"id":"342221","messageId":"20180319110735.56f860f2794c36b1e2e6180c@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-3-pclouds@gmail.com","subject":"Re: [PATCH 02/44] repository.c: move env-related setup code back to environment.c","fromName":"Jonathan Tan","fromEmail":"jonathantanmy@google.com","sentAt":"2018-03-19T18:07:35Z","receivedAt":"2018-03-19T18:08:08Z","isPatch":true,"sender":{"key":"jonathantanmy@fastmail.com","avatar":null},"body":"On Sat,  3 Mar 2018 18:35:55 +0700\nNguyễn Thái Ngọc Duy  <pclouds@gmail.com> wrote:\n\n> It does not make sense that generic repository code contains handling\n> of environment variables, which are specific for the main repository\n> only. Refactor repo_set_gitdir() function to take $GIT_DIR and\n> optionally _all_ other customizable paths. These optional paths can be\n> NULL and will be calculated according to the default directory layout.\n> \n> Note that some dead functions are left behind to reduce diff\n> noise. They will be deleted in the next patch.\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nThanks - I've reviewed up to this patch, and patches 1 and 2 look good.\n\n> -extern void repo_set_gitdir(struct repository *repo, const char *path);\n> +struct set_gitdir_args {\n> +\tconst char *commondir;\n> +\tconst char *object_dir;\n> +\tconst char *graft_file;\n> +\tconst char *index_file;\n> +};\n> +\n> +extern void repo_set_gitdir(struct repository *repo,\n> +\t\t\t    const char *root,\n> +\t\t\t    const struct set_gitdir_args *optional);\n\nOptional: Reading this header file alone makes me think that the 3rd\nargument can be NULL, but it actually can't. I would name it\n\"extra_args\" and add a comment inside \"struct set_gitdir_args\"\nexplaining (e.g.):\n\n  /*\n   * Any of these fields may be NULL. If so, the name of that directory\n   * is instead derived from the root path of the repository.\n   */\n"},{"id":"342226","messageId":"CACsJy8D3Dn8FeSX9su8edYFM28N-qG2bjNYRpajNWaEi6qdTDQ@mail.gmail.com","threadId":"47963","inReplyTo":"20180319110735.56f860f2794c36b1e2e6180c@google.com","subject":"Re: [PATCH 02/44] repository.c: move env-related setup code back to environment.c","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-19T18:56:20Z","receivedAt":"2018-03-19T18:57:05Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Mar 19, 2018 at 7:07 PM, Jonathan Tan <jonathantanmy@google.com> wrote:\n>> -extern void repo_set_gitdir(struct repository *repo, const char *path);\n>> +struct set_gitdir_args {\n>> +     const char *commondir;\n>> +     const char *object_dir;\n>> +     const char *graft_file;\n>> +     const char *index_file;\n>> +};\n>> +\n>> +extern void repo_set_gitdir(struct repository *repo,\n>> +                         const char *root,\n>> +                         const struct set_gitdir_args *optional);\n>\n> Optional: Reading this header file alone makes me think that the 3rd\n> argument can be NULL, but it actually can't. I would name it\n> \"extra_args\" and add a comment inside \"struct set_gitdir_args\"\n> explaining (e.g.):\n>\n>   /*\n>    * Any of these fields may be NULL. If so, the name of that directory\n>    * is instead derived from the root path of the repository.\n>    */\n\nYeah. I think Eric made the same comment. I'm still (very slowly) in\nthe process of unifying the repo setup for the main repo and\nsubmodules, which hopefully may kill this function or replace it with\nsomething better. But it's too early to tell. Since this part of the\nseries has landed in 'next', I'll post a fixup patch soon with your\nsuggestion.\n-- \nDuy\n"},{"id":"342240","messageId":"20180319123914.6767c0660fb3e77247f02989@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-11-pclouds@gmail.com","subject":"Re: [PATCH 10/44] object-store: move packed_git and packed_git_mru to object store","fromName":"Jonathan Tan","fromEmail":"jonathantanmy@google.com","sentAt":"2018-03-19T19:39:14Z","receivedAt":"2018-03-19T19:39:24Z","isPatch":true,"sender":{"key":"jonathantanmy@fastmail.com","avatar":null},"body":"On Sat,  3 Mar 2018 18:36:03 +0700\nNguyễn Thái Ngọc Duy  <pclouds@gmail.com> wrote:\n\n> From: Stefan Beller <sbeller@google.com>\n> \n> In a process with multiple repositories open, packfile accessors\n> should be associated to a single repository and not shared globally.\n> Move packed_git and packed_git_mru into the_repository and adjust\n> callers to reflect this.\n> \n> [nd: while at there, wrap access to these two fields in get_packed_git()\n> and get_packed_git_mru(). This allows us to lazily initialize these\n> fields without caller doing that explicitly]\n\nThe patches up to this one look good. (I didn't reply for each\nindividual one to avoid unnecessarily sending messages to the list.)\n\nAbout this patch: will lazily initializing these fields be done in a\nlater patch?\n\n> Patch 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. Apply the following semantic patch to adjust callers:\n>     @@ @@\n>     - packed_git\n>     + the_repository->objects.packed_git\n> \n>     @@ @@\n>     - packed_git_mru\n>     + the_repository->objects.packed_git_mru\n\nThis doesn't seem up-to-date - they are being replaced with a function\ncall, not a field access. I would be OK with just removing this \"Patch\ngenerated by\" section.\n\n[snip remainder of \"Patch generated by\" section]\n\n> @@ -246,7 +244,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\nHere (and elsewhere), \"the_repository->objects.packed_git\" instead of\n\"get_packed_git\" is still used.\n"},{"id":"342244","messageId":"20180319131057.7cf5c90d55b34542f691cee8@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-40-pclouds@gmail.com","subject":"Re: [PATCH 39/44] packfile: allow prepare_packed_git_one to handle arbitrary repositories","fromName":"Jonathan Tan","fromEmail":"jonathantanmy@google.com","sentAt":"2018-03-19T20:10:57Z","receivedAt":"2018-03-19T20:11:10Z","isPatch":true,"sender":{"key":"jonathantanmy@fastmail.com","avatar":null},"body":"On Sat,  3 Mar 2018 18:36:32 +0700\nNguyễn Thái Ngọc Duy  <pclouds@gmail.com> wrote:\n\n> From: Stefan Beller <sbeller@google.com>\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nThanks - I've checked that none of the functions invoked in\nprepare_packed_git_one() access the_repository. (add_packed_git() does\nnot, despite its name.)\n\nThe patches up to this one are fine.\n\n[snip]\n\n> -\t\t\tfor (p = the_repository->objects.packed_git; p;\n> +\t\t\tfor (p = r->objects.packed_git; p;\n\nOptional: this could be get_packed_git(r).\n"},{"id":"342248","messageId":"20180319133428.1f26cd2ec85af8eb22b09376@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-45-pclouds@gmail.com","subject":"Re: [PATCH 44/44] packfile: keep prepare_packed_git() private","fromName":"Jonathan Tan","fromEmail":"jonathantanmy@google.com","sentAt":"2018-03-19T20:34:28Z","receivedAt":"2018-03-19T20:34:43Z","isPatch":true,"sender":{"key":"jonathantanmy@fastmail.com","avatar":null},"body":"On Sat,  3 Mar 2018 18:36:37 +0700\nNguyễn Thái Ngọc Duy  <pclouds@gmail.com> wrote:\n\n> The reason callers have to call this is to make sure either packed_git\n> or packed_git_mru pointers are initialized since we don't do that by\n> default. Sometimes it's hard to see this connection between where the\n> function is called and where packed_git pointer is used (sometimes in\n> separate functions).\n> \n> Keep this dependency internal because now all access to packed_git and\n> packed_git_mru must go through get_xxx() wrappers.\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nThe patches up to and including this one look good.\n\nI also see that the question I asked in patch 10 about lazily\ninitializing some fields is answered here.\n\nIf we're planning to avoid making the user call prepare_packed_git()\n(which I agree with), I think we also need to ensure that we always use\nthe get_xxx() wrapper whenever we access objects.packed_git. Currently,\nthere are still some functions in packfile.c that do not do so (notably\nfor_each_packed_object()). Could these be changed too? (This should not\nbe too difficult for you to do on your own, but I can send a fixup\npatch if you want.)\n"},{"id":"342460","messageId":"20180321214606.GA18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-2-pclouds@gmail.com","subject":"Re: [PATCH 01/44] repository: initialize the_repository in main()","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T21:46:06Z","receivedAt":"2018-03-21T21:46:16Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> This simplifies initialization of struct repository and anything\n> inside. Easier to read. Easier to add/remove fields.\n> \n> Everything will go through main() common-main.c so this should cover all\n> programs, including t/helper.\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  common-main.c |  2 ++\n>  repository.c  | 18 +++++++++++++-----\n>  repository.h  |  2 +-\n>  3 files changed, 16 insertions(+), 6 deletions(-)\n> \n> diff --git a/common-main.c b/common-main.c\n> index 6a689007e7..7d716d5a54 100644\n> --- a/common-main.c\n> +++ b/common-main.c\n> @@ -34,6 +34,8 @@ int main(int argc, const char **argv)\n>  \n>  \tgit_setup_gettext();\n>  \n> +\tinitialize_the_repository();\n> +\n>  \tattr_start();\n>  \n>  \tgit_extract_argv0_path(argv[0]);\n> diff --git a/repository.c b/repository.c\n> index 4ffbe9bc94..0eddf28fcd 100644\n> --- a/repository.c\n> +++ b/repository.c\n> @@ -4,10 +4,16 @@\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, &hash_algos[GIT_HASH_SHA1], 0, 0\n> -};\n> -struct repository *the_repository = &the_repo;\n> +static struct repository the_repo;\n> +struct repository *the_repository;\n> +\n> +void initialize_the_repository(void)\n> +{\n> +\tthe_repository = &the_repo;\n> +\n> +\tthe_repo.index = &the_index;\n> +\trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n> +}\n\nNice, one place to do all the crazy initialization for the_repo.  I\nwanted to do something like this when I introduced the repository but I\nshied away from it because it didn't seem like the right thing to do at\nthe time.  Now that its grown a bit, its definitely the right move until\nusing the repository object is ubiquitous enough that the setup code can\nproduce a repository struct instead of relying on a global one.\n\n>  \n>  static char *git_path_from_env(const char *envvar, const char *git_dir,\n>  \t\t\t       const char *path, int fromenv)\n> @@ -128,7 +134,9 @@ static int read_and_verify_repository_format(struct repository_format *format,\n>   * Initialize 'repo' based on the provided 'gitdir'.\n>   * Return 0 upon success and a non-zero value upon failure.\n>   */\n> -int repo_init(struct repository *repo, const char *gitdir, const char *worktree)\n> +static int repo_init(struct repository *repo,\n> +\t\t     const char *gitdir,\n> +\t\t     const char *worktree)\n>  {\n>  \tstruct repository_format format;\n>  \tmemset(repo, 0, sizeof(*repo));\n> diff --git a/repository.h b/repository.h\n> index 0329e40c7f..40c1c81bdc 100644\n> --- a/repository.h\n> +++ b/repository.h\n> @@ -91,7 +91,7 @@ extern struct repository *the_repository;\n>  extern void repo_set_gitdir(struct repository *repo, const char *path);\n>  extern void repo_set_worktree(struct repository *repo, const char *path);\n>  extern void repo_set_hash_algo(struct repository *repo, int algo);\n> -extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree);\n\nI had to double check that this was ok, it indeed is as repo_init is\nonly used in repository.c.\n\n> +extern void initialize_the_repository(void);\n>  extern int repo_submodule_init(struct repository *submodule,\n>  \t\t\t       struct repository *superproject,\n>  \t\t\t       const char *path);\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342464","messageId":"20180321215315.GB18406@google.com","threadId":"47963","inReplyTo":"CACsJy8D3Dn8FeSX9su8edYFM28N-qG2bjNYRpajNWaEi6qdTDQ@mail.gmail.com","subject":"Re: [PATCH 02/44] repository.c: move env-related setup code back to environment.c","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T21:53:15Z","receivedAt":"2018-03-21T21:53:28Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/19, Duy Nguyen wrote:\n> On Mon, Mar 19, 2018 at 7:07 PM, Jonathan Tan <jonathantanmy@google.com> wrote:\n> >> -extern void repo_set_gitdir(struct repository *repo, const char *path);\n> >> +struct set_gitdir_args {\n> >> +     const char *commondir;\n> >> +     const char *object_dir;\n> >> +     const char *graft_file;\n> >> +     const char *index_file;\n> >> +};\n> >> +\n> >> +extern void repo_set_gitdir(struct repository *repo,\n> >> +                         const char *root,\n> >> +                         const struct set_gitdir_args *optional);\n> >\n> > Optional: Reading this header file alone makes me think that the 3rd\n> > argument can be NULL, but it actually can't. I would name it\n> > \"extra_args\" and add a comment inside \"struct set_gitdir_args\"\n> > explaining (e.g.):\n> >\n> >   /*\n> >    * Any of these fields may be NULL. If so, the name of that directory\n> >    * is instead derived from the root path of the repository.\n> >    */\n> \n> Yeah. I think Eric made the same comment. I'm still (very slowly) in\n> the process of unifying the repo setup for the main repo and\n> submodules, which hopefully may kill this function or replace it with\n> something better. But it's too early to tell. Since this part of the\n> series has landed in 'next', I'll post a fixup patch soon with your\n> suggestion.\n> -- \n> Duy\n\nYeah looking at the patch this is probably my only complaint.  The rest\nlooked good.\n\n-- \nBrandon Williams\n"},{"id":"342466","messageId":"20180321215730.GC18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-4-pclouds@gmail.com","subject":"Re: [PATCH 03/44] repository.c: delete dead functions","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T21:57:30Z","receivedAt":"2018-03-21T21:57:37Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  repository.c | 25 -------------------------\n>  1 file changed, 25 deletions(-)\n> \n> diff --git a/repository.c b/repository.c\n> index bb53b54b6d..e65f4138a7 100644\n> --- a/repository.c\n> +++ b/repository.c\n> @@ -15,31 +15,6 @@ void initialize_the_repository(void)\n>  \trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n>  }\n>  \n> -static char *git_path_from_env(const char *envvar, const char *git_dir,\n> -\t\t\t       const char *path, int fromenv)\n> -{\n> -\tif (fromenv) {\n> -\t\tconst char *value = getenv(envvar);\n> -\t\tif (value)\n> -\t\t\treturn xstrdup(value);\n> -\t}\n> -\n> -\treturn xstrfmt(\"%s/%s\", git_dir, path);\n> -}\n> -\n> -static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)\n> -{\n> -\tif (fromenv) {\n> -\t\tconst char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT);\n> -\t\tif (value) {\n> -\t\t\tstrbuf_addstr(sb, value);\n> -\t\t\treturn 1;\n> -\t\t}\n> -\t}\n> -\n> -\treturn get_common_dir_noenv(sb, gitdir);\n> -}\n> -\n>  static void expand_base_dir(char **out, const char *in,\n>  \t\t\t    const char *base_dir, const char *def_in)\n>  {\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\nThis patch needs to be squashed into the previous one, the build breaks\notherwise (unless built with -Werror=unused-function).\n\n-- \nBrandon Williams\n"},{"id":"342467","messageId":"20180321215909.GD18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-5-pclouds@gmail.com","subject":"Re: [PATCH 04/44] sha1_file.c: move delayed getenv(altdb) back to setup_git_env()","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T21:59:09Z","receivedAt":"2018-03-21T21:59:16Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> getenv() is supposed to work on the main repository only. This delayed\n> getenv() code in sha1_file.c makes it more difficult to convert\n> sha1_file.c to a generic object store that could be used by both\n> submodule and main repositories.\n> \n> Move the getenv() back in setup_git_env() where other env vars are\n> also fetched.\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nLooks good\n\n> ---\n>  environment.c | 1 +\n>  repository.c  | 3 +++\n>  repository.h  | 4 ++++\n>  sha1_file.c   | 6 +-----\n>  4 files changed, 9 insertions(+), 5 deletions(-)\n> \n> diff --git a/environment.c b/environment.c\n> index da3f7daa09..a5eaa97fb1 100644\n> --- a/environment.c\n> +++ b/environment.c\n> @@ -174,6 +174,7 @@ void setup_git_env(const char *git_dir)\n>  \targs.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);\n>  \targs.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);\n>  \targs.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);\n> +\targs.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);\n>  \trepo_set_gitdir(the_repository, git_dir, &args);\n>  \targv_array_clear(&to_free);\n>  \n> diff --git a/repository.c b/repository.c\n> index e65f4138a7..04d85a2869 100644\n> --- a/repository.c\n> +++ b/repository.c\n> @@ -60,6 +60,8 @@ void repo_set_gitdir(struct repository *repo,\n>  \trepo_set_commondir(repo, o->commondir);\n>  \texpand_base_dir(&repo->objectdir, o->object_dir,\n>  \t\t\trepo->commondir, \"objects\");\n> +\tfree(repo->alternate_db);\n> +\trepo->alternate_db = xstrdup_or_null(o->alternate_db);\n>  \texpand_base_dir(&repo->graft_file, o->graft_file,\n>  \t\t\trepo->commondir, \"info/grafts\");\n>  \texpand_base_dir(&repo->index_file, o->index_file,\n> @@ -215,6 +217,7 @@ void repo_clear(struct repository *repo)\n>  \tFREE_AND_NULL(repo->gitdir);\n>  \tFREE_AND_NULL(repo->commondir);\n>  \tFREE_AND_NULL(repo->objectdir);\n> +\tFREE_AND_NULL(repo->alternate_db);\n>  \tFREE_AND_NULL(repo->graft_file);\n>  \tFREE_AND_NULL(repo->index_file);\n>  \tFREE_AND_NULL(repo->worktree);\n> diff --git a/repository.h b/repository.h\n> index 84aeac2825..2bfbf762f3 100644\n> --- a/repository.h\n> +++ b/repository.h\n> @@ -26,6 +26,9 @@ struct repository {\n>  \t */\n>  \tchar *objectdir;\n>  \n> +\t/* Path to extra alternate object database if not NULL */\n> +\tchar *alternate_db;\n> +\n>  \t/*\n>  \t * Path to the repository's graft file.\n>  \t * Cannot be NULL after initialization.\n> @@ -93,6 +96,7 @@ struct set_gitdir_args {\n>  \tconst char *object_dir;\n>  \tconst char *graft_file;\n>  \tconst char *index_file;\n> +\tconst char *alternate_db;\n>  };\n>  \n>  extern void repo_set_gitdir(struct repository *repo,\n> diff --git a/sha1_file.c b/sha1_file.c\n> index 831d9e7343..4af422e3cf 100644\n> --- a/sha1_file.c\n> +++ b/sha1_file.c\n> @@ -667,15 +667,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n>  \n>  void prepare_alt_odb(void)\n>  {\n> -\tconst char *alt;\n> -\n>  \tif (alt_odb_tail)\n>  \t\treturn;\n>  \n> -\talt = getenv(ALTERNATE_DB_ENVIRONMENT);\n> -\n>  \talt_odb_tail = &alt_odb_list;\n> -\tlink_alt_odb_entries(alt, PATH_SEP, NULL, 0);\n> +\tlink_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);\n>  \n>  \tread_info_alternates(get_object_directory(), 0);\n>  }\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342468","messageId":"20180321215949.GE18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-6-pclouds@gmail.com","subject":"Re: [PATCH 05/44] repository: delete ignore_env member","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T21:59:49Z","receivedAt":"2018-03-21T21:59:57Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> This variable was added because the repo_set_gitdir() was created to\n> cover both submodule and main repos, but these two are initialized a\n> bit differently so ignore_env == 0 means main repo, while ignore_env\n> != 0 is submodules.\n> \n> Since the difference part (env variables) has been moved out of\n> repo_set_gitdir(), this function works the same way for both repo\n> types and ignore_env is not needed anymore.\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nSweet! Thanks for getting rid of this.\n\n> ---\n>  repository.c | 2 --\n>  repository.h | 9 ---------\n>  2 files changed, 11 deletions(-)\n> \n> diff --git a/repository.c b/repository.c\n> index 04d85a2869..62f52f47fc 100644\n> --- a/repository.c\n> +++ b/repository.c\n> @@ -140,8 +140,6 @@ static int repo_init(struct repository *repo,\n>  \tstruct repository_format format;\n>  \tmemset(repo, 0, sizeof(*repo));\n>  \n> -\trepo->ignore_env = 1;\n> -\n>  \tif (repo_init_gitdir(repo, gitdir))\n>  \t\tgoto error;\n>  \n> diff --git a/repository.h b/repository.h\n> index 2bfbf762f3..e7127baffb 100644\n> --- a/repository.h\n> +++ b/repository.h\n> @@ -75,15 +75,6 @@ struct repository {\n>  \tconst struct git_hash_algo *hash_algo;\n>  \n>  \t/* Configurations */\n> -\t/*\n> -\t * Bit used during initialization to indicate if repository state (like\n> -\t * the location of the 'objectdir') should be read from the\n> -\t * environment.  By default this bit will be set at the begining of\n> -\t * 'repo_init()' so that all repositories will ignore the environment.\n> -\t * The exception to this is 'the_repository', which doesn't go through\n> -\t * the normal 'repo_init()' process.\n> -\t */\n> -\tunsigned ignore_env:1;\n>  \n>  \t/* Indicate if a repository has a different 'commondir' from 'gitdir' */\n>  \tunsigned different_commondir:1;\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342469","messageId":"20180321220432.GF18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-7-pclouds@gmail.com","subject":"Re: [PATCH 06/44] repository: introduce raw object store field","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:04:32Z","receivedAt":"2018-03-21T22:04:41Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> The raw object store field will contain any objects needed for\n> access to objects in a given repository.\n> \n> This patch introduces the raw object store and populates it with the\n> `objectdir`, which used to be part of the repository struct.\n> \n> As the struct gains members, we'll also populate the function to clear\n> the memory for these members.\n> \n> In a later we'll introduce a struct object_parser, that will complement\n> the object parsing in a repository struct: The raw object parser is the\n> layer that will provide access to raw object content, while the higher\n> level object parser code will parse raw objects and keeps track of\n> parenthood and other object relationships using 'struct object'.\n> For now only add the lower level to the repository struct.\n\nPatch looks good. Only nit would be that I prefer the embedded struct to\nbe a pointer simply because I don't have to worry about putting '&' at\nsome points.  I know others probably feel the opposite so its not worth\nchanging for me :)\n\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  builtin/grep.c |  2 +-\n>  environment.c  |  5 +++--\n>  object-store.h | 18 ++++++++++++++++++\n>  object.c       | 10 ++++++++++\n>  path.c         |  2 +-\n>  repository.c   | 14 +++++++++-----\n>  repository.h   | 10 ++++------\n>  sha1_file.c    |  3 ++-\n>  8 files changed, 48 insertions(+), 16 deletions(-)\n>  create mode 100644 object-store.h\n> \n> diff --git a/builtin/grep.c b/builtin/grep.c\n> index 3ca4ac80d8..0f0c195705 100644\n> --- a/builtin/grep.c\n> +++ b/builtin/grep.c\n> @@ -432,7 +432,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,\n>  \t * object.\n>  \t */\n>  \tgrep_read_lock();\n> -\tadd_to_alternates_memory(submodule.objectdir);\n> +\tadd_to_alternates_memory(submodule.objects.objectdir);\n>  \tgrep_read_unlock();\n>  \n>  \tif (oid) {\n> diff --git a/environment.c b/environment.c\n> index a5eaa97fb1..c05705e384 100644\n> --- a/environment.c\n> +++ b/environment.c\n> @@ -14,6 +14,7 @@\n>  #include \"fmt-merge-msg.h\"\n>  #include \"commit.h\"\n>  #include \"argv-array.h\"\n> +#include \"object-store.h\"\n>  \n>  int trust_executable_bit = 1;\n>  int trust_ctime = 1;\n> @@ -270,9 +271,9 @@ const char *get_git_work_tree(void)\n>  \n>  char *get_object_directory(void)\n>  {\n> -\tif (!the_repository->objectdir)\n> +\tif (!the_repository->objects.objectdir)\n>  \t\tBUG(\"git environment hasn't been setup\");\n> -\treturn the_repository->objectdir;\n> +\treturn the_repository->objects.objectdir;\n>  }\n>  \n>  int odb_mkstemp(struct strbuf *template, const char *pattern)\n> diff --git a/object-store.h b/object-store.h\n> new file mode 100644\n> index 0000000000..69bb5ac065\n> --- /dev/null\n> +++ b/object-store.h\n> @@ -0,0 +1,18 @@\n> +#ifndef OBJECT_STORE_H\n> +#define OBJECT_STORE_H\n> +\n> +struct raw_object_store {\n> +\t/*\n> +\t * Path to the repository's object store.\n> +\t * Cannot be NULL after initialization.\n> +\t */\n> +\tchar *objectdir;\n> +\n> +\t/* Path to extra alternate object database if not NULL */\n> +\tchar *alternate_db;\n> +};\n> +\n> +void raw_object_store_init(struct raw_object_store *o);\n> +void raw_object_store_clear(struct raw_object_store *o);\n> +\n> +#endif /* OBJECT_STORE_H */\n> diff --git a/object.c b/object.c\n> index 9e6f9ff20b..e91711dd56 100644\n> --- a/object.c\n> +++ b/object.c\n> @@ -445,3 +445,13 @@ void clear_commit_marks_all(unsigned int flags)\n>  \t\t\tobj->flags &= ~flags;\n>  \t}\n>  }\n> +\n> +void raw_object_store_init(struct raw_object_store *o)\n> +{\n> +\tmemset(o, 0, sizeof(*o));\n> +}\n> +void raw_object_store_clear(struct raw_object_store *o)\n> +{\n> +\tFREE_AND_NULL(o->objectdir);\n> +\tFREE_AND_NULL(o->alternate_db);\n> +}\n> diff --git a/path.c b/path.c\n> index da8b655730..81a42d9115 100644\n> --- a/path.c\n> +++ b/path.c\n> @@ -382,7 +382,7 @@ static void adjust_git_path(const struct repository *repo,\n>  \t\tstrbuf_splice(buf, 0, buf->len,\n>  \t\t\t      repo->index_file, strlen(repo->index_file));\n>  \telse if (dir_prefix(base, \"objects\"))\n> -\t\treplace_dir(buf, git_dir_len + 7, repo->objectdir);\n> +\t\treplace_dir(buf, git_dir_len + 7, repo->objects.objectdir);\n>  \telse if (git_hooks_path && dir_prefix(base, \"hooks\"))\n>  \t\treplace_dir(buf, git_dir_len + 5, git_hooks_path);\n>  \telse if (repo->different_commondir)\n> diff --git a/repository.c b/repository.c\n> index 62f52f47fc..34c0a7f180 100644\n> --- a/repository.c\n> +++ b/repository.c\n> @@ -1,5 +1,6 @@\n>  #include \"cache.h\"\n>  #include \"repository.h\"\n> +#include \"object-store.h\"\n>  #include \"config.h\"\n>  #include \"submodule-config.h\"\n>  \n> @@ -12,6 +13,7 @@ void initialize_the_repository(void)\n>  \tthe_repository = &the_repo;\n>  \n>  \tthe_repo.index = &the_index;\n> +\traw_object_store_init(&the_repo.objects);\n>  \trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n>  }\n>  \n> @@ -58,10 +60,10 @@ void repo_set_gitdir(struct repository *repo,\n>  \tfree(old_gitdir);\n>  \n>  \trepo_set_commondir(repo, o->commondir);\n> -\texpand_base_dir(&repo->objectdir, o->object_dir,\n> +\texpand_base_dir(&repo->objects.objectdir, o->object_dir,\n>  \t\t\trepo->commondir, \"objects\");\n> -\tfree(repo->alternate_db);\n> -\trepo->alternate_db = xstrdup_or_null(o->alternate_db);\n> +\tfree(repo->objects.alternate_db);\n> +\trepo->objects.alternate_db = xstrdup_or_null(o->alternate_db);\n>  \texpand_base_dir(&repo->graft_file, o->graft_file,\n>  \t\t\trepo->commondir, \"info/grafts\");\n>  \texpand_base_dir(&repo->index_file, o->index_file,\n> @@ -140,6 +142,8 @@ static int repo_init(struct repository *repo,\n>  \tstruct repository_format format;\n>  \tmemset(repo, 0, sizeof(*repo));\n>  \n> +\traw_object_store_init(&repo->objects);\n> +\n>  \tif (repo_init_gitdir(repo, gitdir))\n>  \t\tgoto error;\n>  \n> @@ -214,13 +218,13 @@ void repo_clear(struct repository *repo)\n>  {\n>  \tFREE_AND_NULL(repo->gitdir);\n>  \tFREE_AND_NULL(repo->commondir);\n> -\tFREE_AND_NULL(repo->objectdir);\n> -\tFREE_AND_NULL(repo->alternate_db);\n>  \tFREE_AND_NULL(repo->graft_file);\n>  \tFREE_AND_NULL(repo->index_file);\n>  \tFREE_AND_NULL(repo->worktree);\n>  \tFREE_AND_NULL(repo->submodule_prefix);\n>  \n> +\traw_object_store_clear(&repo->objects);\n> +\n>  \tif (repo->config) {\n>  \t\tgit_configset_clear(repo->config);\n>  \t\tFREE_AND_NULL(repo->config);\n> diff --git a/repository.h b/repository.h\n> index e7127baffb..6c383c05c6 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> @@ -21,13 +23,9 @@ struct repository {\n>  \tchar *commondir;\n>  \n>  \t/*\n> -\t * Path to the repository's object store.\n> -\t * Cannot be NULL after initialization.\n> +\t * Holds any information related to accessing the raw object content.\n>  \t */\n> -\tchar *objectdir;\n> -\n> -\t/* Path to extra alternate object database if not NULL */\n> -\tchar *alternate_db;\n> +\tstruct raw_object_store objects;\n>  \n>  \t/*\n>  \t * Path to the repository's graft file.\n> diff --git a/sha1_file.c b/sha1_file.c\n> index 4af422e3cf..792bb21c15 100644\n> --- a/sha1_file.c\n> +++ b/sha1_file.c\n> @@ -671,7 +671,8 @@ void prepare_alt_odb(void)\n>  \t\treturn;\n>  \n>  \talt_odb_tail = &alt_odb_list;\n> -\tlink_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);\n> +\tlink_alt_odb_entries(the_repository->objects.alternate_db,\n> +\t\t\t     PATH_SEP, NULL, 0);\n>  \n>  \tread_info_alternates(get_object_directory(), 0);\n>  }\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342471","messageId":"20180321221050.GG18406@google.com","threadId":"47963","inReplyTo":"CAPig+cSkU8j-NiNeMP-F3VygF1sAoXP3qzn4fx7C1qxTZoO5+g@mail.gmail.com","subject":"Re: [PATCH 09/44] object-store: free alt_odb_list","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:10:50Z","receivedAt":"2018-03-21T22:10:57Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Eric Sunshine wrote:\n> On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> > Free the memory and reset alt_odb_{list, tail} to NULL.\n> >\n> > Signed-off-by: Stefan Beller <sbeller@google.com>\n> > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> > ---\n> > diff --git a/object.c b/object.c\n> > @@ -450,8 +450,26 @@ void raw_object_store_init(struct raw_object_store *o)\n> > +static void free_alt_odb(struct alternate_object_database *alt)\n> > +{\n> > +       strbuf_release(&alt->scratch);\n> > +       oid_array_clear(&alt->loose_objects_cache);\n> > +}\n> \n> This doesn't free the 'struct alternate_object_database' entry itself, right?\n> \n> Is that intentional? Isn't the idea that this should free the entries too?\n\nYep it definitely should free the entry itself.  Should be fixed easy\nenough by freeing the list entry after grabbing the next entry\n\n> \n> > +static void free_alt_odbs(struct raw_object_store *o)\n> > +{\n> > +       while (o->alt_odb_list) {\n\n                    struct alternate_object_database old = o->alt_odb_list;\n\n> > +               free_alt_odb(o->alt_odb_list);\n> > +               o->alt_odb_list = o->alt_odb_list->next;\n\n                    free(old);\n\n> > +       }\n> > +}\n> \n> Accessing an entry's 'next' member after invoking free_alt_odb() works\n> because the entry itself hasn't been freed (as noted above).\n> \n> Is leaking the entries themselves intentional?\n> \n> >  void raw_object_store_clear(struct raw_object_store *o)\n> >  {\n> >         FREE_AND_NULL(o->objectdir);\n> >         FREE_AND_NULL(o->alternate_db);\n> > +\n> > +       free_alt_odbs(o);\n> > +       o->alt_odb_tail = NULL;\n> >  }\n> \n> The commit message talks about freeing memory and resetting\n> alt_odb_list and alt_odb_tail, but this code only resets alt_odb_tail.\n\n-- \nBrandon Williams\n"},{"id":"342472","messageId":"20180321221842.GH18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-11-pclouds@gmail.com","subject":"Re: [PATCH 10/44] object-store: move packed_git and packed_git_mru to object store","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:18:42Z","receivedAt":"2018-03-21T22:18:51Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> In a process with multiple repositories open, packfile accessors\n> should be associated to a single repository and not shared globally.\n> Move packed_git and packed_git_mru into the_repository and adjust\n> callers to reflect this.\n> \n> [nd: while at there, wrap access to these two fields in get_packed_git()\n> and get_packed_git_mru(). This allows us to lazily initialize these\n> fields without caller doing that explicitly]\n> \n> Patch 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. Apply the following semantic patch to adjust callers:\n>     @@ @@\n>     - packed_git\n>     + the_repository->objects.packed_git\n> \n>     @@ @@\n>     - packed_git_mru\n>     + the_repository->objects.packed_git_mru\n\nAs Jonathan mentioned, this should probably be taken out of the commit\nmessage because it doesn't reflect what the code actually does.  What it\nactually does took me a second to figure out.  You're marking packed_git\nas \"private\"...well C has no notion of private vs public fields in a\nstruct so it might be difficult to keep that convention, it also took me\na second to realize that it was only in the scope of packfile.c where it\nwas ok to reference it directly.  Maybe it'll be ok?  If we really\nwanted something to be private we'd need it to be an opaque type\ninstead, which may be out of the scope of this code refactor.\n\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 where needed.\n> \n>  5. As the packfiles are now owned by an objectstore, which is ephemeral\n>     unlike globals, we introduce memory leaks. So address them in\n>     raw_object_store_clear(). Defer freeing packed_git to the next\n>     patch due to the size of this patch.\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  builtin/count-objects.c  |  5 ++--\n>  builtin/fsck.c           |  6 +++--\n>  builtin/gc.c             |  3 ++-\n>  builtin/pack-objects.c   | 20 ++++++++--------\n>  builtin/pack-redundant.c |  5 ++--\n>  cache.h                  | 29 ------------------------\n>  fast-import.c            |  7 ++++--\n>  http-backend.c           |  5 ++--\n>  object-store.h           | 28 +++++++++++++++++++++++\n>  object.c                 |  7 ++++++\n>  pack-bitmap.c            |  3 ++-\n>  packfile.c               | 49 ++++++++++++++++++++++++----------------\n>  packfile.h               |  3 +++\n>  server-info.c            |  5 ++--\n>  sha1_name.c              |  5 ++--\n>  15 files changed, 107 insertions(+), 73 deletions(-)\n> \n> diff --git a/builtin/count-objects.c b/builtin/count-objects.c\n> index 33343818c8..5c7c3c6ae3 100644\n> --- a/builtin/count-objects.c\n> +++ b/builtin/count-objects.c\n> @@ -7,6 +7,7 @@\n>  #include \"cache.h\"\n>  #include \"config.h\"\n>  #include \"dir.h\"\n> +#include \"repository.h\"\n>  #include \"builtin.h\"\n>  #include \"parse-options.h\"\n>  #include \"quote.h\"\n> @@ -120,9 +121,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 (!get_packed_git(the_repository))\n>  \t\t\tprepare_packed_git();\n> -\t\tfor (p = packed_git; p; p = p->next) {\n> +\t\tfor (p = get_packed_git(the_repository); p; p = p->next) {\n>  \t\t\tif (!p->pack_local)\n>  \t\t\t\tcontinue;\n>  \t\t\tif (open_pack_index(p))\n> diff --git a/builtin/fsck.c b/builtin/fsck.c\n> index b284a3a74e..7aca9699f6 100644\n> --- a/builtin/fsck.c\n> +++ b/builtin/fsck.c\n> @@ -729,7 +729,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 = get_packed_git(the_repository); 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> @@ -737,7 +738,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 = get_packed_git(the_repository); 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))\n> diff --git a/builtin/gc.c b/builtin/gc.c\n> index 77fa720bd0..dd30067ac1 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> @@ -173,7 +174,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 = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tif (!p->pack_local)\n>  \t\t\tcontinue;\n>  \t\tif (p->pack_keep)\n> diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\n> index 83dcbc9773..0e5fde1d6b 100644\n> --- a/builtin/pack-objects.c\n> +++ b/builtin/pack-objects.c\n> @@ -1,5 +1,6 @@\n>  #include \"builtin.h\"\n>  #include \"cache.h\"\n> +#include \"repository.h\"\n>  #include \"config.h\"\n>  #include \"attr.h\"\n>  #include \"object.h\"\n> @@ -1025,8 +1026,7 @@ static int want_object_in_pack(const struct object_id *oid,\n>  \t\tif (want != -1)\n>  \t\t\treturn want;\n>  \t}\n> -\n> -\tlist_for_each(pos, &packed_git_mru) {\n> +\tlist_for_each(pos, get_packed_git_mru(the_repository)) {\n>  \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n>  \t\toff_t offset;\n>  \n> @@ -1044,7 +1044,8 @@ static int want_object_in_pack(const struct object_id *oid,\n>  \t\t\t}\n>  \t\t\twant = want_found_object(exclude, p);\n>  \t\t\tif (!exclude && want > 0)\n> -\t\t\t\tlist_move(&p->mru, &packed_git_mru);\n> +\t\t\t\tlist_move(&p->mru,\n> +\t\t\t\t\t  get_packed_git_mru(the_repository));\n>  \t\t\tif (want != -1)\n>  \t\t\t\treturn want;\n>  \t\t}\n> @@ -2673,7 +2674,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 = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tstruct object_id oid;\n>  \t\tstruct object *o;\n>  \n> @@ -2736,7 +2737,8 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\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\tget_packed_git(the_repository);\n>  \n>  \twhile (p) {\n>  \t\tif ((!p->pack_local || p->pack_keep) &&\n> @@ -2745,7 +2747,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\n>  \t\t\treturn 1;\n>  \t\t}\n>  \t\tif (p == last_found)\n> -\t\t\tp = packed_git;\n> +\t\t\tp = get_packed_git(the_repository);\n>  \t\telse\n>  \t\t\tp = p->next;\n>  \t\tif (p == last_found)\n> @@ -2781,7 +2783,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 = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tif (!p->pack_local || p->pack_keep)\n>  \t\t\tcontinue;\n>  \n> @@ -3152,7 +3154,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 = get_packed_git(the_repository); 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> @@ -3165,7 +3167,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 = get_packed_git(the_repository); 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;\n> diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\n> index aaa8136322..d6d8a44959 100644\n> --- a/builtin/pack-redundant.c\n> +++ b/builtin/pack-redundant.c\n> @@ -7,6 +7,7 @@\n>  */\n>  \n>  #include \"builtin.h\"\n> +#include \"repository.h\"\n>  #include \"packfile.h\"\n>  \n>  #define BLKSIZE 512\n> @@ -571,7 +572,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 = get_packed_git(the_repository);\n>  \n>  \tif (strlen(filename) < 40)\n>  \t\tdie(\"Bad pack filename: %s\", filename);\n> @@ -586,7 +587,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 = get_packed_git(the_repository);\n>  \n>  \twhile (p) {\n>  \t\tadd_pack(p);\n> diff --git a/cache.h b/cache.h\n> index 41530d5d16..d3429a0d48 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1585,35 +1585,6 @@ struct pack_window {\n>  \tunsigned int inuse_cnt;\n>  };\n>  \n> -extern struct packed_git {\n> -\tstruct packed_git *next;\n> -\tstruct list_head mru;\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> -\t\t pack_promisor: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.\n> - */\n> -extern struct list_head packed_git_mru;\n> -\n>  struct pack_entry {\n>  \toff_t offset;\n>  \tunsigned char sha1[20];\n> diff --git a/fast-import.c b/fast-import.c\n> index b70ac025e0..0dba555478 100644\n> --- a/fast-import.c\n> +++ b/fast-import.c\n> @@ -154,6 +154,7 @@ 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.h\"\n> @@ -1110,7 +1111,8 @@ 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,\n> +\t\t\t\t  get_packed_git(the_repository))) {\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,8 @@ 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,\n> +\t\t\t\t  get_packed_git(the_repository))) {\n>  \t\te->type = OBJ_BLOB;\n>  \t\te->pack_id = MAX_PACK_ID;\n>  \t\te->idx.offset = 1; /* just not zero! */\n> diff --git a/http-backend.c b/http-backend.c\n> index f3dc218b2a..22921d169a 100644\n> --- a/http-backend.c\n> +++ b/http-backend.c\n> @@ -1,5 +1,6 @@\n>  #include \"cache.h\"\n>  #include \"config.h\"\n> +#include \"repository.h\"\n>  #include \"refs.h\"\n>  #include \"pkt-line.h\"\n>  #include \"object.h\"\n> @@ -518,13 +519,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 = get_packed_git(the_repository); 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 = get_packed_git(the_repository); 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}\n> diff --git a/object-store.h b/object-store.h\n> index 0ca9233a85..1f3e66a3b8 100644\n> --- a/object-store.h\n> +++ b/object-store.h\n> @@ -52,6 +52,30 @@ void add_to_alternates_memory(const char *dir);\n>   */\n>  struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);\n>  \n> +struct packed_git {\n> +\tstruct packed_git *next;\n> +\tstruct list_head mru;\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> +\t\t pack_promisor: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>  struct raw_object_store {\n>  \t/*\n>  \t * Path to the repository's object store.\n> @@ -62,6 +86,10 @@ struct raw_object_store {\n>  \t/* Path to extra alternate object database if not NULL */\n>  \tchar *alternate_db;\n>  \n> +\tstruct packed_git *packed_git; /* private */\n> +\t/* A most-recently-used ordered version of the packed_git list. */\n> +\tstruct list_head packed_git_mru; /* private */\n> +\n>  \tstruct alternate_object_database *alt_odb_list;\n>  \tstruct alternate_object_database **alt_odb_tail;\n>  };\n> diff --git a/object.c b/object.c\n> index a71ab34e69..83be6b1ecb 100644\n> --- a/object.c\n> +++ b/object.c\n> @@ -449,6 +449,7 @@ void clear_commit_marks_all(unsigned int flags)\n>  void raw_object_store_init(struct raw_object_store *o)\n>  {\n>  \tmemset(o, 0, sizeof(*o));\n> +\tINIT_LIST_HEAD(&o->packed_git_mru);\n>  }\n>  \n>  static void free_alt_odb(struct alternate_object_database *alt)\n> @@ -472,4 +473,10 @@ void raw_object_store_clear(struct raw_object_store *o)\n>  \n>  \tfree_alt_odbs(o);\n>  \to->alt_odb_tail = NULL;\n> +\n> +\tINIT_LIST_HEAD(&o->packed_git_mru);\n> +\t/*\n> +\t * TODO: call close_all_packs once migrated to\n> +\t * take an object store argument\n> +\t */\n>  }\n> diff --git a/pack-bitmap.c b/pack-bitmap.c\n> index 9270983e5f..abed43cdb5 100644\n> --- a/pack-bitmap.c\n> +++ b/pack-bitmap.c\n> @@ -10,6 +10,7 @@\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 +336,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 = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tif (open_pack_bitmap_1(p) == 0)\n>  \t\t\tret = 0;\n>  \t}\n> diff --git a/packfile.c b/packfile.c\n> index 216ea836ee..d3c4a12ae0 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -45,8 +45,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> -LIST_HEAD(packed_git_mru);\n>  \n>  #define SZ_FMT PRIuMAX\n>  static inline uintmax_t sz_fmt(size_t s) { return s; }\n> @@ -246,7 +244,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> @@ -316,7 +314,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> @@ -384,7 +382,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> @@ -686,8 +684,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> @@ -769,7 +767,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> @@ -820,7 +819,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> @@ -869,18 +868,19 @@ 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> -\tINIT_LIST_HEAD(&packed_git_mru);\n> +\tINIT_LIST_HEAD(&the_repository->objects.packed_git_mru);\n>  \n> -\tfor (p = packed_git; p; p = p->next)\n> -\t\tlist_add_tail(&p->mru, &packed_git_mru);\n> +\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n> +\t\tlist_add_tail(&p->mru, &the_repository->objects.packed_git_mru);\n>  }\n>  \n>  static int prepare_packed_git_run_once = 0;\n> @@ -906,6 +906,16 @@ void reprepare_packed_git(void)\n>  \tprepare_packed_git();\n>  }\n>  \n> +struct packed_git *get_packed_git(struct repository *r)\n> +{\n> +\treturn r->objects.packed_git;\n> +}\n> +\n> +struct list_head *get_packed_git_mru(struct repository *r)\n> +{\n> +\treturn &r->objects.packed_git_mru;\n> +}\n> +\n>  unsigned long unpack_object_header_buffer(const unsigned char *buf,\n>  \t\tunsigned long len, enum object_type *type, unsigned long *sizep)\n>  {\n> @@ -1014,7 +1024,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> @@ -1845,13 +1855,14 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n>  \tstruct list_head *pos;\n>  \n>  \tprepare_packed_git();\n> -\tif (!packed_git)\n> +\tif (!the_repository->objects.packed_git)\n>  \t\treturn 0;\n>  \n> -\tlist_for_each(pos, &packed_git_mru) {\n> +\tlist_for_each(pos, &the_repository->objects.packed_git_mru) {\n>  \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n>  \t\tif (fill_pack_entry(sha1, e, p)) {\n> -\t\t\tlist_move(&p->mru, &packed_git_mru);\n> +\t\t\tlist_move(&p->mru,\n> +\t\t\t\t  &the_repository->objects.packed_git_mru);\n>  \t\t\treturn 1;\n>  \t\t}\n>  \t}\n> @@ -1898,7 +1909,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 ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&\n> diff --git a/packfile.h b/packfile.h\n> index a7fca598d6..76496226bb 100644\n> --- a/packfile.h\n> +++ b/packfile.h\n> @@ -38,6 +38,9 @@ extern void prepare_packed_git(void);\n>  extern void reprepare_packed_git(void);\n>  extern void install_packed_git(struct packed_git *pack);\n>  \n> +struct packed_git *get_packed_git(struct repository *r);\n> +struct list_head *get_packed_git_mru(struct repository *r);\n> +\n>  /*\n>   * Give a rough count of objects in the repository. This sacrifices accuracy\n>   * for speed.\n> diff --git a/server-info.c b/server-info.c\n> index 26a6c20b7d..6fe64ede17 100644\n> --- a/server-info.c\n> +++ b/server-info.c\n> @@ -1,4 +1,5 @@\n>  #include \"cache.h\"\n> +#include \"repository.h\"\n>  #include \"refs.h\"\n>  #include \"object.h\"\n>  #include \"commit.h\"\n> @@ -200,7 +201,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 = get_packed_git(the_repository); 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 +211,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 = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tif (!p->pack_local)\n>  \t\t\tcontinue;\n>  \t\tinfo[i] = xcalloc(1, sizeof(struct pack_info));\n> diff --git a/sha1_name.c b/sha1_name.c\n> index 957ce25680..bd4d7352ce 100644\n> --- a/sha1_name.c\n> +++ b/sha1_name.c\n> @@ -196,7 +196,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 = get_packed_git(the_repository); p && !ds->ambiguous;\n> +\t     p = p->next)\n>  \t\tunique_in_pack(p, ds);\n>  }\n>  \n> @@ -566,7 +567,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n>  \tstruct packed_git *p;\n>  \n>  \tprepare_packed_git();\n> -\tfor (p = packed_git; p; p = p->next)\n> +\tfor (p = get_packed_git(the_repository); p; p = p->next)\n>  \t\tfind_abbrev_len_for_pack(p, mad);\n>  }\n>  \n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342473","messageId":"20180321221927.GI18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-12-pclouds@gmail.com","subject":"Re: [PATCH 11/44] object-store: close all packs upon clearing the object store","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:19:27Z","receivedAt":"2018-03-21T22:19:34Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nLooks good.\n\n> ---\n>  builtin/am.c           | 2 +-\n>  builtin/clone.c        | 2 +-\n>  builtin/fetch.c        | 2 +-\n>  builtin/merge.c        | 2 +-\n>  builtin/receive-pack.c | 2 +-\n>  object.c               | 7 +++----\n>  packfile.c             | 4 ++--\n>  packfile.h             | 2 +-\n>  8 files changed, 11 insertions(+), 12 deletions(-)\n> \n> diff --git a/builtin/am.c b/builtin/am.c\n> index 5bdd2d7578..4762a702e3 100644\n> --- a/builtin/am.c\n> +++ b/builtin/am.c\n> @@ -1859,7 +1859,7 @@ static void am_run(struct am_state *state, int resume)\n>  \t */\n>  \tif (!state->rebasing) {\n>  \t\tam_destroy(state);\n> -\t\tclose_all_packs();\n> +\t\tclose_all_packs(&the_repository->objects);\n>  \t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n>  \t}\n>  }\n> diff --git a/builtin/clone.c b/builtin/clone.c\n> index 101c27a593..13cfaa6488 100644\n> --- a/builtin/clone.c\n> +++ b/builtin/clone.c\n> @@ -1217,7 +1217,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n>  \ttransport_disconnect(transport);\n>  \n>  \tif (option_dissociate) {\n> -\t\tclose_all_packs();\n> +\t\tclose_all_packs(&the_repository->objects);\n>  \t\tdissociate_from_references();\n>  \t}\n>  \n> diff --git a/builtin/fetch.c b/builtin/fetch.c\n> index 8ee998ea2e..4d72efca78 100644\n> --- a/builtin/fetch.c\n> +++ b/builtin/fetch.c\n> @@ -1478,7 +1478,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>  \n>  \tstring_list_clear(&list, 0);\n>  \n> -\tclose_all_packs();\n> +\tclose_all_packs(&the_repository->objects);\n>  \n>  \targv_array_pushl(&argv_gc_auto, \"gc\", \"--auto\", NULL);\n>  \tif (verbosity < 0)\n> diff --git a/builtin/merge.c b/builtin/merge.c\n> index 30264cfd7c..907ae44ab5 100644\n> --- a/builtin/merge.c\n> +++ b/builtin/merge.c\n> @@ -411,7 +411,7 @@ static void finish(struct commit *head_commit,\n>  \t\t\t * We ignore errors in 'gc --auto', since the\n>  \t\t\t * user should see them.\n>  \t\t\t */\n> -\t\t\tclose_all_packs();\n> +\t\t\tclose_all_packs(&the_repository->objects);\n>  \t\t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n>  \t\t}\n>  \t}\n> diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\n> index b7ce7c7f52..ac478b7b99 100644\n> --- a/builtin/receive-pack.c\n> +++ b/builtin/receive-pack.c\n> @@ -2026,7 +2026,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n>  \t\t\tproc.git_cmd = 1;\n>  \t\t\tproc.argv = argv_gc_auto;\n>  \n> -\t\t\tclose_all_packs();\n> +\t\t\tclose_all_packs(&the_repository->objects);\n>  \t\t\tif (!start_command(&proc)) {\n>  \t\t\t\tif (use_sideband)\n>  \t\t\t\t\tcopy_to_sideband(proc.err, -1, NULL);\n> diff --git a/object.c b/object.c\n> index 83be6b1ecb..60ca76b285 100644\n> --- a/object.c\n> +++ b/object.c\n> @@ -4,6 +4,7 @@\n>  #include \"tree.h\"\n>  #include \"commit.h\"\n>  #include \"tag.h\"\n> +#include \"packfile.h\"\n>  \n>  static struct object **obj_hash;\n>  static int nr_objs, obj_hash_size;\n> @@ -475,8 +476,6 @@ void raw_object_store_clear(struct raw_object_store *o)\n>  \to->alt_odb_tail = NULL;\n>  \n>  \tINIT_LIST_HEAD(&o->packed_git_mru);\n> -\t/*\n> -\t * TODO: call close_all_packs once migrated to\n> -\t * take an object store argument\n> -\t */\n> +\tclose_all_packs(o);\n> +\to->packed_git = NULL;\n>  }\n> diff --git a/packfile.c b/packfile.c\n> index d3c4a12ae0..1e38334ba2 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -310,11 +310,11 @@ static void close_pack(struct packed_git *p)\n>  \tclose_pack_index(p);\n>  }\n>  \n> -void close_all_packs(void)\n> +void close_all_packs(struct raw_object_store *o)\n>  {\n>  \tstruct packed_git *p;\n>  \n> -\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n> +\tfor (p = o->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> diff --git a/packfile.h b/packfile.h\n> index 76496226bb..5b1ce00f84 100644\n> --- a/packfile.h\n> +++ b/packfile.h\n> @@ -66,7 +66,7 @@ extern void close_pack_index(struct packed_git *);\n>  \n>  extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);\n>  extern void close_pack_windows(struct packed_git *);\n> -extern void close_all_packs(void);\n> +extern void close_all_packs(struct raw_object_store *o);\n>  extern void unuse_pack(struct pack_window **);\n>  extern void clear_delta_base_cache(void);\n>  extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342474","messageId":"20180321222514.GJ18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-13-pclouds@gmail.com","subject":"Re: [PATCH 12/44] pack: move prepare_packed_git_run_once to object store","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:25:14Z","receivedAt":"2018-03-21T22:25:22Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> Each repository's object store can be initialized independently, so\n> they must not share a run_once variable.\n\nLooks good.\n\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  object-store.h | 6 ++++++\n>  packfile.c     | 7 +++----\n>  2 files changed, 9 insertions(+), 4 deletions(-)\n> \n> diff --git a/object-store.h b/object-store.h\n> index 1f3e66a3b8..b954396615 100644\n> --- a/object-store.h\n> +++ b/object-store.h\n> @@ -92,6 +92,12 @@ struct raw_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>  \n>  void raw_object_store_init(struct raw_object_store *o);\n> diff --git a/packfile.c b/packfile.c\n> index 1e38334ba2..caeab0f68c 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -883,12 +883,11 @@ static void prepare_packed_git_mru(void)\n>  \t\tlist_add_tail(&p->mru, &the_repository->objects.packed_git_mru);\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> @@ -896,13 +895,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> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342475","messageId":"20180321222656.GK18406@google.com","threadId":"47963","inReplyTo":"CACsJy8CQxsTPH15jtvDUhc8DFdtPdLNDYtFe7HNn3ntUHAv=tg@mail.gmail.com","subject":"Re: [PATCH 13/44] pack: move approximate object count to object store","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:26:56Z","receivedAt":"2018-03-21T22:27:03Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/04, Duy Nguyen wrote:\n> On Sun, Mar 4, 2018 at 9:47 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> > On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> >> The approximate_object_count() function maintains a rough count of\n> >> objects in a repository to estimate how long object name abbreviates\n> >> should be.  Object names are scoped to a repository and the\n> >> appropriate length may differ by repository, so the object count\n> >> should not be global.\n> >>\n> >> Signed-off-by: Stefan Beller <sbeller@google.com>\n> >> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> >> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> >> ---\n> >> diff --git a/packfile.c b/packfile.c\n> >> @@ -813,8 +811,8 @@ static int approximate_object_count_valid;\n> >>  unsigned long approximate_object_count(void)\n> >>  {\n> >> -       static unsigned long count;\n> >> -       if (!approximate_object_count_valid) {\n> >> +       if (!the_repository->objects.approximate_object_count_valid) {\n> >> +               unsigned long count;\n> >>                 struct packed_git *p;\n> >>\n> >>                 prepare_packed_git();\n> >> @@ -824,8 +822,9 @@ unsigned long approximate_object_count(void)\n> >>                                 continue;\n> >>                         count += p->num_objects;\n> >>                 }\n> >> +               the_repository->objects.approximate_object_count = count;\n> >>         }\n> >> -       return count;\n> >> +       return the_repository->objects.approximate_object_count;\n> >>  }\n> >> @@ -900,7 +899,7 @@ void prepare_packed_git(void)\n> >>  void reprepare_packed_git(void)\n> >>  {\n> >> -       approximate_object_count_valid = 0;\n> >> +       the_repository->objects.approximate_object_count_valid = 0;\n> >\n> > Not an issue specific to this patch, but where, how, when does\n> > 'approximate_object_count_valid' ever get set to anything other than\n> > 0? Even in the existing code (without this patch), there doesn't seem\n> > to be anyplace which sets this to a non-zero value. Am I missing\n> > something obvious (or subtle)?\n> \n> Probably related to this\n> https://public-inbox.org/git/20180226085508.GA30343@sigill.intra.peff.net/#t\n\nYeah as far as doing a conversion this should be fine, we can come by\nand clean it up at a later point.\n\n-- \nBrandon Williams\n"},{"id":"342476","messageId":"20180321223001.GL18406@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-20-pclouds@gmail.com","subject":"Re: [PATCH 19/44] sha1_file: allow link_alt_odb_entries to handle arbitrary repositories","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:30:01Z","receivedAt":"2018-03-21T22:30:09Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> Actually this also allows read_info_alternates and link_alt_odb_entry to\n> handle arbitrary repositories, but link_alt_odb_entries is the most\n> interesting function in this set of functions, hence the commit subject.\n> \n> These functions span a strongly connected component in the function\n> graph, i.e. the recursive call chain might look like\n> \n>   -> link_alt_odb_entries\n>     -> link_alt_odb_entry\n>       -> read_info_alternates\n>         -> link_alt_odb_entries\n> \n> That is why we need to convert all these functions at the same time.\n\nThis conversion looks good.\n\n> \n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  object-store.h |  4 ++++\n>  sha1_file.c    | 36 ++++++++++++++++--------------------\n>  2 files changed, 20 insertions(+), 20 deletions(-)\n> \n> diff --git a/object-store.h b/object-store.h\n> index 3d0f8a87cb..20ba136c1f 100644\n> --- a/object-store.h\n> +++ b/object-store.h\n> @@ -18,6 +18,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 alternative object store. If this is a relative path,\n> +\t * it is relative to the current working directory.\n> +\t */\n>  \tchar path[FLEX_ARRAY];\n>  };\n>  #define prepare_alt_odb(r) prepare_alt_odb_##r()\n> diff --git a/sha1_file.c b/sha1_file.c\n> index 027e0f3741..f34eb69e39 100644\n> --- a/sha1_file.c\n> +++ b/sha1_file.c\n> @@ -390,11 +390,10 @@ static int alt_odb_usable(struct raw_object_store *o,\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> @@ -420,7 +419,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->objects, &pathbuf, normalized_objdir)) {\n> +\tif (!alt_odb_usable(&r->objects, &pathbuf, normalized_objdir)) {\n>  \t\tstrbuf_release(&pathbuf);\n>  \t\treturn -1;\n>  \t}\n> @@ -428,12 +427,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> @@ -468,12 +467,8 @@ static const char *parse_alt_odb_entry(const char *string,\n>  \treturn end;\n>  }\n>  \n> -#define link_alt_odb_entries(r, a, s, rb, d) \\\n> -\tlink_alt_odb_entries_##r(a, s, rb, d)\n> -static void link_alt_odb_entries_the_repository(const char *alt,\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,\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> @@ -487,7 +482,7 @@ static void link_alt_odb_entries_the_repository(const char *alt,\n>  \t\treturn;\n>  \t}\n>  \n> -\tstrbuf_add_absolute_path(&objdirbuf, get_object_directory());\n> +\tstrbuf_add_absolute_path(&objdirbuf, r->objects.objectdir);\n>  \tif (strbuf_normalize_path(&objdirbuf) < 0)\n>  \t\tdie(\"unable to normalize object directory: %s\",\n>  \t\t    objdirbuf.buf);\n> @@ -496,15 +491,16 @@ static void link_alt_odb_entries_the_repository(const char *alt,\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 *path;\n>  \tstruct strbuf buf = STRBUF_INIT;\n> @@ -516,7 +512,7 @@ static void read_info_alternates_the_repository(const char *relative_base,\n>  \t\treturn;\n>  \t}\n>  \n> -\tlink_alt_odb_entries(the_repository, buf.buf, '\\n', relative_base, depth);\n> +\tlink_alt_odb_entries(r, buf.buf, '\\n', relative_base, depth);\n>  \tstrbuf_release(&buf);\n>  \tfree(path);\n>  }\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342479","messageId":"20180321223440.GA202156@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-33-pclouds@gmail.com","subject":"Re: [PATCH 32/44] sha1_file: allow sha1_loose_object_info to handle arbitrary repositories","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:34:40Z","receivedAt":"2018-03-21T22:35:23Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> From: Jonathan Nieder <jrnieder@gmail.com>\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nPatches up to here look sane.\n\n> ---\n>  sha1_file.c | 11 +++++------\n>  1 file changed, 5 insertions(+), 6 deletions(-)\n> \n> diff --git a/sha1_file.c b/sha1_file.c\n> index c5a8b00aed..7066d4c9ce 100644\n> --- a/sha1_file.c\n> +++ b/sha1_file.c\n> @@ -1149,10 +1149,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> @@ -1176,14 +1175,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> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342481","messageId":"20180321223923.GB202156@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-41-pclouds@gmail.com","subject":"Re: [PATCH 40/44] packfile: allow prepare_packed_git to handle arbitrary repositories","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:39:23Z","receivedAt":"2018-03-21T22:39:30Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n\nThis is an invalid conversion.\n\n>  packfile.c | 18 +++++++++---------\n>  packfile.h |  3 +--\n>  2 files changed, 10 insertions(+), 11 deletions(-)\n> \n> diff --git a/packfile.c b/packfile.c\n> index 52febba932..2276e2ad26 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -882,19 +882,19 @@ static void prepare_packed_git_mru(struct repository *r)\n>  \t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\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, get_object_directory(), 1);\n\nCalling get_object_directory() returns the_repository's object dir,\nthis needs to be replaced with r->objects.objectdir.\n\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)\n> diff --git a/packfile.h b/packfile.h\n> index ab5046938c..3fd9092472 100644\n> --- a/packfile.h\n> +++ b/packfile.h\n> @@ -34,8 +34,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> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342483","messageId":"20180321224241.GC202156@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-45-pclouds@gmail.com","subject":"Re: [PATCH 44/44] packfile: keep prepare_packed_git() private","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:42:41Z","receivedAt":"2018-03-21T22:42:48Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> The reason callers have to call this is to make sure either packed_git\n> or packed_git_mru pointers are initialized since we don't do that by\n> default. Sometimes it's hard to see this connection between where the\n> function is called and where packed_git pointer is used (sometimes in\n> separate functions).\n> \n> Keep this dependency internal because now all access to packed_git and\n> packed_git_mru must go through get_xxx() wrappers.\n\nAhh now I understand the rational for trying to make it \"private\".\n\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  builtin/count-objects.c  | 3 +--\n>  builtin/fsck.c           | 2 --\n>  builtin/gc.c             | 1 -\n>  builtin/pack-objects.c   | 1 -\n>  builtin/pack-redundant.c | 2 --\n>  fast-import.c            | 1 -\n>  http-backend.c           | 1 -\n>  pack-bitmap.c            | 1 -\n>  packfile.c               | 5 ++++-\n>  packfile.h               | 1 -\n>  server-info.c            | 1 -\n>  sha1_name.c              | 2 --\n>  12 files changed, 5 insertions(+), 16 deletions(-)\n> \n> diff --git a/builtin/count-objects.c b/builtin/count-objects.c\n> index 2793c98ed3..ee6ae35244 100644\n> --- a/builtin/count-objects.c\n> +++ b/builtin/count-objects.c\n> @@ -121,8 +121,7 @@ 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 (!get_packed_git(the_repository))\n> -\t\t\tprepare_packed_git(the_repository);\n> +\n>  \t\tfor (p = get_packed_git(the_repository); p; p = p->next) {\n>  \t\t\tif (!p->pack_local)\n>  \t\t\t\tcontinue;\n> diff --git a/builtin/fsck.c b/builtin/fsck.c\n> index 7a3e323e9e..9911c52bc8 100644\n> --- a/builtin/fsck.c\n> +++ b/builtin/fsck.c\n> @@ -726,8 +726,6 @@ 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(the_repository);\n> -\n>  \t\t\tif (show_progress) {\n>  \t\t\t\tfor (p = get_packed_git(the_repository); p;\n>  \t\t\t\t     p = p->next) {\n> diff --git a/builtin/gc.c b/builtin/gc.c\n> index 560d58daec..be63bec09c 100644\n> --- a/builtin/gc.c\n> +++ b/builtin/gc.c\n> @@ -173,7 +173,6 @@ static int too_many_packs(void)\n>  \tif (gc_auto_pack_limit <= 0)\n>  \t\treturn 0;\n>  \n> -\tprepare_packed_git(the_repository);\n>  \tfor (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tif (!p->pack_local)\n>  \t\t\tcontinue;\n> diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\n> index 6020a7e230..435f091a69 100644\n> --- a/builtin/pack-objects.c\n> +++ b/builtin/pack-objects.c\n> @@ -3151,7 +3151,6 @@ 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(the_repository);\n>  \tif (ignore_packed_keep) {\n>  \t\tstruct packed_git *p;\n>  \t\tfor (p = get_packed_git(the_repository); p; p = p->next)\n> diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\n> index bf42e164eb..02b5f0becc 100644\n> --- a/builtin/pack-redundant.c\n> +++ b/builtin/pack-redundant.c\n> @@ -630,8 +630,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)\n>  \t\t\tbreak;\n>  \t}\n>  \n> -\tprepare_packed_git(the_repository);\n> -\n>  \tif (load_all_packs)\n>  \t\tload_all();\n>  \telse\n> diff --git a/fast-import.c b/fast-import.c\n> index 985eb2eccc..2298bfcdfd 100644\n> --- a/fast-import.c\n> +++ b/fast-import.c\n> @@ -3472,7 +3472,6 @@ 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(the_repository);\n>  \tstart_packfile();\n>  \tset_die_routine(die_nicely);\n>  \tset_checkpoint_signal();\n> diff --git a/http-backend.c b/http-backend.c\n> index 659ddfb5f1..22d2e1668e 100644\n> --- a/http-backend.c\n> +++ b/http-backend.c\n> @@ -518,7 +518,6 @@ static void get_info_packs(struct strbuf *hdr, char *arg)\n>  \tsize_t cnt = 0;\n>  \n>  \tselect_getanyfile(hdr);\n> -\tprepare_packed_git(the_repository);\n>  \tfor (p = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tif (p->pack_local)\n>  \t\t\tcnt++;\n> diff --git a/pack-bitmap.c b/pack-bitmap.c\n> index 01c9cd1642..2a007b5539 100644\n> --- a/pack-bitmap.c\n> +++ b/pack-bitmap.c\n> @@ -335,7 +335,6 @@ static int open_pack_bitmap(void)\n>  \n>  \tassert(!bitmap_git.map && !bitmap_git.loaded);\n>  \n> -\tprepare_packed_git(the_repository);\n>  \tfor (p = get_packed_git(the_repository); p; p = p->next) {\n>  \t\tif (open_pack_bitmap_1(p) == 0)\n>  \t\t\tret = 0;\n> diff --git a/packfile.c b/packfile.c\n> index bafe81544d..773cd99a13 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -802,6 +802,7 @@ static void prepare_packed_git_one(struct repository *r, char *objdir, int local\n>  \tstrbuf_release(&path);\n>  }\n>  \n> +static void prepare_packed_git(struct repository *r);\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> @@ -882,7 +883,7 @@ static void prepare_packed_git_mru(struct repository *r)\n>  \t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\n>  }\n>  \n> -void prepare_packed_git(struct repository *r)\n> +static void prepare_packed_git(struct repository *r)\n>  {\n>  \tstruct alternate_object_database *alt;\n>  \n> @@ -906,11 +907,13 @@ void reprepare_packed_git(struct repository *r)\n>  \n>  struct packed_git *get_packed_git(struct repository *r)\n>  {\n> +\tprepare_packed_git(r);\n>  \treturn r->objects.packed_git;\n>  }\n>  \n>  struct list_head *get_packed_git_mru(struct repository *r)\n>  {\n> +\tprepare_packed_git(r);\n>  \treturn &r->objects.packed_git_mru;\n>  }\n>  \n> diff --git a/packfile.h b/packfile.h\n> index fe1a6380e6..efda10329c 100644\n> --- a/packfile.h\n> +++ b/packfile.h\n> @@ -34,7 +34,6 @@ 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(struct repository *r);\n>  extern void reprepare_packed_git(struct repository *r);\n>  extern void install_packed_git(struct repository *r, struct packed_git *pack);\n>  \n> diff --git a/server-info.c b/server-info.c\n> index 9604772522..af737acd24 100644\n> --- a/server-info.c\n> +++ b/server-info.c\n> @@ -200,7 +200,6 @@ static void init_pack_info(const char *infofile, int force)\n>  \tobjdir = get_object_directory();\n>  \tobjdirlen = strlen(objdir);\n>  \n> -\tprepare_packed_git(the_repository);\n>  \tfor (p = get_packed_git(the_repository); 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> diff --git a/sha1_name.c b/sha1_name.c\n> index cb42e398b2..f25a0970ca 100644\n> --- a/sha1_name.c\n> +++ b/sha1_name.c\n> @@ -195,7 +195,6 @@ static void find_short_packed_object(struct disambiguate_state *ds)\n>  {\n>  \tstruct packed_git *p;\n>  \n> -\tprepare_packed_git(the_repository);\n>  \tfor (p = get_packed_git(the_repository); p && !ds->ambiguous;\n>  \t     p = p->next)\n>  \t\tunique_in_pack(p, ds);\n> @@ -566,7 +565,6 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n>  {\n>  \tstruct packed_git *p;\n>  \n> -\tprepare_packed_git(the_repository);\n>  \tfor (p = get_packed_git(the_repository); p; p = p->next)\n>  \t\tfind_abbrev_len_for_pack(p, mad);\n>  }\n> -- \n> 2.16.1.435.g8f24da2e1a\n> \n\n-- \nBrandon Williams\n"},{"id":"342484","messageId":"20180321224350.GD202156@google.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"Re: [PATCH 00/44] reroll nd/remove-ignore-env.. sb/object-store and sb/packfiles..","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-21T22:43:50Z","receivedAt":"2018-03-21T22:43:57Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/03, Nguyễn Thái Ngọc Duy wrote:\n> On Sat, Mar 3, 2018 at 9:54 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> > On Thu, Mar 1, 2018 at 2:09 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> >> Stefan Beller <sbeller@google.com> writes:\n> >>\n> >>> On Wed, Feb 28, 2018 at 9:59 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> >>>> Duy Nguyen <pclouds@gmail.com> writes:\n> >>>>\n> >>>>> Looking at the full-series diff though, it makes me wonder if we\n> >>>>> should keep prepare_packed_git() private (i.e. how we initialize the\n> >>>>> object store, packfile included, is a private matter). How about\n> >>>>> something like this on top?\n> >>>>\n> >>>> Yup, that looks cleaner.\n> >>>\n> >>> I agree that it looks cleaner. So we plan on just putting\n> >>> it on top of that series?\n> >>\n> >> We tend to avoid \"oops, that was wrong and here is a band aid on\n> >> top\" for things that are still mushy, so it would be preferrable to\n> >> get it fixed inline, especially if there are more changes to the\n> >> other parts of the series coming.\n> >\n> > I agree with this. Stefan, if you're getting bored with rerolling\n> > refactor patches, I can update this series and send out v2.\n> \n> Since Stefan is traveling, I take this opportunity to reroll it.\n> Unfortunately, I think the fix should go in 46cd557bd9 (object-store:\n> move packed_git and packed_git_mru to object store - 2018-02-23) where\n> we start removing the global \"packed_git\". But that's in\n> sb/object-store, so.. I'm rerolling all three\n> \n> 01/44 - 05/44: nd/remove-ignore-env-field\n> \n>   This series is moved up top. After this the patch that touch\n>   alternate-db in sha1_file.c looks natural because no env is involved\n>   anymore\n> \n>   I also take this opportunity to introduce a new patch 01/44 to avoid\n>   struct initialization that makes it hard to read and update. Later\n>   patches are also simplified thanks to this.\n> \n> 06/44 - 32/44: sb/object-store\n> \n>   06/44 is updated to introduce raw_object_store_init() instead of\n>   RAW_OBJECT_STORE_INIT macro. This function is now used to initialize\n>   both main repo and submodule ones.\n> \n>   10/44 (moving \"packed_git\") also introduces two new access wrapper\n>   get_packed_git() and get_packed_git_mru()\n> \n> 33/44 - 44/44: sb/packfiles-in-repository\n> \n>   The only thing new here is 44/44 which makes prepare_packed_git()\n>   internal. get_packed_git() and get_packed_git_mru() introduced\n>   earlier will call prepare_packed_git() automatically.\n> \n> The whole thing is also available at\n> \n> https://github.com/pclouds/git/tree/ignore-env-object-store-packfiles\n> \n> And interdiff of all three, compared to what is currently in 'pu'.\n> Looks pretty good in my opinon:\n\nThe only major issue I could find is with patch 40 and must be fixed\nbefore this can be merged.  The rest of the series looks good.\n\n-- \nBrandon Williams\n"},{"id":"342488","messageId":"xmqqr2ocnaox.fsf@gitster-ct.c.googlers.com","threadId":"47963","inReplyTo":"20180321223923.GB202156@google.com","subject":"Re: [PATCH 40/44] packfile: allow prepare_packed_git to handle arbitrary repositories","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-03-22T01:47:10Z","receivedAt":"2018-03-22T01:47:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brandon Williams <bmwill@google.com> writes:\n\n> On 03/03, Nguyễn Thái Ngọc Duy wrote:\n>> From: Stefan Beller <sbeller@google.com>\n>> \n>> Signed-off-by: Stefan Beller <sbeller@google.com>\n>> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>> ---\n>\n> This is an invalid conversion.\n>\n>>  packfile.c | 18 +++++++++---------\n>>  packfile.h |  3 +--\n>>  2 files changed, 10 insertions(+), 11 deletions(-)\n>> \n>> diff --git a/packfile.c b/packfile.c\n>> index 52febba932..2276e2ad26 100644\n>> --- a/packfile.c\n>> +++ b/packfile.c\n>> @@ -882,19 +882,19 @@ static void prepare_packed_git_mru(struct repository *r)\n>>  \t\tlist_add_tail(&p->mru, &r->objects.packed_git_mru);\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, get_object_directory(), 1);\n>\n> Calling get_object_directory() returns the_repository's object dir,\n> this needs to be replaced with r->objects.objectdir.\n\nNicely spotted.  I think this was inherited from the orginal,\ne.g. the one from the end of last month\n\nhttps://public-inbox.org/git/20180228010608.215505-9-sbeller@google.com/\n\nalso calls get_object_directory().\n\nThanks.\n"},{"id":"342591","messageId":"20180323155523.22269-1-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 0/1] nd/remove-ignore-env-field updates","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T15:55:22Z","receivedAt":"2018-03-23T15:56:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This is a very small, non-functional update. On top of 'next'\n\nNguyễn Thái Ngọc Duy (1):\n  repository.h: add comment and clarify repo_set_gitdir\n\n repository.h | 6 +++++-\n 1 file changed, 5 insertions(+), 1 deletion(-)\n\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342592","messageId":"20180323155523.22269-2-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323155523.22269-1-pclouds@gmail.com","subject":"[PATCH 1/1] repository.h: add comment and clarify repo_set_gitdir","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T15:55:23Z","receivedAt":"2018-03-23T15:56:06Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The argument name \"optional\" may mislead the reader to think this\noption could be NULL. But it can't be. While at there, document a bit\nmore about struct set_gitdir_args.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n repository.h | 6 +++++-\n 1 file changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/repository.h b/repository.h\nindex e7127baffb..f21fd93f72 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -82,6 +82,10 @@ struct repository {\n \n extern struct repository *the_repository;\n \n+/*\n+ * Define a custom repository layout. Any field can be NULL, which\n+ * will default back to the path according to the default layout.\n+ */\n struct set_gitdir_args {\n \tconst char *commondir;\n \tconst char *object_dir;\n@@ -92,7 +96,7 @@ struct set_gitdir_args {\n \n extern void repo_set_gitdir(struct repository *repo,\n \t\t\t    const char *root,\n-\t\t\t    const struct set_gitdir_args *optional);\n+\t\t\t    const struct set_gitdir_args *extra_args);\n extern void repo_set_worktree(struct repository *repo, const char *path);\n extern void repo_set_hash_algo(struct repository *repo, int algo);\n extern void initialize_the_repository(void);\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342598","messageId":"CACsJy8AKd4osxTCo=SRJz3RbFwsW5rB9SBu+WS4HBPCP0MdO9g@mail.gmail.com","threadId":"47963","inReplyTo":"20180319123914.6767c0660fb3e77247f02989@google.com","subject":"Re: [PATCH 10/44] object-store: move packed_git and packed_git_mru to object store","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T16:57:01Z","receivedAt":"2018-03-23T16:57:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Mar 19, 2018 at 8:39 PM, Jonathan Tan <jonathantanmy@google.com> wrote:\n> On Sat,  3 Mar 2018 18:36:03 +0700\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> wrote:\n>\n>> From: Stefan Beller <sbeller@google.com>\n>>\n>> In a process with multiple repositories open, packfile accessors\n>> should be associated to a single repository and not shared globally.\n>> Move packed_git and packed_git_mru into the_repository and adjust\n>> callers to reflect this.\n>>\n>> [nd: while at there, wrap access to these two fields in get_packed_git()\n>> and get_packed_git_mru(). This allows us to lazily initialize these\n>> fields without caller doing that explicitly]\n>\n> The patches up to this one look good. (I didn't reply for each\n> individual one to avoid unnecessarily sending messages to the list.)\n>\n> About this patch: will lazily initializing these fields be done in a\n> later patch?\n\nYes.\n\n\n>> Patch 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. Apply the following semantic patch to adjust callers:\n>>     @@ @@\n>>     - packed_git\n>>     + the_repository->objects.packed_git\n>>\n>>     @@ @@\n>>     - packed_git_mru\n>>     + the_repository->objects.packed_git_mru\n>\n> This doesn't seem up-to-date - they are being replaced with a function\n> call, not a field access. I would be OK with just removing this \"Patch\n> generated by\" section.\n\nI'll just drop this part. I'm manually updating the series anyway.\n\n\n> [snip remainder of \"Patch generated by\" section]\n>\n>> @@ -246,7 +244,7 @@ static int unuse_one_window(struct packed_git *current)\n>>\n>>       if (current)\n>>               scan_windows(current, &lru_p, &lru_w, &lru_l);\n>> -     for (p = packed_git; p; p = p->next)\n>> +     for (p = the_repository->objects.packed_git; p; p = p->next)\n>>               scan_windows(p, &lru_p, &lru_w, &lru_l);\n>>       if (lru_p) {\n>>               munmap(lru_w->base, lru_w->len);\n>\n> Here (and elsewhere), \"the_repository->objects.packed_git\" instead of\n> \"get_packed_git\" is still used.\n\n\nYeah. I saw your other comment about the not converting in packfile.c\ntoo. My view is, packfile has intimate knowledge about pack\nmanipulation and we don't need to try to \"protect\" from misuse of\npacked_git pointer without prepare_packed_git. People how modify this\ncode probably know that by heart at this point. And we can't avoid it\ncompletely anyway because it will have access to the static function\nprepare_packed_git.\n-- \nDuy\n"},{"id":"342599","messageId":"CACsJy8As=iDtLm6GGxbeHB=VDUvOgefrSpBduY=Kq1O3D2x1Tg@mail.gmail.com","threadId":"47963","inReplyTo":"20180321221842.GH18406@google.com","subject":"Re: [PATCH 10/44] object-store: move packed_git and packed_git_mru to object store","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:03:43Z","receivedAt":"2018-03-23T17:04:21Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Mar 21, 2018 at 11:18 PM, Brandon Williams <bmwill@google.com> wrote:\n> You're marking packed_git\n> as \"private\"...well C has no notion of private vs public fields in a\n> struct so it might be difficult to keep that convention, it also took me\n> a second to realize that it was only in the scope of packfile.c where it\n> was ok to reference it directly.  Maybe it'll be ok?  If we really\n> wanted something to be private we'd need it to be an opaque type\n> instead, which may be out of the scope of this code refactor.\n\nIt's true C syntax does not support private/public scoping, but it\ndoes not mean we must avoid that. Python has \"private convention\" with\nthe underscore prefix, no special support from the language either.\nYes having compiler support to enforce scoping is nice, but I think we\ncan still live without it (Go devs live fine without \"const\"\narguments, e.g.)\n\nSo I'm going to make it clearer that these fields are not supposed to\nbe accessed outside packfile.c\n-- \nDuy\n"},{"id":"342601","messageId":"CACsJy8BcHdvUn5VPc9+mzE1SpvsJG-P2iUW=jg2VD5YhU4kVJg@mail.gmail.com","threadId":"47963","inReplyTo":"CACsJy8As=iDtLm6GGxbeHB=VDUvOgefrSpBduY=Kq1O3D2x1Tg@mail.gmail.com","subject":"Re: [PATCH 10/44] object-store: move packed_git and packed_git_mru to object store","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:07:08Z","receivedAt":"2018-03-23T17:07:47Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Mar 23, 2018 at 6:03 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Wed, Mar 21, 2018 at 11:18 PM, Brandon Williams <bmwill@google.com> wrote:\n>> You're marking packed_git\n>> as \"private\"...well C has no notion of private vs public fields in a\n>> struct so it might be difficult to keep that convention, it also took me\n>> a second to realize that it was only in the scope of packfile.c where it\n>> was ok to reference it directly.  Maybe it'll be ok?  If we really\n>> wanted something to be private we'd need it to be an opaque type\n>> instead, which may be out of the scope of this code refactor.\n>\n> It's true C syntax does not support private/public scoping, but it\n> does not mean we must avoid that. Python has \"private convention\" with\n> the underscore prefix, no special support from the language either.\n> Yes having compiler support to enforce scoping is nice, but I think we\n> can still live without it (Go devs live fine without \"const\"\n> arguments, e.g.)\n>\n> So I'm going to make it clearer that these fields are not supposed to\n> be accessed outside packfile.c\n\nI'm not counting out the making these fields completely opaque of\ncourse. And with your suggestion of not embedding raw_object_store to\nrepository, that's actually possible to do. But I'm still not doing it\nnow :) The series is getting long and extending its scope will drag it\neven longer (in terms of both time and number of patches)\n-- \nDuy\n"},{"id":"342608","messageId":"20180323172121.17725-1-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 00/27] sb/object-store updates","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:20:54Z","receivedAt":"2018-03-23T17:21:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"I think I have addressed all comments I've received so far. What I\ndecided not to do, I have responded individually. One comment I did\nnot respond nor do is the approximate thing, which could be done\nlater.\n\nInterdiff is big due to the \"objects.\" to \"objects->\" conversion\n(blame Brandon for his suggestion, don't blame me :D)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 4762a702e3..47beddbe24 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1859,7 +1859,7 @@ static void am_run(struct am_state *state, int resume)\n \t */\n \tif (!state->rebasing) {\n \t\tam_destroy(state);\n-\t\tclose_all_packs(&the_repository->objects);\n+\t\tclose_all_packs(the_repository->objects);\n \t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n \t}\n }\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 13cfaa6488..7df5932b85 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -27,6 +27,7 @@\n #include \"connected.h\"\n #include \"packfile.h\"\n #include \"list-objects-filter-options.h\"\n+#include \"object-store.h\"\n \n /*\n  * Overall FIXMEs:\n@@ -1217,7 +1218,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \ttransport_disconnect(transport);\n \n \tif (option_dissociate) {\n-\t\tclose_all_packs(&the_repository->objects);\n+\t\tclose_all_packs(the_repository->objects);\n \t\tdissociate_from_references();\n \t}\n \ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 5c7c3c6ae3..b28ff00be2 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -12,6 +12,7 @@\n #include \"parse-options.h\"\n #include \"quote.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static unsigned long garbage;\n static off_t size_garbage;\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 4d72efca78..a39e9d7b15 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -1478,7 +1478,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \n \tstring_list_clear(&list, 0);\n \n-\tclose_all_packs(&the_repository->objects);\n+\tclose_all_packs(the_repository->objects);\n \n \targv_array_pushl(&argv_gc_auto, \"gc\", \"--auto\", NULL);\n \tif (verbosity < 0)\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex b0abba6e04..3ef25fab97 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -17,6 +17,7 @@\n #include \"streaming.h\"\n #include \"decorate.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define REACHABLE 0x0001\n #define SEEN      0x0002\n@@ -714,11 +715,13 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \t\tfor_each_loose_object(mark_loose_for_connectivity, NULL, 0);\n \t\tfor_each_packed_object(mark_packed_for_connectivity, NULL, 0);\n \t} else {\n+\t\tstruct alternate_object_database *alt_odb_list;\n+\n \t\tfsck_object_dir(get_object_directory());\n \n \t\tprepare_alt_odb(the_repository);\n-\t\tfor (alt = the_repository->objects.alt_odb_list;\n-\t\t     alt; alt = alt->next)\n+\t\talt_odb_list = the_repository->objects->alt_odb_list;\n+\t\tfor (alt = alt_odb_list; alt; alt = alt->next)\n \t\t\tfsck_object_dir(alt->path);\n \n \t\tif (check_full) {\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex dd30067ac1..b00238cd5d 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -21,6 +21,7 @@\n #include \"argv-array.h\"\n #include \"commit.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define FAILED_RUN \"failed to run %s\"\n \ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 0f0c195705..1e9cdbdf78 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -22,6 +22,7 @@\n #include \"pathspec.h\"\n #include \"submodule.h\"\n #include \"submodule-config.h\"\n+#include \"object-store.h\"\n \n static char const * const grep_usage[] = {\n \tN_(\"git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]\"),\n@@ -432,7 +433,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,\n \t * object.\n \t */\n \tgrep_read_lock();\n-\tadd_to_alternates_memory(submodule.objects.objectdir);\n+\tadd_to_alternates_memory(submodule.objects->objectdir);\n \tgrep_read_unlock();\n \n \tif (oid) {\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex 5ebd370c56..1d6bc87b76 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -13,6 +13,7 @@\n #include \"streaming.h\"\n #include \"thread-utils.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static const char index_pack_usage[] =\n \"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])\";\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 907ae44ab5..96d56cbdd2 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -411,7 +411,7 @@ static void finish(struct commit *head_commit,\n \t\t\t * We ignore errors in 'gc --auto', since the\n \t\t\t * user should see them.\n \t\t\t */\n-\t\t\tclose_all_packs(&the_repository->objects);\n+\t\t\tclose_all_packs(the_repository->objects);\n \t\t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n \t\t}\n \t}\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 0e5fde1d6b..223f2d9fc0 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -29,6 +29,7 @@\n #include \"argv-array.h\"\n #include \"list.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static const char *pack_usage[] = {\n \tN_(\"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]\"),\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex d6d8a44959..b5b007e706 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -9,6 +9,7 @@\n #include \"builtin.h\"\n #include \"repository.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define BLKSIZE 512\n \ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex ac478b7b99..1a298a6711 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2026,7 +2026,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\t\tproc.git_cmd = 1;\n \t\t\tproc.argv = argv_gc_auto;\n \n-\t\t\tclose_all_packs(&the_repository->objects);\n+\t\t\tclose_all_packs(the_repository->objects);\n \t\t\tif (!start_command(&proc)) {\n \t\t\t\tif (use_sideband)\n \t\t\t\t\tcopy_to_sideband(proc.err, -1, NULL);\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex b1daca995f..6d8e002be7 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -16,6 +16,7 @@\n #include \"revision.h\"\n #include \"diffcore.h\"\n #include \"diff.h\"\n+#include \"object-store.h\"\n \n #define OPT_QUIET (1 << 0)\n #define OPT_CACHED (1 << 1)\ndiff --git a/environment.c b/environment.c\nindex c05705e384..93c9fbb0ba 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -271,9 +271,9 @@ const char *get_git_work_tree(void)\n \n char *get_object_directory(void)\n {\n-\tif (!the_repository->objects.objectdir)\n+\tif (!the_repository->objects->objectdir)\n \t\tBUG(\"git environment hasn't been setup\");\n-\treturn the_repository->objects.objectdir;\n+\treturn the_repository->objects->objectdir;\n }\n \n int odb_mkstemp(struct strbuf *template, const char *pattern)\ndiff --git a/fast-import.c b/fast-import.c\nindex 0dba555478..b3492fce5c 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -169,6 +169,7 @@ Format of STDIN stream:\n #include \"dir.h\"\n #include \"run-command.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define PACK_ID_BITS 16\n #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)\ndiff --git a/http-backend.c b/http-backend.c\nindex 22921d169a..64dde78c1b 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -11,6 +11,7 @@\n #include \"url.h\"\n #include \"argv-array.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static const char content_type[] = \"Content-Type\";\n static const char content_length[] = \"Content-Length\";\ndiff --git a/http-push.c b/http-push.c\nindex 0913f8ab86..97fe22a705 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -12,6 +12,7 @@\n #include \"sigchain.h\"\n #include \"argv-array.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #ifdef EXPAT_NEEDS_XMLPARSE_H\n #include <xmlparse.h>\ndiff --git a/http-walker.c b/http-walker.c\nindex 2c33969123..75d55d42a9 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -6,6 +6,7 @@\n #include \"list.h\"\n #include \"transport.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n struct alt_base {\n \tchar *base;\ndiff --git a/http.c b/http.c\nindex df9dbea59c..4d613d5f6b 100644\n--- a/http.c\n+++ b/http.c\n@@ -14,6 +14,7 @@\n #include \"packfile.h\"\n #include \"protocol.h\"\n #include \"string-list.h\"\n+#include \"object-store.h\"\n \n static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);\n static int trace_curl_data = 1;\ndiff --git a/object-store.h b/object-store.h\nindex 521f5a1755..fef33f345f 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -90,13 +90,19 @@ struct raw_object_store {\n \t/* Path to extra alternate object database if not NULL */\n \tchar *alternate_db;\n \n-\tstruct packed_git *packed_git; /* private */\n-\t/* A most-recently-used ordered version of the packed_git list. */\n-\tstruct list_head packed_git_mru; /* private */\n-\n \tstruct alternate_object_database *alt_odb_list;\n \tstruct alternate_object_database **alt_odb_tail;\n \n+\t/*\n+\t * private data\n+\t *\n+\t * should only be accessed directly by packfile.c\n+\t */\n+\n+\tstruct packed_git *packed_git;\n+\t/* A most-recently-used ordered version of the packed_git list. */\n+\tstruct list_head packed_git_mru;\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@@ -112,7 +118,7 @@ struct raw_object_store {\n \tunsigned packed_git_initialized : 1;\n };\n \n-void raw_object_store_init(struct raw_object_store *o);\n+struct raw_object_store *raw_object_store_new(void);\n void raw_object_store_clear(struct raw_object_store *o);\n \n /*\ndiff --git a/object.c b/object.c\nindex 60ca76b285..4c2cf7ff5d 100644\n--- a/object.c\n+++ b/object.c\n@@ -4,6 +4,7 @@\n #include \"tree.h\"\n #include \"commit.h\"\n #include \"tag.h\"\n+#include \"object-store.h\"\n #include \"packfile.h\"\n \n static struct object **obj_hash;\n@@ -447,23 +448,30 @@ void clear_commit_marks_all(unsigned int flags)\n \t}\n }\n \n-void raw_object_store_init(struct raw_object_store *o)\n+struct raw_object_store *raw_object_store_new(void)\n {\n+\tstruct raw_object_store *o = xmalloc(sizeof(*o));\n+\n \tmemset(o, 0, sizeof(*o));\n \tINIT_LIST_HEAD(&o->packed_git_mru);\n+\treturn o;\n }\n \n static void free_alt_odb(struct alternate_object_database *alt)\n {\n \tstrbuf_release(&alt->scratch);\n \toid_array_clear(&alt->loose_objects_cache);\n+\tfree(alt);\n }\n \n static void free_alt_odbs(struct raw_object_store *o)\n {\n \twhile (o->alt_odb_list) {\n+\t\tstruct alternate_object_database *next;\n+\n+\t\tnext = o->alt_odb_list->next;\n \t\tfree_alt_odb(o->alt_odb_list);\n-\t\to->alt_odb_list = o->alt_odb_list->next;\n+\t\to->alt_odb_list = next;\n \t}\n }\n \ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex abed43cdb5..22cd425788 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -11,6 +11,7 @@\n #include \"pack-objects.h\"\n #include \"packfile.h\"\n #include \"repository.h\"\n+#include \"object-store.h\"\n \n /*\n  * An entry on the bitmap index, representing the bitmap for a given\ndiff --git a/pack-check.c b/pack-check.c\nindex 073c1fbd46..2378f25999 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -3,6 +3,7 @@\n #include \"pack-revindex.h\"\n #include \"progress.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n struct idx_entry {\n \toff_t                offset;\ndiff --git a/pack-revindex.c b/pack-revindex.c\nindex ff5f62c033..bb521cf7fb 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 a0842521e5..17170fc662 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -14,6 +14,7 @@\n #include \"tag.h\"\n #include \"tree-walk.h\"\n #include \"tree.h\"\n+#include \"object-store.h\"\n \n char *odb_pack_name(struct strbuf *buf,\n \t\t    const unsigned char *sha1,\n@@ -244,7 +245,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 = the_repository->objects.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@@ -382,7 +383,7 @@ static int close_one_pack(void)\n \tstruct pack_window *mru_w = NULL;\n \tint accept_windows_inuse = 1;\n \n-\tfor (p = the_repository->objects.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@@ -684,8 +685,8 @@ void install_packed_git(struct packed_git *pack)\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 = 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@@ -767,7 +768,7 @@ 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 = the_repository->objects.packed_git; p;\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@@ -811,20 +812,20 @@ static void prepare_packed_git_one(char *objdir, int local)\n  */\n unsigned long approximate_object_count(void)\n {\n-\tif (!the_repository->objects.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 \t\tcount = 0;\n-\t\tfor (p = the_repository->objects.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 \t\t}\n-\t\tthe_repository->objects.approximate_object_count = count;\n+\t\tthe_repository->objects->approximate_object_count = count;\n \t}\n-\treturn the_repository->objects.approximate_object_count;\n+\treturn the_repository->objects->approximate_object_count;\n }\n \n static void *get_next_packed_git(const void *p)\n@@ -867,8 +868,8 @@ static int sort_pack(const void *a_, const void *b_)\n \n static void rearrange_packed_git(void)\n {\n-\tthe_repository->objects.packed_git = llist_mergesort(\n-\t\tthe_repository->objects.packed_git, get_next_packed_git,\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@@ -876,42 +877,42 @@ static void prepare_packed_git_mru(void)\n {\n \tstruct packed_git *p;\n \n-\tINIT_LIST_HEAD(&the_repository->objects.packed_git_mru);\n+\tINIT_LIST_HEAD(&the_repository->objects->packed_git_mru);\n \n-\tfor (p = the_repository->objects.packed_git; p; p = p->next)\n-\t\tlist_add_tail(&p->mru, &the_repository->objects.packed_git_mru);\n+\tfor (p = the_repository->objects->packed_git; p; p = p->next)\n+\t\tlist_add_tail(&p->mru, &the_repository->objects->packed_git_mru);\n }\n \n void prepare_packed_git(void)\n {\n \tstruct alternate_object_database *alt;\n \n-\tif (the_repository->objects.packed_git_initialized)\n+\tif (the_repository->objects->packed_git_initialized)\n \t\treturn;\n \tprepare_packed_git_one(get_object_directory(), 1);\n \tprepare_alt_odb(the_repository);\n-\tfor (alt = the_repository->objects.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();\n-\tthe_repository->objects.packed_git_initialized = 1;\n+\tthe_repository->objects->packed_git_initialized = 1;\n }\n \n void reprepare_packed_git(void)\n {\n-\tthe_repository->objects.approximate_object_count_valid = 0;\n-\tthe_repository->objects.packed_git_initialized = 0;\n+\tthe_repository->objects->approximate_object_count_valid = 0;\n+\tthe_repository->objects->packed_git_initialized = 0;\n \tprepare_packed_git();\n }\n \n struct packed_git *get_packed_git(struct repository *r)\n {\n-\treturn r->objects.packed_git;\n+\treturn r->objects->packed_git;\n }\n \n struct list_head *get_packed_git_mru(struct repository *r)\n {\n-\treturn &r->objects.packed_git_mru;\n+\treturn &r->objects->packed_git_mru;\n }\n \n unsigned long unpack_object_header_buffer(const unsigned char *buf,\n@@ -1022,7 +1023,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 = the_repository->objects.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@@ -1853,14 +1854,14 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n \tstruct list_head *pos;\n \n \tprepare_packed_git();\n-\tif (!the_repository->objects.packed_git)\n+\tif (!the_repository->objects->packed_git)\n \t\treturn 0;\n \n-\tlist_for_each(pos, &the_repository->objects.packed_git_mru) {\n+\tlist_for_each(pos, &the_repository->objects->packed_git_mru) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\tif (fill_pack_entry(sha1, e, p)) {\n \t\t\tlist_move(&p->mru,\n-\t\t\t\t  &the_repository->objects.packed_git_mru);\n+\t\t\t\t  &the_repository->objects->packed_git_mru);\n \t\t\treturn 1;\n \t\t}\n \t}\n@@ -1907,7 +1908,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 = the_repository->objects.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 ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&\n@@ -1938,7 +1939,7 @@ static int add_promisor_object(const struct object_id *oid,\n \n \t/*\n \t * If this is a tree, commit, or tag, the objects it refers\n-\t * to are also promisor objects. (Blobs refer to no objects.)\n+\t * to are also promisor objects-> (Blobs refer to no objects->)\n \t */\n \tif (obj->type == OBJ_TREE) {\n \t\tstruct tree *tree = (struct tree *)obj;\ndiff --git a/path.c b/path.c\nindex 81a42d9115..3308b7b958 100644\n--- a/path.c\n+++ b/path.c\n@@ -10,6 +10,7 @@\n #include \"submodule-config.h\"\n #include \"path.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static int get_st_mode_bits(const char *path, int *mode)\n {\n@@ -382,7 +383,7 @@ static void adjust_git_path(const struct repository *repo,\n \t\tstrbuf_splice(buf, 0, buf->len,\n \t\t\t      repo->index_file, strlen(repo->index_file));\n \telse if (dir_prefix(base, \"objects\"))\n-\t\treplace_dir(buf, git_dir_len + 7, repo->objects.objectdir);\n+\t\treplace_dir(buf, git_dir_len + 7, repo->objects->objectdir);\n \telse if (git_hooks_path && dir_prefix(base, \"hooks\"))\n \t\treplace_dir(buf, git_dir_len + 5, git_hooks_path);\n \telse if (repo->different_commondir)\ndiff --git a/reachable.c b/reachable.c\nindex 88d7d679da..25cfd99d1c 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -11,6 +11,7 @@\n #include \"list-objects.h\"\n #include \"packfile.h\"\n #include \"worktree.h\"\n+#include \"object-store.h\"\n \n struct connectivity_progress {\n \tstruct progress *progress;\ndiff --git a/repository.c b/repository.c\nindex 34c0a7f180..a4848c1bd0 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -13,7 +13,7 @@ void initialize_the_repository(void)\n \tthe_repository = &the_repo;\n \n \tthe_repo.index = &the_index;\n-\traw_object_store_init(&the_repo.objects);\n+\tthe_repo.objects = raw_object_store_new();\n \trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n }\n \n@@ -60,10 +60,10 @@ void repo_set_gitdir(struct repository *repo,\n \tfree(old_gitdir);\n \n \trepo_set_commondir(repo, o->commondir);\n-\texpand_base_dir(&repo->objects.objectdir, o->object_dir,\n+\texpand_base_dir(&repo->objects->objectdir, o->object_dir,\n \t\t\trepo->commondir, \"objects\");\n-\tfree(repo->objects.alternate_db);\n-\trepo->objects.alternate_db = xstrdup_or_null(o->alternate_db);\n+\tfree(repo->objects->alternate_db);\n+\trepo->objects->alternate_db = xstrdup_or_null(o->alternate_db);\n \texpand_base_dir(&repo->graft_file, o->graft_file,\n \t\t\trepo->commondir, \"info/grafts\");\n \texpand_base_dir(&repo->index_file, o->index_file,\n@@ -142,7 +142,7 @@ static int repo_init(struct repository *repo,\n \tstruct repository_format format;\n \tmemset(repo, 0, sizeof(*repo));\n \n-\traw_object_store_init(&repo->objects);\n+\trepo->objects = raw_object_store_new();\n \n \tif (repo_init_gitdir(repo, gitdir))\n \t\tgoto error;\n@@ -223,7 +223,8 @@ void repo_clear(struct repository *repo)\n \tFREE_AND_NULL(repo->worktree);\n \tFREE_AND_NULL(repo->submodule_prefix);\n \n-\traw_object_store_clear(&repo->objects);\n+\traw_object_store_clear(repo->objects);\n+\tFREE_AND_NULL(repo->objects);\n \n \tif (repo->config) {\n \t\tgit_configset_clear(repo->config);\ndiff --git a/repository.h b/repository.h\nindex 6c383c05c6..abba2c09bc 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -1,12 +1,11 @@\n #ifndef REPOSITORY_H\n #define REPOSITORY_H\n \n-#include \"object-store.h\"\n-\n struct config_set;\n+struct git_hash_algo;\n struct index_state;\n+struct raw_object_store;\n struct submodule_cache;\n-struct git_hash_algo;\n \n struct repository {\n \t/* Environment */\n@@ -25,7 +24,7 @@ struct repository {\n \t/*\n \t * Holds any information related to accessing the raw object content.\n \t */\n-\tstruct raw_object_store objects;\n+\tstruct raw_object_store *objects;\n \n \t/*\n \t * Path to the repository's graft file.\ndiff --git a/server-info.c b/server-info.c\nindex 6fe64ede17..75a8b65e47 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -5,6 +5,7 @@\n #include \"commit.h\"\n #include \"tag.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n /*\n  * Create the file \"path\" by writing to a temporary file and renaming\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 7066d4c9ce..0989bbd948 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -23,7 +23,6 @@\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 \"list.h\"\n@@ -31,6 +30,7 @@\n #include \"quote.h\"\n #include \"packfile.h\"\n #include \"fetch-object.h\"\n+#include \"object-store.h\"\n \n const unsigned char null_sha1[GIT_MAX_RAWSZ];\n const struct object_id null_oid;\n@@ -325,7 +325,7 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)\n \n void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1)\n {\n-\tstrbuf_addstr(buf, r->objects.objectdir);\n+\tstrbuf_addstr(buf, r->objects->objectdir);\n \tstrbuf_addch(buf, '/');\n \tfill_sha1_path(buf, sha1);\n }\n@@ -419,7 +419,7 @@ static int link_alt_odb_entry(struct repository *r, 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(&r->objects, &pathbuf, normalized_objdir)) {\n+\tif (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir)) {\n \t\tstrbuf_release(&pathbuf);\n \t\treturn -1;\n \t}\n@@ -427,8 +427,8 @@ static int link_alt_odb_entry(struct repository *r, const char *entry,\n \tent = alloc_alt_odb(pathbuf.buf);\n \n \t/* add the alternate entry */\n-\t*r->objects.alt_odb_tail = ent;\n-\tr->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@@ -482,7 +482,7 @@ static void link_alt_odb_entries(struct repository *r, const char *alt,\n \t\treturn;\n \t}\n \n-\tstrbuf_add_absolute_path(&objdirbuf, r->objects.objectdir);\n+\tstrbuf_add_absolute_path(&objdirbuf, r->objects->objectdir);\n \tif (strbuf_normalize_path(&objdirbuf) < 0)\n \t\tdie(\"unable to normalize object directory: %s\",\n \t\t    objdirbuf.buf);\n@@ -565,7 +565,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 (the_repository->objects.alt_odb_tail)\n+\t\tif (the_repository->objects->alt_odb_tail)\n \t\t\tlink_alt_odb_entries(the_repository, reference,\n \t\t\t\t\t     '\\n', NULL, 0);\n \t}\n@@ -665,7 +665,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \tint r = 0;\n \n \tprepare_alt_odb(the_repository);\n-\tfor (ent = the_repository->objects.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@@ -675,13 +675,13 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \n void prepare_alt_odb(struct repository *r)\n {\n-\tif (r->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-\tlink_alt_odb_entries(r, r->objects.alternate_db, PATH_SEP, NULL, 0);\n+\tr->objects->alt_odb_tail = &r->objects->alt_odb_list;\n+\tlink_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0);\n \n-\tread_info_alternates(r, r->objects.objectdir, 0);\n+\tread_info_alternates(r, r->objects->objectdir, 0);\n }\n \n /* Returns 1 if we have successfully freshened the file, 0 otherwise. */\n@@ -722,7 +722,7 @@ static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)\n {\n \tstruct alternate_object_database *alt;\n \tprepare_alt_odb(the_repository);\n-\tfor (alt = the_repository->objects.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@@ -882,7 +882,7 @@ static int stat_sha1_file(struct repository *r, const unsigned char *sha1,\n \n \tprepare_alt_odb(r);\n \terrno = ENOENT;\n-\tfor (alt = r->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@@ -913,7 +913,7 @@ static int open_sha1_file(struct repository *r,\n \tmost_interesting_errno = errno;\n \n \tprepare_alt_odb(r);\n-\tfor (alt = r->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\tfd = git_open(*path);\n \t\tif (fd >= 0)\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 2065be90d2..4325f74e0c 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 \"object-store.h\"\n #include \"repository.h\"\n \n static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);\n@@ -105,7 +106,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 = the_repository->objects.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;\ndiff --git a/submodule.c b/submodule.c\nindex 47ddc9b273..b03e5f5045 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -21,6 +21,7 @@\n #include \"remote.h\"\n #include \"worktree.h\"\n #include \"parse-options.h\"\n+#include \"object-store.h\"\n \n static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;\n static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex 7120634b04..7314b5943e 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -1,6 +1,7 @@\n #include \"cache.h\"\n #include \"refs.h\"\n #include \"worktree.h\"\n+#include \"object-store.h\"\n \n static const char *notnull(const char *arg, const char *name)\n {\ndiff --git a/tmp-objdir.c b/tmp-objdir.c\nindex b2d9280f10..fea3f55545 100644\n--- a/tmp-objdir.c\n+++ b/tmp-objdir.c\n@@ -6,6 +6,7 @@\n #include \"strbuf.h\"\n #include \"argv-array.h\"\n #include \"quote.h\"\n+#include \"object-store.h\"\n \n struct tmp_objdir {\n \tstruct strbuf path;\ndiff --git a/transport.c b/transport.c\nindex 00d48b5b56..3afc632472 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -18,6 +18,7 @@\n #include \"sha1-array.h\"\n #include \"sigchain.h\"\n #include \"transport-internal.h\"\n+#include \"object-store.h\"\n \n static void set_upstreams(struct transport *transport, struct ref *refs,\n \tint pretend)\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342609","messageId":"20180323172121.17725-5-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 04/27] object-store: free alt_odb_list","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:20:58Z","receivedAt":"2018-03-23T17:21:59Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nFree the memory and reset alt_odb_{list, tail} to NULL.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object.c | 22 ++++++++++++++++++++++\n 1 file changed, 22 insertions(+)\n\ndiff --git a/object.c b/object.c\nindex 6ddd61242c..581347b535 100644\n--- a/object.c\n+++ b/object.c\n@@ -454,8 +454,30 @@ struct raw_object_store *raw_object_store_new(void)\n \tmemset(o, 0, sizeof(*o));\n \treturn o;\n }\n+\n+static void free_alt_odb(struct alternate_object_database *alt)\n+{\n+\tstrbuf_release(&alt->scratch);\n+\toid_array_clear(&alt->loose_objects_cache);\n+\tfree(alt);\n+}\n+\n+static void free_alt_odbs(struct raw_object_store *o)\n+{\n+\twhile (o->alt_odb_list) {\n+\t\tstruct alternate_object_database *next;\n+\n+\t\tnext = o->alt_odb_list->next;\n+\t\tfree_alt_odb(o->alt_odb_list);\n+\t\to->alt_odb_list = next;\n+\t}\n+}\n+\n void raw_object_store_clear(struct raw_object_store *o)\n {\n \tFREE_AND_NULL(o->objectdir);\n \tFREE_AND_NULL(o->alternate_db);\n+\n+\tfree_alt_odbs(o);\n+\to->alt_odb_tail = NULL;\n }\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342610","messageId":"20180323172121.17725-3-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 02/27] object-store: migrate alternates struct and functions from cache.h","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:20:56Z","receivedAt":"2018-03-23T17:22:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nMigrate the struct alternate_object_database and all its related\nfunctions to the object store as these functions are easier found in\nthat header. The migration is just a verbatim copy, no need to\ninclude the object store header at any C file, because cache.h includes\nrepository.h which in turn includes the object-store.h\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clone.c             |  1 +\n builtin/count-objects.c     |  1 +\n builtin/fsck.c              |  1 +\n builtin/submodule--helper.c |  1 +\n cache.h                     | 51 -------------------------------------\n object-store.h              | 51 +++++++++++++++++++++++++++++++++++++\n packfile.c                  |  1 +\n sha1_name.c                 |  1 +\n submodule.c                 |  1 +\n t/helper/test-ref-store.c   |  1 +\n tmp-objdir.c                |  1 +\n transport.c                 |  1 +\n 12 files changed, 61 insertions(+), 51 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 101c27a593..855947f1ab 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -27,6 +27,7 @@\n #include \"connected.h\"\n #include \"packfile.h\"\n #include \"list-objects-filter-options.h\"\n+#include \"object-store.h\"\n \n /*\n  * Overall FIXMEs:\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex 33343818c8..ced8958e43 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -11,6 +11,7 @@\n #include \"parse-options.h\"\n #include \"quote.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static unsigned long garbage;\n static off_t size_garbage;\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 7a8a679d4f..b0eba4c3c9 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -16,6 +16,7 @@\n #include \"streaming.h\"\n #include \"decorate.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define REACHABLE 0x0001\n #define SEEN      0x0002\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex b1daca995f..6d8e002be7 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -16,6 +16,7 @@\n #include \"revision.h\"\n #include \"diffcore.h\"\n #include \"diff.h\"\n+#include \"object-store.h\"\n \n #define OPT_QUIET (1 << 0)\n #define OPT_CACHED (1 << 1)\ndiff --git a/cache.h b/cache.h\nindex 41ba67cc16..41530d5d16 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1576,57 +1576,6 @@ 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-\tstruct alternate_object_database *next;\n-\n-\t/* see alt_scratch_buf() */\n-\tstruct strbuf scratch;\n-\tsize_t base_len;\n-\n-\t/*\n-\t * Used to store the results of readdir(3) calls when searching\n-\t * for unique abbreviated hashes.  This cache is never\n-\t * invalidated, thus it's racy and not necessarily accurate.\n-\t * That's fine for its purpose; don't use it for tasks requiring\n-\t * greater accuracy!\n-\t */\n-\tchar loose_objects_subdir_seen[256];\n-\tstruct oid_array loose_objects_cache;\n-\n-\tchar path[FLEX_ARRAY];\n-} *alt_odb_list;\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*);\n-\n-/*\n- * Allocate a \"struct alternate_object_database\" but do _not_ actually\n- * add it to the list of alternates.\n- */\n-struct alternate_object_database *alloc_alt_odb(const char *dir);\n-\n-/*\n- * Add the directory to the on-disk alternates file; the new entry will also\n- * take effect in the current process.\n- */\n-extern void add_to_alternates_file(const char *dir);\n-\n-/*\n- * Add the directory to the in-memory list of alternates (along with any\n- * recursive alternates it points to), but do not modify the on-disk alternates\n- * file.\n- */\n-extern void add_to_alternates_memory(const char *dir);\n-\n-/*\n- * Returns a scratch strbuf pre-filled with the alternate object directory,\n- * including a trailing slash, which can be used to access paths in the\n- * alternate. Always use this over direct access to alt->scratch, as it\n- * cleans up any previous use of the scratch buffer.\n- */\n-extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);\n-\n struct pack_window {\n \tstruct pack_window *next;\n \tunsigned char *base;\ndiff --git a/object-store.h b/object-store.h\nindex abfaae059b..5002e373cd 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -1,6 +1,57 @@\n #ifndef OBJECT_STORE_H\n #define OBJECT_STORE_H\n \n+extern struct alternate_object_database {\n+\tstruct alternate_object_database *next;\n+\n+\t/* see alt_scratch_buf() */\n+\tstruct strbuf scratch;\n+\tsize_t base_len;\n+\n+\t/*\n+\t * Used to store the results of readdir(3) calls when searching\n+\t * for unique abbreviated hashes.  This cache is never\n+\t * invalidated, thus it's racy and not necessarily accurate.\n+\t * That's fine for its purpose; don't use it for tasks requiring\n+\t * greater accuracy!\n+\t */\n+\tchar loose_objects_subdir_seen[256];\n+\tstruct oid_array loose_objects_cache;\n+\n+\tchar path[FLEX_ARRAY];\n+} *alt_odb_list;\n+void prepare_alt_odb(void);\n+char *compute_alternate_path(const char *path, struct strbuf *err);\n+typedef int alt_odb_fn(struct alternate_object_database *, void *);\n+int foreach_alt_odb(alt_odb_fn, void*);\n+\n+/*\n+ * Allocate a \"struct alternate_object_database\" but do _not_ actually\n+ * add it to the list of alternates.\n+ */\n+struct alternate_object_database *alloc_alt_odb(const char *dir);\n+\n+/*\n+ * Add the directory to the on-disk alternates file; the new entry will also\n+ * take effect in the current process.\n+ */\n+void add_to_alternates_file(const char *dir);\n+\n+/*\n+ * Add the directory to the in-memory list of alternates (along with any\n+ * recursive alternates it points to), but do not modify the on-disk alternates\n+ * file.\n+ */\n+void add_to_alternates_memory(const char *dir);\n+\n+/*\n+ * Returns a scratch strbuf pre-filled with the alternate object directory,\n+ * including a trailing slash, which can be used to access paths in the\n+ * alternate. Always use this over direct access to alt->scratch, as it\n+ * cleans up any previous use of the scratch buffer.\n+ */\n+struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);\n+\n struct raw_object_store {\n \t/*\n \t * Path to the repository's object store.\ndiff --git a/packfile.c b/packfile.c\nindex 7dbe8739d1..c6651682a7 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -13,6 +13,7 @@\n #include \"tag.h\"\n #include \"tree-walk.h\"\n #include \"tree.h\"\n+#include \"object-store.h\"\n \n char *odb_pack_name(struct strbuf *buf,\n \t\t    const unsigned char *sha1,\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 611c7d24dd..434025bf03 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 \"object-store.h\"\n \n static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);\n \ndiff --git a/submodule.c b/submodule.c\nindex 47ddc9b273..b03e5f5045 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -21,6 +21,7 @@\n #include \"remote.h\"\n #include \"worktree.h\"\n #include \"parse-options.h\"\n+#include \"object-store.h\"\n \n static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;\n static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex 7120634b04..7314b5943e 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -1,6 +1,7 @@\n #include \"cache.h\"\n #include \"refs.h\"\n #include \"worktree.h\"\n+#include \"object-store.h\"\n \n static const char *notnull(const char *arg, const char *name)\n {\ndiff --git a/tmp-objdir.c b/tmp-objdir.c\nindex b2d9280f10..fea3f55545 100644\n--- a/tmp-objdir.c\n+++ b/tmp-objdir.c\n@@ -6,6 +6,7 @@\n #include \"strbuf.h\"\n #include \"argv-array.h\"\n #include \"quote.h\"\n+#include \"object-store.h\"\n \n struct tmp_objdir {\n \tstruct strbuf path;\ndiff --git a/transport.c b/transport.c\nindex 00d48b5b56..3afc632472 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -18,6 +18,7 @@\n #include \"sha1-array.h\"\n #include \"sigchain.h\"\n #include \"transport-internal.h\"\n+#include \"object-store.h\"\n \n static void set_upstreams(struct transport *transport, struct ref *refs,\n \tint pretend)\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342611","messageId":"20180323172121.17725-4-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 03/27] object-store: move alt_odb_list and alt_odb_tail to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:20:57Z","receivedAt":"2018-03-23T17:22:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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\nNow that the alternative object data base is per repository, we're\nleaking its memory upon freeing a repository. The next patch plugs\nthis hole.\n\nNo functional change intended.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/fsck.c |  4 ++++\n object-store.h |  7 +++++--\n packfile.c     |  3 ++-\n sha1_file.c    | 25 ++++++++++++-------------\n sha1_name.c    |  3 ++-\n 5 files changed, 25 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex b0eba4c3c9..c736a10a11 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@@ -714,9 +715,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \t\tfor_each_loose_object(mark_loose_for_connectivity, NULL, 0);\n \t\tfor_each_packed_object(mark_packed_for_connectivity, NULL, 0);\n \t} else {\n+\t\tstruct alternate_object_database *alt_odb_list;\n+\n \t\tfsck_object_dir(get_object_directory());\n \n \t\tprepare_alt_odb();\n+\t\talt_odb_list = the_repository->objects->alt_odb_list;\n \t\tfor (alt = alt_odb_list; alt; alt = alt->next)\n \t\t\tfsck_object_dir(alt->path);\n \ndiff --git a/object-store.h b/object-store.h\nindex 5002e373cd..0b4db5867d 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -1,7 +1,7 @@\n #ifndef OBJECT_STORE_H\n #define OBJECT_STORE_H\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@@ -19,7 +19,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 void prepare_alt_odb(void);\n char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n@@ -61,6 +61,9 @@ struct raw_object_store {\n \n \t/* Path to extra alternate object database if not NULL */\n \tchar *alternate_db;\n+\n+\tstruct alternate_object_database *alt_odb_list;\n+\tstruct alternate_object_database **alt_odb_tail;\n };\n \n struct raw_object_store *raw_object_store_new(void);\ndiff --git a/packfile.c b/packfile.c\nindex c6651682a7..fdbf240f81 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1,6 +1,7 @@\n #include \"cache.h\"\n #include \"list.h\"\n #include \"pack.h\"\n+#include \"repository.h\"\n #include \"dir.h\"\n #include \"mergesort.h\"\n #include \"packfile.h\"\n@@ -892,7 +893,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 af5aa83db5..84b361c125 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 \"list.h\"\n@@ -343,9 +344,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@@ -365,7 +363,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@@ -425,8 +423,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@@ -560,7 +558,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, '\\n', NULL, 0);\n \t}\n \tfree(alts);\n@@ -658,7 +656,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@@ -668,10 +666,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)\n \n void prepare_alt_odb(void)\n {\n-\tif (alt_odb_tail)\n+\tif (the_repository->objects->alt_odb_tail)\n \t\treturn;\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(the_repository->objects->alternate_db,\n \t\t\t     PATH_SEP, NULL, 0);\n \n@@ -716,7 +715,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@@ -876,7 +875,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@@ -906,7 +905,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 434025bf03..a22a29cda0 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 \"object-store.h\"\n+#include \"repository.h\"\n \n static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);\n \n@@ -105,7 +106,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342612","messageId":"20180323172121.17725-11-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 10/27] sha1_file: add repository argument to link_alt_odb_entry","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:04Z","receivedAt":"2018-03-23T17:22:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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\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\nThis and the following three patches add repository arguments to\nlink_alt_odb_entry, read_info_alternates, link_alt_odb_entries\nand prepare_alt_odb. Three out of the four functions are found\nin a recursive call chain, calling each other, and one of them\naccesses the repositories `objectdir` (which was migrated; it\nwas an obvious choice) and `ignore_env` (which we need to keep in\nthe repository struct for clarify); hence we will pass through the\nrepository unlike just the object store object + the ignore_env flag.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 097c372d03..7c0ace646a 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -391,8 +391,9 @@ static int alt_odb_usable(struct raw_object_store *o,\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@@ -489,7 +490,8 @@ static void link_alt_odb_entries(const char *alt, 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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342613","messageId":"20180323172121.17725-18-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 17/27] sha1_file: add repository argument to stat_sha1_file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:11Z","receivedAt":"2018-03-23T17:22:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 fe16d30f66..80bac89014 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -867,8 +867,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 \tstatic struct strbuf buf = STRBUF_INIT;\n@@ -1174,7 +1175,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@@ -1388,7 +1389,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342614","messageId":"20180323172121.17725-21-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 20/27] sha1_file: add repository argument to map_sha1_file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:14Z","receivedAt":"2018-03-23T17:22:17Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd 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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n cache.h        | 1 -\n object-store.h | 3 +++\n sha1_file.c    | 4 ++--\n streaming.c    | 5 ++++-\n 4 files changed, 9 insertions(+), 4 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex cbec0ecd23..720664e394 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1242,7 +1242,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 3707f3c495..03671745f4 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -128,4 +128,7 @@ void raw_object_store_clear(struct raw_object_store *o);\n #define sha1_file_name(r, b, s) sha1_file_name_##r(b, s)\n void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1);\n \n+#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n+void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n+\n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 4b6144b7cd..f968f67a14 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -961,7 +961,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@@ -1185,7 +1185,7 @@ static int sha1_loose_object_info(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 5892b50bd8..22d27df55e 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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342615","messageId":"20180323172121.17725-23-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 22/27] sha1_file: allow sha1_file_name to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:16Z","receivedAt":"2018-03-23T17:22:21Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 03671745f4..d9cc875153 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -125,8 +125,7 @@ void raw_object_store_clear(struct raw_object_store *o);\n  * Put in `buf` the name of the file in the local object database that\n  * would be used to store a loose object with the specified sha1.\n  */\n-#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s)\n-void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1);\n+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);\n \n #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 74c68ea776..aed9a558c5 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -323,9 +323,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)\n \t}\n }\n \n-void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1)\n+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1)\n {\n-\tstrbuf_addstr(buf, get_object_directory());\n+\tstrbuf_addstr(buf, r->objects->objectdir);\n \tstrbuf_addch(buf, '/');\n \tfill_sha1_path(buf, sha1);\n }\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342616","messageId":"20180323172121.17725-28-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 27/27] sha1_file: allow sha1_loose_object_info to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:21Z","receivedAt":"2018-03-23T17:22:26Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Jonathan Nieder <jrnieder@gmail.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 9addad6887..0989bbd948 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1149,10 +1149,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@@ -1176,14 +1175,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342617","messageId":"20180323172121.17725-24-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 23/27] sha1_file: allow stat_sha1_file to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:17Z","receivedAt":"2018-03-23T17:22:29Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 aed9a558c5..fc4f209981 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -867,23 +867,22 @@ 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 \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(the_repository, &buf, sha1);\n+\tsha1_file_name(r, &buf, sha1);\n \t*path = buf.buf;\n \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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342618","messageId":"20180323172121.17725-15-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 14/27] sha1_file: allow link_alt_odb_entries to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:08Z","receivedAt":"2018-03-23T17:22:33Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nActually this also allows read_info_alternates and link_alt_odb_entry to\nhandle arbitrary repositories, but link_alt_odb_entries is the most\ninteresting function in this set of functions, hence the commit subject.\n\nThese functions span a strongly connected component in the function\ngraph, i.e. the recursive call chain might look like\n\n  -> link_alt_odb_entries\n    -> link_alt_odb_entry\n      -> read_info_alternates\n        -> link_alt_odb_entries\n\nThat is why we need to convert all these functions at the same time.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h |  4 ++++\n sha1_file.c    | 36 ++++++++++++++++--------------------\n 2 files changed, 20 insertions(+), 20 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 79de470639..3fc461a463 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -18,6 +18,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 alternative object store. If this is a relative path,\n+\t * it is relative to the current working directory.\n+\t */\n \tchar path[FLEX_ARRAY];\n };\n #define prepare_alt_odb(r) prepare_alt_odb_##r()\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 0fac75bd31..d38f5cdb0e 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -390,11 +390,10 @@ static int alt_odb_usable(struct raw_object_store *o,\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@@ -420,7 +419,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->objects, &pathbuf, normalized_objdir)) {\n+\tif (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir)) {\n \t\tstrbuf_release(&pathbuf);\n \t\treturn -1;\n \t}\n@@ -428,12 +427,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@@ -468,12 +467,8 @@ static const char *parse_alt_odb_entry(const char *string,\n \treturn end;\n }\n \n-#define link_alt_odb_entries(r, a, s, rb, d) \\\n-\tlink_alt_odb_entries_##r(a, s, rb, d)\n-static void link_alt_odb_entries_the_repository(const char *alt,\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,\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@@ -487,7 +482,7 @@ static void link_alt_odb_entries_the_repository(const char *alt,\n \t\treturn;\n \t}\n \n-\tstrbuf_add_absolute_path(&objdirbuf, get_object_directory());\n+\tstrbuf_add_absolute_path(&objdirbuf, r->objects->objectdir);\n \tif (strbuf_normalize_path(&objdirbuf) < 0)\n \t\tdie(\"unable to normalize object directory: %s\",\n \t\t    objdirbuf.buf);\n@@ -496,15 +491,16 @@ static void link_alt_odb_entries_the_repository(const char *alt,\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 *path;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -516,7 +512,7 @@ static void read_info_alternates_the_repository(const char *relative_base,\n \t\treturn;\n \t}\n \n-\tlink_alt_odb_entries(the_repository, buf.buf, '\\n', relative_base, depth);\n+\tlink_alt_odb_entries(r, buf.buf, '\\n', relative_base, depth);\n \tstrbuf_release(&buf);\n \tfree(path);\n }\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342619","messageId":"20180323172121.17725-27-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 26/27] sha1_file: allow map_sha1_file to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:20Z","receivedAt":"2018-03-23T17:22:35Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 d9cc875153..fef33f345f 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -127,7 +127,6 @@ void raw_object_store_clear(struct raw_object_store *o);\n  */\n void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);\n \n-#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)\n-void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);\n+void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);\n \n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 1d5d23dfe2..9addad6887 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -957,9 +957,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342620","messageId":"20180323172121.17725-17-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 16/27] sha1_file: add repository argument to sha1_file_name","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:10Z","receivedAt":"2018-03-23T17:22:36Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd 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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n cache.h        |  6 ------\n http-walker.c  |  3 ++-\n http.c         |  5 ++---\n object-store.h |  7 +++++++\n sha1_file.c    | 10 +++++-----\n 5 files changed, 16 insertions(+), 15 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex d3429a0d48..cbec0ecd23 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -961,12 +961,6 @@ extern void check_repository_format(void);\n #define DATA_CHANGED    0x0020\n #define TYPE_CHANGED    0x0040\n \n-/*\n- * Put in `buf` the name of the file in the local object database that\n- * would be used to store a loose object with the specified sha1.\n- */\n-extern void sha1_file_name(struct strbuf *buf, 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 d850408d18..75d55d42a9 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\tstruct strbuf buf = STRBUF_INIT;\n-\t\tsha1_file_name(&buf, req->sha1);\n+\t\tsha1_file_name(the_repository, &buf, req->sha1);\n \t\tret = error(\"unable to write sha1 filename %s\", buf.buf);\n \t\tstrbuf_release(&buf);\n \t}\ndiff --git a/http.c b/http.c\nindex efa977112a..4d613d5f6b 100644\n--- a/http.c\n+++ b/http.c\n@@ -2247,7 +2247,7 @@ struct http_object_request *new_http_object_request(const char *base_url,\n \thashcpy(freq->sha1, sha1);\n \tfreq->localfile = -1;\n \n-\tsha1_file_name(&filename, sha1);\n+\tsha1_file_name(the_repository, &filename, sha1);\n \tsnprintf(freq->tmpfile, sizeof(freq->tmpfile),\n \t\t \"%s.temp\", filename.buf);\n \n@@ -2396,8 +2396,7 @@ int finish_http_object_request(struct http_object_request *freq)\n \t\tunlink_or_warn(freq->tmpfile);\n \t\treturn -1;\n \t}\n-\n-\tsha1_file_name(&filename, freq->sha1);\n+\tsha1_file_name(the_repository, &filename, freq->sha1);\n \tfreq->rename = finalize_object_file(freq->tmpfile, filename.buf);\n \tstrbuf_release(&filename);\n \ndiff --git a/object-store.h b/object-store.h\nindex f54bc0b951..3707f3c495 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -121,4 +121,11 @@ struct raw_object_store {\n struct raw_object_store *raw_object_store_new(void);\n void raw_object_store_clear(struct raw_object_store *o);\n \n+/*\n+ * Put in `buf` the name of the file in the local object database that\n+ * would be used to store a loose object with the specified sha1.\n+ */\n+#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s)\n+void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1);\n+\n #endif /* OBJECT_STORE_H */\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 04118f331c..fe16d30f66 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -323,7 +323,7 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)\n \t}\n }\n \n-void sha1_file_name(struct strbuf *buf, const unsigned char *sha1)\n+void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1)\n {\n \tstrbuf_addstr(buf, get_object_directory());\n \tstrbuf_addch(buf, '/');\n@@ -713,7 +713,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(&buf, sha1);\n+\tsha1_file_name(the_repository, &buf, sha1);\n \n \treturn check_and_freshen_file(buf.buf, freshen);\n }\n@@ -874,7 +874,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(&buf, sha1);\n+\tsha1_file_name(the_repository, &buf, sha1);\n \t*path = buf.buf;\n \n \tif (!lstat(*path, st))\n@@ -903,7 +903,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(&buf, sha1);\n+\tsha1_file_name(the_repository, &buf, sha1);\n \t*path = buf.buf;\n \n \tfd = git_open(*path);\n@@ -1588,7 +1588,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,\n \tstatic struct strbuf filename = STRBUF_INIT;\n \n \tstrbuf_reset(&filename);\n-\tsha1_file_name(&filename, sha1);\n+\tsha1_file_name(the_repository, &filename, sha1);\n \n \tfd = create_tmpfile(&tmp_file, filename.buf);\n \tif (fd < 0) {\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342621","messageId":"20180323172121.17725-22-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 21/27] sha1_file: add repository argument to sha1_loose_object_info","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:15Z","receivedAt":"2018-03-23T17:22:38Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 f968f67a14..74c68ea776 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1152,9 +1152,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@@ -1273,7 +1274,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \t\t\tbreak;\n \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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342622","messageId":"20180323172121.17725-25-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 24/27] sha1_file: allow open_sha1_file to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:18Z","receivedAt":"2018-03-23T17:22:40Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 fc4f209981..1fa32c8a06 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -895,9 +895,8 @@ 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@@ -905,7 +904,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,\n \tstatic struct strbuf buf = STRBUF_INIT;\n \n \tstrbuf_reset(&buf);\n-\tsha1_file_name(the_repository, &buf, sha1);\n+\tsha1_file_name(r, &buf, sha1);\n \t*path = buf.buf;\n \n \tfd = git_open(*path);\n@@ -913,8 +912,8 @@ 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(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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342623","messageId":"20180323172121.17725-26-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 25/27] sha1_file: allow map_sha1_file_1 to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:19Z","receivedAt":"2018-03-23T17:22:41Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Jonathan Nieder <jrnieder@gmail.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 1fa32c8a06..1d5d23dfe2 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -929,10 +929,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@@ -940,7 +938,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342624","messageId":"20180323172121.17725-16-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 15/27] sha1_file: allow prepare_alt_odb to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:09Z","receivedAt":"2018-03-23T17:22:45Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h |  3 +--\n sha1_file.c    | 13 +++++--------\n 2 files changed, 6 insertions(+), 10 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 3fc461a463..f54bc0b951 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -24,8 +24,7 @@ struct alternate_object_database {\n \t */\n \tchar path[FLEX_ARRAY];\n };\n-#define prepare_alt_odb(r) prepare_alt_odb_##r()\n-void prepare_alt_odb_the_repository(void);\n+void prepare_alt_odb(struct repository *r);\n char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n int foreach_alt_odb(alt_odb_fn, void*);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex d38f5cdb0e..04118f331c 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -673,18 +673,15 @@ int foreach_alt_odb(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-\tif (the_repository->objects->alt_odb_tail)\n+\tif (r->objects->alt_odb_tail)\n \t\treturn;\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,\n-\t\t\t     the_repository->objects->alternate_db,\n-\t\t\t     PATH_SEP, NULL, 0);\n+\tr->objects->alt_odb_tail = &r->objects->alt_odb_list;\n+\tlink_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0);\n \n-\tread_info_alternates(the_repository, get_object_directory(), 0);\n+\tread_info_alternates(r, r->objects->objectdir, 0);\n }\n \n /* Returns 1 if we have successfully freshened the file, 0 otherwise. */\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342625","messageId":"20180323172121.17725-13-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 12/27] sha1_file: add repository argument to link_alt_odb_entries","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:06Z","receivedAt":"2018-03-23T17:22:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 81ad2a84f2..ba4fc9103b 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -468,8 +468,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 sep,\n-\t\t\t\t const char *relative_base, int depth)\n+#define link_alt_odb_entries(r, a, s, rb, d) \\\n+\tlink_alt_odb_entries_##r(a, s, rb, d)\n+static void link_alt_odb_entries_the_repository(const char *alt,\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@@ -512,7 +516,7 @@ static void read_info_alternates_the_repository(const char *relative_base,\n \t\treturn;\n \t}\n \n-\tlink_alt_odb_entries(buf.buf, '\\n', relative_base, depth);\n+\tlink_alt_odb_entries(the_repository, buf.buf, '\\n', relative_base, depth);\n \tstrbuf_release(&buf);\n \tfree(path);\n }\n@@ -566,7 +570,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, '\\n', NULL, 0);\n+\t\t\tlink_alt_odb_entries(the_repository, reference,\n+\t\t\t\t\t     '\\n', NULL, 0);\n \t}\n \tfree(alts);\n }\n@@ -579,7 +584,8 @@ void add_to_alternates_memory(const char *reference)\n \t */\n \tprepare_alt_odb();\n \n-\tlink_alt_odb_entries(reference, '\\n', NULL, 0);\n+\tlink_alt_odb_entries(the_repository, reference,\n+\t\t\t     '\\n', NULL, 0);\n }\n \n /*\n@@ -678,7 +684,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(the_repository->objects->alternate_db,\n+\tlink_alt_odb_entries(the_repository,\n+\t\t\t     the_repository->objects->alternate_db,\n \t\t\t     PATH_SEP, NULL, 0);\n \n \tread_info_alternates(the_repository, get_object_directory(), 0);\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342626","messageId":"20180323172121.17725-9-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 08/27] pack: move approximate object count to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:02Z","receivedAt":"2018-03-23T17:22:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThe 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>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h |  8 ++++++++\n packfile.c     | 11 +++++------\n 2 files changed, 13 insertions(+), 6 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 6a07a14d63..b53e125902 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -99,6 +99,14 @@ struct raw_object_store {\n \t/* A most-recently-used ordered version of the packed_git list. */\n \tstruct list_head packed_git_mru;\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.\ndiff --git a/packfile.c b/packfile.c\nindex 2a053711cf..b0b24ea9b8 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -803,8 +803,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@@ -814,8 +812,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@@ -825,8 +823,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@@ -901,7 +900,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342627","messageId":"20180323172121.17725-10-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 09/27] sha1_file: add raw_object_store argument to alt_odb_usable","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:03Z","receivedAt":"2018-03-23T17:22:56Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a raw_object_store to alt_odb_usable to be more specific about which\nrepository to act on. The choice of the repository is delegated to its\nonly caller link_alt_odb_entry.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 84b361c125..097c372d03 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -347,7 +347,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+static int alt_odb_usable(struct raw_object_store *o,\n+\t\t\t  struct strbuf *path,\n+\t\t\t  const char *normalized_objdir)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -363,7 +365,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 = the_repository->objects->alt_odb_list; alt; alt = alt->next) {\n+\tfor (alt = o->alt_odb_list; alt; alt = alt->next) {\n \t\tif (!fspathcmp(path->buf, alt->path))\n \t\t\treturn 0;\n \t}\n@@ -415,7 +417,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->objects, &pathbuf, normalized_objdir)) {\n \t\tstrbuf_release(&pathbuf);\n \t\treturn -1;\n \t}\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342628","messageId":"20180323172121.17725-12-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 11/27] sha1_file: add repository argument to read_info_alternates","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:05Z","receivedAt":"2018-03-23T17:23:00Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 7c0ace646a..81ad2a84f2 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -390,7 +390,9 @@ static int alt_odb_usable(struct raw_object_store *o,\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@@ -431,7 +433,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@@ -497,7 +499,8 @@ static void link_alt_odb_entries(const char *alt, 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 *path;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -678,7 +681,7 @@ void prepare_alt_odb(void)\n \tlink_alt_odb_entries(the_repository->objects->alternate_db,\n \t\t\t     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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342629","messageId":"20180323172121.17725-14-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 13/27] sha1_file: add repository argument to prepare_alt_odb","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:07Z","receivedAt":"2018-03-23T17:23:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/fsck.c |  2 +-\n object-store.h |  3 ++-\n packfile.c     |  2 +-\n sha1_file.c    | 12 ++++++------\n sha1_name.c    |  2 +-\n 5 files changed, 11 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 7707407275..3ef25fab97 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -719,7 +719,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)\n \n \t\tfsck_object_dir(get_object_directory());\n \n-\t\tprepare_alt_odb();\n+\t\tprepare_alt_odb(the_repository);\n \t\talt_odb_list = the_repository->objects->alt_odb_list;\n \t\tfor (alt = alt_odb_list; alt; alt = alt->next)\n \t\t\tfsck_object_dir(alt->path);\ndiff --git a/object-store.h b/object-store.h\nindex b53e125902..79de470639 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -20,7 +20,8 @@ struct alternate_object_database {\n \n \tchar path[FLEX_ARRAY];\n };\n-void prepare_alt_odb(void);\n+#define prepare_alt_odb(r) prepare_alt_odb_##r()\n+void prepare_alt_odb_the_repository(void);\n char *compute_alternate_path(const char *path, struct strbuf *err);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n int foreach_alt_odb(alt_odb_fn, void*);\ndiff --git a/packfile.c b/packfile.c\nindex b0b24ea9b8..17170fc662 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -890,7 +890,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 ba4fc9103b..0fac75bd31 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -582,7 +582,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,\n \t\t\t     '\\n', NULL, 0);\n@@ -668,7 +668,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@@ -677,7 +677,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 \tif (the_repository->objects->alt_odb_tail)\n \t\treturn;\n@@ -728,7 +728,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@@ -887,7 +887,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,\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@@ -918,7 +918,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)\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 ffff7d8710..4325f74e0c 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -354,7 +354,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342630","messageId":"20180323172121.17725-19-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 18/27] sha1_file: add repository argument to open_sha1_file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:12Z","receivedAt":"2018-03-23T17:23:06Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 80bac89014..a2ab2b82c3 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -896,7 +896,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@@ -939,7 +941,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342631","messageId":"20180323172121.17725-20-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 19/27] sha1_file: add repository argument to map_sha1_file_1","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:13Z","receivedAt":"2018-03-23T17:23:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?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>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 a2ab2b82c3..4b6144b7cd 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -931,9 +931,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@@ -962,7 +963,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@@ -2192,7 +2193,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342632","messageId":"20180323172121.17725-6-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 05/27] object-store: move packed_git and packed_git_mru to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:20:59Z","receivedAt":"2018-03-23T17:23:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nIn 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\n[nd: while at there, wrap access to these two fields in get_packed_git()\nand get_packed_git_mru(). This allows us to lazily initialize these\nfields without caller doing that explicitly]\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/count-objects.c  |  5 ++--\n builtin/fsck.c           |  6 +++--\n builtin/gc.c             |  4 +++-\n builtin/index-pack.c     |  1 +\n builtin/pack-objects.c   | 21 ++++++++++-------\n builtin/pack-redundant.c |  6 +++--\n cache.h                  | 29 -----------------------\n fast-import.c            |  8 +++++--\n http-backend.c           |  6 +++--\n http-push.c              |  1 +\n http-walker.c            |  1 +\n http.c                   |  1 +\n object-store.h           | 34 +++++++++++++++++++++++++++\n object.c                 |  7 ++++++\n pack-bitmap.c            |  4 +++-\n pack-check.c             |  1 +\n pack-revindex.c          |  1 +\n packfile.c               | 51 ++++++++++++++++++++++++----------------\n packfile.h               |  3 +++\n reachable.c              |  1 +\n server-info.c            |  6 +++--\n sha1_name.c              |  5 ++--\n 22 files changed, 128 insertions(+), 74 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex ced8958e43..b28ff00be2 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -7,6 +7,7 @@\n #include \"cache.h\"\n #include \"config.h\"\n #include \"dir.h\"\n+#include \"repository.h\"\n #include \"builtin.h\"\n #include \"parse-options.h\"\n #include \"quote.h\"\n@@ -121,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 (!get_packed_git(the_repository))\n \t\t\tprepare_packed_git();\n-\t\tfor (p = packed_git; p; p = p->next) {\n+\t\tfor (p = get_packed_git(the_repository); 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 c736a10a11..7707407275 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -732,7 +732,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 = get_packed_git(the_repository); 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@@ -740,7 +741,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 = get_packed_git(the_repository); 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 77fa720bd0..b00238cd5d 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@@ -20,6 +21,7 @@\n #include \"argv-array.h\"\n #include \"commit.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define FAILED_RUN \"failed to run %s\"\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 = get_packed_git(the_repository); 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 5ebd370c56..1d6bc87b76 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -13,6 +13,7 @@\n #include \"streaming.h\"\n #include \"thread-utils.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static const char index_pack_usage[] =\n \"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])\";\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 83dcbc9773..223f2d9fc0 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -1,5 +1,6 @@\n #include \"builtin.h\"\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"config.h\"\n #include \"attr.h\"\n #include \"object.h\"\n@@ -28,6 +29,7 @@\n #include \"argv-array.h\"\n #include \"list.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static const char *pack_usage[] = {\n \tN_(\"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]\"),\n@@ -1025,8 +1027,7 @@ static int want_object_in_pack(const struct object_id *oid,\n \t\tif (want != -1)\n \t\t\treturn want;\n \t}\n-\n-\tlist_for_each(pos, &packed_git_mru) {\n+\tlist_for_each(pos, get_packed_git_mru(the_repository)) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\toff_t offset;\n \n@@ -1044,7 +1045,8 @@ static int want_object_in_pack(const struct object_id *oid,\n \t\t\t}\n \t\t\twant = want_found_object(exclude, p);\n \t\t\tif (!exclude && want > 0)\n-\t\t\t\tlist_move(&p->mru, &packed_git_mru);\n+\t\t\t\tlist_move(&p->mru,\n+\t\t\t\t\t  get_packed_git_mru(the_repository));\n \t\t\tif (want != -1)\n \t\t\t\treturn want;\n \t\t}\n@@ -2673,7 +2675,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 = get_packed_git(the_repository); p; p = p->next) {\n \t\tstruct object_id oid;\n \t\tstruct object *o;\n \n@@ -2736,7 +2738,8 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\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\tget_packed_git(the_repository);\n \n \twhile (p) {\n \t\tif ((!p->pack_local || p->pack_keep) &&\n@@ -2745,7 +2748,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)\n \t\t\treturn 1;\n \t\t}\n \t\tif (p == last_found)\n-\t\t\tp = packed_git;\n+\t\t\tp = get_packed_git(the_repository);\n \t\telse\n \t\t\tp = p->next;\n \t\tif (p == last_found)\n@@ -2781,7 +2784,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 = get_packed_git(the_repository); p; p = p->next) {\n \t\tif (!p->pack_local || p->pack_keep)\n \t\t\tcontinue;\n \n@@ -3152,7 +3155,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 = get_packed_git(the_repository); 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@@ -3165,7 +3168,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 = get_packed_git(the_repository); 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..b5b007e706 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -7,7 +7,9 @@\n */\n \n #include \"builtin.h\"\n+#include \"repository.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define BLKSIZE 512\n \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 = get_packed_git(the_repository);\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 = get_packed_git(the_repository);\n \n \twhile (p) {\n \t\tadd_pack(p);\ndiff --git a/cache.h b/cache.h\nindex 41530d5d16..d3429a0d48 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1585,35 +1585,6 @@ struct pack_window {\n \tunsigned int inuse_cnt;\n };\n \n-extern struct packed_git {\n-\tstruct packed_git *next;\n-\tstruct list_head mru;\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-\t\t pack_promisor: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.\n- */\n-extern struct list_head packed_git_mru;\n-\n struct pack_entry {\n \toff_t offset;\n \tunsigned char sha1[20];\ndiff --git a/fast-import.c b/fast-import.c\nindex b70ac025e0..b3492fce5c 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -154,6 +154,7 @@ 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.h\"\n@@ -168,6 +169,7 @@ Format of STDIN stream:\n #include \"dir.h\"\n #include \"run-command.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #define PACK_ID_BITS 16\n #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)\n@@ -1110,7 +1112,8 @@ 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,\n+\t\t\t\t  get_packed_git(the_repository))) {\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 +1308,8 @@ 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,\n+\t\t\t\t  get_packed_git(the_repository))) {\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 f3dc218b2a..64dde78c1b 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"config.h\"\n+#include \"repository.h\"\n #include \"refs.h\"\n #include \"pkt-line.h\"\n #include \"object.h\"\n@@ -10,6 +11,7 @@\n #include \"url.h\"\n #include \"argv-array.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static const char content_type[] = \"Content-Type\";\n static const char content_length[] = \"Content-Length\";\n@@ -518,13 +520,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 = get_packed_git(the_repository); 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 = get_packed_git(the_repository); 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 0913f8ab86..97fe22a705 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -12,6 +12,7 @@\n #include \"sigchain.h\"\n #include \"argv-array.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n #ifdef EXPAT_NEEDS_XMLPARSE_H\n #include <xmlparse.h>\ndiff --git a/http-walker.c b/http-walker.c\nindex 07c2b1af82..d850408d18 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -5,6 +5,7 @@\n #include \"list.h\"\n #include \"transport.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n struct alt_base {\n \tchar *base;\ndiff --git a/http.c b/http.c\nindex 31755023a4..efa977112a 100644\n--- a/http.c\n+++ b/http.c\n@@ -14,6 +14,7 @@\n #include \"packfile.h\"\n #include \"protocol.h\"\n #include \"string-list.h\"\n+#include \"object-store.h\"\n \n static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);\n static int trace_curl_data = 1;\ndiff --git a/object-store.h b/object-store.h\nindex 0b4db5867d..c687ab7587 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -52,6 +52,30 @@ void add_to_alternates_memory(const char *dir);\n  */\n struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);\n \n+struct packed_git {\n+\tstruct packed_git *next;\n+\tstruct list_head mru;\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+\t\t pack_promisor: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 struct raw_object_store {\n \t/*\n \t * Path to the repository's object store.\n@@ -64,6 +88,16 @@ struct raw_object_store {\n \n \tstruct alternate_object_database *alt_odb_list;\n \tstruct alternate_object_database **alt_odb_tail;\n+\n+\t/*\n+\t * private data\n+\t *\n+\t * should only be accessed directly by packfile.c\n+\t */\n+\n+\tstruct packed_git *packed_git;\n+\t/* A most-recently-used ordered version of the packed_git list. */\n+\tstruct list_head packed_git_mru;\n };\n \n struct raw_object_store *raw_object_store_new(void);\ndiff --git a/object.c b/object.c\nindex 581347b535..04631ee841 100644\n--- a/object.c\n+++ b/object.c\n@@ -452,6 +452,7 @@ struct raw_object_store *raw_object_store_new(void)\n \tstruct raw_object_store *o = xmalloc(sizeof(*o));\n \n \tmemset(o, 0, sizeof(*o));\n+\tINIT_LIST_HEAD(&o->packed_git_mru);\n \treturn o;\n }\n \n@@ -480,4 +481,10 @@ void raw_object_store_clear(struct raw_object_store *o)\n \n \tfree_alt_odbs(o);\n \to->alt_odb_tail = NULL;\n+\n+\tINIT_LIST_HEAD(&o->packed_git_mru);\n+\t/*\n+\t * TODO: call close_all_packs once migrated to\n+\t * take an object store argument\n+\t */\n }\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 9270983e5f..22cd425788 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -10,6 +10,8 @@\n #include \"pack-revindex.h\"\n #include \"pack-objects.h\"\n #include \"packfile.h\"\n+#include \"repository.h\"\n+#include \"object-store.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 = get_packed_git(the_repository); 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..2378f25999 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -3,6 +3,7 @@\n #include \"pack-revindex.h\"\n #include \"progress.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n struct idx_entry {\n \toff_t                offset;\ndiff --git a/pack-revindex.c b/pack-revindex.c\nindex ff5f62c033..bb521cf7fb 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 fdbf240f81..39f4a85200 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -46,8 +46,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-LIST_HEAD(packed_git_mru);\n \n #define SZ_FMT PRIuMAX\n static inline uintmax_t sz_fmt(size_t s) { return s; }\n@@ -247,7 +245,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@@ -317,7 +315,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@@ -385,7 +383,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@@ -687,8 +685,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@@ -770,7 +768,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@@ -821,7 +820,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@@ -870,18 +869,19 @@ 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-\tINIT_LIST_HEAD(&packed_git_mru);\n+\tINIT_LIST_HEAD(&the_repository->objects->packed_git_mru);\n \n-\tfor (p = packed_git; p; p = p->next)\n-\t\tlist_add_tail(&p->mru, &packed_git_mru);\n+\tfor (p = the_repository->objects->packed_git; p; p = p->next)\n+\t\tlist_add_tail(&p->mru, &the_repository->objects->packed_git_mru);\n }\n \n static int prepare_packed_git_run_once = 0;\n@@ -907,6 +907,16 @@ void reprepare_packed_git(void)\n \tprepare_packed_git();\n }\n \n+struct packed_git *get_packed_git(struct repository *r)\n+{\n+\treturn r->objects->packed_git;\n+}\n+\n+struct list_head *get_packed_git_mru(struct repository *r)\n+{\n+\treturn &r->objects->packed_git_mru;\n+}\n+\n unsigned long unpack_object_header_buffer(const unsigned char *buf,\n \t\tunsigned long len, enum object_type *type, unsigned long *sizep)\n {\n@@ -1015,7 +1025,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@@ -1846,13 +1856,14 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n \tstruct list_head *pos;\n \n \tprepare_packed_git();\n-\tif (!packed_git)\n+\tif (!the_repository->objects->packed_git)\n \t\treturn 0;\n \n-\tlist_for_each(pos, &packed_git_mru) {\n+\tlist_for_each(pos, &the_repository->objects->packed_git_mru) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\tif (fill_pack_entry(sha1, e, p)) {\n-\t\t\tlist_move(&p->mru, &packed_git_mru);\n+\t\t\tlist_move(&p->mru,\n+\t\t\t\t  &the_repository->objects->packed_git_mru);\n \t\t\treturn 1;\n \t\t}\n \t}\n@@ -1899,7 +1910,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 ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&\n@@ -1930,7 +1941,7 @@ static int add_promisor_object(const struct object_id *oid,\n \n \t/*\n \t * If this is a tree, commit, or tag, the objects it refers\n-\t * to are also promisor objects. (Blobs refer to no objects.)\n+\t * to are also promisor objects-> (Blobs refer to no objects->)\n \t */\n \tif (obj->type == OBJ_TREE) {\n \t\tstruct tree *tree = (struct tree *)obj;\ndiff --git a/packfile.h b/packfile.h\nindex a7fca598d6..76496226bb 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -38,6 +38,9 @@ extern void prepare_packed_git(void);\n extern void reprepare_packed_git(void);\n extern void install_packed_git(struct packed_git *pack);\n \n+struct packed_git *get_packed_git(struct repository *r);\n+struct list_head *get_packed_git_mru(struct repository *r);\n+\n /*\n  * Give a rough count of objects in the repository. This sacrifices accuracy\n  * for speed.\ndiff --git a/reachable.c b/reachable.c\nindex 88d7d679da..25cfd99d1c 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -11,6 +11,7 @@\n #include \"list-objects.h\"\n #include \"packfile.h\"\n #include \"worktree.h\"\n+#include \"object-store.h\"\n \n struct connectivity_progress {\n \tstruct progress *progress;\ndiff --git a/server-info.c b/server-info.c\nindex 26a6c20b7d..75a8b65e47 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -1,9 +1,11 @@\n #include \"cache.h\"\n+#include \"repository.h\"\n #include \"refs.h\"\n #include \"object.h\"\n #include \"commit.h\"\n #include \"tag.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n /*\n  * Create the file \"path\" by writing to a temporary file and renaming\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 = get_packed_git(the_repository); 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 = get_packed_git(the_repository); 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 a22a29cda0..ffff7d8710 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -197,7 +197,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 = get_packed_git(the_repository); p && !ds->ambiguous;\n+\t     p = p->next)\n \t\tunique_in_pack(p, ds);\n }\n \n@@ -567,7 +568,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n \tstruct packed_git *p;\n \n \tprepare_packed_git();\n-\tfor (p = packed_git; p; p = p->next)\n+\tfor (p = get_packed_git(the_repository); p; p = p->next)\n \t\tfind_abbrev_len_for_pack(p, mad);\n }\n \n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342633","messageId":"20180323172121.17725-7-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 06/27] object-store: close all packs upon clearing the object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:00Z","receivedAt":"2018-03-23T17:23:17Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/am.c           | 2 +-\n builtin/clone.c        | 2 +-\n builtin/fetch.c        | 2 +-\n builtin/merge.c        | 2 +-\n builtin/receive-pack.c | 2 +-\n object.c               | 7 +++----\n packfile.c             | 4 ++--\n packfile.h             | 2 +-\n 8 files changed, 11 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 5bdd2d7578..47beddbe24 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1859,7 +1859,7 @@ static void am_run(struct am_state *state, int resume)\n \t */\n \tif (!state->rebasing) {\n \t\tam_destroy(state);\n-\t\tclose_all_packs();\n+\t\tclose_all_packs(the_repository->objects);\n \t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n \t}\n }\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 855947f1ab..7df5932b85 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -1218,7 +1218,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \ttransport_disconnect(transport);\n \n \tif (option_dissociate) {\n-\t\tclose_all_packs();\n+\t\tclose_all_packs(the_repository->objects);\n \t\tdissociate_from_references();\n \t}\n \ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 8ee998ea2e..a39e9d7b15 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -1478,7 +1478,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \n \tstring_list_clear(&list, 0);\n \n-\tclose_all_packs();\n+\tclose_all_packs(the_repository->objects);\n \n \targv_array_pushl(&argv_gc_auto, \"gc\", \"--auto\", NULL);\n \tif (verbosity < 0)\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 30264cfd7c..96d56cbdd2 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -411,7 +411,7 @@ static void finish(struct commit *head_commit,\n \t\t\t * We ignore errors in 'gc --auto', since the\n \t\t\t * user should see them.\n \t\t\t */\n-\t\t\tclose_all_packs();\n+\t\t\tclose_all_packs(the_repository->objects);\n \t\t\trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n \t\t}\n \t}\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex b7ce7c7f52..1a298a6711 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2026,7 +2026,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\t\tproc.git_cmd = 1;\n \t\t\tproc.argv = argv_gc_auto;\n \n-\t\t\tclose_all_packs();\n+\t\t\tclose_all_packs(the_repository->objects);\n \t\t\tif (!start_command(&proc)) {\n \t\t\t\tif (use_sideband)\n \t\t\t\t\tcopy_to_sideband(proc.err, -1, NULL);\ndiff --git a/object.c b/object.c\nindex 04631ee841..4c2cf7ff5d 100644\n--- a/object.c\n+++ b/object.c\n@@ -5,6 +5,7 @@\n #include \"commit.h\"\n #include \"tag.h\"\n #include \"object-store.h\"\n+#include \"packfile.h\"\n \n static struct object **obj_hash;\n static int nr_objs, obj_hash_size;\n@@ -483,8 +484,6 @@ void raw_object_store_clear(struct raw_object_store *o)\n \to->alt_odb_tail = NULL;\n \n \tINIT_LIST_HEAD(&o->packed_git_mru);\n-\t/*\n-\t * TODO: call close_all_packs once migrated to\n-\t * take an object store argument\n-\t */\n+\tclose_all_packs(o);\n+\to->packed_git = NULL;\n }\ndiff --git a/packfile.c b/packfile.c\nindex 39f4a85200..f2dc084745 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -311,11 +311,11 @@ static void close_pack(struct packed_git *p)\n \tclose_pack_index(p);\n }\n \n-void close_all_packs(void)\n+void close_all_packs(struct raw_object_store *o)\n {\n \tstruct packed_git *p;\n \n-\tfor (p = the_repository->objects->packed_git; p; p = p->next)\n+\tfor (p = o->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\ndiff --git a/packfile.h b/packfile.h\nindex 76496226bb..5b1ce00f84 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -66,7 +66,7 @@ extern void close_pack_index(struct packed_git *);\n \n extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);\n extern void close_pack_windows(struct packed_git *);\n-extern void close_all_packs(void);\n+extern void close_all_packs(struct raw_object_store *o);\n extern void unuse_pack(struct pack_window **);\n extern void clear_delta_base_cache(void);\n extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342634","messageId":"20180323172121.17725-8-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 07/27] pack: move prepare_packed_git_run_once to object store","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:21:01Z","receivedAt":"2018-03-23T17:23:19Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nEach 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>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object-store.h | 6 ++++++\n packfile.c     | 7 +++----\n 2 files changed, 9 insertions(+), 4 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex c687ab7587..6a07a14d63 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -98,6 +98,12 @@ struct raw_object_store {\n \tstruct packed_git *packed_git;\n \t/* A most-recently-used ordered version of the packed_git list. */\n \tstruct list_head packed_git_mru;\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 \n struct raw_object_store *raw_object_store_new(void);\ndiff --git a/packfile.c b/packfile.c\nindex f2dc084745..2a053711cf 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -884,12 +884,11 @@ static void prepare_packed_git_mru(void)\n \t\tlist_add_tail(&p->mru, &the_repository->objects->packed_git_mru);\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@@ -897,13 +896,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342635","messageId":"20180323172121.17725-2-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"[PATCH 01/27] repository: introduce raw object store field","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:20:55Z","receivedAt":"2018-03-23T17:23:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThe raw object store field will contain any objects needed for access\nto objects in a given repository.\n\nThis patch introduces the raw object store and populates it with the\n`objectdir`, which used to be part of the repository struct.\n\nAs the struct gains members, we'll also populate the function to clear\nthe memory for these members.\n\nIn a later step, we'll introduce a struct object_parser, that will\ncomplement the object parsing in a repository struct: The raw object\nparser is the layer that will provide access to raw object content,\nwhile the higher level object parser code will parse raw objects and\nkeeps track of parenthood and other object relationships using 'struct\nobject'.  For now only add the lower level to the repository struct.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/grep.c |  3 ++-\n environment.c  |  5 +++--\n object-store.h | 18 ++++++++++++++++++\n object.c       | 14 ++++++++++++++\n path.c         |  3 ++-\n repository.c   | 15 ++++++++++-----\n repository.h   | 11 ++++-------\n sha1_file.c    |  4 +++-\n 8 files changed, 56 insertions(+), 17 deletions(-)\n create mode 100644 object-store.h\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 3ca4ac80d8..1e9cdbdf78 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -22,6 +22,7 @@\n #include \"pathspec.h\"\n #include \"submodule.h\"\n #include \"submodule-config.h\"\n+#include \"object-store.h\"\n \n static char const * const grep_usage[] = {\n \tN_(\"git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]\"),\n@@ -432,7 +433,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,\n \t * object.\n \t */\n \tgrep_read_lock();\n-\tadd_to_alternates_memory(submodule.objectdir);\n+\tadd_to_alternates_memory(submodule.objects->objectdir);\n \tgrep_read_unlock();\n \n \tif (oid) {\ndiff --git a/environment.c b/environment.c\nindex a5eaa97fb1..93c9fbb0ba 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -14,6 +14,7 @@\n #include \"fmt-merge-msg.h\"\n #include \"commit.h\"\n #include \"argv-array.h\"\n+#include \"object-store.h\"\n \n int trust_executable_bit = 1;\n int trust_ctime = 1;\n@@ -270,9 +271,9 @@ const char *get_git_work_tree(void)\n \n char *get_object_directory(void)\n {\n-\tif (!the_repository->objectdir)\n+\tif (!the_repository->objects->objectdir)\n \t\tBUG(\"git environment hasn't been setup\");\n-\treturn the_repository->objectdir;\n+\treturn the_repository->objects->objectdir;\n }\n \n int odb_mkstemp(struct strbuf *template, const char *pattern)\ndiff --git a/object-store.h b/object-store.h\nnew file mode 100644\nindex 0000000000..abfaae059b\n--- /dev/null\n+++ b/object-store.h\n@@ -0,0 +1,18 @@\n+#ifndef OBJECT_STORE_H\n+#define OBJECT_STORE_H\n+\n+struct raw_object_store {\n+\t/*\n+\t * Path to the repository's object store.\n+\t * Cannot be NULL after initialization.\n+\t */\n+\tchar *objectdir;\n+\n+\t/* Path to extra alternate object database if not NULL */\n+\tchar *alternate_db;\n+};\n+\n+struct raw_object_store *raw_object_store_new(void);\n+void raw_object_store_clear(struct raw_object_store *o);\n+\n+#endif /* OBJECT_STORE_H */\ndiff --git a/object.c b/object.c\nindex 9e6f9ff20b..6ddd61242c 100644\n--- a/object.c\n+++ b/object.c\n@@ -4,6 +4,7 @@\n #include \"tree.h\"\n #include \"commit.h\"\n #include \"tag.h\"\n+#include \"object-store.h\"\n \n static struct object **obj_hash;\n static int nr_objs, obj_hash_size;\n@@ -445,3 +446,16 @@ void clear_commit_marks_all(unsigned int flags)\n \t\t\tobj->flags &= ~flags;\n \t}\n }\n+\n+struct raw_object_store *raw_object_store_new(void)\n+{\n+\tstruct raw_object_store *o = xmalloc(sizeof(*o));\n+\n+\tmemset(o, 0, sizeof(*o));\n+\treturn o;\n+}\n+void raw_object_store_clear(struct raw_object_store *o)\n+{\n+\tFREE_AND_NULL(o->objectdir);\n+\tFREE_AND_NULL(o->alternate_db);\n+}\ndiff --git a/path.c b/path.c\nindex da8b655730..3308b7b958 100644\n--- a/path.c\n+++ b/path.c\n@@ -10,6 +10,7 @@\n #include \"submodule-config.h\"\n #include \"path.h\"\n #include \"packfile.h\"\n+#include \"object-store.h\"\n \n static int get_st_mode_bits(const char *path, int *mode)\n {\n@@ -382,7 +383,7 @@ static void adjust_git_path(const struct repository *repo,\n \t\tstrbuf_splice(buf, 0, buf->len,\n \t\t\t      repo->index_file, strlen(repo->index_file));\n \telse if (dir_prefix(base, \"objects\"))\n-\t\treplace_dir(buf, git_dir_len + 7, repo->objectdir);\n+\t\treplace_dir(buf, git_dir_len + 7, repo->objects->objectdir);\n \telse if (git_hooks_path && dir_prefix(base, \"hooks\"))\n \t\treplace_dir(buf, git_dir_len + 5, git_hooks_path);\n \telse if (repo->different_commondir)\ndiff --git a/repository.c b/repository.c\nindex 62f52f47fc..a4848c1bd0 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"repository.h\"\n+#include \"object-store.h\"\n #include \"config.h\"\n #include \"submodule-config.h\"\n \n@@ -12,6 +13,7 @@ void initialize_the_repository(void)\n \tthe_repository = &the_repo;\n \n \tthe_repo.index = &the_index;\n+\tthe_repo.objects = raw_object_store_new();\n \trepo_set_hash_algo(&the_repo, GIT_HASH_SHA1);\n }\n \n@@ -58,10 +60,10 @@ void repo_set_gitdir(struct repository *repo,\n \tfree(old_gitdir);\n \n \trepo_set_commondir(repo, o->commondir);\n-\texpand_base_dir(&repo->objectdir, o->object_dir,\n+\texpand_base_dir(&repo->objects->objectdir, o->object_dir,\n \t\t\trepo->commondir, \"objects\");\n-\tfree(repo->alternate_db);\n-\trepo->alternate_db = xstrdup_or_null(o->alternate_db);\n+\tfree(repo->objects->alternate_db);\n+\trepo->objects->alternate_db = xstrdup_or_null(o->alternate_db);\n \texpand_base_dir(&repo->graft_file, o->graft_file,\n \t\t\trepo->commondir, \"info/grafts\");\n \texpand_base_dir(&repo->index_file, o->index_file,\n@@ -140,6 +142,8 @@ static int repo_init(struct repository *repo,\n \tstruct repository_format format;\n \tmemset(repo, 0, sizeof(*repo));\n \n+\trepo->objects = raw_object_store_new();\n+\n \tif (repo_init_gitdir(repo, gitdir))\n \t\tgoto error;\n \n@@ -214,13 +218,14 @@ void repo_clear(struct repository *repo)\n {\n \tFREE_AND_NULL(repo->gitdir);\n \tFREE_AND_NULL(repo->commondir);\n-\tFREE_AND_NULL(repo->objectdir);\n-\tFREE_AND_NULL(repo->alternate_db);\n \tFREE_AND_NULL(repo->graft_file);\n \tFREE_AND_NULL(repo->index_file);\n \tFREE_AND_NULL(repo->worktree);\n \tFREE_AND_NULL(repo->submodule_prefix);\n \n+\traw_object_store_clear(repo->objects);\n+\tFREE_AND_NULL(repo->objects);\n+\n \tif (repo->config) {\n \t\tgit_configset_clear(repo->config);\n \t\tFREE_AND_NULL(repo->config);\ndiff --git a/repository.h b/repository.h\nindex e7127baffb..abba2c09bc 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -2,9 +2,10 @@\n #define REPOSITORY_H\n \n struct config_set;\n+struct git_hash_algo;\n struct index_state;\n+struct raw_object_store;\n struct submodule_cache;\n-struct git_hash_algo;\n \n struct repository {\n \t/* Environment */\n@@ -21,13 +22,9 @@ struct repository {\n \tchar *commondir;\n \n \t/*\n-\t * Path to the repository's object store.\n-\t * Cannot be NULL after initialization.\n+\t * Holds any information related to accessing the raw object content.\n \t */\n-\tchar *objectdir;\n-\n-\t/* Path to extra alternate object database if not NULL */\n-\tchar *alternate_db;\n+\tstruct raw_object_store *objects;\n \n \t/*\n \t * Path to the repository's graft file.\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 4af422e3cf..af5aa83db5 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -29,6 +29,7 @@\n #include \"quote.h\"\n #include \"packfile.h\"\n #include \"fetch-object.h\"\n+#include \"object-store.h\"\n \n const unsigned char null_sha1[GIT_MAX_RAWSZ];\n const struct object_id null_oid;\n@@ -671,7 +672,8 @@ void prepare_alt_odb(void)\n \t\treturn;\n \n \talt_odb_tail = &alt_odb_list;\n-\tlink_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);\n+\tlink_alt_odb_entries(the_repository->objects->alternate_db,\n+\t\t\t     PATH_SEP, NULL, 0);\n \n \tread_info_alternates(get_object_directory(), 0);\n }\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342641","messageId":"20180323174527.30337-1-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180303113637.26518-1-pclouds@gmail.com","subject":"[PATCH 00/12] sb/packfiles-in-repository updates","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:15Z","receivedAt":"2018-03-23T17:45:47Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This is the rebased version on the updated sb/object-store I just sent\nout plus the fix for get_object_directory(). The interdiff (after\nrebased) looks small and nice\n\ndiff --git a/packfile.c b/packfile.c\nindex e02136bebb..63c89ee31a 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -890,7 +890,7 @@ static void prepare_packed_git(struct repository *r)\n \n \tif (r->objects->packed_git_initialized)\n \t\treturn;\n-\tprepare_packed_git_one(r, get_object_directory(), 1);\n+\tprepare_packed_git_one(r, r->objects->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\nI notice there's still one get_object_directory() left in packfile.c\nbut that should not cause problems with converted functions. That\ncould be done in \"phase 2\".\n\nNguyễn Thái Ngọc Duy (1):\n  packfile: keep prepare_packed_git() private\n\nStefan Beller (11):\n  packfile: allow prepare_packed_git_mru to handle arbitrary\n    repositories\n  packfile: allow rearrange_packed_git to handle arbitrary repositories\n  packfile: allow install_packed_git to handle arbitrary repositories\n  packfile: add repository argument to prepare_packed_git_one\n  packfile: add repository argument to prepare_packed_git\n  packfile: add repository argument to reprepare_packed_git\n  packfile: allow prepare_packed_git_one to handle arbitrary\n    repositories\n  packfile: allow prepare_packed_git to handle arbitrary repositories\n  packfile: allow reprepare_packed_git to handle arbitrary repositories\n  packfile: add repository argument to find_pack_entry\n  packfile: allow find_pack_entry to handle arbitrary repositories\n\n builtin/count-objects.c  |  3 +-\n builtin/fsck.c           |  2 --\n builtin/gc.c             |  3 +-\n builtin/pack-objects.c   |  1 -\n builtin/pack-redundant.c |  2 --\n builtin/receive-pack.c   |  3 +-\n bulk-checkin.c           |  3 +-\n fast-import.c            |  3 +-\n fetch-pack.c             |  3 +-\n http-backend.c           |  1 -\n http.c                   |  2 +-\n pack-bitmap.c            |  1 -\n packfile.c               | 76 +++++++++++++++++++---------------------\n packfile.h               | 11 +++---\n server-info.c            |  1 -\n sha1_file.c              |  8 ++---\n sha1_name.c              |  2 --\n 17 files changed, 58 insertions(+), 67 deletions(-)\n\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342642","messageId":"20180323174527.30337-2-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 01/12] packfile: allow prepare_packed_git_mru to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:16Z","receivedAt":"2018-03-23T17:45:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThis conversion was done without the #define trick used in the earlier\nseries refactoring to have better repository access, because this function\nis easy to review, as all lines are converted and it has only one caller\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n packfile.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 17170fc662..8c335bdcd1 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -873,14 +873,14 @@ static void rearrange_packed_git(void)\n \t\tset_next_packed_git, sort_pack);\n }\n \n-static void prepare_packed_git_mru(void)\n+static void prepare_packed_git_mru(struct repository *r)\n {\n \tstruct packed_git *p;\n \n-\tINIT_LIST_HEAD(&the_repository->objects->packed_git_mru);\n+\tINIT_LIST_HEAD(&r->objects->packed_git_mru);\n \n-\tfor (p = the_repository->objects->packed_git; p; p = p->next)\n-\t\tlist_add_tail(&p->mru, &the_repository->objects->packed_git_mru);\n+\tfor (p = r->objects->packed_git; p; p = p->next)\n+\t\tlist_add_tail(&p->mru, &r->objects->packed_git_mru);\n }\n \n void prepare_packed_git(void)\n@@ -894,7 +894,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(alt->path, 0);\n \trearrange_packed_git();\n-\tprepare_packed_git_mru();\n+\tprepare_packed_git_mru(the_repository);\n \tthe_repository->objects->packed_git_initialized = 1;\n }\n \n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342643","messageId":"20180323174527.30337-3-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 02/12] packfile: allow rearrange_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:17Z","receivedAt":"2018-03-23T17:45:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n packfile.c | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 8c335bdcd1..bff22a8c81 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -866,10 +866,10 @@ static int sort_pack(const void *a_, const void *b_)\n \treturn -1;\n }\n \n-static void rearrange_packed_git(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@@ -893,7 +893,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(alt->path, 0);\n-\trearrange_packed_git();\n+\trearrange_packed_git(the_repository);\n \tprepare_packed_git_mru(the_repository);\n \tthe_repository->objects->packed_git_initialized = 1;\n }\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342644","messageId":"20180323174527.30337-7-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 06/12] packfile: add repository argument to reprepare_packed_git","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:21Z","receivedAt":"2018-03-23T17:45:57Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSee previous patch for explanation.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/gc.c           | 2 +-\n builtin/receive-pack.c | 3 ++-\n bulk-checkin.c         | 3 ++-\n fetch-pack.c           | 3 ++-\n packfile.c             | 2 +-\n packfile.h             | 3 ++-\n sha1_file.c            | 2 +-\n 7 files changed, 11 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 4c7409946e..a78dad51aa 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -478,7 +478,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 1a298a6711..469b916707 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@@ -1777,7 +1778,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 3310fd210a..eadc2d5172 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/fetch-pack.c b/fetch-pack.c\nindex 8253d746e0..eac5928a27 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@@ -1192,7 +1193,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 bb090f8a29..1b4296277a 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -899,7 +899,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 3f59456e7e..ab5046938c 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -36,7 +36,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 extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \n struct packed_git *get_packed_git(struct repository *r);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 0989bbd948..9c024cd957 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1274,7 +1274,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \t\t\treturn 0;\n \n \t\t/* Not a loose object; someone else may have just packed it. */\n-\t\treprepare_packed_git();\n+\t\treprepare_packed_git(the_repository);\n \t\tif (find_pack_entry(real, &e))\n \t\t\tbreak;\n \n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342645","messageId":"20180323174527.30337-9-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 08/12] packfile: allow prepare_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:23Z","receivedAt":"2018-03-23T17:45:59Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 f49902539b..ad90c61422 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -883,19 +883,19 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tlist_add_tail(&p->mru, &r->objects->packed_git_mru);\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->objects->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 ab5046938c..3fd9092472 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,8 +34,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342646","messageId":"20180323174527.30337-4-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 03/12] packfile: allow install_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:18Z","receivedAt":"2018-03-23T17:46:03Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nThis conversion was done without the #define trick used in the earlier\nseries refactoring to have better repository access, because this function\nis easy to review, as it only has one caller and all lines but the first\ntwo are converted.\n\nWe must not convert 'pack_open_fds' to be a repository specific variable,\nas it is used to monitor resource usage of the machine that Git executes\non.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n fast-import.c | 2 +-\n http.c        | 2 +-\n packfile.c    | 8 ++++----\n packfile.h    | 2 +-\n 4 files changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/fast-import.c b/fast-import.c\nindex b3492fce5c..ae4ced3ae1 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 4d613d5f6b..111e3c12c8 100644\n--- a/http.c\n+++ b/http.c\n@@ -2134,7 +2134,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 bff22a8c81..ff302142c7 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -680,13 +680,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(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);\n@@ -782,7 +782,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 5b1ce00f84..77442172f0 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -36,7 +36,7 @@ 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+extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \n struct packed_git *get_packed_git(struct repository *r);\n struct list_head *get_packed_git_mru(struct repository *r);\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342647","messageId":"20180323174527.30337-10-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 09/12] packfile: allow reprepare_packed_git to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:24Z","receivedAt":"2018-03-23T17:46:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.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 ad90c61422..eb2dc53331 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -898,11 +898,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 struct packed_git *get_packed_git(struct repository *r)\ndiff --git a/packfile.h b/packfile.h\nindex 3fd9092472..ee6da3a9ae 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -35,8 +35,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 struct packed_git *get_packed_git(struct repository *r);\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342648","messageId":"20180323174527.30337-8-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 07/12] packfile: allow prepare_packed_git_one to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:22Z","receivedAt":"2018-03-23T17:46:06Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n packfile.c | 7 +++----\n 1 file changed, 3 insertions(+), 4 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 1b4296277a..f49902539b 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -735,8 +735,7 @@ 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, char *objdir, int local)\n {\n \tstruct strbuf path = STRBUF_INIT;\n \tsize_t dirnamelen;\n@@ -769,7 +768,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\tfor (p = r->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@@ -783,7 +782,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.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342649","messageId":"20180323174527.30337-6-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 05/12] packfile: add repository argument to prepare_packed_git","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:20Z","receivedAt":"2018-03-23T17:46:08Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nAdd a repository argument to allow prepare_packed_git callers to be\nmore specific about which repository to handle. See commit \"sha1_file:\nadd repository argument to link_alt_odb_entry\" for an explanation of\nthe #define trick.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@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 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              |  4 ++--\n 12 files changed, 18 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex b28ff00be2..ea8bd9e2e2 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 (!get_packed_git(the_repository))\n-\t\t\tprepare_packed_git();\n+\t\t\tprepare_packed_git(the_repository);\n \t\tfor (p = get_packed_git(the_repository); 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 3ef25fab97..d40a82b702 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -729,7 +729,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 = get_packed_git(the_repository); p;\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex b00238cd5d..4c7409946e 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 = get_packed_git(the_repository); 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 223f2d9fc0..491ce433da 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -3152,7 +3152,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 = get_packed_git(the_repository); p; p = p->next)\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex b5b007e706..da6637f7fc 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/fast-import.c b/fast-import.c\nindex ae4ced3ae1..47981e6db7 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -3473,7 +3473,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 64dde78c1b..c1b1c2d557 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -519,7 +519,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 = get_packed_git(the_repository); 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 22cd425788..57fec38f3f 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 = get_packed_git(the_repository); 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 0e5fa67526..bb090f8a29 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -817,7 +817,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@@ -884,7 +884,7 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tlist_add_tail(&p->mru, &r->objects->packed_git_mru);\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@@ -903,7 +903,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 struct packed_git *get_packed_git(struct repository *r)\n@@ -1854,7 +1854,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n {\n \tstruct list_head *pos;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tif (!the_repository->objects->packed_git)\n \t\treturn 0;\n \n@@ -1908,7 +1908,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 77442172f0..3f59456e7e 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,7 +34,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 extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \ndiff --git a/server-info.c b/server-info.c\nindex 75a8b65e47..bf5c325867 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 = get_packed_git(the_repository); 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 4325f74e0c..e0b62f3c56 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -196,7 +196,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 = get_packed_git(the_repository); p && !ds->ambiguous;\n \t     p = p->next)\n \t\tunique_in_pack(p, ds);\n@@ -567,7 +567,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git();\n+\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); p; p = p->next)\n \t\tfind_abbrev_len_for_pack(p, mad);\n }\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342650","messageId":"20180323174527.30337-11-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 10/12] packfile: add repository argument to find_pack_entry","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:25Z","receivedAt":"2018-03-23T17:46:12Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nWhile at it move the documentation to the header and mention which pack\nfiles are searched.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n packfile.c  | 8 ++------\n packfile.h  | 7 ++++++-\n sha1_file.c | 6 +++---\n 3 files changed, 11 insertions(+), 10 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex eb2dc53331..26d5a17dfe 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1845,11 +1845,7 @@ static int fill_pack_entry(const unsigned char *sha1,\n \treturn 1;\n }\n \n-/*\n- * Iff a pack file contains the object named by sha1, return true and\n- * store its location to e.\n- */\n-int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n+int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e)\n {\n \tstruct list_head *pos;\n \n@@ -1871,7 +1867,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)\n int has_sha1_pack(const unsigned char *sha1)\n {\n \tstruct pack_entry e;\n-\treturn find_pack_entry(sha1, &e);\n+\treturn find_pack_entry(the_repository, sha1, &e);\n }\n \n int has_pack_index(const unsigned char *sha1)\ndiff --git a/packfile.h b/packfile.h\nindex ee6da3a9ae..e68f790ea7 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -123,7 +123,12 @@ extern int packed_object_info(struct packed_git *pack, off_t offset, struct obje\n extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);\n extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);\n \n-extern int find_pack_entry(const unsigned char *sha1, struct pack_entry *e);\n+/*\n+ * Iff a pack file in the given repository contains the object named by sha1,\n+ * return true and store its location to e.\n+ */\n+#define find_pack_entry(r, s, e) find_pack_entry_##r(s, e)\n+extern int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e);\n \n extern int has_sha1_pack(const unsigned char *sha1);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex 9c024cd957..314ff55b47 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1266,7 +1266,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \t}\n \n \twhile (1) {\n-\t\tif (find_pack_entry(real, &e))\n+\t\tif (find_pack_entry(the_repository, real, &e))\n \t\t\tbreak;\n \n \t\t/* Most likely it's a loose object. */\n@@ -1275,7 +1275,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,\n \n \t\t/* Not a loose object; someone else may have just packed it. */\n \t\treprepare_packed_git(the_repository);\n-\t\tif (find_pack_entry(real, &e))\n+\t\tif (find_pack_entry(the_repository, real, &e))\n \t\t\tbreak;\n \n \t\t/* Check if it is a missing object */\n@@ -1655,7 +1655,7 @@ static int freshen_loose_object(const unsigned char *sha1)\n static int freshen_packed_object(const unsigned char *sha1)\n {\n \tstruct pack_entry e;\n-\tif (!find_pack_entry(sha1, &e))\n+\tif (!find_pack_entry(the_repository, sha1, &e))\n \t\treturn 0;\n \tif (e.p->freshened)\n \t\treturn 1;\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342651","messageId":"20180323174527.30337-12-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 11/12] packfile: allow find_pack_entry to handle arbitrary repositories","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:26Z","receivedAt":"2018-03-23T17:46:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n packfile.c | 11 +++++------\n packfile.h |  3 +--\n 2 files changed, 6 insertions(+), 8 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 26d5a17dfe..89bd0d47bf 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1845,19 +1845,18 @@ static int fill_pack_entry(const unsigned char *sha1,\n \treturn 1;\n }\n \n-int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e)\n+int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e)\n {\n \tstruct list_head *pos;\n \n-\tprepare_packed_git(the_repository);\n-\tif (!the_repository->objects->packed_git)\n+\tprepare_packed_git(r);\n+\tif (!r->objects->packed_git)\n \t\treturn 0;\n \n-\tlist_for_each(pos, &the_repository->objects->packed_git_mru) {\n+\tlist_for_each(pos, &r->objects->packed_git_mru) {\n \t\tstruct packed_git *p = list_entry(pos, struct packed_git, mru);\n \t\tif (fill_pack_entry(sha1, e, p)) {\n-\t\t\tlist_move(&p->mru,\n-\t\t\t\t  &the_repository->objects->packed_git_mru);\n+\t\t\tlist_move(&p->mru, &r->objects->packed_git_mru);\n \t\t\treturn 1;\n \t\t}\n \t}\ndiff --git a/packfile.h b/packfile.h\nindex e68f790ea7..fe1a6380e6 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -127,8 +127,7 @@ extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);\n  * Iff a pack file in the given repository contains the object named by sha1,\n  * return true and store its location to e.\n  */\n-#define find_pack_entry(r, s, e) find_pack_entry_##r(s, e)\n-extern int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e);\n+extern int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e);\n \n extern int has_sha1_pack(const unsigned char *sha1);\n \n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342652","messageId":"20180323174527.30337-13-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 12/12] packfile: keep prepare_packed_git() private","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:27Z","receivedAt":"2018-03-23T17:46:17Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The reason callers have to call this is to make sure either packed_git\nor packed_git_mru pointers are initialized since we don't do that by\ndefault. Sometimes it's hard to see this connection between where the\nfunction is called and where packed_git pointer is used (sometimes in\nseparate functions).\n\nKeep this dependency internal because now all access to packed_git and\npacked_git_mru must go through get_xxx() wrappers.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/count-objects.c  | 3 +--\n builtin/fsck.c           | 2 --\n builtin/gc.c             | 1 -\n builtin/pack-objects.c   | 1 -\n builtin/pack-redundant.c | 2 --\n fast-import.c            | 1 -\n http-backend.c           | 1 -\n pack-bitmap.c            | 1 -\n packfile.c               | 5 ++++-\n packfile.h               | 1 -\n server-info.c            | 1 -\n sha1_name.c              | 2 --\n 12 files changed, 5 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/count-objects.c b/builtin/count-objects.c\nindex ea8bd9e2e2..b054713e1a 100644\n--- a/builtin/count-objects.c\n+++ b/builtin/count-objects.c\n@@ -122,8 +122,7 @@ 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 (!get_packed_git(the_repository))\n-\t\t\tprepare_packed_git(the_repository);\n+\n \t\tfor (p = get_packed_git(the_repository); 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 d40a82b702..f9632353d9 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -729,8 +729,6 @@ 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(the_repository);\n-\n \t\t\tif (show_progress) {\n \t\t\t\tfor (p = get_packed_git(the_repository); p;\n \t\t\t\t     p = p->next) {\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex a78dad51aa..0a667972ab 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -174,7 +174,6 @@ static int too_many_packs(void)\n \tif (gc_auto_pack_limit <= 0)\n \t\treturn 0;\n \n-\tprepare_packed_git(the_repository);\n \tfor (cnt = 0, p = get_packed_git(the_repository); 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 491ce433da..2f49b03cb1 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -3152,7 +3152,6 @@ 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(the_repository);\n \tif (ignore_packed_keep) {\n \t\tstruct packed_git *p;\n \t\tfor (p = get_packed_git(the_repository); p; p = p->next)\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex da6637f7fc..710cd0fb69 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -631,8 +631,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)\n \t\t\tbreak;\n \t}\n \n-\tprepare_packed_git(the_repository);\n-\n \tif (load_all_packs)\n \t\tload_all();\n \telse\ndiff --git a/fast-import.c b/fast-import.c\nindex 47981e6db7..37a44752a8 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -3473,7 +3473,6 @@ 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(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 c1b1c2d557..88d2a9bc40 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -519,7 +519,6 @@ static void get_info_packs(struct strbuf *hdr, char *arg)\n \tsize_t cnt = 0;\n \n \tselect_getanyfile(hdr);\n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); 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 57fec38f3f..3f2dab340f 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -336,7 +336,6 @@ static int open_pack_bitmap(void)\n \n \tassert(!bitmap_git.map && !bitmap_git.loaded);\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); 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 89bd0d47bf..63c89ee31a 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -803,6 +803,7 @@ static void prepare_packed_git_one(struct repository *r, char *objdir, int local\n \tstrbuf_release(&path);\n }\n \n+static void prepare_packed_git(struct repository *r);\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@@ -883,7 +884,7 @@ static void prepare_packed_git_mru(struct repository *r)\n \t\tlist_add_tail(&p->mru, &r->objects->packed_git_mru);\n }\n \n-void prepare_packed_git(struct repository *r)\n+static void prepare_packed_git(struct repository *r)\n {\n \tstruct alternate_object_database *alt;\n \n@@ -907,11 +908,13 @@ void reprepare_packed_git(struct repository *r)\n \n struct packed_git *get_packed_git(struct repository *r)\n {\n+\tprepare_packed_git(r);\n \treturn r->objects->packed_git;\n }\n \n struct list_head *get_packed_git_mru(struct repository *r)\n {\n+\tprepare_packed_git(r);\n \treturn &r->objects->packed_git_mru;\n }\n \ndiff --git a/packfile.h b/packfile.h\nindex fe1a6380e6..efda10329c 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -34,7 +34,6 @@ 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(struct repository *r);\n extern void reprepare_packed_git(struct repository *r);\n extern void install_packed_git(struct repository *r, struct packed_git *pack);\n \ndiff --git a/server-info.c b/server-info.c\nindex bf5c325867..83460ec0d6 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -201,7 +201,6 @@ static void init_pack_info(const char *infofile, int force)\n \tobjdir = get_object_directory();\n \tobjdirlen = strlen(objdir);\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); 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 e0b62f3c56..31c013ac7e 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -196,7 +196,6 @@ static void find_short_packed_object(struct disambiguate_state *ds)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); p && !ds->ambiguous;\n \t     p = p->next)\n \t\tunique_in_pack(p, ds);\n@@ -567,7 +566,6 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)\n {\n \tstruct packed_git *p;\n \n-\tprepare_packed_git(the_repository);\n \tfor (p = get_packed_git(the_repository); p; p = p->next)\n \t\tfind_abbrev_len_for_pack(p, mad);\n }\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342653","messageId":"20180323174527.30337-5-pclouds@gmail.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"[PATCH 04/12] packfile: add repository argument to prepare_packed_git_one","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T17:45:19Z","receivedAt":"2018-03-23T17:46:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Stefan Beller <sbeller@google.com>\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n packfile.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex ff302142c7..0e5fa67526 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -735,7 +735,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@@ -889,10 +890,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(the_repository);\n \tprepare_packed_git_mru(the_repository);\n \tthe_repository->objects->packed_git_initialized = 1;\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n"},{"id":"342660","messageId":"20180323182836.GA243756@google.com","threadId":"47963","inReplyTo":"CACsJy8BcHdvUn5VPc9+mzE1SpvsJG-P2iUW=jg2VD5YhU4kVJg@mail.gmail.com","subject":"Re: [PATCH 10/44] object-store: move packed_git and packed_git_mru to object store","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-23T18:28:36Z","receivedAt":"2018-03-23T18:28:43Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/23, Duy Nguyen wrote:\n> On Fri, Mar 23, 2018 at 6:03 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> > On Wed, Mar 21, 2018 at 11:18 PM, Brandon Williams <bmwill@google.com> wrote:\n> >> You're marking packed_git\n> >> as \"private\"...well C has no notion of private vs public fields in a\n> >> struct so it might be difficult to keep that convention, it also took me\n> >> a second to realize that it was only in the scope of packfile.c where it\n> >> was ok to reference it directly.  Maybe it'll be ok?  If we really\n> >> wanted something to be private we'd need it to be an opaque type\n> >> instead, which may be out of the scope of this code refactor.\n> >\n> > It's true C syntax does not support private/public scoping, but it\n> > does not mean we must avoid that. Python has \"private convention\" with\n> > the underscore prefix, no special support from the language either.\n> > Yes having compiler support to enforce scoping is nice, but I think we\n> > can still live without it (Go devs live fine without \"const\"\n> > arguments, e.g.)\n> >\n> > So I'm going to make it clearer that these fields are not supposed to\n> > be accessed outside packfile.c\n> \n> I'm not counting out the making these fields completely opaque of\n> course. And with your suggestion of not embedding raw_object_store to\n> repository, that's actually possible to do. But I'm still not doing it\n> now :) The series is getting long and extending its scope will drag it\n> even longer (in terms of both time and number of patches)\n\nOh of course. I'm a big proponent of taking small steps, so definitely\navoid scope creep and hopefully this series can land quicker so we have\na better base to work with to make some of those other improvements if\nwe still want to down the road.\n\n-- \nBrandon Williams\n"},{"id":"342661","messageId":"20180323183550.GB243756@google.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-23T18:35:50Z","receivedAt":"2018-03-23T18:35:58Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/23, Nguyễn Thái Ngọc Duy wrote:\n> I think I have addressed all comments I've received so far. What I\n> decided not to do, I have responded individually. One comment I did\n> not respond nor do is the approximate thing, which could be done\n> later.\n> \n> Interdiff is big due to the \"objects.\" to \"objects->\" conversion\n> (blame Brandon for his suggestion, don't blame me :D)\n\nHaha, I'm guessing you prefer having a pointer too then? :P \n\nThe interdiff looks good, though I'll set some time aside today to go\nthrough the series as a whole again.\n\n-- \nBrandon Williams\n"},{"id":"342664","messageId":"20180323184328.GC243756@google.com","threadId":"47963","inReplyTo":"20180323172121.17725-5-pclouds@gmail.com","subject":"Re: [PATCH 04/27] object-store: free alt_odb_list","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-23T18:43:28Z","receivedAt":"2018-03-23T18:43:35Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/23, Nguyễn Thái Ngọc Duy wrote:\n> From: Stefan Beller <sbeller@google.com>\n> \n> Free the memory and reset alt_odb_{list, tail} to NULL.\n> \n> Signed-off-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nThanks for fixing the memory leak.  Looks good now.\n\n> ---\n>  object.c | 22 ++++++++++++++++++++++\n>  1 file changed, 22 insertions(+)\n> \n> diff --git a/object.c b/object.c\n> index 6ddd61242c..581347b535 100644\n> --- a/object.c\n> +++ b/object.c\n> @@ -454,8 +454,30 @@ struct raw_object_store *raw_object_store_new(void)\n>  \tmemset(o, 0, sizeof(*o));\n>  \treturn o;\n>  }\n> +\n> +static void free_alt_odb(struct alternate_object_database *alt)\n> +{\n> +\tstrbuf_release(&alt->scratch);\n> +\toid_array_clear(&alt->loose_objects_cache);\n> +\tfree(alt);\n> +}\n> +\n> +static void free_alt_odbs(struct raw_object_store *o)\n> +{\n> +\twhile (o->alt_odb_list) {\n> +\t\tstruct alternate_object_database *next;\n> +\n> +\t\tnext = o->alt_odb_list->next;\n> +\t\tfree_alt_odb(o->alt_odb_list);\n> +\t\to->alt_odb_list = next;\n> +\t}\n> +}\n> +\n>  void raw_object_store_clear(struct raw_object_store *o)\n>  {\n>  \tFREE_AND_NULL(o->objectdir);\n>  \tFREE_AND_NULL(o->alternate_db);\n> +\n> +\tfree_alt_odbs(o);\n> +\to->alt_odb_tail = NULL;\n>  }\n> -- \n> 2.17.0.rc0.348.gd5a49e0b6f\n> \n\n-- \nBrandon Williams\n"},{"id":"342665","messageId":"20180323185055.GD243756@google.com","threadId":"47963","inReplyTo":"20180323183550.GB243756@google.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-23T18:50:55Z","receivedAt":"2018-03-23T18:51:02Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/23, Brandon Williams wrote:\n> On 03/23, Nguyễn Thái Ngọc Duy wrote:\n> > I think I have addressed all comments I've received so far. What I\n> > decided not to do, I have responded individually. One comment I did\n> > not respond nor do is the approximate thing, which could be done\n> > later.\n> > \n> > Interdiff is big due to the \"objects.\" to \"objects->\" conversion\n> > (blame Brandon for his suggestion, don't blame me :D)\n> \n> Haha, I'm guessing you prefer having a pointer too then? :P \n> \n> The interdiff looks good, though I'll set some time aside today to go\n> through the series as a whole again.\n\nHad some more time than I thought; this series looks good!  Thanks for\ntake the time to keep this rolling.  Hopefully we can see this merged\nsoon :)\n\n-- \nBrandon Williams\n"},{"id":"342666","messageId":"CACsJy8C2MXqsRaoXsk+Kbbc21VG0dXtCEK45Yj6-S2RdOk9pSA@mail.gmail.com","threadId":"47963","inReplyTo":"20180323183550.GB243756@google.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-23T18:58:51Z","receivedAt":"2018-03-23T18:59:26Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Mar 23, 2018 at 7:35 PM, Brandon Williams <bmwill@google.com> wrote:\n> On 03/23, Nguyễn Thái Ngọc Duy wrote:\n>> I think I have addressed all comments I've received so far. What I\n>> decided not to do, I have responded individually. One comment I did\n>> not respond nor do is the approximate thing, which could be done\n>> later.\n>>\n>> Interdiff is big due to the \"objects.\" to \"objects->\" conversion\n>> (blame Brandon for his suggestion, don't blame me :D)\n>\n> Haha, I'm guessing you prefer having a pointer too then? :P\n\nThat goes without saying or I would be arguing against that instead of\nspending time fixing a bunch of compile errors ;-)\n-- \nDuy\n"},{"id":"342675","messageId":"20180323201512.GE243756@google.com","threadId":"47963","inReplyTo":"20180323174527.30337-1-pclouds@gmail.com","subject":"Re: [PATCH 00/12] sb/packfiles-in-repository updates","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-03-23T20:15:12Z","receivedAt":"2018-03-23T20:15:20Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 03/23, Nguyễn Thái Ngọc Duy wrote:\n> This is the rebased version on the updated sb/object-store I just sent\n> out plus the fix for get_object_directory(). The interdiff (after\n> rebased) looks small and nice\n\nNice! Thanks for fixing that.  This series looks good to me :)\n\n> \n> diff --git a/packfile.c b/packfile.c\n> index e02136bebb..63c89ee31a 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -890,7 +890,7 @@ static void prepare_packed_git(struct repository *r)\n>  \n>  \tif (r->objects->packed_git_initialized)\n>  \t\treturn;\n> -\tprepare_packed_git_one(r, get_object_directory(), 1);\n> +\tprepare_packed_git_one(r, r->objects->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> \n> I notice there's still one get_object_directory() left in packfile.c\n> but that should not cause problems with converted functions. That\n> could be done in \"phase 2\".\n> \n> Nguyễn Thái Ngọc Duy (1):\n>   packfile: keep prepare_packed_git() private\n> \n> Stefan Beller (11):\n>   packfile: allow prepare_packed_git_mru to handle arbitrary\n>     repositories\n>   packfile: allow rearrange_packed_git to handle arbitrary repositories\n>   packfile: allow install_packed_git to handle arbitrary repositories\n>   packfile: add repository argument to prepare_packed_git_one\n>   packfile: add repository argument to prepare_packed_git\n>   packfile: add repository argument to reprepare_packed_git\n>   packfile: allow prepare_packed_git_one to handle arbitrary\n>     repositories\n>   packfile: allow prepare_packed_git to handle arbitrary repositories\n>   packfile: allow reprepare_packed_git to handle arbitrary repositories\n>   packfile: add repository argument to find_pack_entry\n>   packfile: allow find_pack_entry to handle arbitrary repositories\n> \n>  builtin/count-objects.c  |  3 +-\n>  builtin/fsck.c           |  2 --\n>  builtin/gc.c             |  3 +-\n>  builtin/pack-objects.c   |  1 -\n>  builtin/pack-redundant.c |  2 --\n>  builtin/receive-pack.c   |  3 +-\n>  bulk-checkin.c           |  3 +-\n>  fast-import.c            |  3 +-\n>  fetch-pack.c             |  3 +-\n>  http-backend.c           |  1 -\n>  http.c                   |  2 +-\n>  pack-bitmap.c            |  1 -\n>  packfile.c               | 76 +++++++++++++++++++---------------------\n>  packfile.h               | 11 +++---\n>  server-info.c            |  1 -\n>  sha1_file.c              |  8 ++---\n>  sha1_name.c              |  2 --\n>  17 files changed, 58 insertions(+), 67 deletions(-)\n> \n> -- \n> 2.17.0.rc0.348.gd5a49e0b6f\n> \n\n-- \nBrandon Williams\n"},{"id":"342694","messageId":"xmqq370qiimo.fsf@gitster-ct.c.googlers.com","threadId":"47963","inReplyTo":"20180323185055.GD243756@google.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-03-23T21:31:27Z","receivedAt":"2018-03-23T21:31:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brandon Williams <bmwill@google.com> writes:\n\n>> > Interdiff is big due to the \"objects.\" to \"objects->\" conversion\n>> > (blame Brandon for his suggestion, don't blame me :D)\n>> \n>> Haha, I'm guessing you prefer having a pointer too then? :P \n>> \n>> The interdiff looks good, though I'll set some time aside today to go\n>> through the series as a whole again.\n>\n> Had some more time than I thought; this series looks good!  Thanks for\n> take the time to keep this rolling.  Hopefully we can see this merged\n> soon :)\n\nYeah, I definitely hope that this one is already 'next'-worthy; the\nmicro-update to ignore-env we saw recently looked good, too.\n\nThanks.\n\n\n\n"},{"id":"342699","messageId":"CAPig+cQ=u2xVaptpVzVd3g_RO+9kTWVitD4V7zpZFuL+a3wmtg@mail.gmail.com","threadId":"47963","inReplyTo":"20180323172121.17725-1-pclouds@gmail.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-03-23T22:07:33Z","receivedAt":"2018-03-23T22:07:38Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Mar 23, 2018 at 1:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> Interdiff is big due to the \"objects.\" to \"objects->\" conversion\n> (blame Brandon for his suggestion, don't blame me :D)\n>\n> diff --git a/packfile.c b/packfile.c\n> @@ -1938,7 +1939,7 @@ static int add_promisor_object(const struct object_id *oid,\n>         /*\n>          * If this is a tree, commit, or tag, the objects it refers\n> -        * to are also promisor objects. (Blobs refer to no objects.)\n> +        * to are also promisor objects-> (Blobs refer to no objects->)\n>          */\n\nMeh.\n"},{"id":"342722","messageId":"20180324053144.GA11420@duynguyen.home","threadId":"47963","inReplyTo":"CAPig+cQ=u2xVaptpVzVd3g_RO+9kTWVitD4V7zpZFuL+a3wmtg@mail.gmail.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-03-24T05:31:45Z","receivedAt":"2018-03-24T05:31:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Mar 23, 2018 at 06:07:33PM -0400, Eric Sunshine wrote:\n> On Fri, Mar 23, 2018 at 1:20 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> > Interdiff is big due to the \"objects.\" to \"objects->\" conversion\n> > (blame Brandon for his suggestion, don't blame me :D)\n> >\n> > diff --git a/packfile.c b/packfile.c\n> > @@ -1938,7 +1939,7 @@ static int add_promisor_object(const struct object_id *oid,\n> >         /*\n> >          * If this is a tree, commit, or tag, the objects it refers\n> > -        * to are also promisor objects. (Blobs refer to no objects.)\n> > +        * to are also promisor objects-> (Blobs refer to no objects->)\n> >          */\n> \n> Meh.\n\nI got too excited when searching and replacing. Here's the fixup\npatch.\n\n-- 8< --\nSubject: [PATCH] fixup! object-store: move packed_git and packed_git_mru to\n object store\n\n---\n packfile.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 63c89ee31a..0906b8f741 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1937,7 +1937,7 @@ static int add_promisor_object(const struct object_id *oid,\n \n \t/*\n \t * If this is a tree, commit, or tag, the objects it refers\n-\t * to are also promisor objects-> (Blobs refer to no objects->)\n+\t * to are also promisor objects. (Blobs refer to no objects.)\n \t */\n \tif (obj->type == OBJ_TREE) {\n \t\tstruct tree *tree = (struct tree *)obj;\n-- \n2.17.0.rc0.348.gd5a49e0b6f\n\n-- 8< --\n"},{"id":"343036","messageId":"CAGZ79kbkc2d-EHDTWP1GvCU62=ogZbP0ffxOHZamdQK+3h1yJw@mail.gmail.com","threadId":"47963","inReplyTo":"20180324053144.GA11420@duynguyen.home","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-03-26T17:45:47Z","receivedAt":"2018-03-26T17:46:04Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Fri, Mar 23, 2018 at 10:31 PM Duy Nguyen <pclouds@gmail.com> wrote:\n\n> I got too excited when searching and replacing. Here's the fixup\n> patch.\n\nThanks for picking up the series that I left unattended over the last weeks.\nI have reviewed nd/remove-ignore-env-field as well as sb/object-store\nas currently queued and found them well done.\n\nThanks for driving this when I was away!\n\nWith the fixup patch, both series are\nReviewed-by: Stefan Beller <sbeller@google.com>\n(No need to apply that as it already looks funny to have\n3-5 sign offs including mine)\n\nWith these 2 series reviewed, I'll continue reviewing\nsb/pack-files-in-repository and the rest of my mail box.\n\nThanks,\nStefan\n\n> -- 8< --\n> Subject: [PATCH] fixup! object-store: move packed_git and packed_git_mru\nto\n>   object store\n\n> ---\n>   packfile.c | 2 +-\n>   1 file changed, 1 insertion(+), 1 deletion(-)\n\n> diff --git a/packfile.c b/packfile.c\n> index 63c89ee31a..0906b8f741 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -1937,7 +1937,7 @@ static int add_promisor_object(const struct\nobject_id *oid,\n\n>          /*\n>           * If this is a tree, commit, or tag, the objects it refers\n> -        * to are also promisor objects-> (Blobs refer to no objects->)\n> +        * to are also promisor objects. (Blobs refer to no objects.)\n>           */\n>          if (obj->type == OBJ_TREE) {\n>                  struct tree *tree = (struct tree *)obj;\n> --\n> 2.17.0.rc0.348.gd5a49e0b6f\n\n> -- 8< --\n"},{"id":"343041","messageId":"xmqq8taed7ze.fsf@gitster-ct.c.googlers.com","threadId":"47963","inReplyTo":"CAGZ79kbkc2d-EHDTWP1GvCU62=ogZbP0ffxOHZamdQK+3h1yJw@mail.gmail.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-03-26T18:09:25Z","receivedAt":"2018-03-26T18:09:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n> Thanks for driving this when I was away!\n>\n> With the fixup patch, both series are\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n\nI think everybody involved agrees that these two you cited above are\nalready in good shape.  Let's have them in 'next' for the remainder\nof this cycle and go incremental, and merge them to 'master' soon\nafter 2.17 final is tagged.\n\nThanks all for working well together.  \n\n"},{"id":"343056","messageId":"xmqqy3iebpsw.fsf@gitster-ct.c.googlers.com","threadId":"47963","inReplyTo":"xmqq8taed7ze.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH 00/27] sb/object-store updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-03-26T19:27:27Z","receivedAt":"2018-03-26T19:27:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Stefan Beller <sbeller@google.com> writes:\n>\n>> Thanks for driving this when I was away!\n>>\n>> With the fixup patch, both series are\n>> Reviewed-by: Stefan Beller <sbeller@google.com>\n>\n> I think everybody involved agrees that these two you cited above are\n> already in good shape.  Let's have them in 'next' for the remainder\n> of this cycle and go incremental, and merge them to 'master' soon\n> after 2.17 final is tagged.\n>\n> Thanks all for working well together.  \n\nJust FYI, when merging the topic nd/pack-objects-pack-struct to a\ncodebase with these two topics, because the former adds a handful of\ninline functions that wants to see packed_git but all existing\nsources have relied on the rule that cache.h is included early and\nthe fact that packed_git was declared in there, the change in\nsb/object-store to move the structure declaration to object-store.h\ncauses quite a trouble.  I plan to resolve this with an evil merge\nto include object-store.h from pack-objects.h to resolve this with\nminimum damage to topics in flight.\n\n\n"},{"id":"343063","messageId":"CAGZ79ka0ptbwHU0Ym7aGm86o+YG27goHR6iS3uf5yUkj0Uj15w@mail.gmail.com","threadId":"47963","inReplyTo":"20180323155523.22269-2-pclouds@gmail.com","subject":"Re: [PATCH 1/1] repository.h: add comment and clarify repo_set_gitdir","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-03-26T21:04:33Z","receivedAt":"2018-03-26T21:04:48Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Fri, Mar 23, 2018 at 8:55 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nwrote:\n\n> The argument name \"optional\" may mislead the reader to think this\n> option could be NULL. But it can't be. While at there, document a bit\n> more about struct set_gitdir_args.\n\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nReviewed-by: Stefan Beller <sbeller@google.com>\n"},{"id":"343064","messageId":"CAGZ79kZp-oxowhguARiaSY713-k5NLpMPVFA8G2GD2Vy4KxoTw@mail.gmail.com","threadId":"47963","inReplyTo":"CAGZ79ka0ptbwHU0Ym7aGm86o+YG27goHR6iS3uf5yUkj0Uj15w@mail.gmail.com","subject":"Re: [PATCH 1/1] repository.h: add comment and clarify repo_set_gitdir","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-03-26T21:05:11Z","receivedAt":"2018-03-26T21:05:27Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Mar 26, 2018 at 2:04 PM Stefan Beller <sbeller@google.com> wrote:\n\n\n\n> On Fri, Mar 23, 2018 at 8:55 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nwrote:\n> >\n> > The argument name \"optional\" may mislead the reader to think this\n> > option could be NULL. But it can't be. While at there, document a bit\n> > more about struct set_gitdir_args.\n> >\n> > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n\nUh, not so fast. Is it worthwhile to align the parameter name in\nthe c file as well?\n"}]}