{"thread":{"id":"49828","subject":"[PATCHv3 00/23] Bring more repository handles into our code base","startedAt":"2018-11-14T00:13:34Z","lastAt":"2018-12-12T20:58:22Z","messageCount":30,"participants":["Stefan Beller","Jonathan Tan","Derrick Stolee"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"363237","messageId":"20181114001306.138053-1-sbeller@google.com","threadId":"49828","inReplyTo":null,"subject":"[PATCHv3 00/23] Bring more repository handles into our code base","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:43Z","receivedAt":"2018-11-14T00:13:34Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"This resends origin/sb/more-repo-in-api.\n\nUnlike the previous resend (v2), this is not rebased to a newer base.\nThis doesn't contain the patch for pending semantic changes, as that\nseems to go in its own topic branch.\n\nPlease have a look at the last 4 patches specifically as they were new in\nthe last iteration (but did not receive any comment), as they demonstrate\nand fix a problem that is only exposed when using GIT_TEST_COMMIT_GRAPH=1\nfor the test suite.\n\nPrevious discussion at\nhttps://public-inbox.org/git/20181030220817.61691-1-sbeller@google.com/\n\nThanks,\nStefan\n\nStefan Beller (23):\n  sha1_file: allow read_object to read objects in arbitrary repositories\n  packfile: allow has_packed_and_bad to handle arbitrary repositories\n  object-store: allow read_object_file_extended to read from any repo\n  object-store: prepare read_object_file to deal with any repo\n  object-store: prepare has_{sha1, object}_file to handle any repo\n  object: parse_object to honor its repository argument\n  commit: allow parse_commit* to handle any repo\n  commit-reach.c: allow paint_down_to_common to handle any repo\n  commit-reach.c: allow merge_bases_many to handle any repo\n  commit-reach.c: allow remove_redundant to handle any repo\n  commit-reach.c: allow get_merge_bases_many_0 to handle any repo\n  commit-reach: prepare get_merge_bases to handle any repo\n  commit-reach: prepare in_merge_bases[_many] to handle any repo\n  commit: prepare get_commit_buffer to handle any repo\n  commit: prepare repo_unuse_commit_buffer to handle any repo\n  commit: prepare logmsg_reencode to handle arbitrary repositories\n  pretty: prepare format_commit_message to handle arbitrary repositories\n  submodule: use submodule repos for object lookup\n  submodule: don't add submodule as odb for push\n  commit-graph: convert remaining functions to handle any repo\n  commit: prepare free_commit_buffer and release_commit_memory for any\n    repo\n  path.h: make REPO_GIT_PATH_FUNC repository agnostic\n  t/helper/test-repository: celebrate independence from the_repository\n\n builtin/fsck.c                                |   3 +-\n builtin/log.c                                 |   6 +-\n builtin/rev-list.c                            |   3 +-\n cache.h                                       |   2 +\n commit-graph.c                                |  40 +++--\n commit-reach.c                                |  73 +++++----\n commit-reach.h                                |  38 +++--\n commit.c                                      |  41 ++---\n commit.h                                      |  43 +++++-\n .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++\n object-store.h                                |  35 ++++-\n object.c                                      |   8 +-\n packfile.c                                    |   5 +-\n packfile.h                                    |   2 +-\n path.h                                        |   2 +-\n pretty.c                                      |  28 ++--\n pretty.h                                      |   7 +-\n sha1-file.c                                   |  34 +++--\n streaming.c                                   |   2 +-\n submodule.c                                   |  76 ++++++---\n t/helper/test-repository.c                    |  10 ++\n 21 files changed, 452 insertions(+), 150 deletions(-)\n create mode 100644 contrib/coccinelle/the_repository.pending.cocci\n\nRange-diff:\n 1:  1b9b5c695e =  1:  ca9fece80e sha1_file: allow read_object to read objects in arbitrary repositories\n 2:  33b94066f2 =  2:  8eac25fe32 packfile: allow has_packed_and_bad to handle arbitrary repositories\n 3:  5217b6b1e1 !  3:  06e5f83b66 object-store: allow read_object_file_extended to read from arbitrary repositories\n    @@ -1,6 +1,6 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    object-store: allow read_object_file_extended to read from arbitrary repositories\n    +    object-store: allow read_object_file_extended to read from any repo\n     \n         read_object_file_extended is not widely used, so migrate it all at once.\n     \n 4:  2b7239b55b !  4:  6167722608 object-store: prepare read_object_file to deal with arbitrary repositories\n    @@ -1,6 +1,6 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    object-store: prepare read_object_file to deal with arbitrary repositories\n    +    object-store: prepare read_object_file to deal with any repo\n     \n         As read_object_file is a widely used function (which is also regularly used\n         in new code in flight between master..pu), changing its signature is painful\n    @@ -13,16 +13,14 @@\n         e675765235 (diff.c: remove implicit dependency on the_index, 2018-09-21)\n     \n         Add a coccinelle patch to convert existing callers, but do not apply\n    -    the resulting patch from 'make coccicheck' to keep the diff of this\n    -    patch small.\n    +    the resulting patch to keep the diff of this patch small.\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n      new file mode 100644\n      --- /dev/null\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n     +// This file is used for the ongoing refactoring of\n     +// bringing the index or repository struct in all of\n 5:  24291f4d84 !  5:  2a88a868bb object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories\n    @@ -1,13 +1,12 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories\n    +    object-store: prepare has_{sha1, object}_file to handle any repo\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - read_object_file(\n      + repo_read_object_file(the_repository,\n 6:  6aa209978e =  6:  fd4a151e07 object: parse_object to honor its repository argument\n 7:  9b2d6aa7c3 !  7:  5484abc785 commit: allow parse_commit* to handle arbitrary repositories\n    @@ -1,6 +1,6 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit: allow parse_commit* to handle arbitrary repositories\n    +    commit: allow parse_commit* to handle any repo\n     \n         Just like the previous commit, parse_commit and friends are used a lot\n         and are found in new patches, so we cannot change their signature easily.\n    @@ -9,7 +9,6 @@\n         argument and keep the original as a shallow macro.\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit.c b/commit.c\n      --- a/commit.c\n    @@ -93,9 +92,9 @@\n      \n      struct buffer_slab;\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - has_object_file_with_flags(\n      + repo_has_object_file_with_flags(the_repository,\n 8:  0e7e681118 !  8:  8cc3054b31 commit-reach.c: allow paint_down_to_common to handle arbitrary repositories\n    @@ -1,11 +1,10 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit-reach.c: allow paint_down_to_common to handle arbitrary repositories\n    +    commit-reach.c: allow paint_down_to_common to handle any repo\n     \n         As the function is file local and not widely used, migrate it all at once.\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit-reach.c b/commit-reach.c\n      --- a/commit-reach.c\n 9:  e83b26f5b3 !  9:  45e67ba283 commit-reach.c: allow merge_bases_many to handle arbitrary repositories\n    @@ -1,9 +1,8 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit-reach.c: allow merge_bases_many to handle arbitrary repositories\n    +    commit-reach.c: allow merge_bases_many to handle any repo\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit-reach.c b/commit-reach.c\n      --- a/commit-reach.c\n10:  d80b9de832 ! 10:  917d8cbaee commit-reach.c: allow remove_redundant to handle arbitrary repositories\n    @@ -1,9 +1,8 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit-reach.c: allow remove_redundant to handle arbitrary repositories\n    +    commit-reach.c: allow remove_redundant to handle any repo\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit-reach.c b/commit-reach.c\n      --- a/commit-reach.c\n11:  3ec21ad503 ! 11:  a008e62fea commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories\n    @@ -1,9 +1,8 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories\n    +    commit-reach.c: allow get_merge_bases_many_0 to handle any repo\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit-reach.c b/commit-reach.c\n      --- a/commit-reach.c\n12:  3f21279f50 ! 12:  a50a7f52b0 commit-reach: prepare get_merge_bases to handle arbitrary repositories\n    @@ -1,6 +1,6 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit-reach: prepare get_merge_bases to handle arbitrary repositories\n    +    commit-reach: prepare get_merge_bases to handle any repo\n     \n         Similarly to previous patches, the get_merge_base functions are used\n         often in the code base, which makes migrating them hard.\n    @@ -9,7 +9,6 @@\n         functions behind a wrapper macro.\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit-reach.c b/commit-reach.c\n      --- a/commit-reach.c\n    @@ -91,9 +90,9 @@\n      int is_descendant_of(struct commit *commit, struct commit_list *with_commit);\n      int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - parse_commit(\n      + repo_parse_commit(the_repository,\n13:  4decc3acc1 ! 13:  d82074d34b commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories\n    @@ -1,9 +1,8 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories\n    +    commit-reach: prepare in_merge_bases[_many] to handle any repo\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit-reach.c b/commit-reach.c\n      --- a/commit-reach.c\n    @@ -76,9 +75,9 @@\n      /*\n       * Takes a list of commits and returns a new list where those\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - get_merge_bases_many_dirty(\n      + repo_get_merge_bases_many_dirty(the_repository,\n14:  141b86ea89 ! 14:  6035c18ca1 commit: prepare get_commit_buffer to handle arbitrary repositories\n    @@ -1,9 +1,8 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit: prepare get_commit_buffer to handle arbitrary repositories\n    +    commit: prepare get_commit_buffer to handle any repo\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit.c b/commit.c\n      --- a/commit.c\n    @@ -46,9 +45,9 @@\n      /*\n       * Tell the commit subsytem that we are done with a particular commit buffer.\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - in_merge_bases_many(\n      + repo_in_merge_bases_many(the_repository,\n15:  2cc415c1db ! 15:  85dcc6f806 commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories\n    @@ -1,9 +1,8 @@\n     Author: Stefan Beller <sbeller@google.com>\n     \n    -    commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories\n    +    commit: prepare repo_unuse_commit_buffer to handle any repo\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/commit.c b/commit.c\n      --- a/commit.c\n    @@ -42,9 +41,9 @@\n      /*\n       * Free any cached object buffer associated with the commit.\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - get_commit_buffer(\n      + repo_get_commit_buffer(the_repository,\n16:  554daa8cfc ! 16:  0e1b98701f commit: prepare logmsg_reencode to handle arbitrary repositories\n    @@ -24,9 +24,9 @@\n      \n      /** Removes the first commit from a list sorted by date, and adds all\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - unuse_commit_buffer(\n      + repo_unuse_commit_buffer(the_repository,\n17:  bd8737176b ! 17:  da611e902b pretty: prepare format_commit_message to handle arbitrary repositories\n    @@ -5,9 +5,9 @@\n         Signed-off-by: Stefan Beller <sbeller@google.com>\n         Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci\n    - --- a/contrib/coccinelle/the_repository.cocci\n    - +++ b/contrib/coccinelle/the_repository.cocci\n    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\n    + --- a/contrib/coccinelle/the_repository.pending.cocci\n    + +++ b/contrib/coccinelle/the_repository.pending.cocci\n     @@\n      - logmsg_reencode(\n      + repo_logmsg_reencode(the_repository,\n18:  b303ef65e7 ! 18:  a98112634e submodule: use submodule repos for object lookup\n    @@ -7,7 +7,6 @@\n         are not added to the main object store.\n     \n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/submodule.c b/submodule.c\n      --- a/submodule.c\n    @@ -46,24 +45,23 @@\n     + * in .gitmodules. This function exists only to preserve historical behavior,\n     + *\n     + * Returns 0 on success, -1 when the submodule is not present.\n    -+ */\n    -+static int open_submodule(struct repository *out, const char *path)\n    +  */\n    +-static void show_submodule_header(struct diff_options *o, const char *path,\n    ++static struct repository *open_submodule(const char *path)\n     +{\n     +\tstruct strbuf sb = STRBUF_INIT;\n    ++\tstruct repository *out = xmalloc(sizeof(*out));\n     +\n     +\tif (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {\n     +\t\tstrbuf_release(&sb);\n    -+\t\treturn -1;\n    ++\t\tfree(out);\n    ++\t\treturn NULL;\n     +\t}\n     +\n     +\tout->submodule_prefix = xstrdup(path);\n    -+\tout->submodule_prefix = xstrfmt(\"%s%s/\",\n    -+\t\t\t\t\tthe_repository->submodule_prefix ?\n    -+\t\t\t\t\tthe_repository->submodule_prefix :\n    -+\t\t\t\t\t\"\", path);\n     +\n     +\tstrbuf_release(&sb);\n    -+\treturn 0;\n    ++\treturn out;\n     +}\n     +\n     +/*\n    @@ -73,8 +71,7 @@\n     + * If it can locate the submodule git directory it will create a repository\n     + * handle for the submodule and lookup both the left and right commits and\n     + * put them into the left and right pointers.\n    -  */\n    --static void show_submodule_header(struct diff_options *o, const char *path,\n    ++ */\n     +static void show_submodule_header(struct diff_options *o,\n     +\t\tconst char *path,\n      \t\tstruct object_id *one, struct object_id *two,\n    @@ -116,11 +113,9 @@\n      \tstruct rev_info rev;\n      \tstruct commit *left = NULL, *right = NULL;\n      \tstruct commit_list *merge_bases = NULL;\n    -+\tstruct repository subrepo, *sub = &subrepo;\n    -+\n    -+\tif (open_submodule(&subrepo, path) < 0)\n    -+\t\tsub = NULL;\n    ++\tstruct repository *sub;\n      \n    ++\tsub = open_submodule(path);\n      \tshow_submodule_header(o, path, one, two, dirty_submodule,\n     -\t\t\t      &left, &right, &merge_bases);\n     +\t\t\t      sub, &left, &right, &merge_bases);\n    @@ -147,8 +142,10 @@\n      \t\tfree_commit_list(merge_bases);\n      \tclear_commit_marks(left, ~0);\n      \tclear_commit_marks(right, ~0);\n    -+\tif (sub)\n    ++\tif (sub) {\n     +\t\trepo_clear(sub);\n    ++\t\tfree(sub);\n    ++\t}\n      }\n      \n      void show_submodule_inline_diff(struct diff_options *o, const char *path,\n    @@ -156,11 +153,9 @@\n      \tstruct commit_list *merge_bases = NULL;\n      \tstruct child_process cp = CHILD_PROCESS_INIT;\n      \tstruct strbuf sb = STRBUF_INIT;\n    -+\tstruct repository subrepo, *sub = &subrepo;\n    -+\n    -+\tif (open_submodule(&subrepo, path) < 0)\n    -+\t\tsub = NULL;\n    ++\tstruct repository *sub;\n      \n    ++\tsub = open_submodule(path);\n      \tshow_submodule_header(o, path, one, two, dirty_submodule,\n     -\t\t\t      &left, &right, &merge_bases);\n     +\t\t\t      sub, &left, &right, &merge_bases);\n    @@ -171,8 +166,10 @@\n      \t\tclear_commit_marks(left, ~0);\n      \tif (right)\n      \t\tclear_commit_marks(right, ~0);\n    -+\tif (sub)\n    ++\tif (sub) {\n     +\t\trepo_clear(sub);\n    ++\t\tfree(sub);\n    ++\t}\n      }\n      \n      int should_update_submodules(void)\n19:  dbb0dd9322 ! 19:  6aad29a006 submodule: don't add submodule as odb for push\n    @@ -8,8 +8,10 @@\n         objects, and the actual push is done by spawning another process,\n         which handles object access by itself.)\n     \n    +    This code of push_submodule() is exercised in t5531 and continues\n    +    to work, showing that the submodule odbc is not needed.\n    +\n         Signed-off-by: Stefan Beller <sbeller@google.com>\n    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>\n     \n      diff --git a/submodule.c b/submodule.c\n      --- a/submodule.c\n -:  ---------- > 20:  1687e96586 commit-graph: convert remaining functions to handle any repo\n -:  ---------- > 21:  d348185ca9 commit: prepare free_commit_buffer and release_commit_memory for any repo\n -:  ---------- > 22:  19f62807cc path.h: make REPO_GIT_PATH_FUNC repository agnostic\n -:  ---------- > 23:  61da0c2812 t/helper/test-repository: celebrate independence from the_repository\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363238","messageId":"20181114001306.138053-2-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 01/23] sha1_file: allow read_object to read objects in arbitrary repositories","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:44Z","receivedAt":"2018-11-14T00:13:36Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Allow read_object (a file local functon in sha1_file) to\nhandle arbitrary repositories by passing the repository down\nto oid_object_info_extended.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1-file.c | 10 ++++++----\n 1 file changed, 6 insertions(+), 4 deletions(-)\n\ndiff --git a/sha1-file.c b/sha1-file.c\nindex dd0b6aa873..b8ce21cbaf 100644\n--- a/sha1-file.c\n+++ b/sha1-file.c\n@@ -1361,7 +1361,9 @@ int oid_object_info(struct repository *r,\n \treturn type;\n }\n \n-static void *read_object(const unsigned char *sha1, enum object_type *type,\n+static void *read_object(struct repository *r,\n+\t\t\t const unsigned char *sha1,\n+\t\t\t enum object_type *type,\n \t\t\t unsigned long *size)\n {\n \tstruct object_id oid;\n@@ -1373,7 +1375,7 @@ static void *read_object(const unsigned char *sha1, enum object_type *type,\n \n \thashcpy(oid.hash, sha1);\n \n-\tif (oid_object_info_extended(the_repository, &oid, &oi, 0) < 0)\n+\tif (oid_object_info_extended(r, &oid, &oi, 0) < 0)\n \t\treturn NULL;\n \treturn content;\n }\n@@ -1414,7 +1416,7 @@ void *read_object_file_extended(const struct object_id *oid,\n \t\tlookup_replace_object(the_repository, oid) : oid;\n \n \terrno = 0;\n-\tdata = read_object(repl->hash, type, size);\n+\tdata = read_object(the_repository, repl->hash, type, size);\n \tif (data)\n \t\treturn data;\n \n@@ -1755,7 +1757,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)\n \n \tif (has_loose_object(oid))\n \t\treturn 0;\n-\tbuf = read_object(oid->hash, &type, &len);\n+\tbuf = read_object(the_repository, oid->hash, &type, &len);\n \tif (!buf)\n \t\treturn error(_(\"cannot read sha1_file for %s\"), oid_to_hex(oid));\n \thdrlen = xsnprintf(hdr, sizeof(hdr), \"%s %lu\", type_name(type), len) + 1;\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363239","messageId":"20181114001306.138053-3-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 02/23] packfile: allow has_packed_and_bad to handle arbitrary repositories","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:45Z","receivedAt":"2018-11-14T00:13:38Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"has_packed_and_bad is not widely used, so just migrate it all at once.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n packfile.c  | 5 +++--\n packfile.h  | 2 +-\n sha1-file.c | 2 +-\n 3 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/packfile.c b/packfile.c\nindex 841b36182f..bc2e0f5043 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1131,12 +1131,13 @@ void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1)\n \tp->num_bad_objects++;\n }\n \n-const struct packed_git *has_packed_and_bad(const unsigned char *sha1)\n+const struct packed_git *has_packed_and_bad(struct repository *r,\n+\t\t\t\t\t    const unsigned char *sha1)\n {\n \tstruct packed_git *p;\n \tunsigned i;\n \n-\tfor (p = the_repository->objects->packed_git; p; p = p->next)\n+\tfor (p = r->objects->packed_git; p; p = p->next)\n \t\tfor (i = 0; i < p->num_bad_objects; i++)\n \t\t\tif (hasheq(sha1,\n \t\t\t\t   p->bad_object_sha1 + the_hash_algo->rawsz * i))\ndiff --git a/packfile.h b/packfile.h\nindex 442625723d..7a62d72231 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -146,7 +146,7 @@ extern int packed_object_info(struct repository *r,\n \t\t\t      off_t offset, struct object_info *);\n \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+extern const struct packed_git *has_packed_and_bad(struct repository *r, const unsigned char *sha1);\n \n /*\n  * Iff a pack file in the given repository contains the object named by sha1,\ndiff --git a/sha1-file.c b/sha1-file.c\nindex b8ce21cbaf..856e000ee1 100644\n--- a/sha1-file.c\n+++ b/sha1-file.c\n@@ -1432,7 +1432,7 @@ void *read_object_file_extended(const struct object_id *oid,\n \t\tdie(_(\"loose object %s (stored in %s) is corrupt\"),\n \t\t    oid_to_hex(repl), path);\n \n-\tif ((p = has_packed_and_bad(repl->hash)) != NULL)\n+\tif ((p = has_packed_and_bad(the_repository, repl->hash)) != NULL)\n \t\tdie(_(\"packed object %s (stored in %s) is corrupt\"),\n \t\t    oid_to_hex(repl), p->pack_name);\n \n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363240","messageId":"20181114001306.138053-4-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 03/23] object-store: allow read_object_file_extended to read from any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:46Z","receivedAt":"2018-11-14T00:13:41Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"read_object_file_extended is not widely used, so migrate it all at once.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n object-store.h |  5 +++--\n sha1-file.c    | 11 ++++++-----\n streaming.c    |  2 +-\n 3 files changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/object-store.h b/object-store.h\nindex 63b7605a3e..3d98a682b2 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -161,12 +161,13 @@ void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned cha\n \n void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);\n \n-extern void *read_object_file_extended(const struct object_id *oid,\n+extern void *read_object_file_extended(struct repository *r,\n+\t\t\t\t       const struct object_id *oid,\n \t\t\t\t       enum object_type *type,\n \t\t\t\t       unsigned long *size, int lookup_replace);\n static inline void *read_object_file(const struct object_id *oid, enum object_type *type, unsigned long *size)\n {\n-\treturn read_object_file_extended(oid, type, size, 1);\n+\treturn read_object_file_extended(the_repository, oid, type, size, 1);\n }\n \n /* Read and unpack an object file into memory, write memory to an object file */\ndiff --git a/sha1-file.c b/sha1-file.c\nindex 856e000ee1..c5b704aec5 100644\n--- a/sha1-file.c\n+++ b/sha1-file.c\n@@ -1403,7 +1403,8 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,\n  * deal with them should arrange to call read_object() and give error\n  * messages themselves.\n  */\n-void *read_object_file_extended(const struct object_id *oid,\n+void *read_object_file_extended(struct repository *r,\n+\t\t\t\tconst struct object_id *oid,\n \t\t\t\tenum object_type *type,\n \t\t\t\tunsigned long *size,\n \t\t\t\tint lookup_replace)\n@@ -1413,10 +1414,10 @@ void *read_object_file_extended(const struct object_id *oid,\n \tconst char *path;\n \tstruct stat st;\n \tconst struct object_id *repl = lookup_replace ?\n-\t\tlookup_replace_object(the_repository, oid) : oid;\n+\t\tlookup_replace_object(r, oid) : oid;\n \n \terrno = 0;\n-\tdata = read_object(the_repository, repl->hash, type, size);\n+\tdata = read_object(r, repl->hash, type, size);\n \tif (data)\n \t\treturn data;\n \n@@ -1428,11 +1429,11 @@ void *read_object_file_extended(const struct object_id *oid,\n \t\tdie(_(\"replacement %s not found for %s\"),\n \t\t    oid_to_hex(repl), oid_to_hex(oid));\n \n-\tif (!stat_sha1_file(the_repository, repl->hash, &st, &path))\n+\tif (!stat_sha1_file(r, repl->hash, &st, &path))\n \t\tdie(_(\"loose object %s (stored in %s) is corrupt\"),\n \t\t    oid_to_hex(repl), path);\n \n-\tif ((p = has_packed_and_bad(the_repository, repl->hash)) != NULL)\n+\tif ((p = has_packed_and_bad(r, repl->hash)) != NULL)\n \t\tdie(_(\"packed object %s (stored in %s) is corrupt\"),\n \t\t    oid_to_hex(repl), p->pack_name);\n \ndiff --git a/streaming.c b/streaming.c\nindex d1e6b2dce6..c843a1230f 100644\n--- a/streaming.c\n+++ b/streaming.c\n@@ -490,7 +490,7 @@ static struct stream_vtbl incore_vtbl = {\n \n static open_method_decl(incore)\n {\n-\tst->u.incore.buf = read_object_file_extended(oid, type, &st->size, 0);\n+\tst->u.incore.buf = read_object_file_extended(the_repository, oid, type, &st->size, 0);\n \tst->u.incore.read_ptr = 0;\n \tst->vtbl = &incore_vtbl;\n \n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363241","messageId":"20181114001306.138053-5-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 04/23] object-store: prepare read_object_file to deal with any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:47Z","receivedAt":"2018-11-14T00:13:43Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"As read_object_file is a widely used function (which is also regularly used\nin new code in flight between master..pu), changing its signature is painful\nis hard, as other series in flight rely on the original signature. It would\nburden the maintainer if we'd just change the signature.\n\nIntroduce repo_read_object_file which takes the repository argument, and\nhide the original read_object_file as a macro behind\nNO_THE_REPOSITORY_COMPATIBILITY_MACROS, similar to\ne675765235 (diff.c: remove implicit dependency on the_index, 2018-09-21)\n\nAdd a coccinelle patch to convert existing callers, but do not apply\nthe resulting patch to keep the diff of this patch small.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n contrib/coccinelle/the_repository.pending.cocci | 12 ++++++++++++\n object-store.h                                  | 10 ++++++++--\n 2 files changed, 20 insertions(+), 2 deletions(-)\n create mode 100644 contrib/coccinelle/the_repository.pending.cocci\n\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nnew file mode 100644\nindex 0000000000..a7ac9e0c46\n--- /dev/null\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -0,0 +1,12 @@\n+// This file is used for the ongoing refactoring of\n+// bringing the index or repository struct in all of\n+// our code base.\n+\n+@@\n+expression E;\n+expression F;\n+expression G;\n+@@\n+- read_object_file(\n++ repo_read_object_file(the_repository,\n+  E, F, G)\ndiff --git a/object-store.h b/object-store.h\nindex 3d98a682b2..00a64622e6 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -165,10 +165,16 @@ extern void *read_object_file_extended(struct repository *r,\n \t\t\t\t       const struct object_id *oid,\n \t\t\t\t       enum object_type *type,\n \t\t\t\t       unsigned long *size, int lookup_replace);\n-static inline void *read_object_file(const struct object_id *oid, enum object_type *type, unsigned long *size)\n+static inline void *repo_read_object_file(struct repository *r,\n+\t\t\t\t\t  const struct object_id *oid,\n+\t\t\t\t\t  enum object_type *type,\n+\t\t\t\t\t  unsigned long *size)\n {\n-\treturn read_object_file_extended(the_repository, oid, type, size, 1);\n+\treturn read_object_file_extended(r, oid, type, size, 1);\n }\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define read_object_file(oid, type, size) repo_read_object_file(the_repository, oid, type, size)\n+#endif\n \n /* Read and unpack an object file into memory, write memory to an object file */\n int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363242","messageId":"20181114001306.138053-6-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 05/23] object-store: prepare has_{sha1, object}_file to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:48Z","receivedAt":"2018-11-14T00:13:46Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n .../coccinelle/the_repository.pending.cocci   | 30 +++++++++++++++++++\n object-store.h                                | 22 ++++++++++----\n sha1-file.c                                   | 15 ++++++----\n 3 files changed, 56 insertions(+), 11 deletions(-)\n\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex a7ac9e0c46..46f3a1b23a 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -10,3 +10,33 @@ expression G;\n - read_object_file(\n + repo_read_object_file(the_repository,\n   E, F, G)\n+\n+@@\n+expression E;\n+@@\n+- has_sha1_file(\n++ repo_has_sha1_file(the_repository,\n+  E)\n+\n+@@\n+expression E;\n+expression F;\n+@@\n+- has_sha1_file_with_flags(\n++ repo_has_sha1_file_with_flags(the_repository,\n+  E)\n+\n+@@\n+expression E;\n+@@\n+- has_object_file(\n++ repo_has_object_file(the_repository,\n+  E)\n+\n+@@\n+expression E;\n+expression F;\n+@@\n+- has_object_file_with_flags(\n++ repo_has_object_file_with_flags(the_repository,\n+  E)\ndiff --git a/object-store.h b/object-store.h\nindex 00a64622e6..2b5e6ff1ed 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -212,15 +212,27 @@ int read_loose_object(const char *path,\n  * object_info. OBJECT_INFO_SKIP_CACHED is automatically set; pass\n  * nonzero flags to also set other flags.\n  */\n-extern int has_sha1_file_with_flags(const unsigned char *sha1, int flags);\n-static inline int has_sha1_file(const unsigned char *sha1)\n+int repo_has_sha1_file_with_flags(struct repository *r,\n+\t\t\t\t  const unsigned char *sha1, int flags);\n+static inline int repo_has_sha1_file(struct repository *r,\n+\t\t\t\t     const unsigned char *sha1)\n {\n-\treturn has_sha1_file_with_flags(sha1, 0);\n+\treturn repo_has_sha1_file_with_flags(r, sha1, 0);\n }\n \n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define has_sha1_file_with_flags(sha1, flags) repo_has_sha1_file_with_flags(the_repository, sha1, flags)\n+#define has_sha1_file(sha1) repo_has_sha1_file(the_repository, sha1)\n+#endif\n+\n /* Same as the above, except for struct object_id. */\n-extern int has_object_file(const struct object_id *oid);\n-extern int has_object_file_with_flags(const struct object_id *oid, int flags);\n+int repo_has_object_file(struct repository *r, const struct object_id *oid);\n+int repo_has_object_file_with_flags(struct repository *r,\n+\t\t\t\t    const struct object_id *oid, int flags);\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define has_object_file(oid) repo_has_object_file(the_repository, oid)\n+#define has_object_file_with_flags(oid, flags) repo_has_object_file_with_flags(the_repository, oid, flags)\n+#endif\n \n /*\n  * Return true iff an alternate object database has a loose object\ndiff --git a/sha1-file.c b/sha1-file.c\nindex c5b704aec5..e77273ccfd 100644\n--- a/sha1-file.c\n+++ b/sha1-file.c\n@@ -1768,24 +1768,27 @@ int force_object_loose(const struct object_id *oid, time_t mtime)\n \treturn ret;\n }\n \n-int has_sha1_file_with_flags(const unsigned char *sha1, int flags)\n+int repo_has_sha1_file_with_flags(struct repository *r,\n+\t\t\t\t  const unsigned char *sha1, int flags)\n {\n \tstruct object_id oid;\n \tif (!startup_info->have_repository)\n \t\treturn 0;\n \thashcpy(oid.hash, sha1);\n-\treturn oid_object_info_extended(the_repository, &oid, NULL,\n+\treturn oid_object_info_extended(r, &oid, NULL,\n \t\t\t\t\tflags | OBJECT_INFO_SKIP_CACHED) >= 0;\n }\n \n-int has_object_file(const struct object_id *oid)\n+int repo_has_object_file(struct repository *r,\n+\t\t\t const struct object_id *oid)\n {\n-\treturn has_sha1_file(oid->hash);\n+\treturn repo_has_sha1_file(r, oid->hash);\n }\n \n-int has_object_file_with_flags(const struct object_id *oid, int flags)\n+int repo_has_object_file_with_flags(struct repository *r,\n+\t\t\t\t    const struct object_id *oid, int flags)\n {\n-\treturn has_sha1_file_with_flags(oid->hash, flags);\n+\treturn repo_has_sha1_file_with_flags(r, oid->hash, flags);\n }\n \n static void check_tree(const void *buf, size_t size)\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363243","messageId":"20181114001306.138053-7-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 06/23] object: parse_object to honor its repository argument","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:49Z","receivedAt":"2018-11-14T00:13:48Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"In 8e4b0b6047 (object.c: allow parse_object to handle\narbitrary repositories, 2018-06-28), we forgot to pass the\nrepository down to the read_object_file.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n object.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/object.c b/object.c\nindex e54160550c..003f870484 100644\n--- a/object.c\n+++ b/object.c\n@@ -259,8 +259,8 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)\n \tif (obj && obj->parsed)\n \t\treturn obj;\n \n-\tif ((obj && obj->type == OBJ_BLOB && has_object_file(oid)) ||\n-\t    (!obj && has_object_file(oid) &&\n+\tif ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||\n+\t    (!obj && repo_has_object_file(r, oid) &&\n \t     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {\n \t\tif (check_object_signature(repl, NULL, 0, NULL) < 0) {\n \t\t\terror(_(\"sha1 mismatch %s\"), oid_to_hex(oid));\n@@ -270,7 +270,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)\n \t\treturn lookup_object(r, oid->hash);\n \t}\n \n-\tbuffer = read_object_file(oid, &type, &size);\n+\tbuffer = repo_read_object_file(r, oid, &type, &size);\n \tif (buffer) {\n \t\tif (check_object_signature(repl, buffer, size, type_name(type)) < 0) {\n \t\t\tfree(buffer);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363244","messageId":"20181114001306.138053-8-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 07/23] commit: allow parse_commit* to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:50Z","receivedAt":"2018-11-14T00:13:51Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Just like the previous commit, parse_commit and friends are used a lot\nand are found in new patches, so we cannot change their signature easily.\n\nRe-introduce these function prefixed with 'repo_' that take a repository\nargument and keep the original as a shallow macro.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n commit.c                                      | 18 ++++++++------\n commit.h                                      | 17 +++++++++----\n .../coccinelle/the_repository.pending.cocci   | 24 +++++++++++++++++++\n 3 files changed, 48 insertions(+), 11 deletions(-)\n\ndiff --git a/commit.c b/commit.c\nindex dc8a39d52a..7a931d7fd4 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -443,7 +443,10 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b\n \treturn 0;\n }\n \n-int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_commit_graph)\n+int repo_parse_commit_internal(struct repository *r,\n+\t\t\t       struct commit *item,\n+\t\t\t       int quiet_on_missing,\n+\t\t\t       int use_commit_graph)\n {\n \tenum object_type type;\n \tvoid *buffer;\n@@ -454,9 +457,9 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com\n \t\treturn -1;\n \tif (item->object.parsed)\n \t\treturn 0;\n-\tif (use_commit_graph && parse_commit_in_graph(the_repository, item))\n+\tif (use_commit_graph && parse_commit_in_graph(r, item))\n \t\treturn 0;\n-\tbuffer = read_object_file(&item->object.oid, &type, &size);\n+\tbuffer = repo_read_object_file(r, &item->object.oid, &type, &size);\n \tif (!buffer)\n \t\treturn quiet_on_missing ? -1 :\n \t\t\terror(\"Could not read %s\",\n@@ -467,18 +470,19 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com\n \t\t\t     oid_to_hex(&item->object.oid));\n \t}\n \n-\tret = parse_commit_buffer(the_repository, item, buffer, size, 0);\n+\tret = parse_commit_buffer(r, item, buffer, size, 0);\n \tif (save_commit_buffer && !ret) {\n-\t\tset_commit_buffer(the_repository, item, buffer, size);\n+\t\tset_commit_buffer(r, item, buffer, size);\n \t\treturn 0;\n \t}\n \tfree(buffer);\n \treturn ret;\n }\n \n-int parse_commit_gently(struct commit *item, int quiet_on_missing)\n+int repo_parse_commit_gently(struct repository *r,\n+\t\t\t     struct commit *item, int quiet_on_missing)\n {\n-\treturn parse_commit_internal(item, quiet_on_missing, 1);\n+\treturn repo_parse_commit_internal(r, item, quiet_on_missing, 1);\n }\n \n void parse_commit_or_die(struct commit *item)\ndiff --git a/commit.h b/commit.h\nindex 1d260d62f5..08935f9a19 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -79,12 +79,21 @@ struct commit *lookup_commit_reference_by_name(const char *name);\n struct commit *lookup_commit_or_die(const struct object_id *oid, const char *ref_name);\n \n int parse_commit_buffer(struct repository *r, struct commit *item, const void *buffer, unsigned long size, int check_graph);\n-int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_commit_graph);\n-int parse_commit_gently(struct commit *item, int quiet_on_missing);\n-static inline int parse_commit(struct commit *item)\n+int repo_parse_commit_internal(struct repository *r, struct commit *item,\n+\t\t\t       int quiet_on_missing, int use_commit_graph);\n+int repo_parse_commit_gently(struct repository *r,\n+\t\t\t     struct commit *item,\n+\t\t\t     int quiet_on_missing);\n+static inline int repo_parse_commit(struct repository *r, struct commit *item)\n {\n-\treturn parse_commit_gently(item, 0);\n+\treturn repo_parse_commit_gently(r, item, 0);\n }\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define parse_commit_internal(item, quiet, use) repo_parse_commit_internal(the_repository, item, quiet, use)\n+#define parse_commit_gently(item, quiet) repo_parse_commit_gently(the_repository, item, quiet)\n+#define parse_commit(item) repo_parse_commit(the_repository, item)\n+#endif\n+\n void parse_commit_or_die(struct commit *item);\n \n struct buffer_slab;\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex 46f3a1b23a..b185fe0a1d 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -40,3 +40,27 @@ expression F;\n - has_object_file_with_flags(\n + repo_has_object_file_with_flags(the_repository,\n   E)\n+\n+@@\n+expression E;\n+expression F;\n+expression G;\n+@@\n+- parse_commit_internal(\n++ repo_parse_commit_internal(the_repository,\n+  E, F, G)\n+\n+@@\n+expression E;\n+expression F;\n+@@\n+- parse_commit_gently(\n++ repo_parse_commit_gently(the_repository,\n+  E, F)\n+\n+@@\n+expression E;\n+@@\n+- parse_commit(\n++ repo_parse_commit(the_repository,\n+  E)\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363245","messageId":"20181114001306.138053-9-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 08/23] commit-reach.c: allow paint_down_to_common to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:51Z","receivedAt":"2018-11-14T00:13:54Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"As the function is file local and not widely used, migrate it all at once.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n commit-reach.c | 15 +++++++++------\n 1 file changed, 9 insertions(+), 6 deletions(-)\n\ndiff --git a/commit-reach.c b/commit-reach.c\nindex 9f79ce0a22..67c2e43d5e 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -30,7 +30,8 @@ static int queue_has_nonstale(struct prio_queue *queue)\n }\n \n /* all input commits in one and twos[] must have been parsed! */\n-static struct commit_list *paint_down_to_common(struct commit *one, int n,\n+static struct commit_list *paint_down_to_common(struct repository *r,\n+\t\t\t\t\t\tstruct commit *one, int n,\n \t\t\t\t\t\tstruct commit **twos,\n \t\t\t\t\t\tint min_generation)\n {\n@@ -83,7 +84,7 @@ static struct commit_list *paint_down_to_common(struct commit *one, int n,\n \t\t\tparents = parents->next;\n \t\t\tif ((p->object.flags & flags) == flags)\n \t\t\t\tcontinue;\n-\t\t\tif (parse_commit(p))\n+\t\t\tif (repo_parse_commit(r, p))\n \t\t\t\treturn NULL;\n \t\t\tp->object.flags |= flags;\n \t\t\tprio_queue_put(&queue, p);\n@@ -116,7 +117,7 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co\n \t\t\treturn NULL;\n \t}\n \n-\tlist = paint_down_to_common(one, n, twos, 0);\n+\tlist = paint_down_to_common(the_repository, one, n, twos, 0);\n \n \twhile (list) {\n \t\tstruct commit *commit = pop_commit(&list);\n@@ -187,8 +188,8 @@ static int remove_redundant(struct commit **array, int cnt)\n \t\t\tif (array[j]->generation < min_generation)\n \t\t\t\tmin_generation = array[j]->generation;\n \t\t}\n-\t\tcommon = paint_down_to_common(array[i], filled, work,\n-\t\t\t\t\t      min_generation);\n+\t\tcommon = paint_down_to_common(the_repository, array[i], filled,\n+\t\t\t\t\t      work, min_generation);\n \t\tif (array[i]->object.flags & PARENT2)\n \t\t\tredundant[i] = 1;\n \t\tfor (j = 0; j < filled; j++)\n@@ -322,7 +323,9 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *\n \tif (commit->generation > min_generation)\n \t\treturn ret;\n \n-\tbases = paint_down_to_common(commit, nr_reference, reference, commit->generation);\n+\tbases = paint_down_to_common(the_repository, commit,\n+\t\t\t\t     nr_reference, reference,\n+\t\t\t\t     commit->generation);\n \tif (commit->object.flags & PARENT2)\n \t\tret = 1;\n \tclear_commit_marks(commit, all_flags);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363246","messageId":"20181114001306.138053-10-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 09/23] commit-reach.c: allow merge_bases_many to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:52Z","receivedAt":"2018-11-14T00:13:56Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n commit-reach.c | 12 +++++++-----\n 1 file changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/commit-reach.c b/commit-reach.c\nindex 67c2e43d5e..a53b31e6a2 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -95,7 +95,9 @@ static struct commit_list *paint_down_to_common(struct repository *r,\n \treturn result;\n }\n \n-static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)\n+static struct commit_list *merge_bases_many(struct repository *r,\n+\t\t\t\t\t    struct commit *one, int n,\n+\t\t\t\t\t    struct commit **twos)\n {\n \tstruct commit_list *list = NULL;\n \tstruct commit_list *result = NULL;\n@@ -110,14 +112,14 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co\n \t\t\treturn commit_list_insert(one, &result);\n \t}\n \n-\tif (parse_commit(one))\n+\tif (repo_parse_commit(r, one))\n \t\treturn NULL;\n \tfor (i = 0; i < n; i++) {\n-\t\tif (parse_commit(twos[i]))\n+\t\tif (repo_parse_commit(r, twos[i]))\n \t\t\treturn NULL;\n \t}\n \n-\tlist = paint_down_to_common(the_repository, one, n, twos, 0);\n+\tlist = paint_down_to_common(r, one, n, twos, 0);\n \n \twhile (list) {\n \t\tstruct commit *commit = pop_commit(&list);\n@@ -224,7 +226,7 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one,\n \tstruct commit_list *result;\n \tint cnt, i;\n \n-\tresult = merge_bases_many(one, n, twos);\n+\tresult = merge_bases_many(the_repository, one, n, twos);\n \tfor (i = 0; i < n; i++) {\n \t\tif (one == twos[i])\n \t\t\treturn result;\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363247","messageId":"20181114001306.138053-11-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 10/23] commit-reach.c: allow remove_redundant to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:53Z","receivedAt":"2018-11-14T00:13:58Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n commit-reach.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/commit-reach.c b/commit-reach.c\nindex a53b31e6a2..81015830cb 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -156,7 +156,7 @@ struct commit_list *get_octopus_merge_bases(struct commit_list *in)\n \treturn ret;\n }\n \n-static int remove_redundant(struct commit **array, int cnt)\n+static int remove_redundant(struct repository *r, struct commit **array, int cnt)\n {\n \t/*\n \t * Some commit in the array may be an ancestor of\n@@ -174,7 +174,7 @@ static int remove_redundant(struct commit **array, int cnt)\n \tALLOC_ARRAY(filled_index, cnt - 1);\n \n \tfor (i = 0; i < cnt; i++)\n-\t\tparse_commit(array[i]);\n+\t\trepo_parse_commit(r, array[i]);\n \tfor (i = 0; i < cnt; i++) {\n \t\tstruct commit_list *common;\n \t\tuint32_t min_generation = array[i]->generation;\n@@ -190,7 +190,7 @@ static int remove_redundant(struct commit **array, int cnt)\n \t\t\tif (array[j]->generation < min_generation)\n \t\t\t\tmin_generation = array[j]->generation;\n \t\t}\n-\t\tcommon = paint_down_to_common(the_repository, array[i], filled,\n+\t\tcommon = paint_down_to_common(r, array[i], filled,\n \t\t\t\t\t      work, min_generation);\n \t\tif (array[i]->object.flags & PARENT2)\n \t\t\tredundant[i] = 1;\n@@ -249,7 +249,7 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one,\n \tclear_commit_marks(one, all_flags);\n \tclear_commit_marks_many(n, twos, all_flags);\n \n-\tcnt = remove_redundant(rslt, cnt);\n+\tcnt = remove_redundant(the_repository, rslt, cnt);\n \tresult = NULL;\n \tfor (i = 0; i < cnt; i++)\n \t\tcommit_list_insert_by_date(rslt[i], &result);\n@@ -370,7 +370,7 @@ struct commit_list *reduce_heads(struct commit_list *heads)\n \t\t\tp->item->object.flags &= ~STALE;\n \t\t}\n \t}\n-\tnum_head = remove_redundant(array, num_head);\n+\tnum_head = remove_redundant(the_repository, array, num_head);\n \tfor (i = 0; i < num_head; i++)\n \t\ttail = &commit_list_insert(array[i], tail)->next;\n \tfree(array);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363248","messageId":"20181114001306.138053-12-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 11/23] commit-reach.c: allow get_merge_bases_many_0 to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:54Z","receivedAt":"2018-11-14T00:14:01Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n commit-reach.c | 13 +++++++------\n 1 file changed, 7 insertions(+), 6 deletions(-)\n\ndiff --git a/commit-reach.c b/commit-reach.c\nindex 81015830cb..b3b1f62aba 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -216,7 +216,8 @@ static int remove_redundant(struct repository *r, struct commit **array, int cnt\n \treturn filled;\n }\n \n-static struct commit_list *get_merge_bases_many_0(struct commit *one,\n+static struct commit_list *get_merge_bases_many_0(struct repository *r,\n+\t\t\t\t\t\t  struct commit *one,\n \t\t\t\t\t\t  int n,\n \t\t\t\t\t\t  struct commit **twos,\n \t\t\t\t\t\t  int cleanup)\n@@ -226,7 +227,7 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one,\n \tstruct commit_list *result;\n \tint cnt, i;\n \n-\tresult = merge_bases_many(the_repository, one, n, twos);\n+\tresult = merge_bases_many(r, one, n, twos);\n \tfor (i = 0; i < n; i++) {\n \t\tif (one == twos[i])\n \t\t\treturn result;\n@@ -249,7 +250,7 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one,\n \tclear_commit_marks(one, all_flags);\n \tclear_commit_marks_many(n, twos, all_flags);\n \n-\tcnt = remove_redundant(the_repository, rslt, cnt);\n+\tcnt = remove_redundant(r, rslt, cnt);\n \tresult = NULL;\n \tfor (i = 0; i < cnt; i++)\n \t\tcommit_list_insert_by_date(rslt[i], &result);\n@@ -261,19 +262,19 @@ struct commit_list *get_merge_bases_many(struct commit *one,\n \t\t\t\t\t int n,\n \t\t\t\t\t struct commit **twos)\n {\n-\treturn get_merge_bases_many_0(one, n, twos, 1);\n+\treturn get_merge_bases_many_0(the_repository, one, n, twos, 1);\n }\n \n struct commit_list *get_merge_bases_many_dirty(struct commit *one,\n \t\t\t\t\t       int n,\n \t\t\t\t\t       struct commit **twos)\n {\n-\treturn get_merge_bases_many_0(one, n, twos, 0);\n+\treturn get_merge_bases_many_0(the_repository, one, n, twos, 0);\n }\n \n struct commit_list *get_merge_bases(struct commit *one, struct commit *two)\n {\n-\treturn get_merge_bases_many_0(one, 1, &two, 1);\n+\treturn get_merge_bases_many_0(the_repository, one, 1, &two, 1);\n }\n \n /*\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363249","messageId":"20181114001306.138053-13-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 12/23] commit-reach: prepare get_merge_bases to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:55Z","receivedAt":"2018-11-14T00:14:03Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Similarly to previous patches, the get_merge_base functions are used\noften in the code base, which makes migrating them hard.\n\nImplement the new functions, prefixed with 'repo_' and hide the old\nfunctions behind a wrapper macro.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n commit-reach.c                                | 24 ++++++++++-------\n commit-reach.h                                | 26 ++++++++++++-------\n .../coccinelle/the_repository.pending.cocci   | 26 +++++++++++++++++++\n 3 files changed, 56 insertions(+), 20 deletions(-)\n\ndiff --git a/commit-reach.c b/commit-reach.c\nindex b3b1f62aba..657a4e9b5a 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -258,23 +258,27 @@ static struct commit_list *get_merge_bases_many_0(struct repository *r,\n \treturn result;\n }\n \n-struct commit_list *get_merge_bases_many(struct commit *one,\n-\t\t\t\t\t int n,\n-\t\t\t\t\t struct commit **twos)\n+struct commit_list *repo_get_merge_bases_many(struct repository *r,\n+\t\t\t\t\t      struct commit *one,\n+\t\t\t\t\t      int n,\n+\t\t\t\t\t      struct commit **twos)\n {\n-\treturn get_merge_bases_many_0(the_repository, one, n, twos, 1);\n+\treturn get_merge_bases_many_0(r, one, n, twos, 1);\n }\n \n-struct commit_list *get_merge_bases_many_dirty(struct commit *one,\n-\t\t\t\t\t       int n,\n-\t\t\t\t\t       struct commit **twos)\n+struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,\n+\t\t\t\t\t\t    struct commit *one,\n+\t\t\t\t\t\t    int n,\n+\t\t\t\t\t\t    struct commit **twos)\n {\n-\treturn get_merge_bases_many_0(the_repository, one, n, twos, 0);\n+\treturn get_merge_bases_many_0(r, one, n, twos, 0);\n }\n \n-struct commit_list *get_merge_bases(struct commit *one, struct commit *two)\n+struct commit_list *repo_get_merge_bases(struct repository *r,\n+\t\t\t\t\t struct commit *one,\n+\t\t\t\t\t struct commit *two)\n {\n-\treturn get_merge_bases_many_0(the_repository, one, 1, &two, 1);\n+\treturn get_merge_bases_many_0(r, one, 1, &two, 1);\n }\n \n /*\ndiff --git a/commit-reach.h b/commit-reach.h\nindex 7d313e2975..52667d64ac 100644\n--- a/commit-reach.h\n+++ b/commit-reach.h\n@@ -8,17 +8,23 @@ struct commit_list;\n struct contains_cache;\n struct ref_filter;\n \n-struct commit_list *get_merge_bases_many(struct commit *one,\n-\t\t\t\t\t int n,\n-\t\t\t\t\t struct commit **twos);\n-struct commit_list *get_merge_bases_many_dirty(struct commit *one,\n-\t\t\t\t\t       int n,\n-\t\t\t\t\t       struct commit **twos);\n-struct commit_list *get_merge_bases(struct commit *one, struct commit *two);\n-struct commit_list *get_octopus_merge_bases(struct commit_list *in);\n-\n+struct commit_list *repo_get_merge_bases(struct repository *r,\n+\t\t\t\t\t struct commit *rev1,\n+\t\t\t\t\t struct commit *rev2);\n+struct commit_list *repo_get_merge_bases_many(struct repository *r,\n+\t\t\t\t\t      struct commit *one, int n,\n+\t\t\t\t\t      struct commit **twos);\n /* To be used only when object flags after this call no longer matter */\n-struct commit_list *get_merge_bases_many_dirty(struct commit *one, int n, struct commit **twos);\n+struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,\n+\t\t\t\t\t\t    struct commit *one, int n,\n+\t\t\t\t\t\t    struct commit **twos);\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define get_merge_bases(r1, r2)           repo_get_merge_bases(the_repository, r1, r2)\n+#define get_merge_bases_many(one, n, two) repo_get_merge_bases_many(the_repository, one, n, two)\n+#define get_merge_bases_many_dirty(one, n, twos) repo_get_merge_bases_many_dirty(the_repository, one, n, twos)\n+#endif\n+\n+struct commit_list *get_octopus_merge_bases(struct commit_list *in);\n \n int is_descendant_of(struct commit *commit, struct commit_list *with_commit);\n int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex b185fe0a1d..f6c2915a4e 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -64,3 +64,29 @@ expression E;\n - parse_commit(\n + repo_parse_commit(the_repository,\n   E)\n+\n+@@\n+expression E;\n+expression F;\n+@@\n+- get_merge_bases(\n++ repo_get_merge_bases(the_repository,\n+  E, F);\n+\n+@@\n+expression E;\n+expression F;\n+expression G;\n+@@\n+- get_merge_bases_many(\n++ repo_get_merge_bases_many(the_repository,\n+  E, F, G);\n+\n+@@\n+expression E;\n+expression F;\n+expression G;\n+@@\n+- get_merge_bases_many_dirty(\n++ repo_get_merge_bases_many_dirty(the_repository,\n+  E, F, G);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363250","messageId":"20181114001306.138053-14-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 13/23] commit-reach: prepare in_merge_bases[_many] to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:56Z","receivedAt":"2018-11-14T00:14:06Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n commit-reach.c                                  | 15 +++++++++------\n commit-reach.h                                  | 12 ++++++++++--\n contrib/coccinelle/the_repository.pending.cocci | 17 +++++++++++++++++\n 3 files changed, 36 insertions(+), 8 deletions(-)\n\ndiff --git a/commit-reach.c b/commit-reach.c\nindex 657a4e9b5a..8715008fef 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -312,16 +312,17 @@ int is_descendant_of(struct commit *commit, struct commit_list *with_commit)\n /*\n  * Is \"commit\" an ancestor of one of the \"references\"?\n  */\n-int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference)\n+int repo_in_merge_bases_many(struct repository *r, struct commit *commit,\n+\t\t\t     int nr_reference, struct commit **reference)\n {\n \tstruct commit_list *bases;\n \tint ret = 0, i;\n \tuint32_t min_generation = GENERATION_NUMBER_INFINITY;\n \n-\tif (parse_commit(commit))\n+\tif (repo_parse_commit(r, commit))\n \t\treturn ret;\n \tfor (i = 0; i < nr_reference; i++) {\n-\t\tif (parse_commit(reference[i]))\n+\t\tif (repo_parse_commit(r, reference[i]))\n \t\t\treturn ret;\n \t\tif (reference[i]->generation < min_generation)\n \t\t\tmin_generation = reference[i]->generation;\n@@ -330,7 +331,7 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *\n \tif (commit->generation > min_generation)\n \t\treturn ret;\n \n-\tbases = paint_down_to_common(the_repository, commit,\n+\tbases = paint_down_to_common(r, commit,\n \t\t\t\t     nr_reference, reference,\n \t\t\t\t     commit->generation);\n \tif (commit->object.flags & PARENT2)\n@@ -344,9 +345,11 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *\n /*\n  * Is \"commit\" an ancestor of (i.e. reachable from) the \"reference\"?\n  */\n-int in_merge_bases(struct commit *commit, struct commit *reference)\n+int repo_in_merge_bases(struct repository *r,\n+\t\t\tstruct commit *commit,\n+\t\t\tstruct commit *reference)\n {\n-\treturn in_merge_bases_many(commit, 1, &reference);\n+\treturn repo_in_merge_bases_many(r, commit, 1, &reference);\n }\n \n struct commit_list *reduce_heads(struct commit_list *heads)\ndiff --git a/commit-reach.h b/commit-reach.h\nindex 52667d64ac..a0d4a29d25 100644\n--- a/commit-reach.h\n+++ b/commit-reach.h\n@@ -27,8 +27,16 @@ struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,\n struct commit_list *get_octopus_merge_bases(struct commit_list *in);\n \n int is_descendant_of(struct commit *commit, struct commit_list *with_commit);\n-int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);\n-int in_merge_bases(struct commit *commit, struct commit *reference);\n+int repo_in_merge_bases(struct repository *r,\n+\t\t\tstruct commit *commit,\n+\t\t\tstruct commit *reference);\n+int repo_in_merge_bases_many(struct repository *r,\n+\t\t\t     struct commit *commit,\n+\t\t\t     int nr_reference, struct commit **reference);\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define in_merge_bases(c1, c2) repo_in_merge_bases(the_repository, c1, c2)\n+#define in_merge_bases_many(c1, n, cs) repo_in_merge_bases_many(the_repository, c1, n, cs)\n+#endif\n \n /*\n  * Takes a list of commits and returns a new list where those\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex f6c2915a4e..8c6a71bf64 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -90,3 +90,20 @@ expression G;\n - get_merge_bases_many_dirty(\n + repo_get_merge_bases_many_dirty(the_repository,\n   E, F, G);\n+\n+@@\n+expression E;\n+expression F;\n+@@\n+- in_merge_bases(\n++ repo_in_merge_bases(the_repository,\n+  E, F);\n+\n+@@\n+expression E;\n+expression F;\n+expression G;\n+@@\n+- in_merge_bases_many(\n++ repo_in_merge_bases_many(the_repository,\n+  E, F, G);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363251","messageId":"20181114001306.138053-15-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 14/23] commit: prepare get_commit_buffer to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:57Z","receivedAt":"2018-11-14T00:14:09Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n commit.c                                        | 8 +++++---\n commit.h                                        | 7 ++++++-\n contrib/coccinelle/the_repository.pending.cocci | 8 ++++++++\n 3 files changed, 19 insertions(+), 4 deletions(-)\n\ndiff --git a/commit.c b/commit.c\nindex 7a931d7fd4..4034def16c 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -297,13 +297,15 @@ const void *get_cached_commit_buffer(struct repository *r, const struct commit *\n \treturn v->buffer;\n }\n \n-const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)\n+const void *repo_get_commit_buffer(struct repository *r,\n+\t\t\t\t   const struct commit *commit,\n+\t\t\t\t   unsigned long *sizep)\n {\n-\tconst void *ret = get_cached_commit_buffer(the_repository, commit, sizep);\n+\tconst void *ret = get_cached_commit_buffer(r, commit, sizep);\n \tif (!ret) {\n \t\tenum object_type type;\n \t\tunsigned long size;\n-\t\tret = read_object_file(&commit->object.oid, &type, &size);\n+\t\tret = repo_read_object_file(r, &commit->object.oid, &type, &size);\n \t\tif (!ret)\n \t\t\tdie(\"cannot read commit object %s\",\n \t\t\t    oid_to_hex(&commit->object.oid));\ndiff --git a/commit.h b/commit.h\nindex 08935f9a19..591a77a5bb 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -117,7 +117,12 @@ const void *get_cached_commit_buffer(struct repository *, const struct commit *,\n  * from disk. The resulting memory should not be modified, and must be given\n  * to unuse_commit_buffer when the caller is done.\n  */\n-const void *get_commit_buffer(const struct commit *, unsigned long *size);\n+const void *repo_get_commit_buffer(struct repository *r,\n+\t\t\t\t   const struct commit *,\n+\t\t\t\t   unsigned long *size);\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define get_commit_buffer(c, s) repo_get_commit_buffer(the_repository, c, s)\n+#endif\n \n /*\n  * Tell the commit subsytem that we are done with a particular commit buffer.\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex 8c6a71bf64..4018e6eaf7 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -107,3 +107,11 @@ expression G;\n - in_merge_bases_many(\n + repo_in_merge_bases_many(the_repository,\n   E, F, G);\n+\n+@@\n+expression E;\n+expression F;\n+@@\n+- get_commit_buffer(\n++ repo_get_commit_buffer(the_repository,\n+  E, F);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363252","messageId":"20181114001306.138053-16-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 15/23] commit: prepare repo_unuse_commit_buffer to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:58Z","receivedAt":"2018-11-14T00:14:12Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n commit.c                                        | 6 ++++--\n commit.h                                        | 7 ++++++-\n contrib/coccinelle/the_repository.pending.cocci | 8 ++++++++\n 3 files changed, 18 insertions(+), 3 deletions(-)\n\ndiff --git a/commit.c b/commit.c\nindex 4034def16c..7d2f3a9a93 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -318,10 +318,12 @@ const void *repo_get_commit_buffer(struct repository *r,\n \treturn ret;\n }\n \n-void unuse_commit_buffer(const struct commit *commit, const void *buffer)\n+void repo_unuse_commit_buffer(struct repository *r,\n+\t\t\t      const struct commit *commit,\n+\t\t\t      const void *buffer)\n {\n \tstruct commit_buffer *v = buffer_slab_peek(\n-\t\tthe_repository->parsed_objects->buffer_slab, commit);\n+\t\tr->parsed_objects->buffer_slab, commit);\n \tif (!(v && v->buffer == buffer))\n \t\tfree((void *)buffer);\n }\ndiff --git a/commit.h b/commit.h\nindex 591a77a5bb..57375e3239 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -130,7 +130,12 @@ const void *repo_get_commit_buffer(struct repository *r,\n  * from an earlier call to get_commit_buffer.  The buffer may or may not be\n  * freed by this call; callers should not access the memory afterwards.\n  */\n-void unuse_commit_buffer(const struct commit *, const void *buffer);\n+void repo_unuse_commit_buffer(struct repository *r,\n+\t\t\t      const struct commit *,\n+\t\t\t      const void *buffer);\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define unuse_commit_buffer(c, b) repo_unuse_commit_buffer(the_repository, c, b)\n+#endif\n \n /*\n  * Free any cached object buffer associated with the commit.\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex 4018e6eaf7..516f19ffee 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -115,3 +115,11 @@ expression F;\n - get_commit_buffer(\n + repo_get_commit_buffer(the_repository,\n   E, F);\n+\n+@@\n+expression E;\n+expression F;\n+@@\n+- unuse_commit_buffer(\n++ repo_unuse_commit_buffer(the_repository,\n+  E, F);\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363253","messageId":"20181114001306.138053-17-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 16/23] commit: prepare logmsg_reencode to handle arbitrary repositories","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:12:59Z","receivedAt":"2018-11-14T00:14:15Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n commit.h                                        |  8 ++++++++\n contrib/coccinelle/the_repository.pending.cocci |  9 +++++++++\n pretty.c                                        | 13 +++++++------\n 3 files changed, 24 insertions(+), 6 deletions(-)\n\ndiff --git a/commit.h b/commit.h\nindex 57375e3239..2e6b799b26 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -180,6 +180,14 @@ extern int has_non_ascii(const char *text);\n extern const char *logmsg_reencode(const struct commit *commit,\n \t\t\t\t   char **commit_encoding,\n \t\t\t\t   const char *output_encoding);\n+const char *repo_logmsg_reencode(struct repository *r,\n+\t\t\t\t const struct commit *commit,\n+\t\t\t\t char **commit_encoding,\n+\t\t\t\t const char *output_encoding);\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define logmsg_reencode(c, enc, out) repo_logmsg_reencode(the_repository, c, enc, out)\n+#endif\n+\n extern const char *skip_blank_lines(const char *msg);\n \n /** Removes the first commit from a list sorted by date, and adds all\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex 516f19ffee..f5b42cfc62 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -123,3 +123,12 @@ expression F;\n - unuse_commit_buffer(\n + repo_unuse_commit_buffer(the_repository,\n   E, F);\n+\n+@@\n+expression E;\n+expression F;\n+expression G;\n+@@\n+- logmsg_reencode(\n++ repo_logmsg_reencode(the_repository,\n+  E, F, G);\ndiff --git a/pretty.c b/pretty.c\nindex 8ca29e9281..b359b68750 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -595,14 +595,15 @@ static char *replace_encoding_header(char *buf, const char *encoding)\n \treturn strbuf_detach(&tmp, NULL);\n }\n \n-const char *logmsg_reencode(const struct commit *commit,\n-\t\t\t    char **commit_encoding,\n-\t\t\t    const char *output_encoding)\n+const char *repo_logmsg_reencode(struct repository *r,\n+\t\t\t\t const struct commit *commit,\n+\t\t\t\t char **commit_encoding,\n+\t\t\t\t const char *output_encoding)\n {\n \tstatic const char *utf8 = \"UTF-8\";\n \tconst char *use_encoding;\n \tchar *encoding;\n-\tconst char *msg = get_commit_buffer(commit, NULL);\n+\tconst char *msg = repo_get_commit_buffer(r, commit, NULL);\n \tchar *out;\n \n \tif (!output_encoding || !*output_encoding) {\n@@ -630,7 +631,7 @@ const char *logmsg_reencode(const struct commit *commit,\n \t\t * the cached copy from get_commit_buffer, we need to duplicate it\n \t\t * to avoid munging the cached copy.\n \t\t */\n-\t\tif (msg == get_cached_commit_buffer(the_repository, commit, NULL))\n+\t\tif (msg == get_cached_commit_buffer(r, commit, NULL))\n \t\t\tout = xstrdup(msg);\n \t\telse\n \t\t\tout = (char *)msg;\n@@ -644,7 +645,7 @@ const char *logmsg_reencode(const struct commit *commit,\n \t\t */\n \t\tout = reencode_string(msg, output_encoding, use_encoding);\n \t\tif (out)\n-\t\t\tunuse_commit_buffer(commit, msg);\n+\t\t\trepo_unuse_commit_buffer(r, commit, msg);\n \t}\n \n \t/*\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363254","messageId":"20181114001306.138053-18-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 17/23] pretty: prepare format_commit_message to handle arbitrary repositories","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:13:00Z","receivedAt":"2018-11-14T00:14:17Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n contrib/coccinelle/the_repository.pending.cocci | 10 ++++++++++\n pretty.c                                        | 15 ++++++++-------\n pretty.h                                        |  7 ++++++-\n 3 files changed, 24 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci\nindex f5b42cfc62..2ee702ecf7 100644\n--- a/contrib/coccinelle/the_repository.pending.cocci\n+++ b/contrib/coccinelle/the_repository.pending.cocci\n@@ -132,3 +132,13 @@ expression G;\n - logmsg_reencode(\n + repo_logmsg_reencode(the_repository,\n   E, F, G);\n+\n+@@\n+expression E;\n+expression F;\n+expression G;\n+expression H;\n+@@\n+- format_commit_message(\n++ repo_format_commit_message(the_repository,\n+  E, F, G, H);\ndiff --git a/pretty.c b/pretty.c\nindex b359b68750..3240495308 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -1508,9 +1508,10 @@ void userformat_find_requirements(const char *fmt, struct userformat_want *w)\n \tstrbuf_release(&dummy);\n }\n \n-void format_commit_message(const struct commit *commit,\n-\t\t\t   const char *format, struct strbuf *sb,\n-\t\t\t   const struct pretty_print_context *pretty_ctx)\n+void repo_format_commit_message(struct repository *r,\n+\t\t\t\tconst struct commit *commit,\n+\t\t\t\tconst char *format, struct strbuf *sb,\n+\t\t\t\tconst struct pretty_print_context *pretty_ctx)\n {\n \tstruct format_commit_context context;\n \tconst char *output_enc = pretty_ctx->output_encoding;\n@@ -1524,9 +1525,9 @@ void format_commit_message(const struct commit *commit,\n \t * convert a commit message to UTF-8 first\n \t * as far as 'format_commit_item' assumes it in UTF-8\n \t */\n-\tcontext.message = logmsg_reencode(commit,\n-\t\t\t\t\t  &context.commit_encoding,\n-\t\t\t\t\t  utf8);\n+\tcontext.message = repo_logmsg_reencode(r, commit,\n+\t\t\t\t\t       &context.commit_encoding,\n+\t\t\t\t\t       utf8);\n \n \tstrbuf_expand(sb, format, format_commit_item, &context);\n \trewrap_message_tail(sb, &context, 0, 0, 0);\n@@ -1550,7 +1551,7 @@ void format_commit_message(const struct commit *commit,\n \t}\n \n \tfree(context.commit_encoding);\n-\tunuse_commit_buffer(commit, context.message);\n+\trepo_unuse_commit_buffer(r, commit, context.message);\n }\n \n static void pp_header(struct pretty_print_context *pp,\ndiff --git a/pretty.h b/pretty.h\nindex 7359d318a9..e6625269cf 100644\n--- a/pretty.h\n+++ b/pretty.h\n@@ -103,9 +103,14 @@ void pp_remainder(struct pretty_print_context *pp, const char **msg_p,\n  * Put the result to \"sb\".\n  * Please use this function for custom formats.\n  */\n-void format_commit_message(const struct commit *commit,\n+void repo_format_commit_message(struct repository *r,\n+\t\t\tconst struct commit *commit,\n \t\t\tconst char *format, struct strbuf *sb,\n \t\t\tconst struct pretty_print_context *context);\n+#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS\n+#define format_commit_message(c, f, s, con) \\\n+\trepo_format_commit_message(the_repository, c, f, s, con)\n+#endif\n \n /*\n  * Parse given arguments from \"arg\", check it for correctness and\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363255","messageId":"20181114001306.138053-19-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 18/23] submodule: use submodule repos for object lookup","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:13:01Z","receivedAt":"2018-11-14T00:14:20Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"This converts the 'show_submodule_header' function to use\nthe repository API properly, such that the submodule objects\nare not added to the main object store.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n submodule.c | 73 ++++++++++++++++++++++++++++++++++++++++++-----------\n 1 file changed, 58 insertions(+), 15 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex d9d3046689..262f03f118 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,\n \treturn prepare_revision_walk(rev);\n }\n \n-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)\n+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)\n {\n \tstatic const char format[] = \"  %m %s\";\n \tstruct strbuf sb = STRBUF_INIT;\n@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o\n \t\tctx.date_mode = rev->date_mode;\n \t\tctx.output_encoding = get_log_output_encoding();\n \t\tstrbuf_setlen(&sb, 0);\n-\t\tformat_commit_message(commit, format, &sb, &ctx);\n+\t\trepo_format_commit_message(r, commit, format, &sb,\n+\t\t\t\t      &ctx);\n \t\tstrbuf_addch(&sb, '\\n');\n \t\tif (commit->object.flags & SYMMETRIC_LEFT)\n \t\t\tdiff_emit_submodule_del(o, sb.buf);\n@@ -481,14 +482,44 @@ void prepare_submodule_repo_env(struct argv_array *out)\n \t\t\t DEFAULT_GIT_DIR_ENVIRONMENT);\n }\n \n-/* Helper function to display the submodule header line prior to the full\n- * summary output. If it can locate the submodule objects directory it will\n- * attempt to lookup both the left and right commits and put them into the\n- * left and right pointers.\n+/*\n+ * Initialize 'out' based on the provided submodule path.\n+ *\n+ * Unlike repo_submodule_init, this tolerates submodules not present\n+ * in .gitmodules. This function exists only to preserve historical behavior,\n+ *\n+ * Returns 0 on success, -1 when the submodule is not present.\n  */\n-static void show_submodule_header(struct diff_options *o, const char *path,\n+static struct repository *open_submodule(const char *path)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tstruct repository *out = xmalloc(sizeof(*out));\n+\n+\tif (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {\n+\t\tstrbuf_release(&sb);\n+\t\tfree(out);\n+\t\treturn NULL;\n+\t}\n+\n+\tout->submodule_prefix = xstrdup(path);\n+\n+\tstrbuf_release(&sb);\n+\treturn out;\n+}\n+\n+/*\n+ * Helper function to display the submodule header line prior to the full\n+ * summary output.\n+ *\n+ * If it can locate the submodule git directory it will create a repository\n+ * handle for the submodule and lookup both the left and right commits and\n+ * put them into the left and right pointers.\n+ */\n+static void show_submodule_header(struct diff_options *o,\n+\t\tconst char *path,\n \t\tstruct object_id *one, struct object_id *two,\n \t\tunsigned dirty_submodule,\n+\t\tstruct repository *sub,\n \t\tstruct commit **left, struct commit **right,\n \t\tstruct commit_list **merge_bases)\n {\n@@ -507,7 +538,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,\n \telse if (is_null_oid(two))\n \t\tmessage = \"(submodule deleted)\";\n \n-\tif (add_submodule_odb(path)) {\n+\tif (!sub) {\n \t\tif (!message)\n \t\t\tmessage = \"(commits not present)\";\n \t\tgoto output_header;\n@@ -517,8 +548,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,\n \t * Attempt to lookup the commit references, and determine if this is\n \t * a fast forward or fast backwards update.\n \t */\n-\t*left = lookup_commit_reference(the_repository, one);\n-\t*right = lookup_commit_reference(the_repository, two);\n+\t*left = lookup_commit_reference(sub, one);\n+\t*right = lookup_commit_reference(sub, two);\n \n \t/*\n \t * Warn about missing commits in the submodule project, but only if\n@@ -528,7 +559,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,\n \t     (!is_null_oid(two) && !*right))\n \t\tmessage = \"(commits not present)\";\n \n-\t*merge_bases = get_merge_bases(*left, *right);\n+\t*merge_bases = repo_get_merge_bases(sub, *left, *right);\n \tif (*merge_bases) {\n \t\tif ((*merge_bases)->item == *left)\n \t\t\tfast_forward = 1;\n@@ -562,16 +593,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,\n \tstruct rev_info rev;\n \tstruct commit *left = NULL, *right = NULL;\n \tstruct commit_list *merge_bases = NULL;\n+\tstruct repository *sub;\n \n+\tsub = open_submodule(path);\n \tshow_submodule_header(o, path, one, two, dirty_submodule,\n-\t\t\t      &left, &right, &merge_bases);\n+\t\t\t      sub, &left, &right, &merge_bases);\n \n \t/*\n \t * If we don't have both a left and a right pointer, there is no\n \t * reason to try and display a summary. The header line should contain\n \t * all the information the user needs.\n \t */\n-\tif (!left || !right)\n+\tif (!left || !right || !sub)\n \t\tgoto out;\n \n \t/* Treat revision walker failure the same as missing commits */\n@@ -580,13 +613,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,\n \t\tgoto out;\n \t}\n \n-\tprint_submodule_summary(&rev, o);\n+\tprint_submodule_summary(sub, &rev, o);\n \n out:\n \tif (merge_bases)\n \t\tfree_commit_list(merge_bases);\n \tclear_commit_marks(left, ~0);\n \tclear_commit_marks(right, ~0);\n+\tif (sub) {\n+\t\trepo_clear(sub);\n+\t\tfree(sub);\n+\t}\n }\n \n void show_submodule_inline_diff(struct diff_options *o, const char *path,\n@@ -598,9 +635,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,\n \tstruct commit_list *merge_bases = NULL;\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tstruct strbuf sb = STRBUF_INIT;\n+\tstruct repository *sub;\n \n+\tsub = open_submodule(path);\n \tshow_submodule_header(o, path, one, two, dirty_submodule,\n-\t\t\t      &left, &right, &merge_bases);\n+\t\t\t      sub, &left, &right, &merge_bases);\n \n \t/* We need a valid left and right commit to display a difference */\n \tif (!(left || is_null_oid(one)) ||\n@@ -661,6 +700,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,\n \t\tclear_commit_marks(left, ~0);\n \tif (right)\n \t\tclear_commit_marks(right, ~0);\n+\tif (sub) {\n+\t\trepo_clear(sub);\n+\t\tfree(sub);\n+\t}\n }\n \n int should_update_submodules(void)\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363256","messageId":"20181114001306.138053-20-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 19/23] submodule: don't add submodule as odb for push","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:13:02Z","receivedAt":"2018-11-14T00:14:21Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"In push_submodule(), because we do not actually need access to objects\nin the submodule, do not invoke add_submodule_odb().\n(for_each_remote_ref_submodule() does not require access to those\nobjects, and the actual push is done by spawning another process,\nwhich handles object access by itself.)\n\nThis code of push_submodule() is exercised in t5531 and continues\nto work, showing that the submodule odbc is not needed.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n submodule.c | 3 ---\n 1 file changed, 3 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex 262f03f118..5818088df2 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1021,9 +1021,6 @@ static int push_submodule(const char *path,\n \t\t\t  const struct string_list *push_options,\n \t\t\t  int dry_run)\n {\n-\tif (add_submodule_odb(path))\n-\t\treturn 1;\n-\n \tif (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {\n \t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\targv_array_push(&cp.args, \"push\");\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363257","messageId":"20181114001306.138053-21-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 20/23] commit-graph: convert remaining functions to handle any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:13:03Z","receivedAt":"2018-11-14T00:14:23Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Convert all functions to handle arbitrary repositories in commit-graph.c\nthat are used by functions taking a repository argument already.\n\nNotable exclusion is write_commit_graph and its local functions as that\nonly works on the_repository.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n commit-graph.c | 40 ++++++++++++++++++++++++----------------\n 1 file changed, 24 insertions(+), 16 deletions(-)\n\ndiff --git a/commit-graph.c b/commit-graph.c\nindex 40c855f185..f78a8e96b5 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -292,7 +292,8 @@ static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t\n \t\t\t    g->chunk_oid_lookup, g->hash_len, pos);\n }\n \n-static struct commit_list **insert_parent_or_die(struct commit_graph *g,\n+static struct commit_list **insert_parent_or_die(struct repository *r,\n+\t\t\t\t\t\t struct commit_graph *g,\n \t\t\t\t\t\t uint64_t pos,\n \t\t\t\t\t\t struct commit_list **pptr)\n {\n@@ -303,7 +304,7 @@ static struct commit_list **insert_parent_or_die(struct commit_graph *g,\n \t\tdie(\"invalid parent position %\"PRIu64, pos);\n \n \thashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * pos);\n-\tc = lookup_commit(the_repository, &oid);\n+\tc = lookup_commit(r, &oid);\n \tif (!c)\n \t\tdie(_(\"could not find commit %s\"), oid_to_hex(&oid));\n \tc->graph_pos = pos;\n@@ -317,7 +318,9 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,\n \titem->generation = get_be32(commit_data + g->hash_len + 8) >> 2;\n }\n \n-static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uint32_t pos)\n+static int fill_commit_in_graph(struct repository *r,\n+\t\t\t\tstruct commit *item,\n+\t\t\t\tstruct commit_graph *g, uint32_t pos)\n {\n \tuint32_t edge_value;\n \tuint32_t *parent_data_ptr;\n@@ -341,13 +344,13 @@ static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uin\n \tedge_value = get_be32(commit_data + g->hash_len);\n \tif (edge_value == GRAPH_PARENT_NONE)\n \t\treturn 1;\n-\tpptr = insert_parent_or_die(g, edge_value, pptr);\n+\tpptr = insert_parent_or_die(r, g, edge_value, pptr);\n \n \tedge_value = get_be32(commit_data + g->hash_len + 4);\n \tif (edge_value == GRAPH_PARENT_NONE)\n \t\treturn 1;\n \tif (!(edge_value & GRAPH_OCTOPUS_EDGES_NEEDED)) {\n-\t\tpptr = insert_parent_or_die(g, edge_value, pptr);\n+\t\tpptr = insert_parent_or_die(r, g, edge_value, pptr);\n \t\treturn 1;\n \t}\n \n@@ -355,7 +358,7 @@ static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uin\n \t\t\t  4 * (uint64_t)(edge_value & GRAPH_EDGE_LAST_MASK));\n \tdo {\n \t\tedge_value = get_be32(parent_data_ptr);\n-\t\tpptr = insert_parent_or_die(g,\n+\t\tpptr = insert_parent_or_die(r, g,\n \t\t\t\t\t    edge_value & GRAPH_EDGE_LAST_MASK,\n \t\t\t\t\t    pptr);\n \t\tparent_data_ptr++;\n@@ -374,7 +377,9 @@ static int find_commit_in_graph(struct commit *item, struct commit_graph *g, uin\n \t}\n }\n \n-static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item)\n+static int parse_commit_in_graph_one(struct repository *r,\n+\t\t\t\t     struct commit_graph *g,\n+\t\t\t\t     struct commit *item)\n {\n \tuint32_t pos;\n \n@@ -382,7 +387,7 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item\n \t\treturn 1;\n \n \tif (find_commit_in_graph(item, g, &pos))\n-\t\treturn fill_commit_in_graph(item, g, pos);\n+\t\treturn fill_commit_in_graph(r, item, g, pos);\n \n \treturn 0;\n }\n@@ -391,7 +396,7 @@ int parse_commit_in_graph(struct repository *r, struct commit *item)\n {\n \tif (!prepare_commit_graph(r))\n \t\treturn 0;\n-\treturn parse_commit_in_graph_one(r->objects->commit_graph, item);\n+\treturn parse_commit_in_graph_one(r, r->objects->commit_graph, item);\n }\n \n void load_commit_graph_info(struct repository *r, struct commit *item)\n@@ -403,19 +408,22 @@ void load_commit_graph_info(struct repository *r, struct commit *item)\n \t\tfill_commit_graph_info(item, r->objects->commit_graph, pos);\n }\n \n-static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c)\n+static struct tree *load_tree_for_commit(struct repository *r,\n+\t\t\t\t\t struct commit_graph *g,\n+\t\t\t\t\t struct commit *c)\n {\n \tstruct object_id oid;\n \tconst unsigned char *commit_data = g->chunk_commit_data +\n \t\t\t\t\t   GRAPH_DATA_WIDTH * (c->graph_pos);\n \n \thashcpy(oid.hash, commit_data);\n-\tc->maybe_tree = lookup_tree(the_repository, &oid);\n+\tc->maybe_tree = lookup_tree(r, &oid);\n \n \treturn c->maybe_tree;\n }\n \n-static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,\n+static struct tree *get_commit_tree_in_graph_one(struct repository *r,\n+\t\t\t\t\t\t struct commit_graph *g,\n \t\t\t\t\t\t const struct commit *c)\n {\n \tif (c->maybe_tree)\n@@ -423,12 +431,12 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,\n \tif (c->graph_pos == COMMIT_NOT_FROM_GRAPH)\n \t\tBUG(\"get_commit_tree_in_graph_one called from non-commit-graph commit\");\n \n-\treturn load_tree_for_commit(g, (struct commit *)c);\n+\treturn load_tree_for_commit(r, g, (struct commit *)c);\n }\n \n struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)\n {\n-\treturn get_commit_tree_in_graph_one(r->objects->commit_graph, c);\n+\treturn get_commit_tree_in_graph_one(r, r->objects->commit_graph, c);\n }\n \n static void write_graph_chunk_fanout(struct hashfile *f,\n@@ -1025,7 +1033,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)\n \t\t}\n \n \t\tgraph_commit = lookup_commit(r, &cur_oid);\n-\t\tif (!parse_commit_in_graph_one(g, graph_commit))\n+\t\tif (!parse_commit_in_graph_one(r, g, graph_commit))\n \t\t\tgraph_report(\"failed to parse %s from commit-graph\",\n \t\t\t\t     oid_to_hex(&cur_oid));\n \t}\n@@ -1061,7 +1069,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)\n \t\t\tcontinue;\n \t\t}\n \n-\t\tif (!oideq(&get_commit_tree_in_graph_one(g, graph_commit)->object.oid,\n+\t\tif (!oideq(&get_commit_tree_in_graph_one(r, g, graph_commit)->object.oid,\n \t\t\t   get_commit_tree_oid(odb_commit)))\n \t\t\tgraph_report(\"root tree OID for commit %s in commit-graph is %s != %s\",\n \t\t\t\t     oid_to_hex(&cur_oid),\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363258","messageId":"20181114001306.138053-22-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 21/23] commit: prepare free_commit_buffer and release_commit_memory for any repo","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:13:04Z","receivedAt":"2018-11-14T00:14:27Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Pass the object pool to free_commit_buffer and release_commit_memory,\nsuch that we can eliminate access to 'the_repository'.\n\nAlso remove the TODO in release_commit_memory, as commit->util was\nremoved in 9d2c97016f (commit.h: delete 'util' field in struct commit,\n2018-05-19)\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n builtin/fsck.c     | 3 ++-\n builtin/log.c      | 6 ++++--\n builtin/rev-list.c | 3 ++-\n commit.c           | 9 ++++-----\n commit.h           | 4 ++--\n object.c           | 2 +-\n 6 files changed, 15 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 06eb421720..c476ac6983 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -382,7 +382,8 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)\n \tif (obj->type == OBJ_TREE)\n \t\tfree_tree_buffer((struct tree *)obj);\n \tif (obj->type == OBJ_COMMIT)\n-\t\tfree_commit_buffer((struct commit *)obj);\n+\t\tfree_commit_buffer(the_repository->parsed_objects,\n+\t\t\t\t   (struct commit *)obj);\n \treturn err;\n }\n \ndiff --git a/builtin/log.c b/builtin/log.c\nindex 061d4fd864..64c2649c7c 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -395,7 +395,8 @@ static int cmd_log_walk(struct rev_info *rev)\n \t\t\t * We may show a given commit multiple times when\n \t\t\t * walking the reflogs.\n \t\t\t */\n-\t\t\tfree_commit_buffer(commit);\n+\t\t\tfree_commit_buffer(the_repository->parsed_objects,\n+\t\t\t\t\t   commit);\n \t\t\tfree_commit_list(commit->parents);\n \t\t\tcommit->parents = NULL;\n \t\t}\n@@ -1922,7 +1923,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\t    open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))\n \t\t\tdie(_(\"Failed to create output files\"));\n \t\tshown = log_tree_commit(&rev, commit);\n-\t\tfree_commit_buffer(commit);\n+\t\tfree_commit_buffer(the_repository->parsed_objects,\n+\t\t\t\t   commit);\n \n \t\t/* We put one extra blank line between formatted\n \t\t * patches and this flag is used by log-tree code\ndiff --git a/builtin/rev-list.c b/builtin/rev-list.c\nindex cc1b70522f..2b301fa315 100644\n--- a/builtin/rev-list.c\n+++ b/builtin/rev-list.c\n@@ -196,7 +196,8 @@ static void finish_commit(struct commit *commit, void *data)\n \t\tfree_commit_list(commit->parents);\n \t\tcommit->parents = NULL;\n \t}\n-\tfree_commit_buffer(commit);\n+\tfree_commit_buffer(the_repository->parsed_objects,\n+\t\t\t   commit);\n }\n \n static inline void finish_object__ma(struct object *obj)\ndiff --git a/commit.c b/commit.c\nindex 7d2f3a9a93..4fe74aa4bc 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -328,10 +328,10 @@ void repo_unuse_commit_buffer(struct repository *r,\n \t\tfree((void *)buffer);\n }\n \n-void free_commit_buffer(struct commit *commit)\n+void free_commit_buffer(struct parsed_object_pool *pool, struct commit *commit)\n {\n \tstruct commit_buffer *v = buffer_slab_peek(\n-\t\tthe_repository->parsed_objects->buffer_slab, commit);\n+\t\tpool->buffer_slab, commit);\n \tif (v) {\n \t\tFREE_AND_NULL(v->buffer);\n \t\tv->size = 0;\n@@ -354,13 +354,12 @@ struct object_id *get_commit_tree_oid(const struct commit *commit)\n \treturn &get_commit_tree(commit)->object.oid;\n }\n \n-void release_commit_memory(struct commit *c)\n+void release_commit_memory(struct parsed_object_pool *pool, struct commit *c)\n {\n \tc->maybe_tree = NULL;\n \tc->index = 0;\n-\tfree_commit_buffer(c);\n+\tfree_commit_buffer(pool, c);\n \tfree_commit_list(c->parents);\n-\t/* TODO: what about commit->util? */\n \n \tc->object.parsed = 0;\n }\ndiff --git a/commit.h b/commit.h\nindex 2e6b799b26..d2779a23f6 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -140,7 +140,7 @@ void repo_unuse_commit_buffer(struct repository *r,\n /*\n  * Free any cached object buffer associated with the commit.\n  */\n-void free_commit_buffer(struct commit *);\n+void free_commit_buffer(struct parsed_object_pool *pool, struct commit *);\n \n struct tree *get_commit_tree(const struct commit *);\n struct object_id *get_commit_tree_oid(const struct commit *);\n@@ -149,7 +149,7 @@ struct object_id *get_commit_tree_oid(const struct commit *);\n  * Release memory related to a commit, including the parent list and\n  * any cached object buffer.\n  */\n-void release_commit_memory(struct commit *c);\n+void release_commit_memory(struct parsed_object_pool *pool, struct commit *c);\n \n /*\n  * Disassociate any cached object buffer from the commit, but do not free it.\ndiff --git a/object.c b/object.c\nindex 003f870484..c4170d2d0c 100644\n--- a/object.c\n+++ b/object.c\n@@ -540,7 +540,7 @@ void parsed_object_pool_clear(struct parsed_object_pool *o)\n \t\tif (obj->type == OBJ_TREE)\n \t\t\tfree_tree_buffer((struct tree*)obj);\n \t\telse if (obj->type == OBJ_COMMIT)\n-\t\t\trelease_commit_memory((struct commit*)obj);\n+\t\t\trelease_commit_memory(o, (struct commit*)obj);\n \t\telse if (obj->type == OBJ_TAG)\n \t\t\trelease_tag_memory((struct tag*)obj);\n \t}\n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363259","messageId":"20181114001306.138053-23-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 22/23] path.h: make REPO_GIT_PATH_FUNC repository agnostic","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:13:05Z","receivedAt":"2018-11-14T00:14:29Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"git_pathdup uses the_repository internally, but the macro\nREPO_GIT_PATH_FUNC is specifically made for arbitrary repositories.\nSwitch to repo_git_path which works on arbitrary repositories.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n path.h | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/path.h b/path.h\nindex b654ea8ff5..651e6157fc 100644\n--- a/path.h\n+++ b/path.h\n@@ -165,7 +165,7 @@ extern void report_linked_checkout_garbage(void);\n \tconst char *git_path_##var(struct repository *r) \\\n \t{ \\\n \t\tif (!r->cached_paths.var) \\\n-\t\t\tr->cached_paths.var = git_pathdup(filename); \\\n+\t\t\tr->cached_paths.var = repo_git_path(r, filename); \\\n \t\treturn r->cached_paths.var; \\\n \t}\n \n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363260","messageId":"20181114001306.138053-24-sbeller@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"[PATCH 23/23] t/helper/test-repository: celebrate independence from the_repository","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-14T00:13:06Z","receivedAt":"2018-11-14T00:14:32Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"dade47c06c (commit-graph: add repo arg to graph readers, 2018-07-11)\nbrought more independence from the_repository to the commit graph, however\nit was not completely independent of the_repository, as the previous\npatches show.\n\nTo ensure we're not accessing the_repository by accident, we'd ideally\nassign NULL to the_repository to trigger a segfault on access.\n\nWe currently have a temporary hack in cache.h, which relies on\nthe_hash_algo (which is a short form of the_repository->hash_algo) to\nbe set, so we cannot do that. The next best thing is to set all fields of\nthe_repository to 0, so any accidental access is more likely to be found.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n cache.h                    |  2 ++\n t/helper/test-repository.c | 10 ++++++++++\n 2 files changed, 12 insertions(+)\n\ndiff --git a/cache.h b/cache.h\nindex 59c8a93046..8864d7ec15 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1033,6 +1033,8 @@ static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)\n \t *\n \t * This will need to be extended or ripped out when we learn about\n \t * hashes of different sizes.\n+\t *\n+\t * When ripping this out, see TODO in test-repository.c.\n \t */\n \tif (the_hash_algo->rawsz != 20)\n \t\tBUG(\"hash size not yet supported by hashcmp\");\ndiff --git a/t/helper/test-repository.c b/t/helper/test-repository.c\nindex 6a84a53efb..f7f8618445 100644\n--- a/t/helper/test-repository.c\n+++ b/t/helper/test-repository.c\n@@ -17,6 +17,11 @@ static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,\n \n \tsetup_git_env(gitdir);\n \n+\tmemset(the_repository, 0, sizeof(*the_repository));\n+\n+\t/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */\n+\trepo_set_hash_algo(the_repository, GIT_HASH_SHA1);\n+\n \tif (repo_init(&r, gitdir, worktree))\n \t\tdie(\"Couldn't init repo\");\n \n@@ -43,6 +48,11 @@ static void test_get_commit_tree_in_graph(const char *gitdir,\n \n \tsetup_git_env(gitdir);\n \n+\tmemset(the_repository, 0, sizeof(*the_repository));\n+\n+\t/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */\n+\trepo_set_hash_algo(the_repository, GIT_HASH_SHA1);\n+\n \tif (repo_init(&r, gitdir, worktree))\n \t\tdie(\"Couldn't init repo\");\n \n-- \n2.19.1.1215.g8438c0b245-goog\n\n"},{"id":"363448","messageId":"20181115195416.21890-1-jonathantanmy@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-19-sbeller@google.com","subject":"Re: [PATCH 18/23] submodule: use submodule repos for object lookup","fromName":"Jonathan Tan","fromEmail":"jonathantanmy@google.com","sentAt":"2018-11-15T19:54:16Z","receivedAt":"2018-11-15T19:54:22Z","isPatch":true,"sender":{"key":"jonathantanmy@fastmail.com","avatar":null},"body":"> +/*\n> + * Initialize 'out' based on the provided submodule path.\n> + *\n> + * Unlike repo_submodule_init, this tolerates submodules not present\n> + * in .gitmodules. This function exists only to preserve historical behavior,\n> + *\n> + * Returns 0 on success, -1 when the submodule is not present.\n>   */\n> -static void show_submodule_header(struct diff_options *o, const char *path,\n> +static struct repository *open_submodule(const char *path)\n\nThe function documentation needs to be reworded - there's no \"out\", and\nthe return value is now a possibly NULL pointer to struct repository.\n\n> +{\n> +\tstruct strbuf sb = STRBUF_INIT;\n> +\tstruct repository *out = xmalloc(sizeof(*out));\n> +\n> +\tif (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {\n> +\t\tstrbuf_release(&sb);\n> +\t\tfree(out);\n> +\t\treturn NULL;\n> +\t}\n> +\n> +\tout->submodule_prefix = xstrdup(path);\n\nI've discussed this submodule_prefix line before [1] - do we really need\nthis? Tests pass even if I remove this line.\n\nOther than that, this patch looks good.\n\n[1] https://public-inbox.org/git/20181019203750.110741-1-jonathantanmy@google.com/\n"},{"id":"363451","messageId":"CAGZ79kZ72eQPiQ_KW1QkiRqMFUAUpCQCHZdk3RSMVK7TGPE2aw@mail.gmail.com","threadId":"49828","inReplyTo":"20181115195416.21890-1-jonathantanmy@google.com","subject":"Re: [PATCH 18/23] submodule: use submodule repos for object lookup","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-11-15T20:36:56Z","receivedAt":"2018-11-15T20:37:11Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Thu, Nov 15, 2018 at 11:54 AM Jonathan Tan <jonathantanmy@google.com> wrote:\n>\n> > +/*\n> > + * Initialize 'out' based on the provided submodule path.\n> > + *\n> > + * Unlike repo_submodule_init, this tolerates submodules not present\n> > + * in .gitmodules. This function exists only to preserve historical behavior,\n> > + *\n> > + * Returns 0 on success, -1 when the submodule is not present.\n> >   */\n> > -static void show_submodule_header(struct diff_options *o, const char *path,\n> > +static struct repository *open_submodule(const char *path)\n>\n> The function documentation needs to be reworded - there's no \"out\", and\n> the return value is now a possibly NULL pointer to struct repository.\n\nNoted.\n\n>\n> > +{\n> > +     struct strbuf sb = STRBUF_INIT;\n> > +     struct repository *out = xmalloc(sizeof(*out));\n> > +\n> > +     if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {\n> > +             strbuf_release(&sb);\n> > +             free(out);\n> > +             return NULL;\n> > +     }\n> > +\n> > +     out->submodule_prefix = xstrdup(path);\n>\n> I've discussed this submodule_prefix line before [1] - do we really need\n> this? Tests pass even if I remove this line.\n\nWe might not need it yet as the tests indicate, but it's the right thing to do:\n/*\n * Path from the root of the top-level superproject down to this\n * repository.  This is only non-NULL if the repository is initialized\n * as a submodule of another repository.\n */\n\nWe're not (yet) using this string in our error reporting, but\nI anticipate that we'll do eventually.\n\n> Other than that, this patch looks good.\n\nThanks,\nStefan\n"},{"id":"363455","messageId":"20181115221254.45373-1-jonathantanmy@google.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"Re: [PATCHv3 00/23] Bring more repository handles into our code base","fromName":"Jonathan Tan","fromEmail":"jonathantanmy@google.com","sentAt":"2018-11-15T22:12:54Z","receivedAt":"2018-11-15T22:13:01Z","isPatch":false,"sender":{"key":"jonathantanmy@fastmail.com","avatar":null},"body":"> Please have a look at the last 4 patches specifically as they were new in\n> the last iteration (but did not receive any comment), as they demonstrate\n> and fix a problem that is only exposed when using GIT_TEST_COMMIT_GRAPH=1\n> for the test suite.\n\nThanks. I only reviewed patches 18 and 20-23, as only those are\ndifferent from the previous iteration according to the range-diff.\n\nI've written my comments about patch 18 already [1], and the other\npatches look good to me.\n\nIn patch 21, I could go either way about whether it's more desirable to\npass the pool or the repository to the freeing functions.\n\nThanks for discovering the issue that patch 23 illustrates. I thought\nthat the tests were written carefully enough in that the_repository\ndidn't have any relevant objects or configurations (all relevant data\nwas in a path that is not the default repository), but apparently some\nstill slipped through.\n\n[1] https://public-inbox.org/git/20181115195416.21890-1-jonathantanmy@google.com/\n"},{"id":"363511","messageId":"ffe3a5c3-58ff-43e3-0c35-bf68f16e928c@gmail.com","threadId":"49828","inReplyTo":"20181114001306.138053-1-sbeller@google.com","subject":"Re: [PATCHv3 00/23] Bring more repository handles into our code base","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2018-11-16T13:15:26Z","receivedAt":"2018-11-16T13:15:31Z","isPatch":false,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 11/13/2018 7:12 PM, Stefan Beller wrote:\n> Please have a look at the last 4 patches specifically as they were new in\n> the last iteration (but did not receive any comment), as they demonstrate\n> and fix a problem that is only exposed when using GIT_TEST_COMMIT_GRAPH=1\n> for the test suite.\n\nI took a look at these last four and didn't find anything wrong. Rest of \nthe series looks good.\n\nWhile all of the TODOs in the last patch are an imperfect solution, I \nthink it's probably the best we can do for now.\n\nThanks,\n-Stolee\n"},{"id":"365201","messageId":"20181212202205.170998-1-sbeller@google.com","threadId":"49828","inReplyTo":"CAGZ79kZ72eQPiQ_KW1QkiRqMFUAUpCQCHZdk3RSMVK7TGPE2aw@mail.gmail.com","subject":"Re: [PATCH 18/23] submodule: use submodule repos for object lookup","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-12-12T20:22:05Z","receivedAt":"2018-12-12T20:22:10Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Signed-off-by: Stefan Beller <sbeller@google.com>\n---\n\nOn Thu, Nov 15, 2018 at 11:54 AM Jonathan Tan <jonathantanmy@google.com> wrote:\n> Other than that, this patch looks good.\n\nI'll incorporate these changes once resending.\n\nStefan\n\n\n submodule.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex 262f03f118..4486ff664b 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -483,12 +483,13 @@ void prepare_submodule_repo_env(struct argv_array *out)\n }\n \n /*\n- * Initialize 'out' based on the provided submodule path.\n+ * Initialize a repository struct for a submodule based on the provided 'path'.\n  *\n  * Unlike repo_submodule_init, this tolerates submodules not present\n  * in .gitmodules. This function exists only to preserve historical behavior,\n  *\n- * Returns 0 on success, -1 when the submodule is not present.\n+ * Returns the repository struct on success,\n+ * NULL when the submodule is not present.\n  */\n static struct repository *open_submodule(const char *path)\n {\n@@ -501,6 +502,7 @@ static struct repository *open_submodule(const char *path)\n \t\treturn NULL;\n \t}\n \n+\t/* Mark it as a submodule */\n \tout->submodule_prefix = xstrdup(path);\n \n \tstrbuf_release(&sb);\n-- \n2.20.0.rc2.230.gc28305e538\n\n"},{"id":"365202","messageId":"20181212205812.182398-1-sbeller@google.com","threadId":"49828","inReplyTo":"20181212202205.170998-1-sbeller@google.com","subject":"[PATCH] submodule: correct documentation for open_submodule","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-12-12T20:58:12Z","receivedAt":"2018-12-12T20:58:22Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"When 99017ffac8 (submodule: use submodule repos for object lookup, 2018-11-13)\nwas merged, I had not yet addressed all outstanding review comments, such\nas adapting the documentation for the function `open_submodule`, which\nchanged its signature during the development of that series.\nFix the documentation, and annotate setting of `submodule_prefix`\nto indicate we're dealing with a submodule repository.\n\nSigned-off-by: Stefan Beller <sbeller@google.com>\n---\n\n> I'll incorporate these changes once resending.\n\n... only to realize it hit next already, so we'd prefer updates instead\nof resending the whole series.\n\nMaybe a patch like this?\n\n submodule.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex 262f03f118..4486ff664b 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -483,12 +483,13 @@ void prepare_submodule_repo_env(struct argv_array *out)\n }\n \n /*\n- * Initialize 'out' based on the provided submodule path.\n+ * Initialize a repository struct for a submodule based on the provided 'path'.\n  *\n  * Unlike repo_submodule_init, this tolerates submodules not present\n  * in .gitmodules. This function exists only to preserve historical behavior,\n  *\n- * Returns 0 on success, -1 when the submodule is not present.\n+ * Returns the repository struct on success,\n+ * NULL when the submodule is not present.\n  */\n static struct repository *open_submodule(const char *path)\n {\n@@ -501,6 +502,7 @@ static struct repository *open_submodule(const char *path)\n \t\treturn NULL;\n \t}\n \n+\t/* Mark it as a submodule */\n \tout->submodule_prefix = xstrdup(path);\n \n \tstrbuf_release(&sb);\n-- \n2.20.0.rc2.230.gc28305e538\n\n"}]}