{"thread":{"id":"61621","subject":"[PATCH 00/21] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","startedAt":"2024-06-11T11:57:39Z","lastAt":"2024-06-18T20:22:41Z","messageCount":94,"participants":["Patrick Steinhardt","Ghanshyam Thakkar","brian m. carlson","Phillip Wood","Junio C Hamano","Ramsay Jones","Karthik Nayak"],"isPatch":true,"patchVersion":1,"patchTotal":21},"messages":[{"id":"496892","messageId":"cover.1718106284.git.ps@pks.im","threadId":"61621","inReplyTo":null,"subject":"[PATCH 00/21] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:57:33Z","receivedAt":"2024-06-11T11:57:39Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nuse of the `the_repository` variable is nowadays considered to be\ndeprecated, and over time we want to convert our codebase to stop using\nit in favor of explicitly passing down the repository to functions via\nparameters. This effort faces some important problems though.\n\n  - It is hard to prove that a certain code unit does not use\n    `the_repository` anymore when sending patch series. The reviewer has\n    no way to verify that it's not used anymore without reading through\n    the code itself.\n\n  - It is easy to sneak in new usages of `the_repository` by accident\n    into a code unit that is already `the_repository`-clean.\n\n  - There are many functions which implicitly use `the_repository`,\n    which is really hard to spot.\n\nThis patch series aims to address those problems by introducing a new\n`USE_THE_REPOSITORY_VARIABLE` macro. When unset, then the declarations\nof `the_repository`, `the_hash_algo` and some functions that implicitly\ndepend on them will be hidden away. This makes it trivial to demonstrate\nthat a code unit is `the_repository`-free by removing the definition of\nany such macro.\n\nThe patch series doesn't aim to be perfect. There are still many\nfunctions that implicitly depend on `the_repository` which are not\nhidden away. Those can be addressed over time, either by guarding them\nas required or, even better, removing such functions altogether.\n\nThe series is structured as follows:\n\n  - Patches 1 to 8 refactor \"hash.h\" such that its functions do not\n    depend on `the_repository` anymore. As these are used almost\n    everywhere, the whole patch series would be rather moot without such\n    a refactoring as everything would depend on `the_repository`.\n\n  - Patch 9 introduces `USE_THE_REPOSITORY_VARIABLE`, guarding the\n    declaration of `the_repository` and `the_hash_algo`.\n\n  - Patch 11 merges \"hash-ll.h\" back into \"hash.h\" as the split is now\n    mostly pointless.\n\n  - Patches 12 to 20 refactor various users of \"hex.h\" to not use\n    functions depending on `the_repository` anymore.\n\n  - Patch 21 guards declarations of functions that depend on\n    `the_repository` in \"hex.h\".\n\nThe series depends on ps/ref-sotrage-migration at 25a0023f28\n(builtin/refs: new command to migrate ref storage formats, 2024-06-06).\nThis is moslty due to patch 10, which fixes a cyclic include that breaks\nthe build once we merge \"hash-ll.h\" back into \"hash.h\".\n\nThere are some minor textual and semantic conflicts with \"seen\" that can\nbe fixed as shown below.\n\nThanks!\n\nPatrick\n\n    diff --cc bloom.c\n    index bbf146fc30,d080a1b616..0000000000\n    --- a/bloom.c\n    +++ b/bloom.c\n    @@@ -6,7 -6,9 +6,10 @@@\n      #include \"commit-graph.h\"\n      #include \"commit.h\"\n      #include \"commit-slab.h\"\n     +#include \"repository.h\"\n    + #include \"tree.h\"\n    + #include \"tree-walk.h\"\n    + #include \"config.h\"\n      \n      define_commit_slab(bloom_filter_slab, struct bloom_filter);\n      \n    diff --cc midx.c\n    index 3992b05465,5aa7e2a6e6..0000000000\n    --- a/midx.c\n    +++ b/midx.c\n    @@@ -303,11 -530,12 +532,13 @@@ struct object_id *nth_midxed_object_oid\n                        struct multi_pack_index *m,\n                        uint32_t n)\n      {\n    - \tif (n >= m->num_objects)\n    + \tif (n >= m->num_objects + m->num_objects_in_base)\n            return NULL;\n      \n    + \tn = midx_for_object(&m, n);\n    + \n     -\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n));\n     +\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n),\n     +\t\tthe_repository->hash_algo);\n        return oid;\n      }\n      \n    diff --cc pack-bitmap-write.c\n    index 37a8ad0fb3,6e8060f8a0..0000000000\n    --- a/pack-bitmap-write.c\n    +++ b/pack-bitmap-write.c\n    @@@ -817,8 -1022,8 +1024,8 @@@ void bitmap_writer_finish(struct bitmap\n        memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE));\n        header.version = htons(default_version);\n        header.options = htons(flags | options);\n    - \theader.entry_count = htonl(writer->selected_nr);\n    + \theader.entry_count = htonl(bitmap_writer_nr_selected_commits(writer));\n     -\thashcpy(header.checksum, writer->pack_checksum);\n     +\thashcpy(header.checksum, writer->pack_checksum, the_repository->hash_algo);\n      \n        hashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz);\n        dump_bitmap(f, writer->commits);\n    diff --git a/pseudo-merge.c b/pseudo-merge.c\n    index e3e0393f11..f0fde13c47 100644\n    --- a/pseudo-merge.c\n    +++ b/pseudo-merge.c\n    @@ -1,3 +1,5 @@\n    +#define USE_THE_REPOSITORY_VARIABLE\n    +\n     #include \"git-compat-util.h\"\n     #include \"pseudo-merge.h\"\n     #include \"date.h\"\n    diff --git a/t/unit-tests/lib-oid.h b/t/unit-tests/lib-oid.h\n    index bfde639190..8d2acca768 100644\n    --- a/t/unit-tests/lib-oid.h\n    +++ b/t/unit-tests/lib-oid.h\n    @@ -1,7 +1,7 @@\n     #ifndef LIB_OID_H\n     #define LIB_OID_H\n     \n    -#include \"hash-ll.h\"\n    +#include \"hash.h\"\n     \n     /*\n      * Convert arbitrary hex string to object_id.\n    diff --git a/t/unit-tests/t-example-decorate.c b/t/unit-tests/t-example-decorate.c\n    index 3c856a8cf2..a4a75db735 100644\n    --- a/t/unit-tests/t-example-decorate.c\n    +++ b/t/unit-tests/t-example-decorate.c\n    @@ -1,3 +1,5 @@\n    +#define USE_THE_REPOSITORY_VARIABLE\n    +\n     #include \"test-lib.h\"\n     #include \"object.h\"\n     #include \"decorate.h\"\n\nPatrick Steinhardt (21):\n  hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions\n  hash: require hash algorithm in `hasheq()`, `hashcmp()` and\n    `hashclr()`\n  hash: require hash algorithm in `oidread()` and `oidclr()`\n  global: ensure that object IDs are always padded\n  hash: convert `oidcmp()` and `oideq()` to compare whole hash\n  hash: make `is_null_oid()` independent of `the_repository`\n  hash: require hash algorithm in `is_empty_{blob,tree}_oid()`\n  hash: require hash algorithm in `empty_tree_oid_hex()`\n  global: introduce `USE_THE_REPOSITORY_VARIABLE` macro\n  refs: avoid include cycle with \"repository.h\"\n  hash-ll: merge with \"hash.h\"\n  http-fetch: don't crash when parsing packfile without a repo\n  oidset: pass hash algorithm when parsing file\n  protocol-caps: use hash algorithm from passed-in repository\n  replace-object: use hash algorithm from passed-in repository\n  compat/fsmonitor: remove dependency on `the_repository` in Darwin IPC\n  t/helper: use correct object hash in partial-clone helper\n  t/helper: fix segfault in \"oid-array\" command without repository\n  t/helper: remove dependency on `the_repository` in \"oidtree\"\n  t/helper: remove dependency on `the_repository` in \"proc-receive\"\n  hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`\n\n add-interactive.c                            |   4 +-\n add-patch.c                                  |   4 +-\n apply.c                                      |   4 +-\n apply.h                                      |   2 +-\n archive-tar.c                                |   3 +\n archive-zip.c                                |   3 +\n archive.c                                    |   2 +\n attr.c                                       |   2 +\n bisect.c                                     |   2 +\n blame.c                                      |   4 +-\n bloom.c                                      |   1 +\n branch.c                                     |   2 +\n builtin.h                                    |   8 +\n builtin/am.c                                 |   8 +-\n builtin/blame.c                              |   3 +-\n builtin/fast-export.c                        |   2 +-\n builtin/fast-import.c                        |  43 ++-\n builtin/fetch-pack.c                         |   4 +-\n builtin/index-pack.c                         |  11 +-\n builtin/log.c                                |   4 +-\n builtin/merge.c                              |   7 +-\n builtin/notes.c                              |   2 +-\n builtin/pack-objects.c                       |   3 +-\n builtin/pack-redundant.c                     |  10 +-\n builtin/patch-id.c                           |   6 +-\n builtin/pull.c                               |   6 +-\n builtin/receive-pack.c                       |   4 +-\n builtin/replace.c                            |   2 +-\n builtin/rm.c                                 |   2 +-\n builtin/tag.c                                |   2 +-\n builtin/unpack-objects.c                     |   9 +-\n builtin/update-ref.c                         |   8 +-\n bulk-checkin.c                               |   3 +\n bundle-uri.c                                 |   2 +\n bundle.c                                     |   2 +\n cache-tree.c                                 |   7 +-\n checkout.c                                   |   2 +\n checkout.h                                   |   2 +-\n chunk-format.c                               |   2 +\n chunk-format.h                               |   2 +-\n combine-diff.c                               |   2 +\n commit-graph.c                               |  22 +-\n commit-graph.h                               |   2 +\n commit-reach.c                               |   2 +\n commit.c                                     |   2 +\n common-main.c                                |   2 +\n compat/fsmonitor/fsm-ipc-darwin.c            |   5 +-\n compat/sha1-chunked.c                        |   2 +-\n compat/win32/trace2_win32_process_info.c     |   2 +\n config.c                                     |   3 +\n connected.c                                  |   2 +\n convert.c                                    |   2 +\n convert.h                                    |   2 +-\n csum-file.c                                  |   9 +-\n csum-file.h                                  |   2 +-\n delta-islands.c                              |   2 +\n diagnose.c                                   |   2 +\n diff-lib.c                                   |   7 +-\n diff.c                                       |   9 +-\n diff.h                                       |   2 +-\n diffcore-break.c                             |   3 +\n diffcore-rename.c                            |   7 +-\n diffcore.h                                   |   2 +-\n dir.c                                        |   9 +-\n dir.h                                        |   2 +-\n entry.c                                      |   2 +\n environment.c                                |   3 +\n fetch-pack.c                                 |   2 +\n fmt-merge-msg.c                              |   2 +\n fsck.c                                       |   5 +-\n fsmonitor-ipc.c                              |   2 +\n git.c                                        |   2 +\n hash-ll.h                                    | 310 ----------------\n hash-lookup.c                                |   5 +-\n hash.h                                       | 366 ++++++++++++++++---\n help.c                                       |   2 +\n hex.c                                        |   8 +-\n hex.h                                        |  28 +-\n http-backend.c                               |   2 +\n http-fetch.c                                 |   8 +-\n http-push.c                                  |   5 +-\n http-walker.c                                |   6 +-\n http.c                                       |   2 +\n list-objects-filter-options.c                |   2 +\n list-objects-filter.c                        |   2 +\n list-objects.c                               |   2 +\n log-tree.c                                   |   2 +\n loose.c                                      |   2 +\n loose.h                                      |   2 +\n ls-refs.c                                    |   2 +\n mailmap.c                                    |   2 +\n match-trees.c                                |   6 +-\n merge-blobs.c                                |   2 +\n merge-ort.c                                  |   2 +\n merge-ort.h                                  |   2 +-\n merge-recursive.c                            |   3 +\n merge.c                                      |   2 +\n midx-write.c                                 |   2 +\n midx.c                                       |   5 +-\n negotiator/default.c                         |   2 +\n negotiator/skipping.c                        |   2 +\n notes-cache.c                                |   2 +\n notes-merge.c                                |   8 +-\n notes-utils.c                                |   2 +\n notes.c                                      |  14 +-\n object-file-convert.c                        |   6 +-\n object-file.c                                |  19 +-\n object-name.c                                |   2 +\n object.c                                     |   2 +\n object.h                                     |   2 +-\n oid-array.c                                  |   2 +\n oidmap.h                                     |   2 +-\n oidset.c                                     |   8 +-\n oidset.h                                     |   4 +-\n oidtree.c                                    |   4 +-\n oidtree.h                                    |   2 +-\n oss-fuzz/fuzz-commit-graph.c                 |   2 +\n pack-bitmap-write.c                          |   6 +-\n pack-bitmap.c                                |   5 +-\n pack-check.c                                 |   7 +-\n pack-revindex.c                              |   2 +\n pack-write.c                                 |   5 +-\n packfile.c                                   |  20 +-\n packfile.h                                   |   2 +\n parallel-checkout.c                          |   8 +-\n parse-options-cb.c                           |   2 +\n path.c                                       |   3 +\n pathspec.c                                   |   2 +\n pretty.c                                     |   2 +\n progress.c                                   |   2 +\n promisor-remote.c                            |   2 +\n protocol-caps.c                              |   5 +-\n range-diff.c                                 |   2 +\n reachable.c                                  |   2 +\n read-cache-ll.h                              |   2 +-\n read-cache.c                                 |  21 +-\n rebase-interactive.c                         |   2 +\n ref-filter.c                                 |   2 +\n reflog-walk.c                                |   2 +\n reflog.c                                     |   2 +\n refs.c                                       |   8 +-\n refs.h                                       |   8 +-\n refs/files-backend.c                         |   8 +-\n refs/packed-backend.c                        |   8 +-\n refs/ref-cache.h                             |   2 +-\n refs/reftable-backend.c                      |  39 +-\n refspec.c                                    |   2 +\n reftable/dump.c                              |   2 +-\n reftable/reftable-record.h                   |   2 +-\n reftable/system.h                            |   2 +-\n remote-curl.c                                |   2 +\n remote.c                                     |  10 +-\n remote.h                                     |   2 +-\n replace-object.c                             |   2 +-\n repository.h                                 |   9 +-\n rerere.c                                     |   2 +\n reset.c                                      |   2 +\n reset.h                                      |   2 +-\n resolve-undo.c                               |   5 +-\n resolve-undo.h                               |   2 +-\n revision.c                                   |   2 +\n run-command.c                                |   2 +\n scalar.c                                     |   2 +\n send-pack.c                                  |   2 +\n sequencer.c                                  |   8 +-\n serve.c                                      |   4 +-\n server-info.c                                |   2 +\n setup.c                                      |   2 +\n shallow.c                                    |   2 +\n split-index.c                                |   4 +-\n split-index.h                                |   2 +-\n streaming.c                                  |   3 +\n submodule-config.c                           |   4 +-\n submodule.c                                  |   8 +-\n t/helper/test-bitmap.c                       |   2 +\n t/helper/test-bloom.c                        |   2 +\n t/helper/test-cache-tree.c                   |   2 +\n t/helper/test-dump-cache-tree.c              |   2 +\n t/helper/test-dump-fsmonitor.c               |   2 +\n t/helper/test-dump-split-index.c             |   2 +\n t/helper/test-dump-untracked-cache.c         |   2 +\n t/helper/test-example-decorate.c             |   2 +\n t/helper/test-find-pack.c                    |   2 +\n t/helper/test-fsmonitor-client.c             |   2 +\n t/helper/test-hash-speed.c                   |   2 +-\n t/helper/test-lazy-init-name-hash.c          |   2 +\n t/helper/test-match-trees.c                  |   2 +\n t/helper/test-oid-array.c                    |   4 +\n t/helper/test-oidmap.c                       |   2 +\n t/helper/test-oidtree.c                      |   5 +-\n t/helper/test-pack-mtimes.c                  |   2 +\n t/helper/test-partial-clone.c                |   2 +-\n t/helper/test-proc-receive.c                 |   9 +-\n t/helper/test-reach.c                        |   2 +\n t/helper/test-read-cache.c                   |   2 +\n t/helper/test-read-graph.c                   |   2 +\n t/helper/test-read-midx.c                    |   2 +\n t/helper/test-ref-store.c                    |   2 +\n t/helper/test-repository.c                   |   2 +\n t/helper/test-revision-walking.c             |   2 +\n t/helper/test-scrap-cache-tree.c             |   2 +\n t/helper/test-sha1.c                         |   2 +-\n t/helper/test-sha256.c                       |   2 +-\n t/helper/test-submodule-config.c             |   4 +-\n t/helper/test-submodule-nested-repo-config.c |   2 +\n t/helper/test-submodule.c                    |   2 +\n t/helper/test-trace2.c                       |   2 +\n t/helper/test-write-cache.c                  |   2 +\n t/t0064-oid-array.sh                         |  18 +\n t/t5550-http-fetch-dumb.sh                   |   6 +\n t/test-lib-functions.sh                      |   5 +\n tag.c                                        |   2 +\n tmp-objdir.c                                 |   2 +\n transport-helper.c                           |   2 +\n transport.c                                  |   2 +\n tree-diff.c                                  |   1 +\n tree-walk.c                                  |   6 +-\n tree-walk.h                                  |   2 +-\n tree.c                                       |   2 +\n unpack-trees.c                               |   2 +\n upload-pack.c                                |   2 +\n walker.c                                     |   2 +\n worktree.c                                   |   2 +\n wt-status.c                                  |   6 +-\n xdiff-interface.c                            |   2 +\n xdiff-interface.h                            |   2 +-\n 226 files changed, 993 insertions(+), 619 deletions(-)\n delete mode 100644 hash-ll.h\n\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496893","messageId":"f839013744d2401ab1a3186876379e6354811c7c.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 01/21] hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:57:38Z","receivedAt":"2024-06-11T11:57:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The functions `is_empty_{blob,tree}_sha1()` are mostly unused, except\nfor a single callsite in \"read-cache.c\". Most callsites have long since\nbeen converted to use the equivalents that accept a `struct object_id`\ninstead of a string.\n\nAdapt the remaining callsite and drop those functions.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash.h       | 10 ----------\n read-cache.c |  2 +-\n 2 files changed, 1 insertion(+), 11 deletions(-)\n\ndiff --git a/hash.h b/hash.h\nindex e064807c17..a1161e1b22 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -84,21 +84,11 @@ static inline void oidread(struct object_id *oid, const unsigned char *hash)\n \toidread_algop(oid, hash, the_hash_algo);\n }\n \n-static inline int is_empty_blob_sha1(const unsigned char *sha1)\n-{\n-\treturn hasheq(sha1, the_hash_algo->empty_blob->hash);\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\n }\n \n-static inline int is_empty_tree_sha1(const unsigned char *sha1)\n-{\n-\treturn hasheq(sha1, the_hash_algo->empty_tree->hash);\n-}\n-\n static inline int is_empty_tree_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_tree);\ndiff --git a/read-cache.c b/read-cache.c\nindex 447109aa76..10e002ce6d 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -337,7 +337,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)\n \n \t/* Racily smudged entry? */\n \tif (!ce->ce_stat_data.sd_size) {\n-\t\tif (!is_empty_blob_sha1(ce->oid.hash))\n+\t\tif (!is_empty_blob_oid(&ce->oid))\n \t\t\tchanged |= DATA_CHANGED;\n \t}\n \n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496894","messageId":"687ad9fc02f05dada24c6367262e74f039662604.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 02/21] hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:57:42Z","receivedAt":"2024-06-11T11:57:47Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Many of our hash functions have two variants, one receiving a `struct\ngit_hash_algo` and one that derives it via `the_repository`. Adapt all\nof those functions to always require the hash algorithm as input and\ndrop the variants that do not accept one.\n\nAs those functions are now independent of `the_repository`, we can move\nthem from \"hash.h\" to \"hash-ll.h\".\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/index-pack.c     |  6 +++---\n builtin/pack-redundant.c |  8 +++++---\n builtin/unpack-objects.c |  3 ++-\n commit-graph.c           |  3 ++-\n csum-file.c              |  6 +++---\n hash-ll.h                | 15 +++++++++++++--\n hash-lookup.c            |  3 ++-\n hash.h                   | 24 ++----------------------\n http-walker.c            |  2 +-\n match-trees.c            |  2 +-\n notes.c                  |  2 +-\n pack-bitmap-write.c      |  4 ++--\n pack-bitmap.c            |  3 ++-\n pack-check.c             |  5 +++--\n pack-write.c             |  3 ++-\n packfile.c               |  8 ++++----\n read-cache.c             |  8 ++++----\n 17 files changed, 52 insertions(+), 53 deletions(-)\n\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex 856428fef9..ea727fba16 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -1204,7 +1204,7 @@ static void parse_pack_objects(unsigned char *hash)\n \tthe_hash_algo->init_fn(&tmp_ctx);\n \tthe_hash_algo->clone_fn(&tmp_ctx, &input_ctx);\n \tthe_hash_algo->final_fn(hash, &tmp_ctx);\n-\tif (!hasheq(fill(the_hash_algo->rawsz), hash))\n+\tif (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo))\n \t\tdie(_(\"pack is corrupted (SHA1 mismatch)\"));\n \tuse(the_hash_algo->rawsz);\n \n@@ -1307,11 +1307,11 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha\n \t\tstop_progress_msg(&progress, msg.buf);\n \t\tstrbuf_release(&msg);\n \t\tfinalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0);\n-\t\thashcpy(read_hash, pack_hash);\n+\t\thashcpy(read_hash, pack_hash, the_repository->hash_algo);\n \t\tfixup_pack_header_footer(output_fd, pack_hash,\n \t\t\t\t\t curr_pack, nr_objects,\n \t\t\t\t\t read_hash, consumed_bytes-the_hash_algo->rawsz);\n-\t\tif (!hasheq(read_hash, tail_hash))\n+\t\tif (!hasheq(read_hash, tail_hash, the_repository->hash_algo))\n \t\t\tdie(_(\"Unexpected tail checksum for %s \"\n \t\t\t      \"(disk corruption?)\"), curr_pack);\n \t}\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 4c735ba069..103c11b9d3 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -155,7 +155,7 @@ static inline struct llist_item * llist_sorted_remove(struct llist *list, const\n \tl = (hint == NULL) ? list->front : hint;\n \tprev = NULL;\n \twhile (l) {\n-\t\tconst int cmp = hashcmp(l->oid.hash, oid);\n+\t\tconst int cmp = hashcmp(l->oid.hash, oid, the_repository->hash_algo);\n \t\tif (cmp > 0) /* not in list, since sorted */\n \t\t\treturn prev;\n \t\tif (!cmp) { /* found */\n@@ -258,7 +258,8 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)\n \twhile (p1_off < p1->pack->num_objects * p1_step &&\n \t       p2_off < p2->pack->num_objects * p2_step)\n \t{\n-\t\tconst int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);\n+\t\tconst int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,\n+\t\t\t\t\tthe_repository->hash_algo);\n \t\t/* cmp ~ p1 - p2 */\n \t\tif (cmp == 0) {\n \t\t\tp1_hint = llist_sorted_remove(p1->unique_objects,\n@@ -296,7 +297,8 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)\n \twhile (p1_off < p1->num_objects * p1_step &&\n \t       p2_off < p2->num_objects * p2_step)\n \t{\n-\t\tint cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);\n+\t\tint cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,\n+\t\t\t\t  the_repository->hash_algo);\n \t\t/* cmp ~ p1 - p2 */\n \t\tif (cmp == 0) {\n \t\t\tret++;\ndiff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c\nindex f1c85a00ae..0855572c27 100644\n--- a/builtin/unpack-objects.c\n+++ b/builtin/unpack-objects.c\n@@ -674,7 +674,8 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)\n \t\tif (fsck_finish(&fsck_options))\n \t\t\tdie(_(\"fsck error in pack objects\"));\n \t}\n-\tif (!hasheq(fill(the_hash_algo->rawsz), oid.hash))\n+\tif (!hasheq(fill(the_hash_algo->rawsz), oid.hash,\n+\t\t    the_repository->hash_algo))\n \t\tdie(\"final sha1 did not match\");\n \tuse(the_hash_algo->rawsz);\n \ndiff --git a/commit-graph.c b/commit-graph.c\nindex e5dd3553df..3429156b28 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -565,7 +565,8 @@ static int add_graph_to_chain(struct commit_graph *g,\n \n \t\tif (!cur_g ||\n \t\t    !oideq(&oids[n], &cur_g->oid) ||\n-\t\t    !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n))) {\n+\t\t    !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n),\n+\t\t\t    the_repository->hash_algo)) {\n \t\t\twarning(_(\"commit-graph chain does not match\"));\n \t\t\treturn 0;\n \t\t}\ndiff --git a/csum-file.c b/csum-file.c\nindex 870748e016..f4be0804b7 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -68,12 +68,12 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result,\n \thashflush(f);\n \n \tif (f->skip_hash)\n-\t\thashclr(f->buffer);\n+\t\thashclr(f->buffer, the_repository->hash_algo);\n \telse\n \t\tthe_hash_algo->final_fn(f->buffer, &f->ctx);\n \n \tif (result)\n-\t\thashcpy(result, f->buffer);\n+\t\thashcpy(result, f->buffer, the_repository->hash_algo);\n \tif (flags & CSUM_HASH_IN_STREAM)\n \t\tflush(f, f->buffer, the_hash_algo->rawsz);\n \tif (flags & CSUM_FSYNC)\n@@ -237,5 +237,5 @@ int hashfile_checksum_valid(const unsigned char *data, size_t total_len)\n \tthe_hash_algo->update_fn(&ctx, data, data_len);\n \tthe_hash_algo->final_fn(got, &ctx);\n \n-\treturn hasheq(got, data + data_len);\n+\treturn hasheq(got, data + data_len, the_repository->hash_algo);\n }\ndiff --git a/hash-ll.h b/hash-ll.h\nindex 2cfde63ae1..fabdd8ecc7 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -245,7 +245,7 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n \n const struct object_id *null_oid(void);\n \n-static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n {\n \t/*\n \t * Teach the compiler that there are only two possibilities of hash size\n@@ -256,7 +256,7 @@ static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *\n \treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n }\n \n-static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n {\n \t/*\n \t * We write this here instead of deferring to hashcmp so that the\n@@ -267,6 +267,17 @@ static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *s\n \treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n }\n \n+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(sha_dst, sha_src, algop->rawsz);\n+}\n+\n+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n+{\n+\tmemset(hash, 0, algop->rawsz);\n+}\n+\n static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n {\n \tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\ndiff --git a/hash-lookup.c b/hash-lookup.c\nindex 9f0f95e2b9..9aa6b82eb7 100644\n--- a/hash-lookup.c\n+++ b/hash-lookup.c\n@@ -112,7 +112,8 @@ int bsearch_hash(const unsigned char *hash, const uint32_t *fanout_nbo,\n \n \twhile (lo < hi) {\n \t\tunsigned mi = lo + (hi - lo) / 2;\n-\t\tint cmp = hashcmp(table + mi * stride, hash);\n+\t\tint cmp = hashcmp(table + mi * stride, hash,\n+\t\t\t\t  the_repository->hash_algo);\n \n \t\tif (!cmp) {\n \t\t\tif (result)\ndiff --git a/hash.h b/hash.h\nindex a1161e1b22..714938e2eb 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,11 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)\n-{\n-\treturn hashcmp_algop(sha1, sha2, the_hash_algo);\n-}\n-\n static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n {\n \tconst struct git_hash_algo *algop;\n@@ -18,12 +13,7 @@ static inline int oidcmp(const struct object_id *oid1, const struct object_id *o\n \t\talgop = the_hash_algo;\n \telse\n \t\talgop = &hash_algos[oid1->algo];\n-\treturn hashcmp_algop(oid1->hash, oid2->hash, algop);\n-}\n-\n-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2)\n-{\n-\treturn hasheq_algop(sha1, sha2, the_hash_algo);\n+\treturn hashcmp(oid1->hash, oid2->hash, algop);\n }\n \n static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n@@ -33,7 +23,7 @@ static inline int oideq(const struct object_id *oid1, const struct object_id *oi\n \t\talgop = the_hash_algo;\n \telse\n \t\talgop = &hash_algos[oid1->algo];\n-\treturn hasheq_algop(oid1->hash, oid2->hash, algop);\n+\treturn hasheq(oid1->hash, oid2->hash, algop);\n }\n \n static inline int is_null_oid(const struct object_id *oid)\n@@ -41,11 +31,6 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn oideq(oid, null_oid());\n }\n \n-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)\n-{\n-\tmemcpy(sha_dst, sha_src, the_hash_algo->rawsz);\n-}\n-\n /* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */\n static inline void oidcpy_with_padding(struct object_id *dst,\n \t\t\t\t       const struct object_id *src)\n@@ -62,11 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,\n \tdst->algo = src->algo;\n }\n \n-static inline void hashclr(unsigned char *hash)\n-{\n-\tmemset(hash, 0, the_hash_algo->rawsz);\n-}\n-\n static inline void oidclr(struct object_id *oid)\n {\n \tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\ndiff --git a/http-walker.c b/http-walker.c\nindex b395ef1327..cf7f8c82bc 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -485,7 +485,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)\n \n \tlist_for_each(pos, head) {\n \t\tobj_req = list_entry(pos, struct object_request, node);\n-\t\tif (hasheq(obj_req->oid.hash, hash))\n+\t\tif (hasheq(obj_req->oid.hash, hash, the_repository->hash_algo))\n \t\t\tbreak;\n \t}\n \tif (!obj_req)\ndiff --git a/match-trees.c b/match-trees.c\nindex 3412b6a140..849b391d3d 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -237,7 +237,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,\n \t} else {\n \t\trewrite_with = oid2;\n \t}\n-\thashcpy(rewrite_here, rewrite_with->hash);\n+\thashcpy(rewrite_here, rewrite_with->hash, the_repository->hash_algo);\n \tstatus = write_object_file(buf, sz, OBJ_TREE, result);\n \tfree(buf);\n \treturn status;\ndiff --git a/notes.c b/notes.c\nindex 53ca25c814..5296fd863f 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -149,7 +149,7 @@ static struct leaf_node *note_tree_find(struct notes_tree *t,\n \tvoid **p = note_tree_search(t, &tree, &n, key_sha1);\n \tif (GET_PTR_TYPE(*p) == PTR_TYPE_NOTE) {\n \t\tstruct leaf_node *l = (struct leaf_node *) CLR_PTR_TYPE(*p);\n-\t\tif (hasheq(key_sha1, l->key_oid.hash))\n+\t\tif (hasheq(key_sha1, l->key_oid.hash, the_repository->hash_algo))\n \t\t\treturn l;\n \t}\n \treturn NULL;\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 6cae670412..59d2e3a387 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -790,7 +790,7 @@ static void write_hash_cache(struct hashfile *f,\n void bitmap_writer_set_checksum(struct bitmap_writer *writer,\n \t\t\t\tconst unsigned char *sha1)\n {\n-\thashcpy(writer->pack_checksum, sha1);\n+\thashcpy(writer->pack_checksum, sha1, the_repository->hash_algo);\n }\n \n void bitmap_writer_finish(struct bitmap_writer *writer,\n@@ -816,7 +816,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,\n \theader.version = htons(default_version);\n \theader.options = htons(flags | options);\n \theader.entry_count = htonl(writer->selected_nr);\n-\thashcpy(header.checksum, writer->pack_checksum);\n+\thashcpy(header.checksum, writer->pack_checksum, the_repository->hash_algo);\n \n \thashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz);\n \tdump_bitmap(f, writer->commits);\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex fe8e8a51d3..184d28f05c 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -367,7 +367,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,\n \tif (load_bitmap_header(bitmap_git) < 0)\n \t\tgoto cleanup;\n \n-\tif (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum)) {\n+\tif (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum,\n+\t\t    the_repository->hash_algo)) {\n \t\terror(_(\"checksum doesn't match in MIDX and bitmap\"));\n \t\tgoto cleanup;\n \t}\ndiff --git a/pack-check.c b/pack-check.c\nindex 25104d5b14..288f5a3479 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -78,10 +78,11 @@ static int verify_packfile(struct repository *r,\n \t} while (offset < pack_sig_ofs);\n \tr->hash_algo->final_fn(hash, &ctx);\n \tpack_sig = use_pack(p, w_curs, pack_sig_ofs, NULL);\n-\tif (!hasheq(hash, pack_sig))\n+\tif (!hasheq(hash, pack_sig, r->hash_algo))\n \t\terr = error(\"%s pack checksum mismatch\",\n \t\t\t    p->pack_name);\n-\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig))\n+\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig,\n+\t\t    r->hash_algo))\n \t\terr = error(\"%s pack checksum does not match its index\",\n \t\t\t    p->pack_name);\n \tunuse_pack(w_curs);\ndiff --git a/pack-write.c b/pack-write.c\nindex 80ecfa544c..eef625fa5b 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -428,7 +428,8 @@ void fixup_pack_header_footer(int pack_fd,\n \t\tif (partial_pack_offset == 0) {\n \t\t\tunsigned char hash[GIT_MAX_RAWSZ];\n \t\t\tthe_hash_algo->final_fn(hash, &old_hash_ctx);\n-\t\t\tif (!hasheq(hash, partial_pack_hash))\n+\t\t\tif (!hasheq(hash, partial_pack_hash,\n+\t\t\t\t    the_repository->hash_algo))\n \t\t\t\tdie(\"Unexpected checksum for %s \"\n \t\t\t\t    \"(disk corruption?)\", pack_name);\n \t\t\t/*\ndiff --git a/packfile.c b/packfile.c\nindex d4df7fdeea..9156e9122c 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -242,7 +242,7 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)\n \tstruct packed_git *p = alloc_packed_git(alloc);\n \n \tmemcpy(p->pack_name, path, alloc); /* includes NUL */\n-\thashcpy(p->hash, sha1);\n+\thashcpy(p->hash, sha1, the_repository->hash_algo);\n \tif (check_packed_git_idx(idx_path, p)) {\n \t\tfree(p);\n \t\treturn NULL;\n@@ -596,7 +596,7 @@ static int open_packed_git_1(struct packed_git *p)\n \tif (read_result != hashsz)\n \t\treturn error(\"packfile %s signature is unavailable\", p->pack_name);\n \tidx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;\n-\tif (!hasheq(hash, idx_hash))\n+\tif (!hasheq(hash, idx_hash, the_repository->hash_algo))\n \t\treturn error(\"packfile %s does not match index\", p->pack_name);\n \treturn 0;\n }\n@@ -751,7 +751,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n \tp->mtime = st.st_mtime;\n \tif (path_len < the_hash_algo->hexsz ||\n \t    get_hash_hex(path + path_len - the_hash_algo->hexsz, p->hash))\n-\t\thashclr(p->hash);\n+\t\thashclr(p->hash, the_repository->hash_algo);\n \treturn p;\n }\n \n@@ -1971,7 +1971,7 @@ off_t find_pack_entry_one(const unsigned char *sha1,\n \t\t\treturn 0;\n \t}\n \n-\thashcpy(oid.hash, sha1);\n+\thashcpy(oid.hash, sha1, the_repository->hash_algo);\n \tif (bsearch_pack(&oid, p, &result))\n \t\treturn nth_packed_object_offset(p, result);\n \treturn 0;\ndiff --git a/read-cache.c b/read-cache.c\nindex 10e002ce6d..2642ac9558 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1735,7 +1735,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)\n \tthe_hash_algo->init_fn(&c);\n \tthe_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz);\n \tthe_hash_algo->final_fn(hash, &c);\n-\tif (!hasheq(hash, start))\n+\tif (!hasheq(hash, start, the_repository->hash_algo))\n \t\treturn error(_(\"bad index file sha1 signature\"));\n \treturn 0;\n }\n@@ -2641,7 +2641,7 @@ static void copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,\n \tondisk->uid  = htonl(ce->ce_stat_data.sd_uid);\n \tondisk->gid  = htonl(ce->ce_stat_data.sd_gid);\n \tondisk->size = htonl(ce->ce_stat_data.sd_size);\n-\thashcpy(ondisk->data, ce->oid.hash);\n+\thashcpy(ondisk->data, ce->oid.hash, the_repository->hash_algo);\n \n \tflags = ce->ce_flags & ~CE_NAMEMASK;\n \tflags |= (ce_namelen(ce) >= CE_NAMEMASK ? CE_NAMEMASK : ce_namelen(ce));\n@@ -2730,7 +2730,7 @@ static int verify_index_from(const struct index_state *istate, const char *path)\n \tif (n != the_hash_algo->rawsz)\n \t\tgoto out;\n \n-\tif (!hasheq(istate->oid.hash, hash))\n+\tif (!hasheq(istate->oid.hash, hash, the_repository->hash_algo))\n \t\tgoto out;\n \n \tclose(fd);\n@@ -3603,7 +3603,7 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size)\n \t\tsrc_offset += extsize;\n \t}\n \tthe_hash_algo->final_fn(hash, &c);\n-\tif (!hasheq(hash, (const unsigned char *)index))\n+\tif (!hasheq(hash, (const unsigned char *)index, the_repository->hash_algo))\n \t\treturn 0;\n \n \t/* Validate that the extension offsets returned us back to the eoie extension. */\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496895","messageId":"346ca76a7c419e227e82398d1fc3d2b3c0bd71a3.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 03/21] hash: require hash algorithm in `oidread()` and `oidclr()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:57:47Z","receivedAt":"2024-06-11T11:57:51Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both `oidread()` and `oidclr()` use `the_repository` to derive the hash\nfunction that shall be used. Require callers to pass in the hash\nalgorithm to get rid of this implicit dependency.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n apply.c                          |  2 +-\n blame.c                          |  2 +-\n builtin/am.c                     |  8 +++----\n builtin/fast-export.c            |  2 +-\n builtin/fast-import.c            | 39 +++++++++++++++++---------------\n builtin/fetch-pack.c             |  4 ++--\n builtin/index-pack.c             |  5 ++--\n builtin/log.c                    |  2 +-\n builtin/merge.c                  |  4 ++--\n builtin/notes.c                  |  2 +-\n builtin/pack-objects.c           |  3 ++-\n builtin/pack-redundant.c         |  2 +-\n builtin/patch-id.c               |  6 ++---\n builtin/pull.c                   |  6 ++---\n builtin/receive-pack.c           |  2 +-\n builtin/replace.c                |  2 +-\n builtin/rm.c                     |  2 +-\n builtin/tag.c                    |  2 +-\n builtin/unpack-objects.c         |  6 ++---\n builtin/update-ref.c             |  8 +++----\n cache-tree.c                     |  3 ++-\n commit-graph.c                   | 17 +++++++++-----\n diff-lib.c                       |  4 ++--\n diff.c                           |  6 ++---\n dir.c                            |  6 ++---\n hash-ll.h                        | 14 ++++++++++++\n hash.h                           | 17 --------------\n http-push.c                      |  2 +-\n http-walker.c                    |  2 +-\n match-trees.c                    |  2 +-\n midx.c                           |  3 ++-\n notes-merge.c                    |  6 ++---\n notes.c                          |  8 +++----\n object-file-convert.c            |  2 +-\n object-file.c                    |  4 ++--\n packfile.c                       | 10 ++++----\n read-cache.c                     |  8 ++++---\n refs.c                           |  6 ++---\n refs/files-backend.c             |  6 ++---\n refs/packed-backend.c            |  6 ++---\n refs/reftable-backend.c          | 37 ++++++++++++++++++------------\n remote.c                         |  8 +++----\n resolve-undo.c                   |  3 ++-\n sequencer.c                      |  4 ++--\n split-index.c                    |  2 +-\n submodule-config.c               |  2 +-\n t/helper/test-submodule-config.c |  2 +-\n tree-walk.c                      |  4 ++--\n 48 files changed, 163 insertions(+), 140 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 901b67e625..528939abb6 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -3680,7 +3680,7 @@ static int try_threeway(struct apply_state *state,\n \tif (status) {\n \t\tpatch->conflicted_threeway = 1;\n \t\tif (patch->is_new)\n-\t\t\toidclr(&patch->threeway_stage[0]);\n+\t\t\toidclr(&patch->threeway_stage[0], the_repository->hash_algo);\n \t\telse\n \t\t\toidcpy(&patch->threeway_stage[0], &pre_oid);\n \t\toidcpy(&patch->threeway_stage[1], &our_oid);\ndiff --git a/blame.c b/blame.c\nindex 33586b9777..a80f5e2e61 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -1246,7 +1246,7 @@ static int fill_blob_sha1_and_mode(struct repository *r,\n \t\tgoto error_out;\n \treturn 0;\n  error_out:\n-\toidclr(&origin->blob_oid);\n+\toidclr(&origin->blob_oid, the_repository->hash_algo);\n \torigin->mode = S_IFINVALID;\n \treturn -1;\n }\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 36839029d2..45c305ec86 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -408,7 +408,7 @@ static void am_load(struct am_state *state)\n \tread_commit_msg(state);\n \n \tif (read_state_file(&sb, state, \"original-commit\", 1) < 0)\n-\t\toidclr(&state->orig_commit);\n+\t\toidclr(&state->orig_commit, the_repository->hash_algo);\n \telse if (get_oid_hex(sb.buf, &state->orig_commit) < 0)\n \t\tdie(_(\"could not parse %s\"), am_path(state, \"original-commit\"));\n \n@@ -1121,7 +1121,7 @@ static void am_next(struct am_state *state)\n \tunlink(am_path(state, \"author-script\"));\n \tunlink(am_path(state, \"final-commit\"));\n \n-\toidclr(&state->orig_commit);\n+\toidclr(&state->orig_commit, the_repository->hash_algo);\n \tunlink(am_path(state, \"original-commit\"));\n \trefs_delete_ref(get_main_ref_store(the_repository), NULL,\n \t\t\t\"REBASE_HEAD\", NULL, REF_NO_DEREF);\n@@ -2151,11 +2151,11 @@ static int safe_to_abort(const struct am_state *state)\n \t\tif (get_oid_hex(sb.buf, &abort_safety))\n \t\t\tdie(_(\"could not parse %s\"), am_path(state, \"abort-safety\"));\n \t} else\n-\t\toidclr(&abort_safety);\n+\t\toidclr(&abort_safety, the_repository->hash_algo);\n \tstrbuf_release(&sb);\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &head))\n-\t\toidclr(&head);\n+\t\toidclr(&head, the_repository->hash_algo);\n \n \tif (oideq(&head, &abort_safety))\n \t\treturn 1;\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 4693d18cc9..4b6e8c6832 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -415,7 +415,7 @@ static char *generate_fake_oid(void)\n \tstruct object_id oid;\n \tchar *hex = xmallocz(GIT_MAX_HEXSZ);\n \n-\toidclr(&oid);\n+\toidclr(&oid, the_repository->hash_algo);\n \tput_be32(oid.hash + hashsz - 4, counter++);\n \treturn oid_to_hex_r(hex, &oid);\n }\ndiff --git a/builtin/fast-import.c b/builtin/fast-import.c\nindex d1c0243d04..12543488f3 100644\n--- a/builtin/fast-import.c\n+++ b/builtin/fast-import.c\n@@ -1279,8 +1279,10 @@ static void load_tree(struct tree_entry *root)\n \t\te->versions[0].mode = e->versions[1].mode;\n \t\te->name = to_atom(c, strlen(c));\n \t\tc += e->name->str_len + 1;\n-\t\toidread(&e->versions[0].oid, (unsigned char *)c);\n-\t\toidread(&e->versions[1].oid, (unsigned char *)c);\n+\t\toidread(&e->versions[0].oid, (unsigned char *)c,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&e->versions[1].oid, (unsigned char *)c,\n+\t\t\tthe_repository->hash_algo);\n \t\tc += the_hash_algo->rawsz;\n \t}\n \tfree(buf);\n@@ -1386,7 +1388,7 @@ static void tree_content_replace(\n {\n \tif (!S_ISDIR(mode))\n \t\tdie(\"Root cannot be a non-directory\");\n-\toidclr(&root->versions[0].oid);\n+\toidclr(&root->versions[0].oid, the_repository->hash_algo);\n \toidcpy(&root->versions[1].oid, oid);\n \tif (root->tree)\n \t\trelease_tree_content_recursive(root->tree);\n@@ -1445,7 +1447,7 @@ static int tree_content_set(\n \t\t\t\tif (S_ISDIR(e->versions[0].mode))\n \t\t\t\t\te->versions[0].mode |= NO_DELTA;\n \n-\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \t\t\t\treturn 1;\n \t\t\t}\n \t\t\tif (!S_ISDIR(e->versions[1].mode)) {\n@@ -1455,7 +1457,7 @@ static int tree_content_set(\n \t\t\tif (!e->tree)\n \t\t\t\tload_tree(e);\n \t\t\tif (tree_content_set(e, slash1 + 1, oid, mode, subtree)) {\n-\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \t\t\t\treturn 1;\n \t\t\t}\n \t\t\treturn 0;\n@@ -1467,7 +1469,7 @@ static int tree_content_set(\n \te = new_tree_entry();\n \te->name = to_atom(p, n);\n \te->versions[0].mode = 0;\n-\toidclr(&e->versions[0].oid);\n+\toidclr(&e->versions[0].oid, the_repository->hash_algo);\n \tt->entries[t->entry_count++] = e;\n \tif (*slash1) {\n \t\te->tree = new_tree_content(8);\n@@ -1478,7 +1480,7 @@ static int tree_content_set(\n \t\te->versions[1].mode = mode;\n \t\toidcpy(&e->versions[1].oid, oid);\n \t}\n-\toidclr(&root->versions[1].oid);\n+\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \treturn 1;\n }\n \n@@ -1523,7 +1525,8 @@ static int tree_content_remove(\n \t\t\tif (tree_content_remove(e, slash1 + 1, backup_leaf, 0)) {\n \t\t\t\tfor (n = 0; n < e->tree->entry_count; n++) {\n \t\t\t\t\tif (e->tree->entries[n]->versions[1].mode) {\n-\t\t\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\t\t\toidclr(&root->versions[1].oid,\n+\t\t\t\t\t\t       the_repository->hash_algo);\n \t\t\t\t\t\treturn 1;\n \t\t\t\t\t}\n \t\t\t\t}\n@@ -1542,8 +1545,8 @@ static int tree_content_remove(\n \t\trelease_tree_content_recursive(e->tree);\n \te->tree = NULL;\n \te->versions[1].mode = 0;\n-\toidclr(&e->versions[1].oid);\n-\toidclr(&root->versions[1].oid);\n+\toidclr(&e->versions[1].oid, the_repository->hash_algo);\n+\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \treturn 1;\n }\n \n@@ -1609,7 +1612,7 @@ static int update_branch(struct branch *b)\n \t\treturn 0;\n \t}\n \tif (refs_read_ref(get_main_ref_store(the_repository), b->name, &old_oid))\n-\t\toidclr(&old_oid);\n+\t\toidclr(&old_oid, the_repository->hash_algo);\n \tif (!force_update && !is_null_oid(&old_oid)) {\n \t\tstruct commit *old_cmit, *new_cmit;\n \t\tint ret;\n@@ -2550,8 +2553,8 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa\n static void file_change_deleteall(struct branch *b)\n {\n \trelease_tree_content_recursive(b->branch_tree.tree);\n-\toidclr(&b->branch_tree.versions[0].oid);\n-\toidclr(&b->branch_tree.versions[1].oid);\n+\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \tload_tree(&b->branch_tree);\n \tb->num_notes = 0;\n }\n@@ -2570,8 +2573,8 @@ static void parse_from_commit(struct branch *b, char *buf, unsigned long size)\n static void parse_from_existing(struct branch *b)\n {\n \tif (is_null_oid(&b->oid)) {\n-\t\toidclr(&b->branch_tree.versions[0].oid);\n-\t\toidclr(&b->branch_tree.versions[1].oid);\n+\t\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \t} else {\n \t\tunsigned long size;\n \t\tchar *buf;\n@@ -2894,9 +2897,9 @@ static void parse_reset_branch(const char *arg)\n \n \tb = lookup_branch(arg);\n \tif (b) {\n-\t\toidclr(&b->oid);\n-\t\toidclr(&b->branch_tree.versions[0].oid);\n-\t\toidclr(&b->branch_tree.versions[1].oid);\n+\t\toidclr(&b->oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \t\tif (b->branch_tree.tree) {\n \t\t\trelease_tree_content_recursive(b->branch_tree.tree);\n \t\t\tb->branch_tree.tree = NULL;\ndiff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c\nindex 44c05ee86c..af329e8d5c 100644\n--- a/builtin/fetch-pack.c\n+++ b/builtin/fetch-pack.c\n@@ -29,11 +29,11 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,\n \t\t\t; /* <oid>, leave oid as name */\n \t\t} else {\n \t\t\t/* <ref>, clear cruft from oid */\n-\t\t\toidclr(&oid);\n+\t\t\toidclr(&oid, the_repository->hash_algo);\n \t\t}\n \t} else {\n \t\t/* <ref>, clear cruft from get_oid_hex */\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t}\n \n \tref = alloc_ref(name);\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex ea727fba16..fd968d673d 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -528,7 +528,8 @@ static void *unpack_raw_entry(struct object_entry *obj,\n \n \tswitch (obj->type) {\n \tcase OBJ_REF_DELTA:\n-\t\toidread(ref_oid, fill(the_hash_algo->rawsz));\n+\t\toidread(ref_oid, fill(the_hash_algo->rawsz),\n+\t\t\tthe_repository->hash_algo);\n \t\tuse(the_hash_algo->rawsz);\n \t\tbreak;\n \tcase OBJ_OFS_DELTA:\n@@ -1372,7 +1373,7 @@ static struct object_entry *append_obj_to_pack(struct hashfile *f,\n \tobj[1].idx.offset += write_compressed(f, buf, size);\n \tobj[0].idx.crc32 = crc32_end(f);\n \thashflush(f);\n-\toidread(&obj->idx.oid, sha1);\n+\toidread(&obj->idx.oid, sha1, the_repository->hash_algo);\n \treturn obj;\n }\n \ndiff --git a/builtin/log.c b/builtin/log.c\nindex 78a247d8a9..ccbda8a005 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1938,7 +1938,7 @@ static void print_bases(struct base_tree_info *bases, FILE *file)\n \tfree(bases->patch_id);\n \tbases->nr_patch_id = 0;\n \tbases->alloc_patch_id = 0;\n-\toidclr(&bases->base_commit);\n+\toidclr(&bases->base_commit, the_repository->hash_algo);\n }\n \n static const char *diff_title(struct strbuf *sb,\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex daed2d4e1e..abe66311c7 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -494,7 +494,7 @@ static void merge_name(const char *remote, struct strbuf *msg)\n \tstrbuf_branchname(&bname, remote, 0);\n \tremote = bname.buf;\n \n-\toidclr(&branch_head);\n+\toidclr(&branch_head, the_repository->hash_algo);\n \tremote_head = get_merge_parent(remote);\n \tif (!remote_head)\n \t\tdie(_(\"'%s' does not point to a commit\"), remote);\n@@ -1690,7 +1690,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t * index and working tree polluted.\n \t */\n \tif (save_state(&stash))\n-\t\toidclr(&stash);\n+\t\toidclr(&stash, the_repository->hash_algo);\n \n \tfor (i = 0; i < use_strategies_nr; i++) {\n \t\tint ret, cnt;\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 7f80b3449b..d9c356e354 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -828,7 +828,7 @@ static int merge_commit(struct notes_merge_options *o)\n \tif (partial->parents)\n \t\toidcpy(&parent_oid, &partial->parents->item->object.oid);\n \telse\n-\t\toidclr(&parent_oid);\n+\t\toidclr(&parent_oid, the_repository->hash_algo);\n \n \tCALLOC_ARRAY(t, 1);\n \tinit_notes(t, \"NOTES_MERGE_PARTIAL\", combine_notes_overwrite, 0);\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 638f5c57f0..2b00983a99 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -2078,7 +2078,8 @@ static void check_object(struct object_entry *entry, uint32_t object_index)\n \t\t\t\toidread(&base_ref,\n \t\t\t\t\tuse_pack(p, &w_curs,\n \t\t\t\t\t\t entry->in_pack_offset + used,\n-\t\t\t\t\t\t NULL));\n+\t\t\t\t\t\t NULL),\n+\t\t\t\t\tthe_repository->hash_algo);\n \t\t\t\thave_base = 1;\n \t\t\t}\n \t\t\tentry->in_pack_header_size = used + the_hash_algo->rawsz;\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 103c11b9d3..dd9bf35f5b 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -100,7 +100,7 @@ static inline struct llist_item *llist_insert(struct llist *list,\n \t\t\t\t\t      const unsigned char *oid)\n {\n \tstruct llist_item *new_item = llist_item_get();\n-\toidread(&new_item->oid, oid);\n+\toidread(&new_item->oid, oid, the_repository->hash_algo);\n \tnew_item->next = NULL;\n \n \tif (after) {\ndiff --git a/builtin/patch-id.c b/builtin/patch-id.c\nindex 583099cacf..d790ae6354 100644\n--- a/builtin/patch-id.c\n+++ b/builtin/patch-id.c\n@@ -70,7 +70,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,\n \tgit_hash_ctx ctx;\n \n \tthe_hash_algo->init_fn(&ctx);\n-\toidclr(result);\n+\toidclr(result, the_repository->hash_algo);\n \n \twhile (strbuf_getwholeline(line_buf, stdin, '\\n') != EOF) {\n \t\tchar *line = line_buf->buf;\n@@ -166,7 +166,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,\n \t}\n \n \tif (!found_next)\n-\t\toidclr(next_oid);\n+\t\toidclr(next_oid, the_repository->hash_algo);\n \n \tflush_one_hunk(result, &ctx);\n \n@@ -179,7 +179,7 @@ static void generate_id_list(int stable, int verbatim)\n \tint patchlen;\n \tstruct strbuf line_buf = STRBUF_INIT;\n \n-\toidclr(&oid);\n+\toidclr(&oid, the_repository->hash_algo);\n \twhile (!feof(stdin)) {\n \t\tpatchlen = get_one_patchid(&n, &result, &line_buf, stable, verbatim);\n \t\tflush_current_id(patchlen, &oid, &result);\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex d622202bce..2a73e673f3 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1038,7 +1038,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\tdie_conclude_merge();\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &orig_head))\n-\t\toidclr(&orig_head);\n+\t\toidclr(&orig_head, the_repository->hash_algo);\n \n \tif (opt_rebase) {\n \t\tif (opt_autostash == -1)\n@@ -1053,7 +1053,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t\t\t_(\"Please commit or stash them.\"), 1, 0);\n \n \t\tif (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))\n-\t\t\toidclr(&rebase_fork_point);\n+\t\t\toidclr(&rebase_fork_point, the_repository->hash_algo);\n \t}\n \n \tif (run_fetch(repo, refspecs))\n@@ -1063,7 +1063,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\treturn 0;\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &curr_head))\n-\t\toidclr(&curr_head);\n+\t\toidclr(&curr_head, the_repository->hash_algo);\n \n \tif (!is_null_oid(&orig_head) && !is_null_oid(&curr_head) &&\n \t\t\t!oideq(&orig_head, &curr_head)) {\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 01c1f04ece..aa5ba27d17 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -741,7 +741,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)\n \t\talready_done = 1;\n \t\tif (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB,\n \t\t\t\t      &push_cert_oid))\n-\t\t\toidclr(&push_cert_oid);\n+\t\t\toidclr(&push_cert_oid, the_repository->hash_algo);\n \n \t\tmemset(&sigcheck, '\\0', sizeof(sigcheck));\n \ndiff --git a/builtin/replace.c b/builtin/replace.c\nindex ce9f6974d2..1ef833c07f 100644\n--- a/builtin/replace.c\n+++ b/builtin/replace.c\n@@ -167,7 +167,7 @@ static int check_ref_valid(struct object_id *object,\n \t\treturn error(_(\"'%s' is not a valid ref name\"), ref->buf);\n \n \tif (refs_read_ref(get_main_ref_store(the_repository), ref->buf, prev))\n-\t\toidclr(prev);\n+\t\toidclr(prev, the_repository->hash_algo);\n \telse if (!force)\n \t\treturn error(_(\"replace ref '%s' already exists\"), ref->buf);\n \treturn 0;\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex d195c16e74..0e79cbab62 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -377,7 +377,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tif (!force) {\n \t\tstruct object_id oid;\n \t\tif (repo_get_oid(the_repository, \"HEAD\", &oid))\n-\t\t\toidclr(&oid);\n+\t\t\toidclr(&oid, the_repository->hash_algo);\n \t\tif (check_local_mod(&oid, index_only))\n \t\t\texit(1);\n \t}\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 6e2c0cf342..a1fb218512 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -650,7 +650,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\tdie(_(\"'%s' is not a valid tag name.\"), tag);\n \n \tif (refs_read_ref(get_main_ref_store(the_repository), ref.buf, &prev))\n-\t\toidclr(&prev);\n+\t\toidclr(&prev, the_repository->hash_algo);\n \telse if (!force)\n \t\tdie(_(\"tag '%s' already exists\"), tag);\n \ndiff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c\nindex 0855572c27..08fa2a7a74 100644\n--- a/builtin/unpack-objects.c\n+++ b/builtin/unpack-objects.c\n@@ -439,7 +439,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \tstruct object_id base_oid;\n \n \tif (type == OBJ_REF_DELTA) {\n-\t\toidread(&base_oid, fill(the_hash_algo->rawsz));\n+\t\toidread(&base_oid, fill(the_hash_algo->rawsz), the_repository->hash_algo);\n \t\tuse(the_hash_algo->rawsz);\n \t\tdelta_data = get_data(delta_size);\n \t\tif (!delta_data)\n@@ -451,7 +451,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \t\t\treturn; /* we are done */\n \t\telse {\n \t\t\t/* cannot resolve yet --- queue it */\n-\t\t\toidclr(&obj_list[nr].oid);\n+\t\t\toidclr(&obj_list[nr].oid, the_repository->hash_algo);\n \t\t\tadd_delta_to_list(nr, &base_oid, 0, delta_data, delta_size);\n \t\t\treturn;\n \t\t}\n@@ -500,7 +500,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \t\t\t * The delta base object is itself a delta that\n \t\t\t * has not been resolved yet.\n \t\t\t */\n-\t\t\toidclr(&obj_list[nr].oid);\n+\t\t\toidclr(&obj_list[nr].oid, the_repository->hash_algo);\n \t\t\tadd_delta_to_list(nr, null_oid(), base_offset,\n \t\t\t\t\t  delta_data, delta_size);\n \t\t\treturn;\ndiff --git a/builtin/update-ref.c b/builtin/update-ref.c\nindex 6cda1c08aa..f8a5b087f8 100644\n--- a/builtin/update-ref.c\n+++ b/builtin/update-ref.c\n@@ -122,7 +122,7 @@ static int parse_next_oid(const char **next, const char *end,\n \t\t\t\tgoto invalid;\n \t\t} else {\n \t\t\t/* Without -z, an empty value means all zeros: */\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t}\n \t} else {\n \t\t/* With -z, read the next NUL-terminated line */\n@@ -142,7 +142,7 @@ static int parse_next_oid(const char **next, const char *end,\n \t\t\t/* With -z, treat an empty value as all zeros: */\n \t\t\twarning(\"%s %s: missing <new-oid>, treating as zero\",\n \t\t\t\tcommand, refname);\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t} else {\n \t\t\t/*\n \t\t\t * With -z, an empty non-required value means\n@@ -291,7 +291,7 @@ static void parse_cmd_verify(struct ref_transaction *transaction,\n \n \tif (parse_next_oid(&next, end, &old_oid, \"verify\", refname,\n \t\t\t   PARSE_SHA1_OLD))\n-\t\toidclr(&old_oid);\n+\t\toidclr(&old_oid, the_repository->hash_algo);\n \n \tif (*next != line_termination)\n \t\tdie(\"verify %s: extra input: %s\", refname, next);\n@@ -564,7 +564,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)\n \t\t\t * The empty string implies that the reference\n \t\t\t * must not already exist:\n \t\t\t */\n-\t\t\toidclr(&oldoid);\n+\t\t\toidclr(&oldoid, the_repository->hash_algo);\n \t\telse if (repo_get_oid(the_repository, oldval, &oldoid))\n \t\t\tdie(\"%s: not a valid old SHA1\", oldval);\n \t}\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 387c0a3e5b..e4255c4d02 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -578,7 +578,8 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)\n \tif (0 <= it->entry_count) {\n \t\tif (size < rawsz)\n \t\t\tgoto free_return;\n-\t\toidread(&it->oid, (const unsigned char *)buf);\n+\t\toidread(&it->oid, (const unsigned char *)buf,\n+\t\t\tthe_repository->hash_algo);\n \t\tbuf += rawsz;\n \t\tsize -= rawsz;\n \t}\ndiff --git a/commit-graph.c b/commit-graph.c\nindex 3429156b28..e4eefd83bf 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -475,7 +475,8 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,\n \t\tFREE_AND_NULL(graph->bloom_filter_settings);\n \t}\n \n-\toidread(&graph->oid, graph->data + graph->data_len - graph->hash_len);\n+\toidread(&graph->oid, graph->data + graph->data_len - graph->hash_len,\n+\t\tthe_repository->hash_algo);\n \n \tfree_chunkfile(cf);\n \treturn graph;\n@@ -838,7 +839,8 @@ static void load_oid_from_graph(struct commit_graph *g,\n \n \tlex_index = pos - g->num_commits_in_base;\n \n-\toidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index));\n+\toidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index),\n+\t\tthe_repository->hash_algo);\n }\n \n static struct commit_list **insert_parent_or_die(struct repository *r,\n@@ -1080,7 +1082,7 @@ static struct tree *load_tree_for_commit(struct repository *r,\n \tcommit_data = g->chunk_commit_data +\n \t\t\tst_mult(GRAPH_DATA_WIDTH, graph_pos - g->num_commits_in_base);\n \n-\toidread(&oid, commit_data);\n+\toidread(&oid, commit_data, r->hash_algo);\n \tset_commit_tree(c, lookup_tree(r, &oid));\n \n \treturn c->maybe_tree;\n@@ -2556,7 +2558,8 @@ int write_commit_graph(struct object_directory *odb,\n \t\tstruct commit_graph *g = ctx->r->objects->commit_graph;\n \t\tfor (i = 0; i < g->num_commits; i++) {\n \t\t\tstruct object_id oid;\n-\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\t\tr->hash_algo);\n \t\t\toid_array_append(&ctx->oids, &oid);\n \t\t}\n \t}\n@@ -2675,7 +2678,8 @@ static int verify_one_commit_graph(struct repository *r,\n \tfor (i = 0; i < g->num_commits; i++) {\n \t\tstruct commit *graph_commit;\n \n-\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\tr->hash_algo);\n \n \t\tif (i && oidcmp(&prev_oid, &cur_oid) >= 0)\n \t\t\tgraph_report(_(\"commit-graph has incorrect OID order: %s then %s\"),\n@@ -2719,7 +2723,8 @@ static int verify_one_commit_graph(struct repository *r,\n \t\ttimestamp_t generation;\n \n \t\tdisplay_progress(progress, ++(*seen));\n-\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\tthe_repository->hash_algo);\n \n \t\tgraph_commit = lookup_commit(r, &cur_oid);\n \t\todb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 5a5a50c5a1..3fb8d79fef 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -160,7 +160,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)\n \t\t\tdpath->next = NULL;\n \t\t\tmemcpy(dpath->path, ce->name, path_len);\n \t\t\tdpath->path[path_len] = '\\0';\n-\t\t\toidclr(&dpath->oid);\n+\t\t\toidclr(&dpath->oid, the_repository->hash_algo);\n \t\t\tmemset(&(dpath->parent[0]), 0,\n \t\t\t       sizeof(struct combine_diff_parent)*5);\n \n@@ -412,7 +412,7 @@ static int show_modified(struct rev_info *revs,\n \t\tmemcpy(p->path, new_entry->name, pathlen);\n \t\tp->path[pathlen] = 0;\n \t\tp->mode = mode;\n-\t\toidclr(&p->oid);\n+\t\toidclr(&p->oid, the_repository->hash_algo);\n \t\tmemset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));\n \t\tp->parent[0].status = DIFF_STATUS_MODIFIED;\n \t\tp->parent[0].mode = new_entry->ce_mode;\ndiff --git a/diff.c b/diff.c\nindex e70301df76..60d1f7be81 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4567,7 +4567,7 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is\n \t\tif (!one->oid_valid) {\n \t\t\tstruct stat st;\n \t\t\tif (one->is_stdin) {\n-\t\t\t\toidclr(&one->oid);\n+\t\t\t\toidclr(&one->oid, the_repository->hash_algo);\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tif (lstat(one->path, &st) < 0)\n@@ -4577,7 +4577,7 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is\n \t\t}\n \t}\n \telse\n-\t\toidclr(&one->oid);\n+\t\toidclr(&one->oid, the_repository->hash_algo);\n }\n \n static void strip_prefix(int prefix_length, const char **namep, const char **otherp)\n@@ -6404,7 +6404,7 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid\n \tthe_hash_algo->init_fn(&ctx);\n \tmemset(&data, 0, sizeof(struct patch_id_t));\n \tdata.ctx = &ctx;\n-\toidclr(oid);\n+\toidclr(oid, the_repository->hash_algo);\n \n \tfor (i = 0; i < q->nr; i++) {\n \t\txpparam_t xpp;\ndiff --git a/dir.c b/dir.c\nindex f6066cc01d..9f9c1f3822 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1655,7 +1655,7 @@ static void prep_exclude(struct dir_struct *dir,\n \t\t}\n \n \t\t/* Try to read per-directory file */\n-\t\toidclr(&oid_stat.oid);\n+\t\toidclr(&oid_stat.oid, the_repository->hash_algo);\n \t\toid_stat.valid = 0;\n \t\tif (dir->exclude_per_dir &&\n \t\t    /*\n@@ -3762,7 +3762,7 @@ static void read_oid(size_t pos, void *cb)\n \t\trd->data = rd->end + 1;\n \t\treturn;\n \t}\n-\toidread(&ud->exclude_oid, rd->data);\n+\toidread(&ud->exclude_oid, rd->data, the_repository->hash_algo);\n \trd->data += the_hash_algo->rawsz;\n }\n \n@@ -3770,7 +3770,7 @@ static void load_oid_stat(struct oid_stat *oid_stat, const unsigned char *data,\n \t\t\t  const unsigned char *sha1)\n {\n \tstat_data_from_disk(&oid_stat->stat, data);\n-\toidread(&oid_stat->oid, sha1);\n+\toidread(&oid_stat->oid, sha1, the_repository->hash_algo);\n \toid_stat->valid = 1;\n }\n \ndiff --git a/hash-ll.h b/hash-ll.h\nindex fabdd8ecc7..dbb96369fc 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -284,6 +284,20 @@ static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n \tdst->algo = src->algo;\n }\n \n+static inline void oidread(struct object_id *oid, const unsigned char *hash,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(oid->hash, hash, algop->rawsz);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline void oidclr(struct object_id *oid,\n+\t\t\t  const struct git_hash_algo *algop)\n+{\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n static inline struct object_id *oiddup(const struct object_id *src)\n {\n \tstruct object_id *dst = xmalloc(sizeof(struct object_id));\ndiff --git a/hash.h b/hash.h\nindex 714938e2eb..43623a0c86 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -47,23 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,\n \tdst->algo = src->algo;\n }\n \n-static inline void oidclr(struct object_id *oid)\n-{\n-\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n-\toid->algo = hash_algo_by_ptr(the_hash_algo);\n-}\n-\n-static inline void oidread_algop(struct object_id *oid, const unsigned char *hash, const struct git_hash_algo *algop)\n-{\n-\tmemcpy(oid->hash, hash, algop->rawsz);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline void oidread(struct object_id *oid, const unsigned char *hash)\n-{\n-\toidread_algop(oid, hash, the_hash_algo);\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\ndiff --git a/http-push.c b/http-push.c\nindex 1fe51226fd..86de238b84 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1552,7 +1552,7 @@ static void fetch_symref(const char *path, char **symref, struct object_id *oid)\n \tfree(url);\n \n \tFREE_AND_NULL(*symref);\n-\toidclr(oid);\n+\toidclr(oid, the_repository->hash_algo);\n \n \tif (buffer.len == 0)\n \t\treturn;\ndiff --git a/http-walker.c b/http-walker.c\nindex cf7f8c82bc..b7110b6f82 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -152,7 +152,7 @@ static void prefetch(struct walker *walker, unsigned char *sha1)\n \n \tnewreq = xmalloc(sizeof(*newreq));\n \tnewreq->walker = walker;\n-\toidread(&newreq->oid, sha1);\n+\toidread(&newreq->oid, sha1, the_repository->hash_algo);\n \tnewreq->repo = data->alt;\n \tnewreq->state = WAITING;\n \tnewreq->req = NULL;\ndiff --git a/match-trees.c b/match-trees.c\nindex 849b391d3d..50c42e2061 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -229,7 +229,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,\n \t\t    oid_to_hex(oid1));\n \tif (*subpath) {\n \t\tstruct object_id tree_oid;\n-\t\toidread(&tree_oid, rewrite_here);\n+\t\toidread(&tree_oid, rewrite_here, the_repository->hash_algo);\n \t\tstatus = splice_tree(&tree_oid, subpath, oid2, &subtree);\n \t\tif (status)\n \t\t\treturn status;\ndiff --git a/midx.c b/midx.c\nindex bc4797196f..1e75f1a7eb 100644\n--- a/midx.c\n+++ b/midx.c\n@@ -304,7 +304,8 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid,\n \tif (n >= m->num_objects)\n \t\treturn NULL;\n \n-\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n));\n+\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n),\n+\t\tthe_repository->hash_algo);\n \treturn oid;\n }\n \ndiff --git a/notes-merge.c b/notes-merge.c\nindex 6a9a139b12..801941c2d1 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -240,7 +240,7 @@ static void diff_tree_local(struct notes_merge_options *o,\n \t\t\t *     (will be overwritten by following addition)\n \t\t\t */\n \t\t\tif (oideq(&mp->local, &uninitialized))\n-\t\t\t\toidclr(&mp->local);\n+\t\t\t\toidclr(&mp->local, the_repository->hash_algo);\n \t\t} else if (is_null_oid(&p->one->oid)) { /* addition */\n \t\t\t/*\n \t\t\t * Either this is a true addition (1), or it is part\n@@ -556,7 +556,7 @@ int notes_merge(struct notes_merge_options *o,\n \n \tassert(o->local_ref && o->remote_ref);\n \tassert(!strcmp(o->local_ref, local_tree->ref));\n-\toidclr(result_oid);\n+\toidclr(result_oid, the_repository->hash_algo);\n \n \ttrace_printf(\"notes_merge(o->local_ref = %s, o->remote_ref = %s)\\n\",\n \t       o->local_ref, o->remote_ref);\n@@ -579,7 +579,7 @@ int notes_merge(struct notes_merge_options *o,\n \t\t * unborn ref, perform the merge using an empty notes tree.\n \t\t */\n \t\tif (!check_refname_format(o->remote_ref, 0)) {\n-\t\t\toidclr(&remote_oid);\n+\t\t\toidclr(&remote_oid, the_repository->hash_algo);\n \t\t\tremote = NULL;\n \t\t} else {\n \t\t\tdie(\"Failed to resolve remote notes ref '%s'\",\ndiff --git a/notes.c b/notes.c\nindex 5296fd863f..3a8da92fb9 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -353,7 +353,7 @@ static void add_non_note(struct notes_tree *t, char *path,\n \tn->next = NULL;\n \tn->path = path;\n \tn->mode = mode;\n-\toidread(&n->oid, sha1);\n+\toidread(&n->oid, sha1, the_repository->hash_algo);\n \tt->prev_non_note = n;\n \n \tif (!t->first_non_note) {\n@@ -1036,7 +1036,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,\n \t\tdie(\"Failed to read notes tree referenced by %s (%s)\",\n \t\t    notes_ref, oid_to_hex(&object_oid));\n \n-\toidclr(&root_tree.key_oid);\n+\toidclr(&root_tree.key_oid, the_repository->hash_algo);\n \toidcpy(&root_tree.val_oid, &oid);\n \tload_subtree(t, &root_tree, t->root, 0);\n }\n@@ -1146,8 +1146,8 @@ int remove_note(struct notes_tree *t, const unsigned char *object_sha1)\n \tif (!t)\n \t\tt = &default_notes_tree;\n \tassert(t->initialized);\n-\toidread(&l.key_oid, object_sha1);\n-\toidclr(&l.val_oid);\n+\toidread(&l.key_oid, object_sha1, the_repository->hash_algo);\n+\toidclr(&l.val_oid, the_repository->hash_algo);\n \tnote_tree_remove(t, t->root, 0, &l);\n \tif (is_null_oid(&l.val_oid)) /* no note was removed */\n \t\treturn 1;\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex 4f6189095b..f684038f7f 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -56,7 +56,7 @@ static int decode_tree_entry_raw(struct object_id *oid, const char **path,\n \t\treturn -1;\n \t*len = strlen(*path) + 1;\n \n-\toidread_algop(oid, (const unsigned char *)*path + *len, algo);\n+\toidread(oid, (const unsigned char *)*path + *len, algo);\n \treturn 0;\n }\n \ndiff --git a/object-file.c b/object-file.c\nindex a40300ce4a..c161e3e2a5 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -1446,7 +1446,7 @@ static int loose_object_info(struct repository *r,\n \tint allow_unknown = flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE;\n \n \tif (oi->delta_base_oid)\n-\t\toidclr(oi->delta_base_oid);\n+\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \n \t/*\n \t * If we don't care about type or size, then we don't\n@@ -1580,7 +1580,7 @@ static int do_oid_object_info_extended(struct repository *r,\n \t\tif (oi->disk_sizep)\n \t\t\t*(oi->disk_sizep) = 0;\n \t\tif (oi->delta_base_oid)\n-\t\t\toidclr(oi->delta_base_oid);\n+\t\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \t\tif (oi->type_name)\n \t\t\tstrbuf_addstr(oi->type_name, type_name(co->type));\n \t\tif (oi->contentp)\ndiff --git a/packfile.c b/packfile.c\nindex 9156e9122c..ec7312cd20 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1251,7 +1251,7 @@ static int get_delta_base_oid(struct packed_git *p,\n {\n \tif (type == OBJ_REF_DELTA) {\n \t\tunsigned char *base = use_pack(p, w_curs, curpos, NULL);\n-\t\toidread(oid, base);\n+\t\toidread(oid, base, the_repository->hash_algo);\n \t\treturn 0;\n \t} else if (type == OBJ_OFS_DELTA) {\n \t\tuint32_t base_pos;\n@@ -1593,7 +1593,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,\n \t\t\t\tgoto out;\n \t\t\t}\n \t\t} else\n-\t\t\toidclr(oi->delta_base_oid);\n+\t\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \t}\n \n \toi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED :\n@@ -1917,10 +1917,12 @@ int nth_packed_object_id(struct object_id *oid,\n \t\treturn -1;\n \tindex += 4 * 256;\n \tif (p->index_version == 1) {\n-\t\toidread(oid, index + st_add(st_mult(hashsz + 4, n), 4));\n+\t\toidread(oid, index + st_add(st_mult(hashsz + 4, n), 4),\n+\t\t\tthe_repository->hash_algo);\n \t} else {\n \t\tindex += 8;\n-\t\toidread(oid, index + st_mult(hashsz, n));\n+\t\toidread(oid, index + st_mult(hashsz, n),\n+\t\t\tthe_repository->hash_algo);\n \t}\n \treturn 0;\n }\ndiff --git a/read-cache.c b/read-cache.c\nindex 2642ac9558..836f1db721 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1728,7 +1728,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)\n \n \tend = (unsigned char *)hdr + size;\n \tstart = end - the_hash_algo->rawsz;\n-\toidread(&oid, start);\n+\toidread(&oid, start, the_repository->hash_algo);\n \tif (oideq(&oid, null_oid()))\n \t\treturn 0;\n \n@@ -1876,7 +1876,8 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,\n \tce->ce_flags = flags & ~CE_NAMEMASK;\n \tce->ce_namelen = len;\n \tce->index = 0;\n-\toidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data));\n+\toidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data),\n+\t\tthe_repository->hash_algo);\n \n \tif (expand_name_field) {\n \t\tif (copy_len)\n@@ -2249,7 +2250,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)\n \tif (verify_hdr(hdr, mmap_size) < 0)\n \t\tgoto unmap;\n \n-\toidread(&istate->oid, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz);\n+\toidread(&istate->oid, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz,\n+\t\tthe_repository->hash_algo);\n \tistate->version = ntohl(hdr->hdr_version);\n \tistate->cache_nr = ntohl(hdr->hdr_entries);\n \tistate->cache_alloc = alloc_nr(istate->cache_nr);\ndiff --git a/refs.c b/refs.c\nindex 1304d3dd87..6e7caefdcf 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1822,7 +1822,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \t\t\t    failure_errno != ENOTDIR)\n \t\t\t\treturn NULL;\n \n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\tif (*flags & REF_BAD_NAME)\n \t\t\t\t*flags |= REF_ISBROKEN;\n \t\t\treturn refname;\n@@ -1832,7 +1832,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \n \t\tif (!(read_flags & REF_ISSYMREF)) {\n \t\t\tif (*flags & REF_BAD_NAME) {\n-\t\t\t\toidclr(oid);\n+\t\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\t\t*flags |= REF_ISBROKEN;\n \t\t\t}\n \t\t\treturn refname;\n@@ -1840,7 +1840,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \n \t\trefname = sb_refname.buf;\n \t\tif (resolve_flags & RESOLVE_REF_NO_RECURSE) {\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\treturn refname;\n \t\t}\n \t\tif (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 4519b46171..b484b5880d 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -246,7 +246,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,\n \n \tif (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING,\n \t\t\t\t     &oid, &flag)) {\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t\tflag |= REF_ISBROKEN;\n \t} else if (is_null_oid(&oid)) {\n \t\t/*\n@@ -263,7 +263,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,\n \tif (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {\n \t\tif (!refname_is_safe(refname))\n \t\t\tdie(\"loose refname is dangerous: %s\", refname);\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t\tflag |= REF_BAD_NAME | REF_ISBROKEN;\n \t}\n \tadd_entry_to_dir(dir, create_ref_entry(refname, &oid, flag));\n@@ -1150,7 +1150,7 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,\n \n \tif (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, 0,\n \t\t\t\t     &lock->old_oid, NULL))\n-\t\toidclr(&lock->old_oid);\n+\t\toidclr(&lock->old_oid, the_repository->hash_algo);\n \tgoto out;\n \n  error_return:\ndiff --git a/refs/packed-backend.c b/refs/packed-backend.c\nindex c4c1e36aa2..5ab1b21d10 100644\n--- a/refs/packed-backend.c\n+++ b/refs/packed-backend.c\n@@ -894,7 +894,7 @@ static int next_record(struct packed_ref_iterator *iter)\n \t\tif (!refname_is_safe(iter->base.refname))\n \t\t\tdie(\"packed refname is dangerous: %s\",\n \t\t\t    iter->base.refname);\n-\t\toidclr(&iter->oid);\n+\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\titer->base.flags |= REF_BAD_NAME | REF_ISBROKEN;\n \t}\n \tif (iter->snapshot->peeled == PEELED_FULLY ||\n@@ -919,13 +919,13 @@ static int next_record(struct packed_ref_iterator *iter)\n \t\t * we suppress it if the reference is broken:\n \t\t */\n \t\tif ((iter->base.flags & REF_ISBROKEN)) {\n-\t\t\toidclr(&iter->peeled);\n+\t\t\toidclr(&iter->peeled, the_repository->hash_algo);\n \t\t\titer->base.flags &= ~REF_KNOWS_PEELED;\n \t\t} else {\n \t\t\titer->base.flags |= REF_KNOWS_PEELED;\n \t\t}\n \t} else {\n-\t\toidclr(&iter->peeled);\n+\t\toidclr(&iter->peeled, the_repository->hash_algo);\n \t}\n \n \treturn ITER_OK;\ndiff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\nindex 9886fc67a4..57df2aba66 100644\n--- a/refs/reftable-backend.c\n+++ b/refs/reftable-backend.c\n@@ -217,7 +217,8 @@ static int read_ref_without_reload(struct reftable_stack *stack,\n \t\tstrbuf_addstr(referent, ref.value.symref);\n \t\t*type |= REF_ISSYMREF;\n \t} else if (reftable_ref_record_val1(&ref)) {\n-\t\toidread(oid, reftable_ref_record_val1(&ref));\n+\t\toidread(oid, reftable_ref_record_val1(&ref),\n+\t\t\tthe_repository->hash_algo);\n \t} else {\n \t\t/* We got a tombstone, which should not happen. */\n \t\tBUG(\"unhandled reference value type %d\", ref.value_type);\n@@ -483,15 +484,17 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)\n \n \t\tswitch (iter->ref.value_type) {\n \t\tcase REFTABLE_REF_VAL1:\n-\t\t\toidread(&iter->oid, iter->ref.value.val1);\n+\t\t\toidread(&iter->oid, iter->ref.value.val1,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tbreak;\n \t\tcase REFTABLE_REF_VAL2:\n-\t\t\toidread(&iter->oid, iter->ref.value.val2.value);\n+\t\t\toidread(&iter->oid, iter->ref.value.val2.value,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tbreak;\n \t\tcase REFTABLE_REF_SYMREF:\n \t\t\tif (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname,\n \t\t\t\t\t\t     RESOLVE_REF_READING, &iter->oid, &flags))\n-\t\t\t\toidclr(&iter->oid);\n+\t\t\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tBUG(\"unhandled reference value type %d\", iter->ref.value_type);\n@@ -503,7 +506,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)\n \t\tif (check_refname_format(iter->ref.refname, REFNAME_ALLOW_ONELEVEL)) {\n \t\t\tif (!refname_is_safe(iter->ref.refname))\n \t\t\t\tdie(_(\"refname is dangerous: %s\"), iter->ref.refname);\n-\t\t\toidclr(&iter->oid);\n+\t\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\t\tflags |= REF_BAD_NAME | REF_ISBROKEN;\n \t\t}\n \n@@ -545,7 +548,8 @@ static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,\n \t\t(struct reftable_ref_iterator *)ref_iterator;\n \n \tif (iter->ref.value_type == REFTABLE_REF_VAL2) {\n-\t\toidread(peeled, iter->ref.value.val2.target_value);\n+\t\toidread(peeled, iter->ref.value.val2.target_value,\n+\t\t\tthe_repository->hash_algo);\n \t\treturn 0;\n \t}\n \n@@ -1776,8 +1780,8 @@ static int yield_log_record(struct reftable_log_record *log,\n \tstruct object_id old_oid, new_oid;\n \tconst char *full_committer;\n \n-\toidread(&old_oid, log->value.update.old_hash);\n-\toidread(&new_oid, log->value.update.new_hash);\n+\toidread(&old_oid, log->value.update.old_hash, the_repository->hash_algo);\n+\toidread(&new_oid, log->value.update.new_hash, the_repository->hash_algo);\n \n \t/*\n \t * When both the old object ID and the new object ID are null\n@@ -2178,7 +2182,8 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \tif (ret < 0)\n \t\tgoto done;\n \tif (reftable_ref_record_val1(&ref_record))\n-\t\toidread(&oid, reftable_ref_record_val1(&ref_record));\n+\t\toidread(&oid, reftable_ref_record_val1(&ref_record),\n+\t\t\tthe_repository->hash_algo);\n \tprepare_fn(refname, &oid, policy_cb_data);\n \n \twhile (1) {\n@@ -2193,8 +2198,10 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \t\t\tbreak;\n \t\t}\n \n-\t\toidread(&old_oid, log.value.update.old_hash);\n-\t\toidread(&new_oid, log.value.update.new_hash);\n+\t\toidread(&old_oid, log.value.update.old_hash,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&new_oid, log.value.update.new_hash,\n+\t\t\tthe_repository->hash_algo);\n \n \t\t/*\n \t\t * Skip over the reflog existence marker. We will add it back\n@@ -2225,8 +2232,10 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \t\tstruct object_id old_oid, new_oid;\n \n \t\t*dest = logs[i];\n-\t\toidread(&old_oid, logs[i].value.update.old_hash);\n-\t\toidread(&new_oid, logs[i].value.update.new_hash);\n+\t\toidread(&old_oid, logs[i].value.update.old_hash,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&new_oid, logs[i].value.update.new_hash,\n+\t\t\tthe_repository->hash_algo);\n \n \t\tif (should_prune_fn(&old_oid, &new_oid, logs[i].value.update.email,\n \t\t\t\t    (timestamp_t)logs[i].value.update.time,\n@@ -2243,7 +2252,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \n \tif (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash &&\n \t    reftable_ref_record_val1(&ref_record))\n-\t\toidread(&arg.update_oid, last_hash);\n+\t\toidread(&arg.update_oid, last_hash, the_repository->hash_algo);\n \n \targ.refs = refs;\n \targ.records = rewritten;\ndiff --git a/remote.c b/remote.c\nindex dcb5492c85..1064171085 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1164,7 +1164,7 @@ static void tail_link_ref(struct ref *ref, struct ref ***tail)\n static struct ref *alloc_delete_ref(void)\n {\n \tstruct ref *ref = alloc_ref(\"(delete)\");\n-\toidclr(&ref->new_oid);\n+\toidclr(&ref->new_oid, the_repository->hash_algo);\n \treturn ref;\n }\n \n@@ -2531,7 +2531,7 @@ static int parse_push_cas_option(struct push_cas_option *cas, const char *arg, i\n \tif (!*colon)\n \t\tentry->use_tracking = 1;\n \telse if (!colon[1])\n-\t\toidclr(&entry->expect);\n+\t\toidclr(&entry->expect, the_repository->hash_algo);\n \telse if (repo_get_oid(the_repository, colon + 1, &entry->expect))\n \t\treturn error(_(\"cannot parse expected object name '%s'\"),\n \t\t\t     colon + 1);\n@@ -2733,7 +2733,7 @@ static void apply_cas(struct push_cas_option *cas,\n \t\telse if (remote_tracking(remote, ref->name,\n \t\t\t\t\t &ref->old_oid_expect,\n \t\t\t\t\t &ref->tracking_ref))\n-\t\t\toidclr(&ref->old_oid_expect);\n+\t\t\toidclr(&ref->old_oid_expect, the_repository->hash_algo);\n \t\telse\n \t\t\tref->check_reachable = cas->use_force_if_includes;\n \t\treturn;\n@@ -2747,7 +2747,7 @@ static void apply_cas(struct push_cas_option *cas,\n \tif (remote_tracking(remote, ref->name,\n \t\t\t    &ref->old_oid_expect,\n \t\t\t    &ref->tracking_ref))\n-\t\toidclr(&ref->old_oid_expect);\n+\t\toidclr(&ref->old_oid_expect, the_repository->hash_algo);\n \telse\n \t\tref->check_reachable = cas->use_force_if_includes;\n }\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex cd02dc9928..4e6f0e4676 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -93,7 +93,8 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)\n \t\t\t\tcontinue;\n \t\t\tif (size < rawsz)\n \t\t\t\tgoto error;\n-\t\t\toidread(&ui->oid[i], (const unsigned char *)data);\n+\t\t\toidread(&ui->oid[i], (const unsigned char *)data,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tsize -= rawsz;\n \t\t\tdata += rawsz;\n \t\t}\ndiff --git a/sequencer.c b/sequencer.c\nindex 30513e87bf..68d62a12ff 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -3334,12 +3334,12 @@ static int rollback_is_safe(void)\n \t\tstrbuf_release(&sb);\n \t}\n \telse if (errno == ENOENT)\n-\t\toidclr(&expected_head);\n+\t\toidclr(&expected_head, the_repository->hash_algo);\n \telse\n \t\tdie_errno(_(\"could not read '%s'\"), git_path_abort_safety_file());\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &actual_head))\n-\t\toidclr(&actual_head);\n+\t\toidclr(&actual_head, the_repository->hash_algo);\n \n \treturn oideq(&actual_head, &expected_head);\n }\ndiff --git a/split-index.c b/split-index.c\nindex 8c38687c04..058a8f448e 100644\n--- a/split-index.c\n+++ b/split-index.c\n@@ -29,7 +29,7 @@ int read_link_extension(struct index_state *istate,\n \tif (sz < the_hash_algo->rawsz)\n \t\treturn error(\"corrupt link extension (too short)\");\n \tsi = init_split_index(istate);\n-\toidread(&si->base_oid, data);\n+\toidread(&si->base_oid, data, the_repository->hash_algo);\n \tdata += the_hash_algo->rawsz;\n \tsz -= the_hash_algo->rawsz;\n \tif (!sz)\ndiff --git a/submodule-config.c b/submodule-config.c\nindex ec45ea67b9..ad43a282da 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -682,7 +682,7 @@ static int gitmodule_oid_from_commit(const struct object_id *treeish_name,\n \tint ret = 0;\n \n \tif (is_null_oid(treeish_name)) {\n-\t\toidclr(gitmodules_oid);\n+\t\toidclr(gitmodules_oid, the_repository->hash_algo);\n \t\treturn 1;\n \t}\n \ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex 9df2f03ac8..4b809d9dca 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -44,7 +44,7 @@ int cmd__submodule_config(int argc, const char **argv)\n \t\tpath_or_name = arg[1];\n \n \t\tif (commit[0] == '\\0')\n-\t\t\toidclr(&commit_oid);\n+\t\t\toidclr(&commit_oid, the_repository->hash_algo);\n \t\telse if (repo_get_oid(the_repository, commit, &commit_oid) < 0)\n \t\t\tdie_usage(argc, argv, \"Commit not found.\");\n \ndiff --git a/tree-walk.c b/tree-walk.c\nindex 6565d9ad99..535a3a2539 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -38,8 +38,8 @@ static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned l\n \tdesc->entry.path = path;\n \tdesc->entry.mode = (desc->flags & TREE_DESC_RAW_MODES) ? mode : canon_mode(mode);\n \tdesc->entry.pathlen = len - 1;\n-\toidread_algop(&desc->entry.oid, (const unsigned char *)path + len,\n-\t\t      desc->algo);\n+\toidread(&desc->entry.oid, (const unsigned char *)path + len,\n+\t\tdesc->algo);\n \n \treturn 0;\n }\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496896","messageId":"3ff28f313b2325cc6917d4c82a3064a94af6fd9d.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 04/21] global: ensure that object IDs are always padded","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:57:51Z","receivedAt":"2024-06-11T11:57:56Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `oidcmp()` and `oideq()` functions only compare the prefix length as\nspecified by the given hash algorithm. This mandates that the object IDs\nhave a valid hash algorithm set, or otherwise we wouldn't be able to\nfigure out that prefix. As we do not have a hash algorithm in many\ncases, for example when handling null object IDs, this assumption cannot\nalways be fulfilled. We thus have a fallback in place that instead uses\n`the_repository` to derive the hash function. This implicit dependency\nis hidden away from callers and can be quite surprising, especially in\ncontexts where there may be no repository.\n\nIn theory, we can adapt those functions to always memcmp(3P) the whole\nlength of their hash arrays. But there exist a couple of sites where we\npopulate `struct object_id`s such that only the prefix of its hash that\nis actually used by the hash algorithm is populated. The remaining bytes\nare left uninitialized. The fact that those bytes are uninitialized also\nleads to warnings under Valgrind in some places where we copy those\nbytes.\n\nRefactor callsites where we populate object IDs to always initialize all\nbytes. This also allows us to get rid of `oidcpy_with_padding()`, for\none because the input is now fully initialized, and because `oidcpy()`\nwill now always copy the whole hash array.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h           |  2 ++\n hash.h              | 16 ----------------\n hex.c               |  6 +++++-\n http-push.c         |  1 +\n notes.c             |  2 ++\n object-file.c       |  2 ++\n oidtree.c           |  4 ++--\n parallel-checkout.c |  8 +-------\n 8 files changed, 15 insertions(+), 26 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex dbb96369fc..b72f84f4ae 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -288,6 +288,8 @@ static inline void oidread(struct object_id *oid, const unsigned char *hash,\n \t\t\t   const struct git_hash_algo *algop)\n {\n \tmemcpy(oid->hash, hash, algop->rawsz);\n+\tif (algop->rawsz < GIT_MAX_RAWSZ)\n+\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n \toid->algo = hash_algo_by_ptr(algop);\n }\n \ndiff --git a/hash.h b/hash.h\nindex 43623a0c86..e43e3d8b5a 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -31,22 +31,6 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn oideq(oid, null_oid());\n }\n \n-/* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */\n-static inline void oidcpy_with_padding(struct object_id *dst,\n-\t\t\t\t       const struct object_id *src)\n-{\n-\tsize_t hashsz;\n-\n-\tif (!src->algo)\n-\t\thashsz = the_hash_algo->rawsz;\n-\telse\n-\t\thashsz = hash_algos[src->algo].rawsz;\n-\n-\tmemcpy(dst->hash, src->hash, hashsz);\n-\tmemset(dst->hash + hashsz, 0, GIT_MAX_RAWSZ - hashsz);\n-\tdst->algo = src->algo;\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\ndiff --git a/hex.c b/hex.c\nindex d42262bdca..bc9e86a978 100644\n--- a/hex.c\n+++ b/hex.c\n@@ -25,8 +25,12 @@ int get_oid_hex_algop(const char *hex, struct object_id *oid,\n \t\t      const struct git_hash_algo *algop)\n {\n \tint ret = get_hash_hex_algop(hex, oid->hash, algop);\n-\tif (!ret)\n+\tif (!ret) {\n \t\toid_set_algo(oid, algop);\n+\t\tif (algop->rawsz != GIT_MAX_RAWSZ)\n+\t\t\tmemset(oid->hash + algop->rawsz, 0,\n+\t\t\t       GIT_MAX_RAWSZ - algop->rawsz);\n+\t}\n \treturn ret;\n }\n \ndiff --git a/http-push.c b/http-push.c\nindex 86de238b84..a97df4a1fb 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1016,6 +1016,7 @@ static void remote_ls(const char *path, int flags,\n /* extract hex from sharded \"xx/x{38}\" filename */\n static int get_oid_hex_from_objpath(const char *path, struct object_id *oid)\n {\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n \toid->algo = hash_algo_by_ptr(the_hash_algo);\n \n \tif (strlen(path) != the_hash_algo->hexsz + 1)\ndiff --git a/notes.c b/notes.c\nindex 3a8da92fb9..afe2e2882e 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -427,6 +427,8 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,\n \t\t\t\t\t hashsz - prefix_len))\n \t\t\t\tgoto handle_non_note; /* entry.path is not a SHA1 */\n \n+\t\t\tmemset(object_oid.hash + hashsz, 0, GIT_MAX_RAWSZ - hashsz);\n+\n \t\t\ttype = PTR_TYPE_NOTE;\n \t\t} else if (path_len == 2) {\n \t\t\t/* This is potentially an internal node */\ndiff --git a/object-file.c b/object-file.c\nindex c161e3e2a5..bb97f8a809 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2743,6 +2743,8 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,\n \t\t    !hex_to_bytes(oid.hash + 1, de->d_name,\n \t\t\t\t  the_hash_algo->rawsz - 1)) {\n \t\t\toid_set_algo(&oid, the_hash_algo);\n+\t\t\tmemset(oid.hash + the_hash_algo->rawsz, 0,\n+\t\t\t       GIT_MAX_RAWSZ - the_hash_algo->rawsz);\n \t\t\tif (obj_cb) {\n \t\t\t\tr = obj_cb(&oid, path->buf, data);\n \t\t\t\tif (r)\ndiff --git a/oidtree.c b/oidtree.c\nindex daef175dc7..92d03b52db 100644\n--- a/oidtree.c\n+++ b/oidtree.c\n@@ -42,7 +42,7 @@ void oidtree_insert(struct oidtree *ot, const struct object_id *oid)\n \t * Clear the padding and copy the result in separate steps to\n \t * respect the 4-byte alignment needed by struct object_id.\n \t */\n-\toidcpy_with_padding(&k, oid);\n+\toidcpy(&k, oid);\n \tmemcpy(on->k, &k, sizeof(k));\n \n \t/*\n@@ -60,7 +60,7 @@ int oidtree_contains(struct oidtree *ot, const struct object_id *oid)\n \tstruct object_id k;\n \tsize_t klen = sizeof(k);\n \n-\toidcpy_with_padding(&k, oid);\n+\toidcpy(&k, oid);\n \n \tif (oid->algo == GIT_HASH_UNKNOWN)\n \t\tklen -= sizeof(oid->algo);\ndiff --git a/parallel-checkout.c b/parallel-checkout.c\nindex b5a714c711..08b960aac8 100644\n--- a/parallel-checkout.c\n+++ b/parallel-checkout.c\n@@ -429,13 +429,7 @@ static void send_one_item(int fd, struct parallel_checkout_item *pc_item)\n \tfixed_portion->ident = pc_item->ca.ident;\n \tfixed_portion->name_len = name_len;\n \tfixed_portion->working_tree_encoding_len = working_tree_encoding_len;\n-\t/*\n-\t * We pad the unused bytes in the hash array because, otherwise,\n-\t * Valgrind would complain about passing uninitialized bytes to a\n-\t * write() syscall. The warning doesn't represent any real risk here,\n-\t * but it could hinder the detection of actual errors.\n-\t */\n-\toidcpy_with_padding(&fixed_portion->oid, &pc_item->ce->oid);\n+\toidcpy(&fixed_portion->oid, &pc_item->ce->oid);\n \n \tvariant = data + sizeof(*fixed_portion);\n \tif (working_tree_encoding_len) {\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496897","messageId":"e2a0f2125d4a4af84a71bab9f07050d37c4a40a4.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 05/21] hash: convert `oidcmp()` and `oideq()` to compare whole hash","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:57:56Z","receivedAt":"2024-06-11T11:58:00Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"With the preceding commit, the hash array of object IDs is now fully\nzero-padded even when the hash algorithm's output is smaller than the\narray length. With that, we can now adapt both `oidcmp()` and `oideq()`\nto unconditionally memcmp(3P) the whole array instead of depending on\nthe hash size.\n\nWhile it may feel inefficient to compare unused bytes for e.g. SHA-1, in\npractice the compiler should now be able to produce code that is better\noptimized both because we have no branch anymore, but also because the\nsize to compare is now known at compile time. Goldbolt spits out the\nfollowing assembly on an x86_64 platform with GCC 14.1 for the old and\nnew implementations of `oidcmp()`:\n\n    oidcmp_old:\n            movsx   rax, DWORD PTR [rdi+32]\n            test    eax, eax\n            jne     .L2\n            mov     rax, QWORD PTR the_repository[rip]\n            cmp     QWORD PTR [rax+16], 32\n            je      .L6\n    .L4:\n            mov     edx, 20\n            jmp     memcmp\n    .L2:\n            lea     rdx, [rax+rax*2]\n            lea     rax, [rax+rdx*4]\n            lea     rax, hash_algos[0+rax*8]\n            cmp     QWORD PTR [rax+16], 32\n            jne     .L4\n    .L6:\n            mov     edx, 32\n            jmp     memcmp\n\n    oidcmp_new:\n            mov     edx, 32\n            jmp     memcmp\n\nThe new implementation gets ridi of all the branches and effectively\nonly ends setting up `edx` for `memcmp()` and then calling it.\n\nAnd for `oideq()`:\n\n    oideq_old:\n            movsx   rcx, DWORD PTR [rdi+32]\n            mov     rax, rdi\n            mov     rdx, rsi\n            test    ecx, ecx\n            jne     .L2\n            mov     rcx, QWORD PTR the_repository[rip]\n            cmp     QWORD PTR [rcx+16], 32\n            mov     rcx, QWORD PTR [rax]\n            je      .L12\n    .L4:\n            mov     rsi, QWORD PTR [rax+8]\n            xor     rcx, QWORD PTR [rdx]\n            xor     rsi, QWORD PTR [rdx+8]\n            or      rcx, rsi\n            je      .L13\n    .L8:\n            mov     eax, 1\n            test    eax, eax\n            sete    al\n            movzx   eax, al\n            ret\n    .L2:\n            lea     rsi, [rcx+rcx*2]\n            lea     rcx, [rcx+rsi*4]\n            lea     rcx, hash_algos[0+rcx*8]\n            cmp     QWORD PTR [rcx+16], 32\n            mov     rcx, QWORD PTR [rax]\n            jne     .L4\n    .L12:\n            mov     rsi, QWORD PTR [rax+8]\n            xor     rcx, QWORD PTR [rdx]\n            xor     rsi, QWORD PTR [rdx+8]\n            or      rcx, rsi\n            jne     .L8\n            mov     rcx, QWORD PTR [rax+16]\n            mov     rax, QWORD PTR [rax+24]\n            xor     rcx, QWORD PTR [rdx+16]\n            xor     rax, QWORD PTR [rdx+24]\n            or      rcx, rax\n            jne     .L8\n            xor     eax, eax\n    .L14:\n            test    eax, eax\n            sete    al\n            movzx   eax, al\n            ret\n    .L13:\n            mov     edi, DWORD PTR [rdx+16]\n            cmp     DWORD PTR [rax+16], edi\n            jne     .L8\n            xor     eax, eax\n            jmp     .L14\n\n    oideq_new:\n            mov     rax, QWORD PTR [rdi]\n            mov     rdx, QWORD PTR [rdi+8]\n            xor     rax, QWORD PTR [rsi]\n            xor     rdx, QWORD PTR [rsi+8]\n            or      rax, rdx\n            je      .L5\n    .L2:\n            mov     eax, 1\n            xor     eax, 1\n            ret\n    .L5:\n            mov     rax, QWORD PTR [rdi+16]\n            mov     rdx, QWORD PTR [rdi+24]\n            xor     rax, QWORD PTR [rsi+16]\n            xor     rdx, QWORD PTR [rsi+24]\n            or      rax, rdx\n            jne     .L2\n            xor     eax, eax\n            xor     eax, 1\n            ret\n\nInterestingly, the compiler decides to split the comparisons into two so\nthat it first compares the lower half of the object ID for equality and\nthen the upper half. If the first check shows a difference, then we\nwouldn't even end up comparing the second half.\n\nIn both cases, the new generated code is significantly shorter and has\nway less branches. While I didn't benchmark the change, I'd be surprised\nif the new code was slower.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h | 10 ++++++++++\n hash.h    | 20 --------------------\n 2 files changed, 10 insertions(+), 20 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex b72f84f4ae..b04fe12aef 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -278,6 +278,16 @@ static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algo\n \tmemset(hash, 0, algop->rawsz);\n }\n \n+static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n {\n \tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\ndiff --git a/hash.h b/hash.h\nindex e43e3d8b5a..ddc2e5ca47 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,26 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\tconst struct git_hash_algo *algop;\n-\tif (!oid1->algo)\n-\t\talgop = the_hash_algo;\n-\telse\n-\t\talgop = &hash_algos[oid1->algo];\n-\treturn hashcmp(oid1->hash, oid2->hash, algop);\n-}\n-\n-static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\tconst struct git_hash_algo *algop;\n-\tif (!oid1->algo)\n-\t\talgop = the_hash_algo;\n-\telse\n-\t\talgop = &hash_algos[oid1->algo];\n-\treturn hasheq(oid1->hash, oid2->hash, algop);\n-}\n-\n static inline int is_null_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, null_oid());\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496898","messageId":"3b6ce3b26c5d2c736cec54074a0aca4183db6b10.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 06/21] hash: make `is_null_oid()` independent of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:01Z","receivedAt":"2024-06-11T11:58:04Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The function `is_null_oid()` uses `oideq(oid, null_oid())` to check\nwhether a given object ID is the all-zero object ID. `null_oid()`\nimplicitly relies on `the_repository` though to return the correct null\nobject ID.\n\nGet rid of this dependency by always comparing the complete hash array\nfor being all-zeroes. This is possible due to the refactoring of object\nIDs so that their hash arrays are always fully initialized.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h | 6 ++++++\n hash.h    | 5 -----\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex b04fe12aef..faf6c292d2 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -341,6 +341,12 @@ static inline unsigned int oidhash(const struct object_id *oid)\n \treturn hash;\n }\n \n+static inline int is_null_oid(const struct object_id *oid)\n+{\n+\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n+\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n+}\n+\n const char *empty_tree_oid_hex(void);\n const char *empty_blob_oid_hex(void);\n \ndiff --git a/hash.h b/hash.h\nindex ddc2e5ca47..84f2296cfb 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,11 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int is_null_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, null_oid());\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496899","messageId":"82a391acaced9182258933123ed27f17463aa0e2.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 07/21] hash: require hash algorithm in `is_empty_{blob,tree}_oid()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:05Z","receivedAt":"2024-06-11T11:58:09Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both functions `is_empty_{blob,tree}_oid()` use `the_repository` to\nderive the hash function that shall be used. Require callers to pass in\nthe hash algorithm to get rid of this implicit dependency.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/fast-import.c |  4 +++-\n cache-tree.c          |  2 +-\n diffcore-rename.c     |  4 ++--\n hash-ll.h             | 12 ++++++++++++\n hash.h                | 10 ----------\n read-cache.c          |  2 +-\n 6 files changed, 19 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/fast-import.c b/builtin/fast-import.c\nindex 12543488f3..d21c4053a7 100644\n--- a/builtin/fast-import.c\n+++ b/builtin/fast-import.c\n@@ -2361,7 +2361,9 @@ static void file_change_m(const char *p, struct branch *b)\n \tparse_path_eol(&path, p, \"path\");\n \n \t/* Git does not track empty, non-toplevel directories. */\n-\tif (S_ISDIR(mode) && is_empty_tree_oid(&oid) && *path.buf) {\n+\tif (S_ISDIR(mode) &&\n+\t    is_empty_tree_oid(&oid, the_repository->hash_algo) &&\n+\t    *path.buf) {\n \t\ttree_content_remove(&b->branch_tree, path.buf, NULL, 0);\n \t\treturn;\n \t}\ndiff --git a/cache-tree.c b/cache-tree.c\nindex e4255c4d02..3290a1b8dd 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -422,7 +422,7 @@ static int update_one(struct cache_tree *it,\n \t\t/*\n \t\t * \"sub\" can be an empty tree if all subentries are i-t-a.\n \t\t */\n-\t\tif (contains_ita && is_empty_tree_oid(oid))\n+\t\tif (contains_ita && is_empty_tree_oid(oid, the_repository->hash_algo))\n \t\t\tcontinue;\n \n \t\tstrbuf_grow(&buffer, entlen + 100);\ndiff --git a/diffcore-rename.c b/diffcore-rename.c\nindex 5a6e2bcac7..5abb958651 100644\n--- a/diffcore-rename.c\n+++ b/diffcore-rename.c\n@@ -1422,7 +1422,7 @@ void diffcore_rename_extended(struct diff_options *options,\n \t\t\t\t strcmp(options->single_follow, p->two->path))\n \t\t\t\tcontinue; /* not interested */\n \t\t\telse if (!options->flags.rename_empty &&\n-\t\t\t\t is_empty_blob_oid(&p->two->oid))\n+\t\t\t\t is_empty_blob_oid(&p->two->oid, the_repository->hash_algo))\n \t\t\t\tcontinue;\n \t\t\telse if (add_rename_dst(p) < 0) {\n \t\t\t\twarning(\"skipping rename detection, detected\"\n@@ -1432,7 +1432,7 @@ void diffcore_rename_extended(struct diff_options *options,\n \t\t\t}\n \t\t}\n \t\telse if (!options->flags.rename_empty &&\n-\t\t\t is_empty_blob_oid(&p->one->oid))\n+\t\t\t is_empty_blob_oid(&p->one->oid, the_repository->hash_algo))\n \t\t\tcontinue;\n \t\telse if (!DIFF_PAIR_UNMERGED(p) && !DIFF_FILE_VALID(p->two)) {\n \t\t\t/*\ndiff --git a/hash-ll.h b/hash-ll.h\nindex faf6c292d2..1000a9af22 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -350,4 +350,16 @@ static inline int is_null_oid(const struct object_id *oid)\n const char *empty_tree_oid_hex(void);\n const char *empty_blob_oid_hex(void);\n \n+static inline int is_empty_blob_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_blob);\n+}\n+\n+static inline int is_empty_tree_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_tree);\n+}\n+\n #endif\ndiff --git a/hash.h b/hash.h\nindex 84f2296cfb..39a0164be3 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,14 +6,4 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int is_empty_blob_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, the_hash_algo->empty_blob);\n-}\n-\n-static inline int is_empty_tree_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, the_hash_algo->empty_tree);\n-}\n-\n #endif\ndiff --git a/read-cache.c b/read-cache.c\nindex 836f1db721..085b22faf3 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -337,7 +337,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)\n \n \t/* Racily smudged entry? */\n \tif (!ce->ce_stat_data.sd_size) {\n-\t\tif (!is_empty_blob_oid(&ce->oid))\n+\t\tif (!is_empty_blob_oid(&ce->oid, the_repository->hash_algo))\n \t\t\tchanged |= DATA_CHANGED;\n \t}\n \n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496900","messageId":"3f091dd94abaea467f87408884b9e6fbda71941a.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 08/21] hash: require hash algorithm in `empty_tree_oid_hex()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:10Z","receivedAt":"2024-06-11T11:58:13Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `empty_tree_oid_hex()` function use `the_repository` to derive the\nhash function that shall be used. Require callers to pass in the hash\nalgorithm to get rid of this implicit dependency.\n\nWhile at it, remove the unused `empty_blob_oid_hex()` function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n add-interactive.c      |  2 +-\n add-patch.c            |  2 +-\n builtin/merge.c        |  3 ++-\n builtin/receive-pack.c |  2 +-\n hash-ll.h              |  3 +--\n object-file.c          | 10 ++--------\n sequencer.c            |  2 +-\n submodule.c            |  6 +++---\n wt-status.c            |  4 ++--\n 9 files changed, 14 insertions(+), 20 deletions(-)\n\ndiff --git a/add-interactive.c b/add-interactive.c\nindex b5d6cd689a..a0961096cd 100644\n--- a/add-interactive.c\n+++ b/add-interactive.c\n@@ -557,7 +557,7 @@ static int get_modified_files(struct repository *r,\n \t\ts.skip_unseen = filter && i;\n \n \t\topt.def = is_initial ?\n-\t\t\tempty_tree_oid_hex() : oid_to_hex(&head_oid);\n+\t\t\tempty_tree_oid_hex(the_repository->hash_algo) : oid_to_hex(&head_oid);\n \n \t\trepo_init_revisions(r, &rev, NULL);\n \t\tsetup_revisions(0, NULL, &rev, &opt);\ndiff --git a/add-patch.c b/add-patch.c\nindex 814de57c4a..86181770f2 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -420,7 +420,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)\n \t\t\t    /* could be on an unborn branch */\n \t\t\t    !strcmp(\"HEAD\", s->revision) &&\n \t\t\t    repo_get_oid(the_repository, \"HEAD\", &oid) ?\n-\t\t\t    empty_tree_oid_hex() : s->revision);\n+\t\t\t    empty_tree_oid_hex(the_repository->hash_algo) : s->revision);\n \t}\n \tcolor_arg_index = args.nr;\n \t/* Use `--no-color` explicitly, just in case `diff.color = always`. */\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex abe66311c7..bb94b7df21 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -330,7 +330,8 @@ static void read_empty(const struct object_id *oid)\n {\n \tstruct child_process cmd = CHILD_PROCESS_INIT;\n \n-\tstrvec_pushl(&cmd.args, \"read-tree\", \"-m\", \"-u\", empty_tree_oid_hex(),\n+\tstrvec_pushl(&cmd.args, \"read-tree\", \"-m\", \"-u\",\n+\t\t     empty_tree_oid_hex(the_repository->hash_algo),\n \t\t     oid_to_hex(oid), NULL);\n \tcmd.git_cmd = 1;\n \ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex aa5ba27d17..41d5fb8e60 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -1371,7 +1371,7 @@ static const char *push_to_deploy(unsigned char *sha1,\n \tstrvec_pushl(&child.args, \"diff-index\", \"--quiet\", \"--cached\",\n \t\t     \"--ignore-submodules\",\n \t\t     /* diff-index with either HEAD or an empty tree */\n-\t\t     head_has_history() ? \"HEAD\" : empty_tree_oid_hex(),\n+\t\t     head_has_history() ? \"HEAD\" : empty_tree_oid_hex(the_repository->hash_algo),\n \t\t     \"--\", NULL);\n \tstrvec_pushv(&child.env, env->v);\n \tchild.no_stdin = 1;\ndiff --git a/hash-ll.h b/hash-ll.h\nindex 1000a9af22..3161c778b9 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -347,8 +347,7 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n }\n \n-const char *empty_tree_oid_hex(void);\n-const char *empty_blob_oid_hex(void);\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n \n static inline int is_empty_blob_oid(const struct object_id *oid,\n \t\t\t\t    const struct git_hash_algo *algop)\ndiff --git a/object-file.c b/object-file.c\nindex bb97f8a809..72318c8dd4 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -227,16 +227,10 @@ const struct object_id *null_oid(void)\n \treturn the_hash_algo->null_oid;\n }\n \n-const char *empty_tree_oid_hex(void)\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop)\n {\n \tstatic char buf[GIT_MAX_HEXSZ + 1];\n-\treturn oid_to_hex_r(buf, the_hash_algo->empty_tree);\n-}\n-\n-const char *empty_blob_oid_hex(void)\n-{\n-\tstatic char buf[GIT_MAX_HEXSZ + 1];\n-\treturn oid_to_hex_r(buf, the_hash_algo->empty_blob);\n+\treturn oid_to_hex_r(buf, algop->empty_tree);\n }\n \n int hash_algo_by_name(const char *name)\ndiff --git a/sequencer.c b/sequencer.c\nindex 68d62a12ff..823691e379 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -2263,7 +2263,7 @@ static int do_pick_commit(struct repository *r,\n \t\t\tunborn = 1;\n \t\t} else if (unborn)\n \t\t\toidcpy(&head, the_hash_algo->empty_tree);\n-\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex() : \"HEAD\",\n+\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : \"HEAD\",\n \t\t\t\t       NULL, 0))\n \t\t\treturn error_dirty_index(r, opts);\n \t}\ndiff --git a/submodule.c b/submodule.c\nindex 759cf1e1cd..caf3aa5600 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -2119,7 +2119,7 @@ static void submodule_reset_index(const char *path, const char *super_prefix)\n \tstrvec_pushf(&cp.args, \"--super-prefix=%s%s/\",\n \t\t     (super_prefix ? super_prefix : \"\"), path);\n \n-\tstrvec_push(&cp.args, empty_tree_oid_hex());\n+\tstrvec_push(&cp.args, empty_tree_oid_hex(the_repository->hash_algo));\n \n \tif (run_command(&cp))\n \t\tdie(_(\"could not reset submodule index\"));\n@@ -2229,9 +2229,9 @@ int submodule_move_head(const char *path, const char *super_prefix,\n \t\tstrvec_push(&cp.args, \"-m\");\n \n \tif (!(flags & SUBMODULE_MOVE_HEAD_FORCE))\n-\t\tstrvec_push(&cp.args, old_head ? old_head : empty_tree_oid_hex());\n+\t\tstrvec_push(&cp.args, old_head ? old_head : empty_tree_oid_hex(the_repository->hash_algo));\n \n-\tstrvec_push(&cp.args, new_head ? new_head : empty_tree_oid_hex());\n+\tstrvec_push(&cp.args, new_head ? new_head : empty_tree_oid_hex(the_repository->hash_algo));\n \n \tif (run_command(&cp)) {\n \t\tret = error(_(\"Submodule '%s' could not be updated.\"), path);\ndiff --git a/wt-status.c b/wt-status.c\nindex ff4be071ca..5051f5e599 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -641,7 +641,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n \n \trepo_init_revisions(s->repo, &rev, NULL);\n \tmemset(&opt, 0, sizeof(opt));\n-\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n+\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n \trev.diffopt.flags.override_submodule_config = 1;\n@@ -1136,7 +1136,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)\n \trev.diffopt.ita_invisible_in_index = 1;\n \n \tmemset(&opt, 0, sizeof(opt));\n-\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n+\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n \trev.diffopt.output_format |= DIFF_FORMAT_PATCH;\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496901","messageId":"479bebdf5361931fdb8d1ce33b511a205527f784.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 09/21] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:14Z","receivedAt":"2024-06-11T11:58:18Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Use of the `the_repository` variable is deprecated nowadays, and we\nslowly but steadily convert the codebase to not use it anymore. Instead,\ncallers should be passing down the repository to work on via parameters.\n\nIt is hard though to prove that a given code unit does not use this\nvariable anymore. The most trivial case, merely demonstrating that there\nis no direct use of `the_repository`, is already a bit of a pain during\ncode reviews as the reviewer needs to manually verify claims made by the\npatch author. The bigger problem though is that we have many interfaces\nthat implicitly rely on `the_repository`.\n\nIntroduce a new `USE_THE_REPOSITORY_VARIABLE` macro that allows code\nunits to opt into usage of `the_repository`. The intent of this macro is\nto demonstrate that a certain code unit does not use this variable\nanymore, and to keep it from new dependencies on it in future changes,\nbe it explicit or implicit\n\nFor now, the macro only guards `the_repository` itself as well as\n`the_hash_algo`. There are many more known interfaces where we have an\nimplicit dependency on `the_repository`, but those are not guarded at\nthe current point in time. Over time though, we should start to add\nguards as required (or even better, just remove them).\n\nDefine the macro as required in our code units. As expected, most of our\ncode still relies on the global variable. Nearly all of our builtins\nrely on the variable as there is no way yet to pass `the_repository` to\ntheir entry point. For now, declare the macro in \"biultin.h\" to keep the\nrequired changes at least a little bit more contained.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n add-interactive.c                            | 2 ++\n add-patch.c                                  | 2 ++\n apply.c                                      | 2 ++\n archive-tar.c                                | 3 +++\n archive-zip.c                                | 3 +++\n archive.c                                    | 2 ++\n attr.c                                       | 2 ++\n bisect.c                                     | 2 ++\n blame.c                                      | 2 ++\n branch.c                                     | 2 ++\n builtin.h                                    | 8 ++++++++\n builtin/blame.c                              | 2 +-\n builtin/log.c                                | 2 +-\n bulk-checkin.c                               | 3 +++\n bundle-uri.c                                 | 2 ++\n bundle.c                                     | 2 ++\n cache-tree.c                                 | 2 ++\n checkout.c                                   | 2 ++\n chunk-format.c                               | 2 ++\n combine-diff.c                               | 2 ++\n commit-graph.c                               | 2 ++\n commit-reach.c                               | 2 ++\n commit.c                                     | 2 ++\n common-main.c                                | 2 ++\n compat/win32/trace2_win32_process_info.c     | 2 ++\n config.c                                     | 3 +++\n connected.c                                  | 2 ++\n convert.c                                    | 2 ++\n csum-file.c                                  | 3 +++\n delta-islands.c                              | 2 ++\n diagnose.c                                   | 2 ++\n diff-lib.c                                   | 3 +++\n diff.c                                       | 3 +++\n diffcore-break.c                             | 3 +++\n diffcore-rename.c                            | 3 +++\n dir.c                                        | 3 +++\n entry.c                                      | 2 ++\n environment.c                                | 3 +++\n fetch-pack.c                                 | 2 ++\n fmt-merge-msg.c                              | 2 ++\n fsck.c                                       | 2 ++\n fsmonitor-ipc.c                              | 2 ++\n git.c                                        | 2 ++\n hash-lookup.c                                | 2 ++\n hash.h                                       | 4 +++-\n help.c                                       | 2 ++\n hex.c                                        | 2 ++\n http-backend.c                               | 2 ++\n http-push.c                                  | 2 ++\n http-walker.c                                | 2 ++\n http.c                                       | 2 ++\n list-objects-filter-options.c                | 2 ++\n list-objects-filter.c                        | 2 ++\n list-objects.c                               | 2 ++\n log-tree.c                                   | 2 ++\n loose.c                                      | 2 ++\n ls-refs.c                                    | 2 ++\n mailmap.c                                    | 2 ++\n match-trees.c                                | 2 ++\n merge-blobs.c                                | 2 ++\n merge-ort.c                                  | 2 ++\n merge-recursive.c                            | 3 +++\n merge.c                                      | 2 ++\n midx-write.c                                 | 2 ++\n midx.c                                       | 2 ++\n negotiator/default.c                         | 2 ++\n negotiator/skipping.c                        | 2 ++\n notes-cache.c                                | 2 ++\n notes-merge.c                                | 2 ++\n notes-utils.c                                | 2 ++\n notes.c                                      | 2 ++\n object-file-convert.c                        | 2 ++\n object-file.c                                | 3 +++\n object-name.c                                | 2 ++\n object.c                                     | 2 ++\n oid-array.c                                  | 2 ++\n oss-fuzz/fuzz-commit-graph.c                 | 2 ++\n pack-bitmap-write.c                          | 2 ++\n pack-bitmap.c                                | 2 ++\n pack-check.c                                 | 2 ++\n pack-revindex.c                              | 2 ++\n pack-write.c                                 | 2 ++\n packfile.c                                   | 2 ++\n parse-options-cb.c                           | 2 ++\n path.c                                       | 3 +++\n pathspec.c                                   | 2 ++\n pretty.c                                     | 2 ++\n progress.c                                   | 2 ++\n promisor-remote.c                            | 2 ++\n range-diff.c                                 | 2 ++\n reachable.c                                  | 2 ++\n read-cache.c                                 | 3 +++\n rebase-interactive.c                         | 2 ++\n ref-filter.c                                 | 2 ++\n reflog-walk.c                                | 2 ++\n reflog.c                                     | 2 ++\n refs.c                                       | 2 ++\n refs/files-backend.c                         | 2 ++\n refs/packed-backend.c                        | 2 ++\n refs/reftable-backend.c                      | 2 ++\n refspec.c                                    | 2 ++\n remote-curl.c                                | 2 ++\n remote.c                                     | 2 ++\n repository.h                                 | 2 ++\n rerere.c                                     | 2 ++\n reset.c                                      | 2 ++\n resolve-undo.c                               | 2 ++\n revision.c                                   | 2 ++\n run-command.c                                | 2 ++\n scalar.c                                     | 2 ++\n send-pack.c                                  | 2 ++\n sequencer.c                                  | 2 ++\n serve.c                                      | 2 ++\n server-info.c                                | 2 ++\n setup.c                                      | 2 ++\n shallow.c                                    | 2 ++\n split-index.c                                | 2 ++\n streaming.c                                  | 3 +++\n submodule-config.c                           | 2 ++\n submodule.c                                  | 2 ++\n t/helper/test-bitmap.c                       | 2 ++\n t/helper/test-bloom.c                        | 2 ++\n t/helper/test-cache-tree.c                   | 2 ++\n t/helper/test-dump-cache-tree.c              | 2 ++\n t/helper/test-dump-fsmonitor.c               | 2 ++\n t/helper/test-dump-split-index.c             | 2 ++\n t/helper/test-dump-untracked-cache.c         | 2 ++\n t/helper/test-example-decorate.c             | 2 ++\n t/helper/test-find-pack.c                    | 2 ++\n t/helper/test-fsmonitor-client.c             | 2 ++\n t/helper/test-lazy-init-name-hash.c          | 2 ++\n t/helper/test-match-trees.c                  | 2 ++\n t/helper/test-oidmap.c                       | 2 ++\n t/helper/test-pack-mtimes.c                  | 2 ++\n t/helper/test-reach.c                        | 2 ++\n t/helper/test-read-cache.c                   | 2 ++\n t/helper/test-read-graph.c                   | 2 ++\n t/helper/test-read-midx.c                    | 2 ++\n t/helper/test-ref-store.c                    | 2 ++\n t/helper/test-repository.c                   | 2 ++\n t/helper/test-revision-walking.c             | 2 ++\n t/helper/test-scrap-cache-tree.c             | 2 ++\n t/helper/test-submodule-config.c             | 2 ++\n t/helper/test-submodule-nested-repo-config.c | 2 ++\n t/helper/test-submodule.c                    | 2 ++\n t/helper/test-trace2.c                       | 2 ++\n t/helper/test-write-cache.c                  | 2 ++\n tag.c                                        | 2 ++\n tmp-objdir.c                                 | 2 ++\n transport-helper.c                           | 2 ++\n transport.c                                  | 2 ++\n tree-walk.c                                  | 2 ++\n tree.c                                       | 2 ++\n unpack-trees.c                               | 2 ++\n upload-pack.c                                | 2 ++\n walker.c                                     | 2 ++\n worktree.c                                   | 2 ++\n wt-status.c                                  | 2 ++\n xdiff-interface.c                            | 2 ++\n 159 files changed, 339 insertions(+), 3 deletions(-)\n\ndiff --git a/add-interactive.c b/add-interactive.c\nindex a0961096cd..49042b3026 100644\n--- a/add-interactive.c\n+++ b/add-interactive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"add-interactive.h\"\n #include \"color.h\"\ndiff --git a/add-patch.c b/add-patch.c\nindex 86181770f2..99e037c1e2 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"add-interactive.h\"\n #include \"advice.h\"\ndiff --git a/apply.c b/apply.c\nindex 528939abb6..ff939f908a 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -7,6 +7,8 @@\n  *\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"base85.h\"\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 8ae30125f8..e7b3489e1e 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2005, 2006 Rene Scharfe\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\ndiff --git a/archive-zip.c b/archive-zip.c\nindex fd1d3f816d..9f32730181 100644\n--- a/archive-zip.c\n+++ b/archive-zip.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2006 Rene Scharfe\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"archive.h\"\ndiff --git a/archive.c b/archive.c\nindex 5287fcdd8e..7bd60d0632 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/attr.c b/attr.c\nindex 300f994ba6..b5ed83c90e 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -6,6 +6,8 @@\n  * an insanely large number of attributes.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/bisect.c b/bisect.c\nindex 4ea703bec1..135f94ba09 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/blame.c b/blame.c\nindex a80f5e2e61..d403c46a35 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"refs.h\"\n #include \"object-store-ll.h\"\ndiff --git a/branch.c b/branch.c\nindex df5d24fec6..c887ea2151 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/builtin.h b/builtin.h\nindex 7eda9b2486..14fa017160 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -1,6 +1,14 @@\n #ifndef BUILTIN_H\n #define BUILTIN_H\n \n+/*\n+ * TODO: Almost all of our builtins access `the_repository` by necessity\n+ * because they do not get passed a pointer to it. We should adapt the function\n+ * signature of those main functions to accept a `struct repository *` and then\n+ * remove the macro here.\n+ */\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n \n /*\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex e09ff0155a..de89fff3f8 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -5,7 +5,7 @@\n  * See COPYING for licensing conditions\n  */\n \n-#include \"git-compat-util.h\"\n+#include \"builtin.h\"\n #include \"config.h\"\n #include \"color.h\"\n #include \"builtin.h\"\ndiff --git a/builtin/log.c b/builtin/log.c\nindex ccbda8a005..00305bea51 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -4,7 +4,7 @@\n  * (C) Copyright 2006 Linus Torvalds\n  *\t\t 2006 Junio Hamano\n  */\n-#include \"git-compat-util.h\"\n+#include \"builtin.h\"\n #include \"abspath.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/bulk-checkin.c b/bulk-checkin.c\nindex eb46b88637..da8673199b 100644\n--- a/bulk-checkin.c\n+++ b/bulk-checkin.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2011, Google Inc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bulk-checkin.h\"\n #include \"environment.h\"\ndiff --git a/bundle-uri.c b/bundle-uri.c\nindex 91b3319a5c..804fbcfbfa 100644\n--- a/bundle-uri.c\n+++ b/bundle-uri.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bundle-uri.h\"\n #include \"bundle.h\"\ndiff --git a/bundle.c b/bundle.c\nindex 95367c2d0a..82c285b905 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"lockfile.h\"\n #include \"bundle.h\"\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 3290a1b8dd..50610c3f3c 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/checkout.c b/checkout.c\nindex cfaea4bd10..0b1cf8b40b 100644\n--- a/checkout.c\n+++ b/checkout.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-name.h\"\n #include \"remote.h\"\ndiff --git a/chunk-format.c b/chunk-format.c\nindex cdc7f39b70..2dde24e6a3 100644\n--- a/chunk-format.c\n+++ b/chunk-format.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"chunk-format.h\"\n #include \"csum-file.h\"\ndiff --git a/combine-diff.c b/combine-diff.c\nindex 4960d904ac..829a44e416 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-store-ll.h\"\n #include \"commit.h\"\ndiff --git a/commit-graph.c b/commit-graph.c\nindex e4eefd83bf..b6bb9df0d0 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"csum-file.h\"\ndiff --git a/commit-reach.c b/commit-reach.c\nindex 384aee1ab3..dabc2972e4 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"commit-graph.h\"\ndiff --git a/commit.c b/commit.c\nindex 1d08951007..4956803e11 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tag.h\"\n #include \"commit.h\"\ndiff --git a/common-main.c b/common-main.c\nindex b86f40600f..8e68ac9e42 100644\n--- a/common-main.c\n+++ b/common-main.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"exec-cmd.h\"\n #include \"gettext.h\"\ndiff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\nindex 3ef0936f6f..f147da706a 100644\n--- a/compat/win32/trace2_win32_process_info.c\n+++ b/compat/win32/trace2_win32_process_info.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../../git-compat-util.h\"\n #include \"../../json-writer.h\"\n #include \"../../repository.h\"\ndiff --git a/config.c b/config.c\nindex abce05b774..7951029644 100644\n--- a/config.c\n+++ b/config.c\n@@ -5,6 +5,9 @@\n  * Copyright (C) Johannes Schindelin, 2005\n  *\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"advice.h\"\ndiff --git a/connected.c b/connected.c\nindex 8f89376dbc..87cc4b57a1 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/convert.c b/convert.c\nindex f2b9f01354..d8737fe0f2 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/csum-file.c b/csum-file.c\nindex f4be0804b7..8abbf01325 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -7,6 +7,9 @@\n  * files. Useful when you write a file that you want to be\n  * able to verify hasn't been messed with afterwards.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"progress.h\"\n #include \"csum-file.h\"\ndiff --git a/delta-islands.c b/delta-islands.c\nindex 89d51b72e3..ffe1ca2814 100644\n--- a/delta-islands.c\n+++ b/delta-islands.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object.h\"\n #include \"commit.h\"\ndiff --git a/diagnose.c b/diagnose.c\nindex 4d096c857f..cc2d535b60 100644\n--- a/diagnose.c\n+++ b/diagnose.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diagnose.h\"\n #include \"compat/disk.h\"\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 3fb8d79fef..b0d0f711e8 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"diff.h\"\ndiff --git a/diff.c b/diff.c\nindex 60d1f7be81..d4579d5f76 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"base85.h\"\ndiff --git a/diffcore-break.c b/diffcore-break.c\nindex 49ba38aa7c..831b66b5c3 100644\n--- a/diffcore-break.c\n+++ b/diffcore-break.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diffcore.h\"\n #include \"hash.h\"\ndiff --git a/diffcore-rename.c b/diffcore-rename.c\nindex 5abb958651..ae504007cf 100644\n--- a/diffcore-rename.c\n+++ b/diffcore-rename.c\n@@ -2,6 +2,9 @@\n  *\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diff.h\"\n #include \"diffcore.h\"\ndiff --git a/dir.c b/dir.c\nindex 9f9c1f3822..99688792e3 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -5,6 +5,9 @@\n  * Copyright (C) Linus Torvalds, 2005-2006\n  *\t\t Junio Hamano, 2005-2006\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/entry.c b/entry.c\nindex b8c257f6f9..fe1f74d140 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-store-ll.h\"\n #include \"dir.h\"\ndiff --git a/environment.c b/environment.c\nindex 701d515135..5cea2c9f54 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -7,6 +7,9 @@\n  * even if you might want to know where the git directory etc\n  * are.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"branch.h\"\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex eba9e420ea..e6e14b3874 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\ndiff --git a/fmt-merge-msg.c b/fmt-merge-msg.c\nindex 7d144b803a..b8bca89c0c 100644\n--- a/fmt-merge-msg.c\n+++ b/fmt-merge-msg.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/fsck.c b/fsck.c\nindex dd0a33028e..432996cbb6 100644\n--- a/fsck.c\n+++ b/fsck.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"date.h\"\n #include \"dir.h\"\ndiff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c\nindex 45471b5b74..f1b1631111 100644\n--- a/fsmonitor-ipc.c\n+++ b/fsmonitor-ipc.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"simple-ipc.h\"\ndiff --git a/git.c b/git.c\nindex 683bb69194..e35af9b0e5 100644\n--- a/git.c\n+++ b/git.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/hash-lookup.c b/hash-lookup.c\nindex 9aa6b82eb7..5f808caa51 100644\n--- a/hash-lookup.c\n+++ b/hash-lookup.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"hash-lookup.h\"\ndiff --git a/hash.h b/hash.h\nindex 39a0164be3..cb85d26a2f 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -4,6 +4,8 @@\n #include \"hash-ll.h\"\n #include \"repository.h\"\n \n-#define the_hash_algo the_repository->hash_algo\n+#ifdef USE_THE_REPOSITORY_VARIABLE\n+# define the_hash_algo the_repository->hash_algo\n+#endif\n \n #endif\ndiff --git a/help.c b/help.c\nindex 1d057aa607..10fdb1a03d 100644\n--- a/help.c\n+++ b/help.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"builtin.h\"\ndiff --git a/hex.c b/hex.c\nindex bc9e86a978..5ca78a7744 100644\n--- a/hex.c\n+++ b/hex.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"hex.h\"\ndiff --git a/http-backend.c b/http-backend.c\nindex 5b65287ac9..7c0b3be968 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/http-push.c b/http-push.c\nindex a97df4a1fb..7315a694aa 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/http-walker.c b/http-walker.c\nindex b7110b6f82..e417a7f51c 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"hex.h\"\ndiff --git a/http.c b/http.c\nindex 67cc47d28f..6536816e81 100644\n--- a/http.c\n+++ b/http.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"git-curl-compat.h\"\n #include \"hex.h\"\ndiff --git a/list-objects-filter-options.c b/list-objects-filter-options.c\nindex c5f363ca6f..00611107d2 100644\n--- a/list-objects-filter-options.c\n+++ b/list-objects-filter-options.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\ndiff --git a/list-objects-filter.c b/list-objects-filter.c\nindex 4346f8da45..49e2fa6f97 100644\n--- a/list-objects-filter.c\n+++ b/list-objects-filter.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"gettext.h\"\ndiff --git a/list-objects.c b/list-objects.c\nindex 11ad8be411..985d008799 100644\n--- a/list-objects.c\n+++ b/list-objects.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tag.h\"\n #include \"commit.h\"\ndiff --git a/log-tree.c b/log-tree.c\nindex 41416de4e3..223a4d9463 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit-reach.h\"\n #include \"config.h\"\ndiff --git a/loose.c b/loose.c\nindex f6faa6216a..a8bf772172 100644\n--- a/loose.c\n+++ b/loose.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"path.h\"\ndiff --git a/ls-refs.c b/ls-refs.c\nindex 398afe4ce3..2dd925b43d 100644\n--- a/ls-refs.c\n+++ b/ls-refs.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/mailmap.c b/mailmap.c\nindex b2efe29b3d..534a3eb4f0 100644\n--- a/mailmap.c\n+++ b/mailmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"string-list.h\"\ndiff --git a/match-trees.c b/match-trees.c\nindex 50c42e2061..f17c74d483 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"match-trees.h\"\ndiff --git a/merge-blobs.c b/merge-blobs.c\nindex 2f659fd014..0ad0390fea 100644\n--- a/merge-blobs.c\n+++ b/merge-blobs.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-ll.h\"\n #include \"blob.h\"\ndiff --git a/merge-ort.c b/merge-ort.c\nindex eaede6cead..691db9050e 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -14,6 +14,8 @@\n  * \"cale\", \"peedy\", or \"ins\" instead of \"ort\"?)\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-ort.h\"\n \ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex 8ff29ed09e..46ee364af7 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -3,6 +3,9 @@\n  * Fredrik Kuivinen.\n  * The thieves were Alex Riesen and Johannes Schindelin, in June/July 2006\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-recursive.h\"\n \ndiff --git a/merge.c b/merge.c\nindex 752a937fa9..fe3efa4b24 100644\n--- a/merge.c\n+++ b/merge.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/midx-write.c b/midx-write.c\nindex 55a6b63bac..9a194e8aac 100644\n--- a/midx-write.c\n+++ b/midx-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/midx.c b/midx.c\nindex 1e75f1a7eb..3992b05465 100644\n--- a/midx.c\n+++ b/midx.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"dir.h\"\ndiff --git a/negotiator/default.c b/negotiator/default.c\nindex 518b3c43b2..e3fa5c3324 100644\n--- a/negotiator/default.c\n+++ b/negotiator/default.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"default.h\"\n #include \"../commit.h\"\ndiff --git a/negotiator/skipping.c b/negotiator/skipping.c\nindex b7e008c2fd..f109928ad0 100644\n--- a/negotiator/skipping.c\n+++ b/negotiator/skipping.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"skipping.h\"\n #include \"../commit.h\"\ndiff --git a/notes-cache.c b/notes-cache.c\nindex 038db01ca0..ecfdf6e43b 100644\n--- a/notes-cache.c\n+++ b/notes-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"notes-cache.h\"\n #include \"object-store-ll.h\"\ndiff --git a/notes-merge.c b/notes-merge.c\nindex 801941c2d1..d95e683414 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"commit.h\"\ndiff --git a/notes-utils.c b/notes-utils.c\nindex e33aa86c4b..bca71274be 100644\n--- a/notes-utils.c\n+++ b/notes-utils.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/notes.c b/notes.c\nindex afe2e2882e..b6a13d0980 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex f684038f7f..958f61f094 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"strbuf.h\"\ndiff --git a/object-file.c b/object-file.c\nindex 72318c8dd4..a6555ed68c 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -6,6 +6,9 @@\n  * This handles basic git object files - packing, unpacking,\n  * creation etc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/object-name.c b/object-name.c\nindex 523af6f64f..d7509514bc 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-name.h\"\n #include \"advice.h\"\ndiff --git a/object.c b/object.c\nindex 93b5d97fdb..0c0fcb76c0 100644\n--- a/object.c\n+++ b/object.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/oid-array.c b/oid-array.c\nindex 1f36651754..9cac974395 100644\n--- a/oid-array.c\n+++ b/oid-array.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"oid-array.h\"\n #include \"hash-lookup.h\"\ndiff --git a/oss-fuzz/fuzz-commit-graph.c b/oss-fuzz/fuzz-commit-graph.c\nindex 75e668a057..951c9c082f 100644\n--- a/oss-fuzz/fuzz-commit-graph.c\n+++ b/oss-fuzz/fuzz-commit-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit-graph.h\"\n #include \"repository.h\"\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 59d2e3a387..37a8ad0fb3 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 184d28f05c..7eafdce4ee 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"gettext.h\"\ndiff --git a/pack-check.c b/pack-check.c\nindex 288f5a3479..d78289da3c 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/pack-revindex.c b/pack-revindex.c\nindex fc63aa76a2..de922b47d2 100644\n--- a/pack-revindex.c\n+++ b/pack-revindex.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"pack-revindex.h\"\ndiff --git a/pack-write.c b/pack-write.c\nindex eef625fa5b..d07f03d0ab 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/packfile.c b/packfile.c\nindex ec7312cd20..813584646f 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/parse-options-cb.c b/parse-options-cb.c\nindex d99d688d3c..3fb7ce68ca 100644\n--- a/parse-options-cb.c\n+++ b/parse-options-cb.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"parse-options.h\"\n #include \"branch.h\"\ndiff --git a/path.c b/path.c\nindex adfb3d3eb7..19f7684f38 100644\n--- a/path.c\n+++ b/path.c\n@@ -1,6 +1,9 @@\n /*\n  * Utilities for paths and pathnames\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"environment.h\"\ndiff --git a/pathspec.c b/pathspec.c\nindex 2133b9fe60..fe1f0f41af 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"parse.h\"\ndiff --git a/pretty.c b/pretty.c\nindex 22a81506b7..2c14a88abc 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/progress.c b/progress.c\nindex c83cb60bf1..0d44c18edc 100644\n--- a/progress.c\n+++ b/progress.c\n@@ -9,6 +9,8 @@\n  */\n \n #define GIT_TEST_PROGRESS_ONLY\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"pager.h\"\n #include \"progress.h\"\ndiff --git a/promisor-remote.c b/promisor-remote.c\nindex 2ca7c2ae48..317e1b127f 100644\n--- a/promisor-remote.c\n+++ b/promisor-remote.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/range-diff.c b/range-diff.c\nindex c45b6d849c..5f01605550 100644\n--- a/range-diff.c\n+++ b/range-diff.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/reachable.c b/reachable.c\nindex 1224b30008..46613a6bb6 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/read-cache.c b/read-cache.c\nindex 085b22faf3..48bf24f87c 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -3,6 +3,9 @@\n  *\n  * Copyright (C) Linus Torvalds, 2005\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bulk-checkin.h\"\n #include \"config.h\"\ndiff --git a/rebase-interactive.c b/rebase-interactive.c\nindex c343e16fcd..e93b385523 100644\n--- a/rebase-interactive.c\n+++ b/rebase-interactive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"editor.h\"\ndiff --git a/ref-filter.c b/ref-filter.c\nindex f7fb0c7e0e..8c5e673fc0 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 5f09552c5c..c7070b13b0 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"refs.h\"\ndiff --git a/reflog.c b/reflog.c\nindex 3c80950186..5ca944529b 100644\n--- a/reflog.c\n+++ b/reflog.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"object-store-ll.h\"\ndiff --git a/refs.c b/refs.c\nindex 6e7caefdcf..727ed6c1d6 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2,6 +2,8 @@\n  * The backend-independent part of the reference module.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex b484b5880d..35931bc71e 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../copy.h\"\n #include \"../environment.h\"\ndiff --git a/refs/packed-backend.c b/refs/packed-backend.c\nindex 5ab1b21d10..a0666407cd 100644\n--- a/refs/packed-backend.c\n+++ b/refs/packed-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../config.h\"\n #include \"../dir.h\"\ndiff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\nindex 57df2aba66..6e34eb2188 100644\n--- a/refs/reftable-backend.c\n+++ b/refs/reftable-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../abspath.h\"\n #include \"../chdir-notify.h\"\ndiff --git a/refspec.c b/refspec.c\nindex d60932f4de..c2e3e24351 100644\n--- a/refspec.c\n+++ b/refspec.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 6008d7e87c..1930f83cc7 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"git-curl-compat.h\"\n #include \"config.h\"\ndiff --git a/remote.c b/remote.c\nindex 1064171085..5fab7f0970 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/repository.h b/repository.h\nindex a35cd77c35..29727edec6 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -197,7 +197,9 @@ struct repository {\n \tunsigned different_commondir:1;\n };\n \n+#ifdef USE_THE_REPOSITORY_VARIABLE\n extern struct repository *the_repository;\n+#endif\n \n /*\n  * Define a custom repository layout. Any field can be NULL, which\ndiff --git a/rerere.c b/rerere.c\nindex c7e1f8fd25..597256fa5b 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/reset.c b/reset.c\nindex 937f11c0f4..9550dea03d 100644\n--- a/reset.c\n+++ b/reset.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"cache-tree.h\"\n #include \"gettext.h\"\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex 4e6f0e4676..8c9911affb 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"hash.h\"\ndiff --git a/revision.c b/revision.c\nindex 7ddf0f151a..40da255953 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/run-command.c b/run-command.c\nindex 1b821042b4..1f25263d6d 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"run-command.h\"\n #include \"environment.h\"\ndiff --git a/scalar.c b/scalar.c\nindex 331b91dbdb..a1cb4b45b5 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -2,6 +2,8 @@\n  * The Scalar command-line interface.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"gettext.h\"\ndiff --git a/send-pack.c b/send-pack.c\nindex 37f59d4f66..b42e6986df 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/sequencer.c b/sequencer.c\nindex 823691e379..8083fe20bf 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"advice.h\"\ndiff --git a/serve.c b/serve.c\nindex aa651b73e9..33608ea4d5 100644\n--- a/serve.c\n+++ b/serve.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\ndiff --git a/server-info.c b/server-info.c\nindex 6feaa457c5..97e839c33d 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"environment.h\"\ndiff --git a/setup.c b/setup.c\nindex 03386dc5ce..58b012f063 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"copy.h\"\ndiff --git a/shallow.c b/shallow.c\nindex a0b181ba8a..31a6ca40fe 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"repository.h\"\ndiff --git a/split-index.c b/split-index.c\nindex 058a8f448e..120c8190b1 100644\n--- a/split-index.c\n+++ b/split-index.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/streaming.c b/streaming.c\nindex 10adf625b2..38839511af 100644\n--- a/streaming.c\n+++ b/streaming.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2011, Google Inc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"convert.h\"\n #include \"environment.h\"\ndiff --git a/submodule-config.c b/submodule-config.c\nindex ad43a282da..9b0bb0b9f4 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"environment.h\"\ndiff --git a/submodule.c b/submodule.c\nindex caf3aa5600..ab99a30253 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c\nindex af43ee1cb5..1f18d57007 100644\n--- a/t/helper/test-bitmap.c\n+++ b/t/helper/test-bitmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"git-compat-util.h\"\n #include \"pack-bitmap.h\"\ndiff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c\nindex 1281e66876..f7f9b62002 100644\n--- a/t/helper/test-bloom.c\n+++ b/t/helper/test-bloom.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"bloom.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c\nindex dc89ecfd71..5cdef3ebef 100644\n--- a/t/helper/test-cache-tree.c\n+++ b/t/helper/test-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c\nindex 02b0b46c3f..3f0c7d0ed0 100644\n--- a/t/helper/test-dump-cache-tree.c\n+++ b/t/helper/test-dump-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hash.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c\nindex 4f215fea02..1b7f37a84f 100644\n--- a/t/helper/test-dump-fsmonitor.c\n+++ b/t/helper/test-dump-fsmonitor.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"read-cache-ll.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c\nindex f472691a3c..a6720faf9c 100644\n--- a/t/helper/test-dump-split-index.c\n+++ b/t/helper/test-dump-split-index.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c\nindex 9ff67c3967..4f010d5324 100644\n--- a/t/helper/test-dump-untracked-cache.c\n+++ b/t/helper/test-dump-untracked-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"dir.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-example-decorate.c b/t/helper/test-example-decorate.c\nindex 8f59f6be4c..e8a8a5dc26 100644\n--- a/t/helper/test-example-decorate.c\n+++ b/t/helper/test-example-decorate.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"git-compat-util.h\"\n #include \"object.h\"\ndiff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c\nindex e8bd793e58..14b2b0c12c 100644\n--- a/t/helper/test-find-pack.c\n+++ b/t/helper/test-find-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"object-name.h\"\n #include \"object-store.h\"\ndiff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\nindex 8280984d08..02bfe92e8d 100644\n--- a/t/helper/test-fsmonitor-client.c\n+++ b/t/helper/test-fsmonitor-client.c\n@@ -3,6 +3,8 @@\n  * a `git fsmonitor--daemon` daemon.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"parse-options.h\"\n #include \"fsmonitor-ipc.h\"\ndiff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c\nindex 5f33bb7b8f..40f5df4412 100644\n--- a/t/helper/test-lazy-init-name-hash.c\n+++ b/t/helper/test-lazy-init-name-hash.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"environment.h\"\n #include \"name-hash.h\"\ndiff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c\nindex d0db5ff26f..e0e2048320 100644\n--- a/t/helper/test-match-trees.c\n+++ b/t/helper/test-match-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"match-trees.h\"\ndiff --git a/t/helper/test-oidmap.c b/t/helper/test-oidmap.c\nindex bd30244a54..c03cfa5ecf 100644\n--- a/t/helper/test-oidmap.c\n+++ b/t/helper/test-oidmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"object-name.h\"\ndiff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c\nindex 67a964ef90..f8f9afbb5b 100644\n--- a/t/helper/test-pack-mtimes.c\n+++ b/t/helper/test-pack-mtimes.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"strbuf.h\"\ndiff --git a/t/helper/test-reach.c b/t/helper/test-reach.c\nindex 1ba226f1f9..5dd374379c 100644\n--- a/t/helper/test-reach.c\n+++ b/t/helper/test-reach.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit.h\"\n #include \"commit-reach.h\"\ndiff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c\nindex e803c43ece..d285c656bd 100644\n--- a/t/helper/test-read-cache.c\n+++ b/t/helper/test-read-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"config.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c\nindex 8c7a83f578..d9e980d04c 100644\n--- a/t/helper/test-read-graph.c\n+++ b/t/helper/test-read-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit-graph.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c\nindex 4acae41bb9..83effc2b5f 100644\n--- a/t/helper/test-read-midx.c\n+++ b/t/helper/test-read-midx.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"midx.h\"\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex ad24300170..637b8b294e 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"refs.h\"\ndiff --git a/t/helper/test-repository.c b/t/helper/test-repository.c\nindex 0c7c5aa4dd..c6a074df3d 100644\n--- a/t/helper/test-repository.c\n+++ b/t/helper/test-repository.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit-graph.h\"\n #include \"commit.h\"\ndiff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c\nindex f346951bc2..071f5bd1e2 100644\n--- a/t/helper/test-revision-walking.c\n+++ b/t/helper/test-revision-walking.c\n@@ -8,6 +8,8 @@\n  * published by the Free Software Foundation.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit.h\"\n #include \"diff.h\"\ndiff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c\nindex 737cbe475b..64fff6e9e3 100644\n--- a/t/helper/test-scrap-cache-tree.c\n+++ b/t/helper/test-scrap-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"lockfile.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex 4b809d9dca..cbe93f2f9e 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"config.h\"\n #include \"hash.h\"\ndiff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c\nindex ecd40ded99..6ca069ce63 100644\n--- a/t/helper/test-submodule-nested-repo-config.c\n+++ b/t/helper/test-submodule-nested-repo-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"repository.h\"\n #include \"setup.h\"\ndiff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c\nindex 7197969a08..22e518d229 100644\n--- a/t/helper/test-submodule.c\n+++ b/t/helper/test-submodule.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"test-tool-utils.h\"\n #include \"parse-options.h\"\ndiff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c\nindex 1adac29a57..cd955ec63e 100644\n--- a/t/helper/test-trace2.c\n+++ b/t/helper/test-trace2.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"strvec.h\"\n #include \"run-command.h\"\ndiff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c\nindex 7e3da380a9..b37dd2c5d6 100644\n--- a/t/helper/test-write-cache.c\n+++ b/t/helper/test-write-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"lockfile.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/tag.c b/tag.c\nindex 52bbe50819..d24170e340 100644\n--- a/tag.c\n+++ b/tag.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"tag.h\"\ndiff --git a/tmp-objdir.c b/tmp-objdir.c\nindex 3509258be5..a8e4553f27 100644\n--- a/tmp-objdir.c\n+++ b/tmp-objdir.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tmp-objdir.h\"\n #include \"abspath.h\"\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 9820947ab2..09b3560ffd 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"transport.h\"\n #include \"quote.h\"\ndiff --git a/transport.c b/transport.c\nindex 83ddea8fbc..b9c8827ed9 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/tree-walk.c b/tree-walk.c\nindex 535a3a2539..a033397965 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tree-walk.h\"\n #include \"dir.h\"\ndiff --git a/tree.c b/tree.c\nindex 7973d3f9a8..ad86ad1ba9 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"tree.h\"\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 304ea2ed86..7dc884fafd 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"strvec.h\"\ndiff --git a/upload-pack.c b/upload-pack.c\nindex b726f7a57d..0052c6a4dc 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/walker.c b/walker.c\nindex 946d86b04e..0fafdc97cf 100644\n--- a/walker.c\n+++ b/walker.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/worktree.c b/worktree.c\nindex 70844d023a..f3c4c8ec54 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"environment.h\"\ndiff --git a/wt-status.c b/wt-status.c\nindex 5051f5e599..8815df419e 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"wt-status.h\"\ndiff --git a/xdiff-interface.c b/xdiff-interface.c\nindex 16ed8ac492..d5dc88661e 100644\n--- a/xdiff-interface.c\n+++ b/xdiff-interface.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"config.h\"\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496902","messageId":"7e718c967a6c419cf1328d385b039654a58cea16.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 10/21] refs: avoid include cycle with \"repository.h\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:19Z","receivedAt":"2024-06-11T11:58:22Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"There is an include cycle between \"refs.h\" and \"repository.h\" via\n\"commit.h\", \"object.h\" and \"hash.h\". This has the effect that several\ndefinitions of structs and enums will not be visible once we merge\n\"hash-ll.h\" back into \"hash.h\" in the next commit.\n\nThe only reason that \"repository.h\" includes \"refs.h\" is the definition\nof `enum ref_storage_format`. Move it into \"repository.h\" and have\n\"refs.h\" include \"repository.h\" instead to fix the cycle.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n refs.h       | 8 +-------\n repository.h | 7 ++++++-\n 2 files changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/refs.h b/refs.h\nindex 76d25df4de..a9716e5d25 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -2,21 +2,15 @@\n #define REFS_H\n \n #include \"commit.h\"\n+#include \"repository.h\"\n \n struct object_id;\n struct ref_store;\n-struct repository;\n struct strbuf;\n struct string_list;\n struct string_list_item;\n struct worktree;\n \n-enum ref_storage_format {\n-\tREF_STORAGE_FORMAT_UNKNOWN,\n-\tREF_STORAGE_FORMAT_FILES,\n-\tREF_STORAGE_FORMAT_REFTABLE,\n-};\n-\n enum ref_storage_format ref_storage_format_by_name(const char *name);\n const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format);\n \ndiff --git a/repository.h b/repository.h\nindex 29727edec6..6ce6826c26 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -1,7 +1,6 @@\n #ifndef REPOSITORY_H\n #define REPOSITORY_H\n \n-#include \"refs.h\"\n #include \"strmap.h\"\n \n struct config_set;\n@@ -27,6 +26,12 @@ enum fetch_negotiation_setting {\n \tFETCH_NEGOTIATION_NOOP,\n };\n \n+enum ref_storage_format {\n+\tREF_STORAGE_FORMAT_UNKNOWN,\n+\tREF_STORAGE_FORMAT_FILES,\n+\tREF_STORAGE_FORMAT_REFTABLE,\n+};\n+\n struct repo_settings {\n \tint initialized;\n \n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496903","messageId":"fb7544181a5ddb0c373f03ad399dbfd9597185a3.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 11/21] hash-ll: merge with \"hash.h\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:23Z","receivedAt":"2024-06-11T11:58:28Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"hash-ll.h\" header was introduced via d1cbe1e6d8 (hash-ll.h: split\nout of hash.h to remove dependency on repository.h, 2023-04-22) to make\nexplicit the split between hash-related functions that rely on the\nglobal `the_repository`, and those that don't. This split is no longer\nnecessary now that we we have removed the reliance on `the_repository`.\n\nMerge \"hash-ll.h\" back into \"hash.h\". This causes some code units to not\ninclude \"repository.h\" anymore, which requires us to add some forward\ndeclarations.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n apply.h                    |   2 +-\n bloom.c                    |   1 +\n checkout.h                 |   2 +-\n chunk-format.h             |   2 +-\n commit-graph.h             |   2 +\n compat/sha1-chunked.c      |   2 +-\n convert.h                  |   2 +-\n csum-file.h                |   2 +-\n diff.h                     |   2 +-\n diffcore.h                 |   2 +-\n dir.h                      |   2 +-\n hash-ll.h                  | 364 -------------------------------------\n hash.h                     | 362 +++++++++++++++++++++++++++++++++++-\n hex.h                      |   2 +-\n loose.h                    |   2 +\n merge-ort.h                |   2 +-\n object-file-convert.c      |   2 +-\n object.h                   |   2 +-\n oidmap.h                   |   2 +-\n oidtree.h                  |   2 +-\n packfile.h                 |   2 +\n protocol-caps.c            |   2 +-\n read-cache-ll.h            |   2 +-\n refs/ref-cache.h           |   2 +-\n reftable/dump.c            |   2 +-\n reftable/reftable-record.h |   2 +-\n reftable/system.h          |   2 +-\n remote.h                   |   2 +-\n reset.h                    |   2 +-\n resolve-undo.h             |   2 +-\n serve.c                    |   2 +-\n split-index.h              |   2 +-\n t/helper/test-hash-speed.c |   2 +-\n t/helper/test-sha1.c       |   2 +-\n t/helper/test-sha256.c     |   2 +-\n tree-diff.c                |   1 +\n tree-walk.h                |   2 +-\n xdiff-interface.h          |   2 +-\n 38 files changed, 399 insertions(+), 397 deletions(-)\n delete mode 100644 hash-ll.h\n\ndiff --git a/apply.h b/apply.h\nindex 7cd38b1443..b9f18ce87d 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -1,7 +1,7 @@\n #ifndef APPLY_H\n #define APPLY_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"lockfile.h\"\n #include \"string-list.h\"\n #include \"strmap.h\"\ndiff --git a/bloom.c b/bloom.c\nindex e529f7605c..bbf146fc30 100644\n--- a/bloom.c\n+++ b/bloom.c\n@@ -6,6 +6,7 @@\n #include \"commit-graph.h\"\n #include \"commit.h\"\n #include \"commit-slab.h\"\n+#include \"repository.h\"\n \n define_commit_slab(bloom_filter_slab, struct bloom_filter);\n \ndiff --git a/checkout.h b/checkout.h\nindex ba15a13fb3..55920e7aeb 100644\n--- a/checkout.h\n+++ b/checkout.h\n@@ -1,7 +1,7 @@\n #ifndef CHECKOUT_H\n #define CHECKOUT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n /*\n  * Check if the branch name uniquely matches a branch name on a remote\ndiff --git a/chunk-format.h b/chunk-format.h\nindex 14b76180ef..212a0a6af1 100644\n--- a/chunk-format.h\n+++ b/chunk-format.h\n@@ -1,7 +1,7 @@\n #ifndef CHUNK_FORMAT_H\n #define CHUNK_FORMAT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct hashfile;\n struct chunkfile;\ndiff --git a/commit-graph.h b/commit-graph.h\nindex e519cb81cb..6781940195 100644\n--- a/commit-graph.h\n+++ b/commit-graph.h\n@@ -122,6 +122,8 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,\n struct commit_graph *read_commit_graph_one(struct repository *r,\n \t\t\t\t\t   struct object_directory *odb);\n \n+struct repo_settings;\n+\n /*\n  * Callers should initialize the repo_settings with prepare_repo_settings()\n  * prior to calling parse_commit_graph().\ndiff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c\nindex a4a6f930d7..0446f9983f 100644\n--- a/compat/sha1-chunked.c\n+++ b/compat/sha1-chunked.c\n@@ -1,5 +1,5 @@\n #include \"git-compat-util.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)\n {\ndiff --git a/convert.h b/convert.h\nindex d925589444..0a6e4086b8 100644\n--- a/convert.h\n+++ b/convert.h\n@@ -4,7 +4,7 @@\n #ifndef CONVERT_H\n #define CONVERT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"string-list.h\"\n \n struct index_state;\ndiff --git a/csum-file.h b/csum-file.h\nindex bc5bec27ac..566e05cbd2 100644\n--- a/csum-file.h\n+++ b/csum-file.h\n@@ -1,7 +1,7 @@\n #ifndef CSUM_FILE_H\n #define CSUM_FILE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"write-or-die.h\"\n \n struct progress;\ndiff --git a/diff.h b/diff.h\nindex 66bd8aeb29..9901c8ca8c 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -4,7 +4,7 @@\n #ifndef DIFF_H\n #define DIFF_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"pathspec.h\"\n #include \"strbuf.h\"\n \ndiff --git a/diffcore.h b/diffcore.h\nindex 5ffe4ec788..1701ed50b9 100644\n--- a/diffcore.h\n+++ b/diffcore.h\n@@ -4,7 +4,7 @@\n #ifndef DIFFCORE_H\n #define DIFFCORE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct diff_options;\n struct mem_pool;\ndiff --git a/dir.h b/dir.h\nindex b9e8e96128..c9b0123e05 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -1,7 +1,7 @@\n #ifndef DIR_H\n #define DIR_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"pathspec.h\"\n #include \"statinfo.h\"\ndiff --git a/hash-ll.h b/hash-ll.h\ndeleted file mode 100644\nindex 3161c778b9..0000000000\n--- a/hash-ll.h\n+++ /dev/null\n@@ -1,364 +0,0 @@\n-#ifndef HASH_LL_H\n-#define HASH_LL_H\n-\n-#if defined(SHA1_APPLE)\n-#include <CommonCrypto/CommonDigest.h>\n-#elif defined(SHA1_OPENSSL)\n-#  include <openssl/sha.h>\n-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n-#    define SHA1_NEEDS_CLONE_HELPER\n-#    include \"sha1/openssl.h\"\n-#  endif\n-#elif defined(SHA1_DC)\n-#include \"sha1dc_git.h\"\n-#else /* SHA1_BLK */\n-#include \"block-sha1/sha1.h\"\n-#endif\n-\n-#if defined(SHA256_NETTLE)\n-#include \"sha256/nettle.h\"\n-#elif defined(SHA256_GCRYPT)\n-#define SHA256_NEEDS_CLONE_HELPER\n-#include \"sha256/gcrypt.h\"\n-#elif defined(SHA256_OPENSSL)\n-#  include <openssl/sha.h>\n-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n-#    define SHA256_NEEDS_CLONE_HELPER\n-#    include \"sha256/openssl.h\"\n-#  endif\n-#else\n-#include \"sha256/block/sha256.h\"\n-#endif\n-\n-#ifndef platform_SHA_CTX\n-/*\n- * platform's underlying implementation of SHA-1; could be OpenSSL,\n- * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant\n- * SHA-1 header may have already defined platform_SHA_CTX for our\n- * own implementations like block-sha1, so we list\n- * the default for OpenSSL compatible SHA-1 implementations here.\n- */\n-#define platform_SHA_CTX\tSHA_CTX\n-#define platform_SHA1_Init\tSHA1_Init\n-#define platform_SHA1_Update\tSHA1_Update\n-#define platform_SHA1_Final    \tSHA1_Final\n-#endif\n-\n-#define git_SHA_CTX\t\tplatform_SHA_CTX\n-#define git_SHA1_Init\t\tplatform_SHA1_Init\n-#define git_SHA1_Update\t\tplatform_SHA1_Update\n-#define git_SHA1_Final\t\tplatform_SHA1_Final\n-\n-#ifdef platform_SHA1_Clone\n-#define git_SHA1_Clone\tplatform_SHA1_Clone\n-#endif\n-\n-#ifndef platform_SHA256_CTX\n-#define platform_SHA256_CTX\tSHA256_CTX\n-#define platform_SHA256_Init\tSHA256_Init\n-#define platform_SHA256_Update\tSHA256_Update\n-#define platform_SHA256_Final\tSHA256_Final\n-#endif\n-\n-#define git_SHA256_CTX\t\tplatform_SHA256_CTX\n-#define git_SHA256_Init\t\tplatform_SHA256_Init\n-#define git_SHA256_Update\tplatform_SHA256_Update\n-#define git_SHA256_Final\tplatform_SHA256_Final\n-\n-#ifdef platform_SHA256_Clone\n-#define git_SHA256_Clone\tplatform_SHA256_Clone\n-#endif\n-\n-#ifdef SHA1_MAX_BLOCK_SIZE\n-#include \"compat/sha1-chunked.h\"\n-#undef git_SHA1_Update\n-#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n-#endif\n-\n-#ifndef SHA1_NEEDS_CLONE_HELPER\n-static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)\n-{\n-\tmemcpy(dst, src, sizeof(*dst));\n-}\n-#endif\n-\n-#ifndef SHA256_NEEDS_CLONE_HELPER\n-static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)\n-{\n-\tmemcpy(dst, src, sizeof(*dst));\n-}\n-#endif\n-\n-/*\n- * Note that these constants are suitable for indexing the hash_algos array and\n- * comparing against each other, but are otherwise arbitrary, so they should not\n- * be exposed to the user or serialized to disk.  To know whether a\n- * git_hash_algo struct points to some usable hash function, test the format_id\n- * field for being non-zero.  Use the name field for user-visible situations and\n- * the format_id field for fixed-length fields on disk.\n- */\n-/* An unknown hash function. */\n-#define GIT_HASH_UNKNOWN 0\n-/* SHA-1 */\n-#define GIT_HASH_SHA1 1\n-/* SHA-256  */\n-#define GIT_HASH_SHA256 2\n-/* Number of algorithms supported (including unknown). */\n-#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)\n-\n-/* \"sha1\", big-endian */\n-#define GIT_SHA1_FORMAT_ID 0x73686131\n-\n-/* The length in bytes and in hex digits of an object name (SHA-1 value). */\n-#define GIT_SHA1_RAWSZ 20\n-#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)\n-/* The block size of SHA-1. */\n-#define GIT_SHA1_BLKSZ 64\n-\n-/* \"s256\", big-endian */\n-#define GIT_SHA256_FORMAT_ID 0x73323536\n-\n-/* The length in bytes and in hex digits of an object name (SHA-256 value). */\n-#define GIT_SHA256_RAWSZ 32\n-#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)\n-/* The block size of SHA-256. */\n-#define GIT_SHA256_BLKSZ 64\n-\n-/* The length in byte and in hex digits of the largest possible hash value. */\n-#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ\n-#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ\n-/* The largest possible block size for any supported hash. */\n-#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ\n-\n-struct object_id {\n-\tunsigned char hash[GIT_MAX_RAWSZ];\n-\tint algo;\t/* XXX requires 4-byte alignment */\n-};\n-\n-#define GET_OID_QUIETLY           01\n-#define GET_OID_COMMIT            02\n-#define GET_OID_COMMITTISH        04\n-#define GET_OID_TREE             010\n-#define GET_OID_TREEISH          020\n-#define GET_OID_BLOB             040\n-#define GET_OID_FOLLOW_SYMLINKS 0100\n-#define GET_OID_RECORD_PATH     0200\n-#define GET_OID_ONLY_TO_DIE    04000\n-#define GET_OID_REQUIRE_PATH  010000\n-#define GET_OID_HASH_ANY      020000\n-\n-#define GET_OID_DISAMBIGUATORS \\\n-\t(GET_OID_COMMIT | GET_OID_COMMITTISH | \\\n-\tGET_OID_TREE | GET_OID_TREEISH | \\\n-\tGET_OID_BLOB)\n-\n-enum get_oid_result {\n-\tFOUND = 0,\n-\tMISSING_OBJECT = -1, /* The requested object is missing */\n-\tSHORT_NAME_AMBIGUOUS = -2,\n-\t/* The following only apply when symlinks are followed */\n-\tDANGLING_SYMLINK = -4, /*\n-\t\t\t\t* The initial symlink is there, but\n-\t\t\t\t* (transitively) points to a missing\n-\t\t\t\t* in-tree file\n-\t\t\t\t*/\n-\tSYMLINK_LOOP = -5,\n-\tNOT_DIR = -6, /*\n-\t\t       * Somewhere along the symlink chain, a path is\n-\t\t       * requested which contains a file as a\n-\t\t       * non-final element.\n-\t\t       */\n-};\n-\n-/* A suitably aligned type for stack allocations of hash contexts. */\n-union git_hash_ctx {\n-\tgit_SHA_CTX sha1;\n-\tgit_SHA256_CTX sha256;\n-};\n-typedef union git_hash_ctx git_hash_ctx;\n-\n-typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);\n-typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);\n-typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);\n-typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);\n-typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);\n-\n-struct git_hash_algo {\n-\t/*\n-\t * The name of the algorithm, as appears in the config file and in\n-\t * messages.\n-\t */\n-\tconst char *name;\n-\n-\t/* A four-byte version identifier, used in pack indices. */\n-\tuint32_t format_id;\n-\n-\t/* The length of the hash in binary. */\n-\tsize_t rawsz;\n-\n-\t/* The length of the hash in hex characters. */\n-\tsize_t hexsz;\n-\n-\t/* The block size of the hash. */\n-\tsize_t blksz;\n-\n-\t/* The hash initialization function. */\n-\tgit_hash_init_fn init_fn;\n-\n-\t/* The hash context cloning function. */\n-\tgit_hash_clone_fn clone_fn;\n-\n-\t/* The hash update function. */\n-\tgit_hash_update_fn update_fn;\n-\n-\t/* The hash finalization function. */\n-\tgit_hash_final_fn final_fn;\n-\n-\t/* The hash finalization function for object IDs. */\n-\tgit_hash_final_oid_fn final_oid_fn;\n-\n-\t/* The OID of the empty tree. */\n-\tconst struct object_id *empty_tree;\n-\n-\t/* The OID of the empty blob. */\n-\tconst struct object_id *empty_blob;\n-\n-\t/* The all-zeros OID. */\n-\tconst struct object_id *null_oid;\n-};\n-extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];\n-\n-/*\n- * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if\n- * the name doesn't match a known algorithm.\n- */\n-int hash_algo_by_name(const char *name);\n-/* Identical, except based on the format ID. */\n-int hash_algo_by_id(uint32_t format_id);\n-/* Identical, except based on the length. */\n-int hash_algo_by_length(int len);\n-/* Identical, except for a pointer to struct git_hash_algo. */\n-static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n-{\n-\treturn p - hash_algos;\n-}\n-\n-const struct object_id *null_oid(void);\n-\n-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n-{\n-\t/*\n-\t * Teach the compiler that there are only two possibilities of hash size\n-\t * here, so that it can optimize for this case as much as possible.\n-\t */\n-\tif (algop->rawsz == GIT_MAX_RAWSZ)\n-\t\treturn memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n-\treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n-}\n-\n-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n-{\n-\t/*\n-\t * We write this here instead of deferring to hashcmp so that the\n-\t * compiler can properly inline it and avoid calling memcmp.\n-\t */\n-\tif (algop->rawsz == GIT_MAX_RAWSZ)\n-\t\treturn !memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n-\treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n-}\n-\n-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n-\t\t\t   const struct git_hash_algo *algop)\n-{\n-\tmemcpy(sha_dst, sha_src, algop->rawsz);\n-}\n-\n-static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n-{\n-\tmemset(hash, 0, algop->rawsz);\n-}\n-\n-static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n-}\n-\n-static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n-}\n-\n-static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n-{\n-\tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\n-\tdst->algo = src->algo;\n-}\n-\n-static inline void oidread(struct object_id *oid, const unsigned char *hash,\n-\t\t\t   const struct git_hash_algo *algop)\n-{\n-\tmemcpy(oid->hash, hash, algop->rawsz);\n-\tif (algop->rawsz < GIT_MAX_RAWSZ)\n-\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline void oidclr(struct object_id *oid,\n-\t\t\t  const struct git_hash_algo *algop)\n-{\n-\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline struct object_id *oiddup(const struct object_id *src)\n-{\n-\tstruct object_id *dst = xmalloc(sizeof(struct object_id));\n-\toidcpy(dst, src);\n-\treturn dst;\n-}\n-\n-static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)\n-{\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-/*\n- * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code\n- * for use in hash tables. Cryptographic hashes are supposed to have\n- * uniform distribution, so in contrast to `memhash()`, this just copies\n- * the first `sizeof(int)` bytes without shuffling any bits. Note that\n- * the results will be different on big-endian and little-endian\n- * platforms, so they should not be stored or transferred over the net.\n- */\n-static inline unsigned int oidhash(const struct object_id *oid)\n-{\n-\t/*\n-\t * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on\n-\t * platforms that don't support unaligned reads.\n-\t */\n-\tunsigned int hash;\n-\tmemcpy(&hash, oid->hash, sizeof(hash));\n-\treturn hash;\n-}\n-\n-static inline int is_null_oid(const struct object_id *oid)\n-{\n-\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n-\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n-}\n-\n-const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n-\n-static inline int is_empty_blob_oid(const struct object_id *oid,\n-\t\t\t\t    const struct git_hash_algo *algop)\n-{\n-\treturn oideq(oid, algop->empty_blob);\n-}\n-\n-static inline int is_empty_tree_oid(const struct object_id *oid,\n-\t\t\t\t    const struct git_hash_algo *algop)\n-{\n-\treturn oideq(oid, algop->empty_tree);\n-}\n-\n-#endif\ndiff --git a/hash.h b/hash.h\nindex cb85d26a2f..72ffbc862e 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -1,11 +1,369 @@\n #ifndef HASH_H\n #define HASH_H\n \n-#include \"hash-ll.h\"\n-#include \"repository.h\"\n+#if defined(SHA1_APPLE)\n+#include <CommonCrypto/CommonDigest.h>\n+#elif defined(SHA1_OPENSSL)\n+#  include <openssl/sha.h>\n+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n+#    define SHA1_NEEDS_CLONE_HELPER\n+#    include \"sha1/openssl.h\"\n+#  endif\n+#elif defined(SHA1_DC)\n+#include \"sha1dc_git.h\"\n+#else /* SHA1_BLK */\n+#include \"block-sha1/sha1.h\"\n+#endif\n+\n+#if defined(SHA256_NETTLE)\n+#include \"sha256/nettle.h\"\n+#elif defined(SHA256_GCRYPT)\n+#define SHA256_NEEDS_CLONE_HELPER\n+#include \"sha256/gcrypt.h\"\n+#elif defined(SHA256_OPENSSL)\n+#  include <openssl/sha.h>\n+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n+#    define SHA256_NEEDS_CLONE_HELPER\n+#    include \"sha256/openssl.h\"\n+#  endif\n+#else\n+#include \"sha256/block/sha256.h\"\n+#endif\n+\n+#ifndef platform_SHA_CTX\n+/*\n+ * platform's underlying implementation of SHA-1; could be OpenSSL,\n+ * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant\n+ * SHA-1 header may have already defined platform_SHA_CTX for our\n+ * own implementations like block-sha1, so we list\n+ * the default for OpenSSL compatible SHA-1 implementations here.\n+ */\n+#define platform_SHA_CTX\tSHA_CTX\n+#define platform_SHA1_Init\tSHA1_Init\n+#define platform_SHA1_Update\tSHA1_Update\n+#define platform_SHA1_Final    \tSHA1_Final\n+#endif\n+\n+#define git_SHA_CTX\t\tplatform_SHA_CTX\n+#define git_SHA1_Init\t\tplatform_SHA1_Init\n+#define git_SHA1_Update\t\tplatform_SHA1_Update\n+#define git_SHA1_Final\t\tplatform_SHA1_Final\n+\n+#ifdef platform_SHA1_Clone\n+#define git_SHA1_Clone\tplatform_SHA1_Clone\n+#endif\n+\n+#ifndef platform_SHA256_CTX\n+#define platform_SHA256_CTX\tSHA256_CTX\n+#define platform_SHA256_Init\tSHA256_Init\n+#define platform_SHA256_Update\tSHA256_Update\n+#define platform_SHA256_Final\tSHA256_Final\n+#endif\n+\n+#define git_SHA256_CTX\t\tplatform_SHA256_CTX\n+#define git_SHA256_Init\t\tplatform_SHA256_Init\n+#define git_SHA256_Update\tplatform_SHA256_Update\n+#define git_SHA256_Final\tplatform_SHA256_Final\n+\n+#ifdef platform_SHA256_Clone\n+#define git_SHA256_Clone\tplatform_SHA256_Clone\n+#endif\n+\n+#ifdef SHA1_MAX_BLOCK_SIZE\n+#include \"compat/sha1-chunked.h\"\n+#undef git_SHA1_Update\n+#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n+#endif\n+\n+#ifndef SHA1_NEEDS_CLONE_HELPER\n+static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)\n+{\n+\tmemcpy(dst, src, sizeof(*dst));\n+}\n+#endif\n+\n+#ifndef SHA256_NEEDS_CLONE_HELPER\n+static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)\n+{\n+\tmemcpy(dst, src, sizeof(*dst));\n+}\n+#endif\n+\n+/*\n+ * Note that these constants are suitable for indexing the hash_algos array and\n+ * comparing against each other, but are otherwise arbitrary, so they should not\n+ * be exposed to the user or serialized to disk.  To know whether a\n+ * git_hash_algo struct points to some usable hash function, test the format_id\n+ * field for being non-zero.  Use the name field for user-visible situations and\n+ * the format_id field for fixed-length fields on disk.\n+ */\n+/* An unknown hash function. */\n+#define GIT_HASH_UNKNOWN 0\n+/* SHA-1 */\n+#define GIT_HASH_SHA1 1\n+/* SHA-256  */\n+#define GIT_HASH_SHA256 2\n+/* Number of algorithms supported (including unknown). */\n+#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)\n+\n+/* \"sha1\", big-endian */\n+#define GIT_SHA1_FORMAT_ID 0x73686131\n+\n+/* The length in bytes and in hex digits of an object name (SHA-1 value). */\n+#define GIT_SHA1_RAWSZ 20\n+#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)\n+/* The block size of SHA-1. */\n+#define GIT_SHA1_BLKSZ 64\n+\n+/* \"s256\", big-endian */\n+#define GIT_SHA256_FORMAT_ID 0x73323536\n+\n+/* The length in bytes and in hex digits of an object name (SHA-256 value). */\n+#define GIT_SHA256_RAWSZ 32\n+#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)\n+/* The block size of SHA-256. */\n+#define GIT_SHA256_BLKSZ 64\n+\n+/* The length in byte and in hex digits of the largest possible hash value. */\n+#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ\n+#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ\n+/* The largest possible block size for any supported hash. */\n+#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ\n+\n+struct object_id {\n+\tunsigned char hash[GIT_MAX_RAWSZ];\n+\tint algo;\t/* XXX requires 4-byte alignment */\n+};\n+\n+#define GET_OID_QUIETLY           01\n+#define GET_OID_COMMIT            02\n+#define GET_OID_COMMITTISH        04\n+#define GET_OID_TREE             010\n+#define GET_OID_TREEISH          020\n+#define GET_OID_BLOB             040\n+#define GET_OID_FOLLOW_SYMLINKS 0100\n+#define GET_OID_RECORD_PATH     0200\n+#define GET_OID_ONLY_TO_DIE    04000\n+#define GET_OID_REQUIRE_PATH  010000\n+#define GET_OID_HASH_ANY      020000\n+\n+#define GET_OID_DISAMBIGUATORS \\\n+\t(GET_OID_COMMIT | GET_OID_COMMITTISH | \\\n+\tGET_OID_TREE | GET_OID_TREEISH | \\\n+\tGET_OID_BLOB)\n+\n+enum get_oid_result {\n+\tFOUND = 0,\n+\tMISSING_OBJECT = -1, /* The requested object is missing */\n+\tSHORT_NAME_AMBIGUOUS = -2,\n+\t/* The following only apply when symlinks are followed */\n+\tDANGLING_SYMLINK = -4, /*\n+\t\t\t\t* The initial symlink is there, but\n+\t\t\t\t* (transitively) points to a missing\n+\t\t\t\t* in-tree file\n+\t\t\t\t*/\n+\tSYMLINK_LOOP = -5,\n+\tNOT_DIR = -6, /*\n+\t\t       * Somewhere along the symlink chain, a path is\n+\t\t       * requested which contains a file as a\n+\t\t       * non-final element.\n+\t\t       */\n+};\n \n #ifdef USE_THE_REPOSITORY_VARIABLE\n+# include \"repository.h\"\n # define the_hash_algo the_repository->hash_algo\n #endif\n \n+/* A suitably aligned type for stack allocations of hash contexts. */\n+union git_hash_ctx {\n+\tgit_SHA_CTX sha1;\n+\tgit_SHA256_CTX sha256;\n+};\n+typedef union git_hash_ctx git_hash_ctx;\n+\n+typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);\n+typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);\n+typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);\n+typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);\n+typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);\n+\n+struct git_hash_algo {\n+\t/*\n+\t * The name of the algorithm, as appears in the config file and in\n+\t * messages.\n+\t */\n+\tconst char *name;\n+\n+\t/* A four-byte version identifier, used in pack indices. */\n+\tuint32_t format_id;\n+\n+\t/* The length of the hash in binary. */\n+\tsize_t rawsz;\n+\n+\t/* The length of the hash in hex characters. */\n+\tsize_t hexsz;\n+\n+\t/* The block size of the hash. */\n+\tsize_t blksz;\n+\n+\t/* The hash initialization function. */\n+\tgit_hash_init_fn init_fn;\n+\n+\t/* The hash context cloning function. */\n+\tgit_hash_clone_fn clone_fn;\n+\n+\t/* The hash update function. */\n+\tgit_hash_update_fn update_fn;\n+\n+\t/* The hash finalization function. */\n+\tgit_hash_final_fn final_fn;\n+\n+\t/* The hash finalization function for object IDs. */\n+\tgit_hash_final_oid_fn final_oid_fn;\n+\n+\t/* The OID of the empty tree. */\n+\tconst struct object_id *empty_tree;\n+\n+\t/* The OID of the empty blob. */\n+\tconst struct object_id *empty_blob;\n+\n+\t/* The all-zeros OID. */\n+\tconst struct object_id *null_oid;\n+};\n+extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];\n+\n+/*\n+ * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if\n+ * the name doesn't match a known algorithm.\n+ */\n+int hash_algo_by_name(const char *name);\n+/* Identical, except based on the format ID. */\n+int hash_algo_by_id(uint32_t format_id);\n+/* Identical, except based on the length. */\n+int hash_algo_by_length(int len);\n+/* Identical, except for a pointer to struct git_hash_algo. */\n+static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n+{\n+\treturn p - hash_algos;\n+}\n+\n+const struct object_id *null_oid(void);\n+\n+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+{\n+\t/*\n+\t * Teach the compiler that there are only two possibilities of hash size\n+\t * here, so that it can optimize for this case as much as possible.\n+\t */\n+\tif (algop->rawsz == GIT_MAX_RAWSZ)\n+\t\treturn memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n+\treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n+}\n+\n+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+{\n+\t/*\n+\t * We write this here instead of deferring to hashcmp so that the\n+\t * compiler can properly inline it and avoid calling memcmp.\n+\t */\n+\tif (algop->rawsz == GIT_MAX_RAWSZ)\n+\t\treturn !memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n+\treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n+}\n+\n+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(sha_dst, sha_src, algop->rawsz);\n+}\n+\n+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n+{\n+\tmemset(hash, 0, algop->rawsz);\n+}\n+\n+static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n+{\n+\tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\n+\tdst->algo = src->algo;\n+}\n+\n+static inline void oidread(struct object_id *oid, const unsigned char *hash,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(oid->hash, hash, algop->rawsz);\n+\tif (algop->rawsz < GIT_MAX_RAWSZ)\n+\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline void oidclr(struct object_id *oid,\n+\t\t\t  const struct git_hash_algo *algop)\n+{\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline struct object_id *oiddup(const struct object_id *src)\n+{\n+\tstruct object_id *dst = xmalloc(sizeof(struct object_id));\n+\toidcpy(dst, src);\n+\treturn dst;\n+}\n+\n+static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)\n+{\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+/*\n+ * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code\n+ * for use in hash tables. Cryptographic hashes are supposed to have\n+ * uniform distribution, so in contrast to `memhash()`, this just copies\n+ * the first `sizeof(int)` bytes without shuffling any bits. Note that\n+ * the results will be different on big-endian and little-endian\n+ * platforms, so they should not be stored or transferred over the net.\n+ */\n+static inline unsigned int oidhash(const struct object_id *oid)\n+{\n+\t/*\n+\t * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on\n+\t * platforms that don't support unaligned reads.\n+\t */\n+\tunsigned int hash;\n+\tmemcpy(&hash, oid->hash, sizeof(hash));\n+\treturn hash;\n+}\n+\n+static inline int is_null_oid(const struct object_id *oid)\n+{\n+\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n+\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n+}\n+\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n+\n+static inline int is_empty_blob_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_blob);\n+}\n+\n+static inline int is_empty_tree_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_tree);\n+}\n+\n #endif\ndiff --git a/hex.h b/hex.h\nindex e0b83f776f..9809667f33 100644\n--- a/hex.h\n+++ b/hex.h\n@@ -1,7 +1,7 @@\n #ifndef HEX_H\n #define HEX_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hex-ll.h\"\n \n /*\ndiff --git a/loose.h b/loose.h\nindex 2c2957072c..28512306e5 100644\n--- a/loose.h\n+++ b/loose.h\n@@ -3,6 +3,8 @@\n \n #include \"khash.h\"\n \n+struct repository;\n+\n struct loose_object_map {\n \tkh_oid_map_t *to_compat;\n \tkh_oid_map_t *to_storage;\ndiff --git a/merge-ort.h b/merge-ort.h\nindex ce56ec1a78..a994c9a5fc 100644\n--- a/merge-ort.h\n+++ b/merge-ort.h\n@@ -2,7 +2,7 @@\n #define MERGE_ORT_H\n \n #include \"merge-recursive.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct commit;\n struct tree;\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex 958f61f094..3887d6d57b 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -5,7 +5,7 @@\n #include \"strbuf.h\"\n #include \"hex.h\"\n #include \"repository.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hash.h\"\n #include \"object.h\"\n #include \"loose.h\"\ndiff --git a/object.h b/object.h\nindex 73b4ec3904..9fa42d51d9 100644\n--- a/object.h\n+++ b/object.h\n@@ -1,7 +1,7 @@\n #ifndef OBJECT_H\n #define OBJECT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct buffer_slab;\n struct repository;\ndiff --git a/oidmap.h b/oidmap.h\nindex 05c673eb7c..fad412827a 100644\n--- a/oidmap.h\n+++ b/oidmap.h\n@@ -1,7 +1,7 @@\n #ifndef OIDMAP_H\n #define OIDMAP_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n \n /*\ndiff --git a/oidtree.h b/oidtree.h\nindex 55c83513fd..77898f510a 100644\n--- a/oidtree.h\n+++ b/oidtree.h\n@@ -2,7 +2,7 @@\n #define OIDTREE_H\n \n #include \"cbtree.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"mem-pool.h\"\n \n struct oidtree {\ndiff --git a/packfile.h b/packfile.h\nindex 28c8fd3e39..eb18ec15db 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -101,6 +101,8 @@ int close_pack_fd(struct packed_git *p);\n \n uint32_t get_pack_fanout(struct packed_git *p, uint32_t value);\n \n+struct raw_object_store;\n+\n unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);\n void close_pack_windows(struct packed_git *);\n void close_pack(struct packed_git *);\ndiff --git a/protocol-caps.c b/protocol-caps.c\nindex 75f4cbb0a7..fe8d1d5c63 100644\n--- a/protocol-caps.c\n+++ b/protocol-caps.c\n@@ -3,7 +3,7 @@\n #include \"gettext.h\"\n #include \"hex.h\"\n #include \"pkt-line.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hex.h\"\n #include \"object.h\"\n #include \"object-store-ll.h\"\ndiff --git a/read-cache-ll.h b/read-cache-ll.h\nindex 09414afd04..e0e39607ef 100644\n--- a/read-cache-ll.h\n+++ b/read-cache-ll.h\n@@ -1,7 +1,7 @@\n #ifndef READ_CACHE_LL_H\n #define READ_CACHE_LL_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"statinfo.h\"\n \ndiff --git a/refs/ref-cache.h b/refs/ref-cache.h\nindex 95c76e27c8..31ebe24f6c 100644\n--- a/refs/ref-cache.h\n+++ b/refs/ref-cache.h\n@@ -1,7 +1,7 @@\n #ifndef REFS_REF_CACHE_H\n #define REFS_REF_CACHE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct ref_dir;\n struct ref_store;\ndiff --git a/reftable/dump.c b/reftable/dump.c\nindex 41abbb8ecf..dd65d9e8bb 100644\n--- a/reftable/dump.c\n+++ b/reftable/dump.c\n@@ -7,7 +7,7 @@ license that can be found in the LICENSE file or at\n */\n \n #include \"git-compat-util.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n #include \"reftable-blocksource.h\"\n #include \"reftable-error.h\"\ndiff --git a/reftable/reftable-record.h b/reftable/reftable-record.h\nindex 2a2943cd13..ff486eb1f7 100644\n--- a/reftable/reftable-record.h\n+++ b/reftable/reftable-record.h\n@@ -9,7 +9,7 @@ license that can be found in the LICENSE file or at\n #ifndef REFTABLE_RECORD_H\n #define REFTABLE_RECORD_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include <stdint.h>\n \n /*\ndiff --git a/reftable/system.h b/reftable/system.h\nindex 5d8b6dede5..d0cabd5d17 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -15,7 +15,7 @@ license that can be found in the LICENSE file or at\n #include \"lockfile.h\"\n #include \"strbuf.h\"\n #include \"tempfile.h\"\n-#include \"hash-ll.h\" /* hash ID, sizes.*/\n+#include \"hash.h\" /* hash ID, sizes.*/\n #include \"dir.h\" /* remove_dir_recursively, for tests.*/\n \n int hash_size(uint32_t id);\ndiff --git a/remote.h b/remote.h\nindex e8c6655e42..7d04e1be1b 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -1,7 +1,7 @@\n #ifndef REMOTE_H\n #define REMOTE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"refspec.h\"\n \ndiff --git a/reset.h b/reset.h\nindex 10708d8ddc..a28f81829d 100644\n--- a/reset.h\n+++ b/reset.h\n@@ -1,7 +1,7 @@\n #ifndef RESET_H\n #define RESET_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"repository.h\"\n \n #define GIT_REFLOG_ACTION_ENVIRONMENT \"GIT_REFLOG_ACTION\"\ndiff --git a/resolve-undo.h b/resolve-undo.h\nindex f3f8462751..89a3227262 100644\n--- a/resolve-undo.h\n+++ b/resolve-undo.h\n@@ -6,7 +6,7 @@ struct index_state;\n struct pathspec;\n struct string_list;\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct resolve_undo_info {\n \tunsigned int mode[3];\ndiff --git a/serve.c b/serve.c\nindex 33608ea4d5..884cd84ca8 100644\n--- a/serve.c\n+++ b/serve.c\n@@ -3,7 +3,7 @@\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"pkt-line.h\"\n #include \"version.h\"\n #include \"ls-refs.h\"\ndiff --git a/split-index.h b/split-index.h\nindex 15a29cd08c..1a153f47ba 100644\n--- a/split-index.h\n+++ b/split-index.h\n@@ -1,7 +1,7 @@\n #ifndef SPLIT_INDEX_H\n #define SPLIT_INDEX_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct index_state;\n struct strbuf;\ndiff --git a/t/helper/test-hash-speed.c b/t/helper/test-hash-speed.c\nindex b235da594f..7de822af51 100644\n--- a/t/helper/test-hash-speed.c\n+++ b/t/helper/test-hash-speed.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n #define NUM_SECONDS 3\n \ndiff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c\nindex dcb7f6c003..e60d000c03 100644\n--- a/t/helper/test-sha1.c\n+++ b/t/helper/test-sha1.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int cmd__sha1(int ac, const char **av)\n {\ndiff --git a/t/helper/test-sha256.c b/t/helper/test-sha256.c\nindex 08cf149001..2fb20438f3 100644\n--- a/t/helper/test-sha256.c\n+++ b/t/helper/test-sha256.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int cmd__sha256(int ac, const char **av)\n {\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 46107772d1..9252481df3 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -8,6 +8,7 @@\n #include \"tree.h\"\n #include \"tree-walk.h\"\n #include \"environment.h\"\n+#include \"repository.h\"\n \n /*\n  * Some mode bits are also used internally for computations.\ndiff --git a/tree-walk.h b/tree-walk.h\nindex 0b1067fbc5..aaea689f9a 100644\n--- a/tree-walk.h\n+++ b/tree-walk.h\n@@ -1,7 +1,7 @@\n #ifndef TREE_WALK_H\n #define TREE_WALK_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct index_state;\n struct repository;\ndiff --git a/xdiff-interface.h b/xdiff-interface.h\nindex 38537169b7..1ed430b622 100644\n--- a/xdiff-interface.h\n+++ b/xdiff-interface.h\n@@ -1,7 +1,7 @@\n #ifndef XDIFF_INTERFACE_H\n #define XDIFF_INTERFACE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"xdiff/xdiff.h\"\n \n /*\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496904","messageId":"b47fa99f3d9b5f4edbeb681dcac56ac2ae26e894.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 12/21] http-fetch: don't crash when parsing packfile without a repo","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:28Z","receivedAt":"2024-06-11T11:58:32Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The git-http-fetch(1) command accepts a `--packfile=` option, which\nallows the user to specify that it shall fetch a specific packfile,\nonly. The parameter here is the hash of the packfile, which is specific\nto the object hash used by the repository. This requirement is implicit\nthough via our use of `parse_oid_hex()`, which internally uses\n`the_repository`.\n\nThe git-http-fetch(1) command allows for there to be no repository\nthough, which only exists such that we can show usage via the \"-h\"\noption. In that case though, starting with c8aed5e8da (repository: stop\nsetting SHA1 as the default object hash, 2024-05-07), `the_repository`\ndoes not have its object hash initialized anymore and thus we would\ncrash when trying to parse the object ID outside of a repository.\n\nFix this issue by dying immediately when we see a \"--packfile=\"\nparameter when outside a Git repository. This is not a functional\nregression as we would die later on with the same error anyway.\n\nAdd a test to detect the segfault. We use the \"nongit\" function to do\nso, which we need to allow-list in `test_must_fail ()`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n http-fetch.c               | 8 +++++++-\n t/t5550-http-fetch-dumb.sh | 6 ++++++\n t/test-lib-functions.sh    | 5 +++++\n 3 files changed, 18 insertions(+), 1 deletion(-)\n\ndiff --git a/http-fetch.c b/http-fetch.c\nindex bec94988bb..d460bb1837 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\n@@ -127,8 +129,12 @@ int cmd_main(int argc, const char **argv)\n \t\t} else if (skip_prefix(argv[arg], \"--packfile=\", &p)) {\n \t\t\tconst char *end;\n \n+\t\t\tif (nongit)\n+\t\t\t\tdie(_(\"not a git repository\"));\n+\n \t\t\tpackfile = 1;\n-\t\t\tif (parse_oid_hex(p, &packfile_hash, &end) || *end)\n+\t\t\tif (parse_oid_hex_algop(p, &packfile_hash, &end,\n+\t\t\t\t\t\tthe_repository->hash_algo) || *end)\n \t\t\t\tdie(_(\"argument to --packfile must be a valid hash (got '%s')\"), p);\n \t\t} else if (skip_prefix(argv[arg], \"--index-pack-arg=\", &p)) {\n \t\t\tstrvec_push(&index_pack_args, p);\ndiff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh\nindex 5f16cbc58d..ea8e48f627 100755\n--- a/t/t5550-http-fetch-dumb.sh\n+++ b/t/t5550-http-fetch-dumb.sh\n@@ -25,6 +25,12 @@ test_expect_success 'setup repository' '\n \tgit commit -m two\n '\n \n+test_expect_success 'packfile without repository does not crash' '\n+\techo \"fatal: not a git repository\" >expect &&\n+\ttest_must_fail nongit git http-fetch --packfile=abc 2>err &&\n+\ttest_cmp expect err\n+'\n+\n setup_post_update_server_info_hook () {\n \ttest_hook --setup -C \"$1\" post-update <<-\\EOF &&\n \texec git update-server-info\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nindex 862d80c974..34bc7d7da4 100644\n--- a/t/test-lib-functions.sh\n+++ b/t/test-lib-functions.sh\n@@ -1096,6 +1096,11 @@ test_must_fail_acceptable () {\n \t\tdone\n \tfi\n \n+\tif test \"$1\" = \"nongit\"\n+\tthen\n+\t\tshift\n+\tfi\n+\n \tcase \"$1\" in\n \tgit|__git*|scalar|test-tool|test_terminal)\n \t\treturn 0\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496905","messageId":"95d9b5fa3e184d10d55971167c55aef36ce31f8f.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 13/21] oidset: pass hash algorithm when parsing file","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:33Z","receivedAt":"2024-06-11T11:58:37Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `oidset_parse_file_carefully()` function implicitly depends on\n`the_repository` when parsing object IDs. Fix this by having callers\npass in the hash algorithm to use.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/blame.c | 1 +\n fsck.c          | 3 ++-\n oidset.c        | 8 +++++---\n oidset.h        | 4 +++-\n 4 files changed, 11 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex de89fff3f8..18f1a3cea0 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -852,6 +852,7 @@ static void build_ignorelist(struct blame_scoreboard *sb,\n \t\t\toidset_clear(&sb->ignore_list);\n \t\telse\n \t\t\toidset_parse_file_carefully(&sb->ignore_list, i->string,\n+\t\t\t\t\t\t    the_repository->hash_algo,\n \t\t\t\t\t\t    peel_to_commit_oid, sb);\n \t}\n \tfor_each_string_list_item(i, ignore_rev_list) {\ndiff --git a/fsck.c b/fsck.c\nindex 432996cbb6..304f4a17ec 100644\n--- a/fsck.c\n+++ b/fsck.c\n@@ -205,7 +205,8 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values)\n \t\tif (!strcmp(buf, \"skiplist\")) {\n \t\t\tif (equal == len)\n \t\t\t\tdie(\"skiplist requires a path\");\n-\t\t\toidset_parse_file(&options->skiplist, buf + equal + 1);\n+\t\t\toidset_parse_file(&options->skiplist, buf + equal + 1,\n+\t\t\t\t\t  the_repository->hash_algo);\n \t\t\tbuf += len + 1;\n \t\t\tcontinue;\n \t\t}\ndiff --git a/oidset.c b/oidset.c\nindex 91d1385910..8d36aef8dc 100644\n--- a/oidset.c\n+++ b/oidset.c\n@@ -48,12 +48,14 @@ void oidset_clear(struct oidset *set)\n \toidset_init(set, 0);\n }\n \n-void oidset_parse_file(struct oidset *set, const char *path)\n+void oidset_parse_file(struct oidset *set, const char *path,\n+\t\t       const struct git_hash_algo *algop)\n {\n-\toidset_parse_file_carefully(set, path, NULL, NULL);\n+\toidset_parse_file_carefully(set, path, algop, NULL, NULL);\n }\n \n void oidset_parse_file_carefully(struct oidset *set, const char *path,\n+\t\t\t\t const struct git_hash_algo *algop,\n \t\t\t\t oidset_parse_tweak_fn fn, void *cbdata)\n {\n \tFILE *fp;\n@@ -79,7 +81,7 @@ void oidset_parse_file_carefully(struct oidset *set, const char *path,\n \t\tif (!sb.len)\n \t\t\tcontinue;\n \n-\t\tif (parse_oid_hex(sb.buf, &oid, &p) || *p != '\\0')\n+\t\tif (parse_oid_hex_algop(sb.buf, &oid, &p, algop) || *p != '\\0')\n \t\t\tdie(\"invalid object name: %s\", sb.buf);\n \t\tif (fn && fn(&oid, cbdata))\n \t\t\tcontinue;\ndiff --git a/oidset.h b/oidset.h\nindex 262f4256d6..0106b6f278 100644\n--- a/oidset.h\n+++ b/oidset.h\n@@ -80,7 +80,8 @@ void oidset_clear(struct oidset *set);\n  * are allowed.  Leading whitespace and empty or white-space only lines are\n  * ignored.\n  */\n-void oidset_parse_file(struct oidset *set, const char *path);\n+void oidset_parse_file(struct oidset *set, const char *path,\n+\t\t       const struct git_hash_algo *algop);\n \n /*\n  * Similar to the above, but with a callback which can (1) return non-zero to\n@@ -89,6 +90,7 @@ void oidset_parse_file(struct oidset *set, const char *path);\n  */\n typedef int (*oidset_parse_tweak_fn)(struct object_id *, void *);\n void oidset_parse_file_carefully(struct oidset *set, const char *path,\n+\t\t\t\t const struct git_hash_algo *algop,\n \t\t\t\t oidset_parse_tweak_fn fn, void *cbdata);\n \n struct oidset_iter {\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496906","messageId":"c877d48f7dc3c4a7ab93fe9a9ab1c38fcb4dd747.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 14/21] protocol-caps: use hash algorithm from passed-in repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:37Z","receivedAt":"2024-06-11T11:58:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In `send_info()`, we pass in a repository but then use `get_oid_hex()`\nto parse passed-in object IDs, which implicitly uses `the_repository`.\nFix this by using the hash algorithm from the passed-in repository\ninstead.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n protocol-caps.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/protocol-caps.c b/protocol-caps.c\nindex fe8d1d5c63..855f279c2f 100644\n--- a/protocol-caps.c\n+++ b/protocol-caps.c\n@@ -7,6 +7,7 @@\n #include \"hex.h\"\n #include \"object.h\"\n #include \"object-store-ll.h\"\n+#include \"repository.h\"\n #include \"string-list.h\"\n #include \"strbuf.h\"\n \n@@ -52,7 +53,7 @@ static void send_info(struct repository *r, struct packet_writer *writer,\n \t\tstruct object_id oid;\n \t\tunsigned long object_size;\n \n-\t\tif (get_oid_hex(oid_str, &oid) < 0) {\n+\t\tif (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {\n \t\t\tpacket_writer_error(\n \t\t\t\twriter,\n \t\t\t\t\"object-info: protocol error, expected to get oid, not '%s'\",\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496907","messageId":"ca5f4056fbdac83fb47ca4c51622e9e45ea2287d.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 15/21] replace-object: use hash algorithm from passed-in repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:43Z","receivedAt":"2024-06-11T11:58:46Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In `register_replace_ref()`, we pass in a repository but then use\n`get_oid_hex()` to parse passed-in object IDs, which implicitly uses\n`the_repository`. Fix this by using the hash algorithm from the\npassed-in repository instead.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n replace-object.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/replace-object.c b/replace-object.c\nindex 73f5acbcd9..59252d565e 100644\n--- a/replace-object.c\n+++ b/replace-object.c\n@@ -20,7 +20,7 @@ static int register_replace_ref(const char *refname,\n \tconst char *hash = slash ? slash + 1 : refname;\n \tstruct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));\n \n-\tif (get_oid_hex(hash, &repl_obj->original.oid)) {\n+\tif (get_oid_hex_algop(hash, &repl_obj->original.oid, r->hash_algo)) {\n \t\tfree(repl_obj);\n \t\twarning(_(\"bad replace ref name: %s\"), refname);\n \t\treturn 0;\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496908","messageId":"d4e87f9d6b4813fe359e22f4b5d5ebda28e09a08.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 16/21] compat/fsmonitor: remove dependency on `the_repository` in Darwin IPC","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:47Z","receivedAt":"2024-06-11T11:58:52Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The IPC socket used by the fsmonitor on Darwin is usually contained in\nthe Git repository itself. When the repository is hosted on a networked\nfilesystem though, we instead create the socket path in the user's home\ndirectory or the socket directory. In that case, we derive the path by\nhashing the repository path.\n\nThe hashing implicitly depends on `the_repository` though via\n`hash_to_hex()`. For one, this is wrong because we really should be\nusing the passed-in repository. But arguably, it is not sensible to\nderive the path hash from the repository's object hash in the first\nplace -- they don't have anything to do with each other, and a\nrepository that is hosted in the same path should always derive the same\nIPC socket path.\n\nFix this by unconditionally using SHA1 to derive the path.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n compat/fsmonitor/fsm-ipc-darwin.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/compat/fsmonitor/fsm-ipc-darwin.c b/compat/fsmonitor/fsm-ipc-darwin.c\nindex 6f3a95410c..b4d21d6dc2 100644\n--- a/compat/fsmonitor/fsm-ipc-darwin.c\n+++ b/compat/fsmonitor/fsm-ipc-darwin.c\n@@ -41,9 +41,10 @@ const char *fsmonitor_ipc__get_path(struct repository *r)\n \t/* Create the socket file in either socketDir or $HOME */\n \tif (sock_dir && *sock_dir) {\n \t\tstrbuf_addf(&ipc_file, \"%s/.git-fsmonitor-%s\",\n-\t\t\t\t\tsock_dir, hash_to_hex(hash));\n+\t\t\t    sock_dir, hash_to_hex_algop(hash, &hash_algos[GIT_HASH_SHA1]));\n \t} else {\n-\t\tstrbuf_addf(&ipc_file, \"~/.git-fsmonitor-%s\", hash_to_hex(hash));\n+\t\tstrbuf_addf(&ipc_file, \"~/.git-fsmonitor-%s\",\n+\t\t\t    hash_to_hex_algop(hash, &hash_algos[GIT_HASH_SHA1]));\n \t}\n \tfree(sock_dir);\n \n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496909","messageId":"5310883469e3366a82dd22d4a552715d3bc580e7.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 17/21] t/helper: use correct object hash in partial-clone helper","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:52Z","receivedAt":"2024-06-11T11:58:56Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `object_info()` function of the partial-clone helper is responsible\nfor checking the object ID of a repository other than `the_repository`.\nWe use `parse_oid_hex()` in this function though, which means that we\nstill depend on `the_repository->hash_algo`.\n\nFix this by using the object hash of the function-local repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-partial-clone.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c\nindex 910a128614..0ead529167 100644\n--- a/t/helper/test-partial-clone.c\n+++ b/t/helper/test-partial-clone.c\n@@ -21,7 +21,7 @@ static void object_info(const char *gitdir, const char *oid_hex)\n \n \tif (repo_init(&r, gitdir, NULL))\n \t\tdie(\"could not init repo\");\n-\tif (parse_oid_hex(oid_hex, &oid, &p))\n+\tif (parse_oid_hex_algop(oid_hex, &oid, &p, r.hash_algo))\n \t\tdie(\"could not parse oid\");\n \tif (oid_object_info_extended(&r, &oid, &oi, 0))\n \t\tdie(\"could not obtain object info\");\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496910","messageId":"2774b8500fdecb0d73543dbfc5ac18c6bb8d8090.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 18/21] t/helper: fix segfault in \"oid-array\" command without repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:58:56Z","receivedAt":"2024-06-11T11:59:01Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"oid-array\" test helper can supposedly work without a Git\nrepository, but will in fact crash because `the_repository->hash_algo`\nis not initialized. This is because `oid_pos()`, which is used by\n`oid_array_lookup()`, depends on `the_hash_algo->rawsz`.\n\nIdeally, we'd adapt `oid_pos()` to not depend on `the_hash_algo`\nanymore. That is a bigger untertaking though, so instead we fall back to\nSHA1 when there is no repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-oid-array.c |  4 ++++\n t/t0064-oid-array.sh      | 18 ++++++++++++++++++\n 2 files changed, 22 insertions(+)\n\ndiff --git a/t/helper/test-oid-array.c b/t/helper/test-oid-array.c\nindex aafe398ef0..076b849cbf 100644\n--- a/t/helper/test-oid-array.c\n+++ b/t/helper/test-oid-array.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"oid-array.h\"\n@@ -17,6 +19,8 @@ int cmd__oid_array(int argc UNUSED, const char **argv UNUSED)\n \tint nongit_ok;\n \n \tsetup_git_directory_gently(&nongit_ok);\n+\tif (nongit_ok)\n+\t\trepo_set_hash_algo(the_repository, GIT_HASH_SHA1);\n \n \twhile (strbuf_getline(&line, stdin) != EOF) {\n \t\tconst char *arg;\ndiff --git a/t/t0064-oid-array.sh b/t/t0064-oid-array.sh\nindex 88c89e8f48..de74b692d0 100755\n--- a/t/t0064-oid-array.sh\n+++ b/t/t0064-oid-array.sh\n@@ -15,6 +15,24 @@ echoid () {\n \tdone\n }\n \n+test_expect_success 'without repository' '\n+\tcat >expect <<-EOF &&\n+\t4444444444444444444444444444444444444444\n+\t5555555555555555555555555555555555555555\n+\t8888888888888888888888888888888888888888\n+\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n+\tEOF\n+\tcat >input <<-EOF &&\n+\tappend 4444444444444444444444444444444444444444\n+\tappend 5555555555555555555555555555555555555555\n+\tappend 8888888888888888888888888888888888888888\n+\tappend aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n+\tfor_each_unique\n+\tEOF\n+\tnongit test-tool oid-array <input >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'ordered enumeration' '\n \techoid \"\" 44 55 88 aa >expect &&\n \t{\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496911","messageId":"339d668da837ab5b4b11399ece4efaf5bc27d313.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 19/21] t/helper: remove dependency on `the_repository` in \"oidtree\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:59:01Z","receivedAt":"2024-06-11T11:59:05Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"oidtree\" test helper sets up a Git repository, but this is really\nonly used such that `get_oid_hex()` can parse both SHA1 and SHA256\nobject hashes. The `struct oidtree` interface itself does not care at\nall about the object hash of `the_repository`, and always asserts that\ninserted object IDs have their hash algorithm set.\n\nStop initializing the repository and instead use `get_oid_hex_any()` to\nparse object IDs for the \"contains\" action, like we already do when\nparsing the \"insert\" action.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-oidtree.c | 5 +----\n 1 file changed, 1 insertion(+), 4 deletions(-)\n\ndiff --git a/t/helper/test-oidtree.c b/t/helper/test-oidtree.c\nindex c7a1d4c642..04ec24cc84 100644\n--- a/t/helper/test-oidtree.c\n+++ b/t/helper/test-oidtree.c\n@@ -1,7 +1,6 @@\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"oidtree.h\"\n-#include \"setup.h\"\n #include \"strbuf.h\"\n \n static enum cb_next print_oid(const struct object_id *oid, void *data UNUSED)\n@@ -14,11 +13,9 @@ int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)\n {\n \tstruct oidtree ot;\n \tstruct strbuf line = STRBUF_INIT;\n-\tint nongit_ok;\n \tint algo = GIT_HASH_UNKNOWN;\n \n \toidtree_init(&ot);\n-\tsetup_git_directory_gently(&nongit_ok);\n \n \twhile (strbuf_getline(&line, stdin) != EOF) {\n \t\tconst char *arg;\n@@ -30,7 +27,7 @@ int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)\n \t\t\talgo = oid.algo;\n \t\t\toidtree_insert(&ot, &oid);\n \t\t} else if (skip_prefix(line.buf, \"contains \", &arg)) {\n-\t\t\tif (get_oid_hex(arg, &oid))\n+\t\t\tif (get_oid_hex_any(arg, &oid) == GIT_HASH_UNKNOWN)\n \t\t\t\tdie(\"contains not a hexadecimal oid: %s\", arg);\n \t\t\tprintf(\"%d\\n\", oidtree_contains(&ot, &oid));\n \t\t} else if (skip_prefix(line.buf, \"each \", &arg)) {\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496912","messageId":"97fa3051fac18aa57b2930425271935762814462.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 20/21] t/helper: remove dependency on `the_repository` in \"proc-receive\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:59:05Z","receivedAt":"2024-06-11T11:59:09Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"proc-receive\" test helper implicitly relies on `the_repository` via\n`parse_oid_hex()`. This isn't necessary though, and in fact the whole\ncommand does not depend on `the_repository` at all.\n\nStop setting up `the_repository` and use `parse_oid_hex_any()` to parse\nobject IDs.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-proc-receive.c | 9 +++------\n 1 file changed, 3 insertions(+), 6 deletions(-)\n\ndiff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c\nindex f30022d222..29361c7aab 100644\n--- a/t/helper/test-proc-receive.c\n+++ b/t/helper/test-proc-receive.c\n@@ -3,8 +3,8 @@\n #include \"hex.h\"\n #include \"parse-options.h\"\n #include \"pkt-line.h\"\n-#include \"setup.h\"\n #include \"sigchain.h\"\n+#include \"string-list.h\"\n \n static const char *proc_receive_usage[] = {\n \t\"test-tool proc-receive [<options>]\",\n@@ -92,9 +92,9 @@ static void proc_receive_read_commands(struct packet_reader *reader,\n \t\tif (die_read_commands)\n \t\t\tdie(\"die with the --die-read-commands option\");\n \n-\t\tif (parse_oid_hex(reader->line, &old_oid, &p) ||\n+\t\tif (parse_oid_hex_any(reader->line, &old_oid, &p) == GIT_HASH_UNKNOWN ||\n \t\t    *p++ != ' ' ||\n-\t\t    parse_oid_hex(p, &new_oid, &p) ||\n+\t\t    parse_oid_hex_any(p, &new_oid, &p) == GIT_HASH_UNKNOWN ||\n \t\t    *p++ != ' ')\n \t\t\tdie(\"protocol error: expected 'old new ref', got '%s'\",\n \t\t\t    reader->line);\n@@ -128,7 +128,6 @@ static void proc_receive_read_push_options(struct packet_reader *reader,\n \n int cmd__proc_receive(int argc, const char **argv)\n {\n-\tint nongit_ok = 0;\n \tstruct packet_reader reader;\n \tstruct command *commands = NULL;\n \tstruct string_list push_options = STRING_LIST_INIT_DUP;\n@@ -154,8 +153,6 @@ int cmd__proc_receive(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n-\tsetup_git_directory_gently(&nongit_ok);\n-\n \targc = parse_options(argc, argv, \"test-tools\", options, proc_receive_usage, 0);\n \tif (argc > 0)\n \t\tusage_msg_opt(\"Too many arguments.\", proc_receive_usage, options);\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496913","messageId":"92c7f542d244c76e3573244f7c3f969a30275c9a.1718106285.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH 21/21] hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-11T11:59:10Z","receivedAt":"2024-06-11T11:59:14Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Guard declarations of functions that implicitly use `the_repository`\nwith `USE_THE_REPOSITORY_VARIABLE` such that callers don't accidentally\nrely on that global variable.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hex.h | 26 ++++++++++++++++----------\n 1 file changed, 16 insertions(+), 10 deletions(-)\n\ndiff --git a/hex.h b/hex.h\nindex 9809667f33..e9ccb54065 100644\n--- a/hex.h\n+++ b/hex.h\n@@ -13,10 +13,6 @@\n  * input, so it is safe to pass this function an arbitrary\n  * null-terminated string.\n  */\n-int get_hash_hex(const char *hex, unsigned char *hash);\n-int get_oid_hex(const char *hex, struct object_id *oid);\n-\n-/* Like get_oid_hex, but for an arbitrary hash algorithm. */\n int get_oid_hex_algop(const char *hex, struct object_id *oid, const struct git_hash_algo *algop);\n \n /*\n@@ -35,7 +31,6 @@ int get_oid_hex_algop(const char *hex, struct object_id *oid, const struct git_h\n char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash, const struct git_hash_algo *);\n char *oid_to_hex_r(char *out, const struct object_id *oid);\n char *hash_to_hex_algop(const unsigned char *hash, const struct git_hash_algo *);\t/* static buffer result! */\n-char *hash_to_hex(const unsigned char *hash);\t\t\t\t\t\t/* same static buffer */\n char *oid_to_hex(const struct object_id *oid);\t\t\t\t\t\t/* same static buffer */\n \n /*\n@@ -45,13 +40,9 @@ char *oid_to_hex(const struct object_id *oid);\t\t\t\t\t\t/* same static buffer */\n  * other invalid character.  end is only updated on success; otherwise, it is\n  * unmodified.\n  */\n-int parse_oid_hex(const char *hex, struct object_id *oid, const char **end);\n-\n-/* Like parse_oid_hex, but for an arbitrary hash algorithm. */\n int parse_oid_hex_algop(const char *hex, struct object_id *oid, const char **end,\n \t\t\tconst struct git_hash_algo *algo);\n \n-\n /*\n  * These functions work like get_oid_hex and parse_oid_hex, but they will parse\n  * a hex value for any algorithm. The algorithm is detected based on the length\n@@ -61,4 +52,19 @@ int parse_oid_hex_algop(const char *hex, struct object_id *oid, const char **end\n int get_oid_hex_any(const char *hex, struct object_id *oid);\n int parse_oid_hex_any(const char *hex, struct object_id *oid, const char **end);\n \n-#endif\n+#ifdef USE_THE_REPOSITORY_VARIABLE\n+\n+/* Like get_oid_hex_algop, but for `the_hash_algo`. */\n+int get_hash_hex(const char *hex, unsigned char *hash);\n+int get_oid_hex(const char *hex, struct object_id *oid);\n+\n+/* Like parse_oid_hex_algop, but uses `the_hash_algo`. */\n+int parse_oid_hex(const char *hex, struct object_id *oid, const char **end);\n+\n+/*\n+ * Same as `hash_to_hex_algop()`, but uses `the_hash_algo`.\n+ */\n+char *hash_to_hex(const unsigned char *hash);\n+\n+#endif /* USE_THE_REPOSITORY_VARIABLE */\n+#endif /* HEX_H */\n-- \n2.45.2.436.gcd77e87115.dirty\n\n"},{"id":"496921","messageId":"3xu573xqbhfb3epktusqdxujal5ibkapnngiyzonae7edhu24p@fdajnz4imrbf","threadId":"61621","inReplyTo":"339d668da837ab5b4b11399ece4efaf5bc27d313.1718106285.git.ps@pks.im","subject":"Re: [PATCH 19/21] t/helper: remove dependency on `the_repository` in \"oidtree\"","fromName":"Ghanshyam Thakkar","fromEmail":"shyamthakkar001@gmail.com","sentAt":"2024-06-11T12:57:51Z","receivedAt":"2024-06-11T12:57:57Z","isPatch":true,"sender":{"key":"shyamthakkar001@gmail.com","avatar":"https://avatars.githubusercontent.com/u/72698233?v=4"},"body":"On Tue, 11 Jun 2024, Patrick Steinhardt <ps@pks.im> wrote:\n> The \"oidtree\" test helper sets up a Git repository, but this is really\n> only used such that `get_oid_hex()` can parse both SHA1 and SHA256\n> object hashes. The `struct oidtree` interface itself does not care at\n> all about the object hash of `the_repository`, and always asserts that\n> inserted object IDs have their hash algorithm set.\n> \n> Stop initializing the repository and instead use `get_oid_hex_any()` to\n> parse object IDs for the \"contains\" action, like we already do when\n> parsing the \"insert\" action.\n\nI think the motive of this patch is already achieved in\n'gt/unit-test-oidtree'[1], if this is to be merged after that.\n\nThanks.\n\n[1]: https://github.com/git/git/commit/79d9e08db3a08c5a06e2633a39cd38b980e654f4\nmailing list: https://lore.kernel.org/git/20240608165731.29467-1-shyamthakkar001@gmail.com/\n\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  t/helper/test-oidtree.c | 5 +----\n>  1 file changed, 1 insertion(+), 4 deletions(-)\n> \n> diff --git a/t/helper/test-oidtree.c b/t/helper/test-oidtree.c\n> index c7a1d4c642..04ec24cc84 100644\n> --- a/t/helper/test-oidtree.c\n> +++ b/t/helper/test-oidtree.c\n> @@ -1,7 +1,6 @@\n>  #include \"test-tool.h\"\n>  #include \"hex.h\"\n>  #include \"oidtree.h\"\n> -#include \"setup.h\"\n>  #include \"strbuf.h\"\n>  \n>  static enum cb_next print_oid(const struct object_id *oid, void *data UNUSED)\n> @@ -14,11 +13,9 @@ int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)\n>  {\n>  \tstruct oidtree ot;\n>  \tstruct strbuf line = STRBUF_INIT;\n> -\tint nongit_ok;\n>  \tint algo = GIT_HASH_UNKNOWN;\n>  \n>  \toidtree_init(&ot);\n> -\tsetup_git_directory_gently(&nongit_ok);\n>  \n>  \twhile (strbuf_getline(&line, stdin) != EOF) {\n>  \t\tconst char *arg;\n> @@ -30,7 +27,7 @@ int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)\n>  \t\t\talgo = oid.algo;\n>  \t\t\toidtree_insert(&ot, &oid);\n>  \t\t} else if (skip_prefix(line.buf, \"contains \", &arg)) {\n> -\t\t\tif (get_oid_hex(arg, &oid))\n> +\t\t\tif (get_oid_hex_any(arg, &oid) == GIT_HASH_UNKNOWN)\n>  \t\t\t\tdie(\"contains not a hexadecimal oid: %s\", arg);\n>  \t\t\tprintf(\"%d\\n\", oidtree_contains(&ot, &oid));\n>  \t\t} else if (skip_prefix(line.buf, \"each \", &arg)) {\n> -- \n> 2.45.2.436.gcd77e87115.dirty\n> \n\n\n"},{"id":"496923","messageId":"cc2go3x24cftqml2byx5oh3ggvsqdz32yufdpn2box2jpehtlo@hnsubup3sefn","threadId":"61621","inReplyTo":"2774b8500fdecb0d73543dbfc5ac18c6bb8d8090.1718106285.git.ps@pks.im","subject":"Re: [PATCH 18/21] t/helper: fix segfault in \"oid-array\" command without repository","fromName":"Ghanshyam Thakkar","fromEmail":"shyamthakkar001@gmail.com","sentAt":"2024-06-11T13:23:39Z","receivedAt":"2024-06-11T13:23:44Z","isPatch":true,"sender":{"key":"shyamthakkar001@gmail.com","avatar":"https://avatars.githubusercontent.com/u/72698233?v=4"},"body":"On Tue, 11 Jun 2024, Patrick Steinhardt <ps@pks.im> wrote:\n> The \"oid-array\" test helper can supposedly work without a Git\n> repository, but will in fact crash because `the_repository->hash_algo`\n> is not initialized. This is because `oid_pos()`, which is used by\n> `oid_array_lookup()`, depends on `the_hash_algo->rawsz`.\n> \n> Ideally, we'd adapt `oid_pos()` to not depend on `the_hash_algo`\n> anymore. That is a bigger untertaking though, so instead we fall back to\n> SHA1 when there is no repository.\n\nThanks for working on this. This would make t-oid-array migration\nsmoother.\n\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  t/helper/test-oid-array.c |  4 ++++\n>  t/t0064-oid-array.sh      | 18 ++++++++++++++++++\n>  2 files changed, 22 insertions(+)\n> \n> diff --git a/t/helper/test-oid-array.c b/t/helper/test-oid-array.c\n> index aafe398ef0..076b849cbf 100644\n> --- a/t/helper/test-oid-array.c\n> +++ b/t/helper/test-oid-array.c\n> @@ -1,3 +1,5 @@\n> +#define USE_THE_REPOSITORY_VARIABLE\n> +\n>  #include \"test-tool.h\"\n>  #include \"hex.h\"\n>  #include \"oid-array.h\"\n> @@ -17,6 +19,8 @@ int cmd__oid_array(int argc UNUSED, const char **argv UNUSED)\n>  \tint nongit_ok;\n>  \n>  \tsetup_git_directory_gently(&nongit_ok);\n> +\tif (nongit_ok)\n> +\t\trepo_set_hash_algo(the_repository, GIT_HASH_SHA1);\n\nIdeally we would want to test with both SHA1 and SHA256 without the\nrepo, but it is not a necessity for this patch as it would get solved\nwhen we migrate to the unit testing framework.\n\n>  \twhile (strbuf_getline(&line, stdin) != EOF) {\n>  \t\tconst char *arg;\n> diff --git a/t/t0064-oid-array.sh b/t/t0064-oid-array.sh\n> index 88c89e8f48..de74b692d0 100755\n> --- a/t/t0064-oid-array.sh\n> +++ b/t/t0064-oid-array.sh\n> @@ -15,6 +15,24 @@ echoid () {\n>  \tdone\n>  }\n>  \n> +test_expect_success 'without repository' '\n> +\tcat >expect <<-EOF &&\n> +\t4444444444444444444444444444444444444444\n> +\t5555555555555555555555555555555555555555\n> +\t8888888888888888888888888888888888888888\n> +\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n> +\tEOF\n> +\tcat >input <<-EOF &&\n> +\tappend 4444444444444444444444444444444444444444\n> +\tappend 5555555555555555555555555555555555555555\n> +\tappend 8888888888888888888888888888888888888888\n> +\tappend aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n> +\tfor_each_unique\n> +\tEOF\n> +\tnongit test-tool oid-array <input >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n>  test_expect_success 'ordered enumeration' '\n>  \techoid \"\" 44 55 88 aa >expect &&\n>  \t{\n> -- \n> 2.45.2.436.gcd77e87115.dirty\n> \n\n\n"},{"id":"496964","messageId":"Zmjas3s9OPJ9Ff5E@tapette.crustytoothpaste.net","threadId":"61621","inReplyTo":"d4e87f9d6b4813fe359e22f4b5d5ebda28e09a08.1718106285.git.ps@pks.im","subject":"Re: [PATCH 16/21] compat/fsmonitor: remove dependency on `the_repository` in Darwin IPC","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2024-06-11T23:16:03Z","receivedAt":"2024-06-11T23:16:11Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2024-06-11 at 11:58:47, Patrick Steinhardt wrote:\n> The IPC socket used by the fsmonitor on Darwin is usually contained in\n> the Git repository itself. When the repository is hosted on a networked\n> filesystem though, we instead create the socket path in the user's home\n> directory or the socket directory. In that case, we derive the path by\n> hashing the repository path.\n> \n> The hashing implicitly depends on `the_repository` though via\n> `hash_to_hex()`. For one, this is wrong because we really should be\n> using the passed-in repository. But arguably, it is not sensible to\n> derive the path hash from the repository's object hash in the first\n> place -- they don't have anything to do with each other, and a\n> repository that is hosted in the same path should always derive the same\n> IPC socket path.\n> \n> Fix this by unconditionally using SHA1 to derive the path.\n\nLet's instead use SHA-256 to derive the path.  I can imagine that there\nmight be a time when some users would like to drop support for SHA-1\naltogether (for FIPS compliance reasons, say) and we'll make our lives a\nlot easier if we avoid more uses of SHA-1.\n\nIt is also typically faster when compiled appropriately, although the\namount of data we're processing is very small.\n-- \nbrian m. carlson (they/them or he/him)\nToronto, Ontario, CA\n"},{"id":"496965","messageId":"ZmjbJU1Rnnx0ggHt@tapette.crustytoothpaste.net","threadId":"61621","inReplyTo":"339d668da837ab5b4b11399ece4efaf5bc27d313.1718106285.git.ps@pks.im","subject":"Re: [PATCH 19/21] t/helper: remove dependency on `the_repository` in \"oidtree\"","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2024-06-11T23:17:57Z","receivedAt":"2024-06-11T23:18:00Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2024-06-11 at 11:59:01, Patrick Steinhardt wrote:\n> diff --git a/t/helper/test-oidtree.c b/t/helper/test-oidtree.c\n> index c7a1d4c642..04ec24cc84 100644\n> --- a/t/helper/test-oidtree.c\n> +++ b/t/helper/test-oidtree.c\n> @@ -1,7 +1,6 @@\n>  #include \"test-tool.h\"\n>  #include \"hex.h\"\n>  #include \"oidtree.h\"\n> -#include \"setup.h\"\n>  #include \"strbuf.h\"\n>  \n>  static enum cb_next print_oid(const struct object_id *oid, void *data UNUSED)\n> @@ -14,11 +13,9 @@ int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)\n>  {\n>  \tstruct oidtree ot;\n>  \tstruct strbuf line = STRBUF_INIT;\n> -\tint nongit_ok;\n>  \tint algo = GIT_HASH_UNKNOWN;\n>  \n>  \toidtree_init(&ot);\n> -\tsetup_git_directory_gently(&nongit_ok);\n>  \n>  \twhile (strbuf_getline(&line, stdin) != EOF) {\n>  \t\tconst char *arg;\n> @@ -30,7 +27,7 @@ int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)\n>  \t\t\talgo = oid.algo;\n>  \t\t\toidtree_insert(&ot, &oid);\n>  \t\t} else if (skip_prefix(line.buf, \"contains \", &arg)) {\n> -\t\t\tif (get_oid_hex(arg, &oid))\n> +\t\t\tif (get_oid_hex_any(arg, &oid) == GIT_HASH_UNKNOWN)\n>  \t\t\t\tdie(\"contains not a hexadecimal oid: %s\", arg);\n\nThis is not a problem in your code, but this might read more naturally\nas \"does not contain a hexadecimal oid\" or \"contains no hexadecimal\noid\".\n-- \nbrian m. carlson (they/them or he/him)\nToronto, Ontario, CA\n"},{"id":"496966","messageId":"ZmjcrqnDnHAZjr6V@tapette.crustytoothpaste.net","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"Re: [PATCH 00/21] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2024-06-11T23:24:30Z","receivedAt":"2024-06-11T23:24:33Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2024-06-11 at 11:57:33, Patrick Steinhardt wrote:\n> Hi,\n> \n> use of the `the_repository` variable is nowadays considered to be\n> deprecated, and over time we want to convert our codebase to stop using\n> it in favor of explicitly passing down the repository to functions via\n> parameters. This effort faces some important problems though.\n> \n>   - It is hard to prove that a certain code unit does not use\n>     `the_repository` anymore when sending patch series. The reviewer has\n>     no way to verify that it's not used anymore without reading through\n>     the code itself.\n> \n>   - It is easy to sneak in new usages of `the_repository` by accident\n>     into a code unit that is already `the_repository`-clean.\n> \n>   - There are many functions which implicitly use `the_repository`,\n>     which is really hard to spot.\n> \n> This patch series aims to address those problems by introducing a new\n> `USE_THE_REPOSITORY_VARIABLE` macro. When unset, then the declarations\n> of `the_repository`, `the_hash_algo` and some functions that implicitly\n> depend on them will be hidden away. This makes it trivial to demonstrate\n> that a code unit is `the_repository`-free by removing the definition of\n> any such macro.\n\nOverall, I left a few comments, but I think this definitely moves us in\nthe right direction and I'm glad to see it.  This obviously improves the\nexperience with libification and unit testing in a lot of ways, which is\ngood.\n\nMy only caution is that using the *_any functions will cause us a world\nof pain if we ever adopt another 256-bit hash function, since it will be\nambiguous which algorithm is to be used.  That's why, traditionally, we\nhaven't assumed a hash algorithm based on the object ID length.  I don't\nthink the amount of uses we have is excessive, even with your changes,\nbut we'll need to be mindful of that going forward.\n-- \nbrian m. carlson (they/them or he/him)\nToronto, Ontario, CA\n"},{"id":"496988","messageId":"ZmlQQadfFyCHo_k1@tanuki","threadId":"61621","inReplyTo":"ZmjcrqnDnHAZjr6V@tapette.crustytoothpaste.net","subject":"Re: [PATCH 00/21] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-12T07:37:37Z","receivedAt":"2024-06-12T07:37:43Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Jun 11, 2024 at 11:24:30PM +0000, brian m. carlson wrote:\n> On 2024-06-11 at 11:57:33, Patrick Steinhardt wrote:\n> > Hi,\n> > \n> > use of the `the_repository` variable is nowadays considered to be\n> > deprecated, and over time we want to convert our codebase to stop using\n> > it in favor of explicitly passing down the repository to functions via\n> > parameters. This effort faces some important problems though.\n> > \n> >   - It is hard to prove that a certain code unit does not use\n> >     `the_repository` anymore when sending patch series. The reviewer has\n> >     no way to verify that it's not used anymore without reading through\n> >     the code itself.\n> > \n> >   - It is easy to sneak in new usages of `the_repository` by accident\n> >     into a code unit that is already `the_repository`-clean.\n> > \n> >   - There are many functions which implicitly use `the_repository`,\n> >     which is really hard to spot.\n> > \n> > This patch series aims to address those problems by introducing a new\n> > `USE_THE_REPOSITORY_VARIABLE` macro. When unset, then the declarations\n> > of `the_repository`, `the_hash_algo` and some functions that implicitly\n> > depend on them will be hidden away. This makes it trivial to demonstrate\n> > that a code unit is `the_repository`-free by removing the definition of\n> > any such macro.\n> \n> Overall, I left a few comments, but I think this definitely moves us in\n> the right direction and I'm glad to see it.  This obviously improves the\n> experience with libification and unit testing in a lot of ways, which is\n> good.\n> \n> My only caution is that using the *_any functions will cause us a world\n> of pain if we ever adopt another 256-bit hash function, since it will be\n> ambiguous which algorithm is to be used.  That's why, traditionally, we\n> haven't assumed a hash algorithm based on the object ID length.  I don't\n> think the amount of uses we have is excessive, even with your changes,\n> but we'll need to be mindful of that going forward.\n\nThe only cases where I add new calls to `_any()` are in test helpers:\n\n  - \"t/helper/test-oidtree.c\". This one is getting converted to a unit\n    test by Ghanshyam, so I'll leave it to him to improve this.\n\n  - \"t/helper/test-proc-receive.c\". Here we don't care about the actual\n    algorithm, the only thing we care about is that we can correctly\n    parse them and then eventually emit them via `oid_to_hex()` again.\n    So even if we introduce a second hash function with the same length\n    this code would continue to work alright.\n\nSo I think it should be fine in the context of this series. But the\nremark is certainly valid and something we should be cautious about\ngoing forward.\n\nThanks!\n\nPatrick\n"},{"id":"496989","messageId":"ZmlQWh9LBzZb_zU-@tanuki","threadId":"61621","inReplyTo":"Zmjas3s9OPJ9Ff5E@tapette.crustytoothpaste.net","subject":"Re: [PATCH 16/21] compat/fsmonitor: remove dependency on `the_repository` in Darwin IPC","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-12T07:38:02Z","receivedAt":"2024-06-12T07:38:07Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Jun 11, 2024 at 11:16:03PM +0000, brian m. carlson wrote:\n> On 2024-06-11 at 11:58:47, Patrick Steinhardt wrote:\n> > The IPC socket used by the fsmonitor on Darwin is usually contained in\n> > the Git repository itself. When the repository is hosted on a networked\n> > filesystem though, we instead create the socket path in the user's home\n> > directory or the socket directory. In that case, we derive the path by\n> > hashing the repository path.\n> > \n> > The hashing implicitly depends on `the_repository` though via\n> > `hash_to_hex()`. For one, this is wrong because we really should be\n> > using the passed-in repository. But arguably, it is not sensible to\n> > derive the path hash from the repository's object hash in the first\n> > place -- they don't have anything to do with each other, and a\n> > repository that is hosted in the same path should always derive the same\n> > IPC socket path.\n> > \n> > Fix this by unconditionally using SHA1 to derive the path.\n> \n> Let's instead use SHA-256 to derive the path.  I can imagine that there\n> might be a time when some users would like to drop support for SHA-1\n> altogether (for FIPS compliance reasons, say) and we'll make our lives a\n> lot easier if we avoid more uses of SHA-1.\n> \n> It is also typically faster when compiled appropriately, although the\n> amount of data we're processing is very small.\n\nI only now realize that this actually a bug. The hash is already getting\ncomputed as SHA1 unconditionally like this:\n\n\tgit_SHA1_Init(&sha1ctx);\n\tgit_SHA1_Update(&sha1ctx, r->worktree, strlen(r->worktree));\n\tgit_SHA1_Final(hash, &sha1ctx);\n\nAnd then we used to pass the computed hash to `hash_to_hex()`, which is\nof course the wrong thing to do in a SHA256 repository because we would\nend up printing `GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ` uninitialized bytes.\n\nI agree that we want to convert this to SHA256 eventually. But I'd say\nwe should keep such a backwards-incompatible change out of this patch\nseries and handle it as a follow-up.\n\nI'll rephrase the commit message though.\n\nPatrick\n"},{"id":"496990","messageId":"ZmlQZUXMB20PBEul@tanuki","threadId":"61621","inReplyTo":"3xu573xqbhfb3epktusqdxujal5ibkapnngiyzonae7edhu24p@fdajnz4imrbf","subject":"Re: [PATCH 19/21] t/helper: remove dependency on `the_repository` in \"oidtree\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-12T07:38:13Z","receivedAt":"2024-06-12T07:38:17Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Jun 11, 2024 at 06:27:51PM +0530, Ghanshyam Thakkar wrote:\n> On Tue, 11 Jun 2024, Patrick Steinhardt <ps@pks.im> wrote:\n> > The \"oidtree\" test helper sets up a Git repository, but this is really\n> > only used such that `get_oid_hex()` can parse both SHA1 and SHA256\n> > object hashes. The `struct oidtree` interface itself does not care at\n> > all about the object hash of `the_repository`, and always asserts that\n> > inserted object IDs have their hash algorithm set.\n> > \n> > Stop initializing the repository and instead use `get_oid_hex_any()` to\n> > parse object IDs for the \"contains\" action, like we already do when\n> > parsing the \"insert\" action.\n> \n> I think the motive of this patch is already achieved in\n> 'gt/unit-test-oidtree'[1], if this is to be merged after that.\n> \n> Thanks.\n> \n> [1]: https://github.com/git/git/commit/79d9e08db3a08c5a06e2633a39cd38b980e654f4\n> mailing list: https://lore.kernel.org/git/20240608165731.29467-1-shyamthakkar001@gmail.com/\n\nOkay. I'll make sure to evict this patch once your patch series gets\nmerged down to \"next\". Thanks for the hint.\n\nPatrick\n"},{"id":"496991","messageId":"ZmlQhSr_nCM-O7IT@tanuki","threadId":"61621","inReplyTo":"ZmjbJU1Rnnx0ggHt@tapette.crustytoothpaste.net","subject":"Re: [PATCH 19/21] t/helper: remove dependency on `the_repository` in \"oidtree\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-12T07:38:45Z","receivedAt":"2024-06-12T07:38:50Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Jun 11, 2024 at 11:17:57PM +0000, brian m. carlson wrote:\n> On 2024-06-11 at 11:59:01, Patrick Steinhardt wrote:\n> > diff --git a/t/helper/test-oidtree.c b/t/helper/test-oidtree.c\n> > index c7a1d4c642..04ec24cc84 100644\n> > --- a/t/helper/test-oidtree.c\n> > +++ b/t/helper/test-oidtree.c\n> > @@ -30,7 +27,7 @@ int cmd__oidtree(int argc UNUSED, const char **argv UNUSED)\n> >  \t\t\talgo = oid.algo;\n> >  \t\t\toidtree_insert(&ot, &oid);\n> >  \t\t} else if (skip_prefix(line.buf, \"contains \", &arg)) {\n> > -\t\t\tif (get_oid_hex(arg, &oid))\n> > +\t\t\tif (get_oid_hex_any(arg, &oid) == GIT_HASH_UNKNOWN)\n> >  \t\t\t\tdie(\"contains not a hexadecimal oid: %s\", arg);\n> \n> This is not a problem in your code, but this might read more naturally\n> as \"does not contain a hexadecimal oid\" or \"contains no hexadecimal\n> oid\".\n\nTrue. I'll leave this as-is though given that Ghanshyam is already busy\nconverting this test to be a unit test anyway, so I don't want to make\nhis life harder here.\n\nPatrick\n"},{"id":"497023","messageId":"nvvhy5jofnvke22xpwauimfk55gnoq4arl5xo6yi7uycevxkt5@gvumdjdsoatp","threadId":"61621","inReplyTo":"ZmlQQadfFyCHo_k1@tanuki","subject":"Re: [PATCH 00/21] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Ghanshyam Thakkar","fromEmail":"shyamthakkar001@gmail.com","sentAt":"2024-06-12T10:12:23Z","receivedAt":"2024-06-12T10:12:27Z","isPatch":true,"sender":{"key":"shyamthakkar001@gmail.com","avatar":"https://avatars.githubusercontent.com/u/72698233?v=4"},"body":"On Wed, 12 Jun 2024, Patrick Steinhardt <ps@pks.im> wrote:\n> On Tue, Jun 11, 2024 at 11:24:30PM +0000, brian m. carlson wrote:\n> > On 2024-06-11 at 11:57:33, Patrick Steinhardt wrote:\n> > > Hi,\n> > > \n> > > use of the `the_repository` variable is nowadays considered to be\n> > > deprecated, and over time we want to convert our codebase to stop using\n> > > it in favor of explicitly passing down the repository to functions via\n> > > parameters. This effort faces some important problems though.\n> > > \n> > >   - It is hard to prove that a certain code unit does not use\n> > >     `the_repository` anymore when sending patch series. The reviewer has\n> > >     no way to verify that it's not used anymore without reading through\n> > >     the code itself.\n> > > \n> > >   - It is easy to sneak in new usages of `the_repository` by accident\n> > >     into a code unit that is already `the_repository`-clean.\n> > > \n> > >   - There are many functions which implicitly use `the_repository`,\n> > >     which is really hard to spot.\n> > > \n> > > This patch series aims to address those problems by introducing a new\n> > > `USE_THE_REPOSITORY_VARIABLE` macro. When unset, then the declarations\n> > > of `the_repository`, `the_hash_algo` and some functions that implicitly\n> > > depend on them will be hidden away. This makes it trivial to demonstrate\n> > > that a code unit is `the_repository`-free by removing the definition of\n> > > any such macro.\n> > \n> > Overall, I left a few comments, but I think this definitely moves us in\n> > the right direction and I'm glad to see it.  This obviously improves the\n> > experience with libification and unit testing in a lot of ways, which is\n> > good.\n> > \n> > My only caution is that using the *_any functions will cause us a world\n> > of pain if we ever adopt another 256-bit hash function, since it will be\n> > ambiguous which algorithm is to be used.  That's why, traditionally, we\n> > haven't assumed a hash algorithm based on the object ID length.  I don't\n> > think the amount of uses we have is excessive, even with your changes,\n> > but we'll need to be mindful of that going forward.\n> \n> The only cases where I add new calls to `_any()` are in test helpers:\n> \n>   - \"t/helper/test-oidtree.c\". This one is getting converted to a unit\n>     test by Ghanshyam, so I'll leave it to him to improve this.\n\nYeah, I don't use '_any()', and explicitly give algo using '_algop()'.\n\nlink:https://lore.kernel.org/git/20240608165731.29467-1-shyamthakkar001@gmail.com/\n\nThanks.\n\n>   - \"t/helper/test-proc-receive.c\". Here we don't care about the actual\n>     algorithm, the only thing we care about is that we can correctly\n>     parse them and then eventually emit them via `oid_to_hex()` again.\n>     So even if we introduce a second hash function with the same length\n>     this code would continue to work alright.\n> \n> So I think it should be fine in the context of this series. But the\n> remark is certainly valid and something we should be cautious about\n> going forward.\n> \n> Thanks!\n> \n> Patrick\n\n\n"},{"id":"497057","messageId":"cover.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:21Z","receivedAt":"2024-06-13T06:13:27Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nthis is the second version of my patch series that introduce a new\n`USE_THE_REPOSITORY_VARIABLE` macro. If undefined, then declarations\nlike `the_repository`, `the_hash_algo` and a subset of functions that\nimplicitly depend on either of these are hidden away. This is a step\ntowards fully deprecating and getting rid of this global state.\n\nChanges compared to v1:\n\n  - Pull in gt/unit-test-oidtree at ed54840872 (t/: migrate\n    helper/test-oidtree.c to unit-tests/t-oidtree.c, 2024-06-08) as a\n    new dependency. I mostly did it because it makes commit 19\n    redundant, so I've it.\n\n  - As the base commit had to be rebuilt anyway I rebased on top of\n    d63586cb31 (The thirteenth batch, 2024-06-12).\n\n  - Rewrote the commit message of patch 16 to explain that this is\n    actually a bug that is getting fixed.\n\nThanks!\n\nPatrick\n\nPatrick Steinhardt (20):\n  hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions\n  hash: require hash algorithm in `hasheq()`, `hashcmp()` and\n    `hashclr()`\n  hash: require hash algorithm in `oidread()` and `oidclr()`\n  global: ensure that object IDs are always padded\n  hash: convert `oidcmp()` and `oideq()` to compare whole hash\n  hash: make `is_null_oid()` independent of `the_repository`\n  hash: require hash algorithm in `is_empty_{blob,tree}_oid()`\n  hash: require hash algorithm in `empty_tree_oid_hex()`\n  global: introduce `USE_THE_REPOSITORY_VARIABLE` macro\n  refs: avoid include cycle with \"repository.h\"\n  hash-ll: merge with \"hash.h\"\n  http-fetch: don't crash when parsing packfile without a repo\n  oidset: pass hash algorithm when parsing file\n  protocol-caps: use hash algorithm from passed-in repository\n  replace-object: use hash algorithm from passed-in repository\n  compat/fsmonitor: fix socket path in networked SHA256 repos\n  t/helper: use correct object hash in partial-clone helper\n  t/helper: fix segfault in \"oid-array\" command without repository\n  t/helper: remove dependency on `the_repository` in \"proc-receive\"\n  hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`\n\n add-interactive.c                            |   4 +-\n add-patch.c                                  |   4 +-\n apply.c                                      |   4 +-\n apply.h                                      |   2 +-\n archive-tar.c                                |   3 +\n archive-zip.c                                |   3 +\n archive.c                                    |   2 +\n attr.c                                       |   2 +\n bisect.c                                     |   2 +\n blame.c                                      |   4 +-\n bloom.c                                      |   1 +\n branch.c                                     |   2 +\n builtin.h                                    |   8 +\n builtin/am.c                                 |   8 +-\n builtin/blame.c                              |   3 +-\n builtin/fast-export.c                        |   2 +-\n builtin/fast-import.c                        |  43 ++-\n builtin/fetch-pack.c                         |   4 +-\n builtin/index-pack.c                         |  11 +-\n builtin/log.c                                |   4 +-\n builtin/merge.c                              |   7 +-\n builtin/notes.c                              |   2 +-\n builtin/pack-objects.c                       |   3 +-\n builtin/pack-redundant.c                     |  10 +-\n builtin/patch-id.c                           |   6 +-\n builtin/pull.c                               |   6 +-\n builtin/receive-pack.c                       |   4 +-\n builtin/replace.c                            |   2 +-\n builtin/rm.c                                 |   2 +-\n builtin/tag.c                                |   2 +-\n builtin/unpack-objects.c                     |   9 +-\n builtin/update-ref.c                         |   8 +-\n bulk-checkin.c                               |   3 +\n bundle-uri.c                                 |   2 +\n bundle.c                                     |   2 +\n cache-tree.c                                 |   7 +-\n checkout.c                                   |   2 +\n checkout.h                                   |   2 +-\n chunk-format.c                               |   2 +\n chunk-format.h                               |   2 +-\n combine-diff.c                               |   2 +\n commit-graph.c                               |  22 +-\n commit-graph.h                               |   2 +\n commit-reach.c                               |   2 +\n commit.c                                     |   2 +\n common-main.c                                |   2 +\n compat/fsmonitor/fsm-ipc-darwin.c            |   7 +-\n compat/sha1-chunked.c                        |   2 +-\n compat/win32/trace2_win32_process_info.c     |   2 +\n config.c                                     |   3 +\n connected.c                                  |   2 +\n convert.c                                    |   2 +\n convert.h                                    |   2 +-\n csum-file.c                                  |   9 +-\n csum-file.h                                  |   2 +-\n delta-islands.c                              |   2 +\n diagnose.c                                   |   2 +\n diff-lib.c                                   |   7 +-\n diff.c                                       |   9 +-\n diff.h                                       |   2 +-\n diffcore-break.c                             |   3 +\n diffcore-rename.c                            |   7 +-\n diffcore.h                                   |   2 +-\n dir.c                                        |   9 +-\n dir.h                                        |   2 +-\n entry.c                                      |   2 +\n environment.c                                |   3 +\n fetch-pack.c                                 |   2 +\n fmt-merge-msg.c                              |   2 +\n fsck.c                                       |   5 +-\n fsmonitor-ipc.c                              |   2 +\n git.c                                        |   2 +\n hash-ll.h                                    | 310 ----------------\n hash-lookup.c                                |   5 +-\n hash.h                                       | 366 ++++++++++++++++---\n help.c                                       |   2 +\n hex.c                                        |   8 +-\n hex.h                                        |  28 +-\n http-backend.c                               |   2 +\n http-fetch.c                                 |   8 +-\n http-push.c                                  |   5 +-\n http-walker.c                                |   6 +-\n http.c                                       |   2 +\n list-objects-filter-options.c                |   2 +\n list-objects-filter.c                        |   2 +\n list-objects.c                               |   2 +\n log-tree.c                                   |   2 +\n loose.c                                      |   2 +\n loose.h                                      |   2 +\n ls-refs.c                                    |   2 +\n mailmap.c                                    |   2 +\n match-trees.c                                |   6 +-\n merge-blobs.c                                |   2 +\n merge-ort.c                                  |   2 +\n merge-ort.h                                  |   2 +-\n merge-recursive.c                            |   3 +\n merge.c                                      |   2 +\n midx-write.c                                 |   2 +\n midx.c                                       |   5 +-\n negotiator/default.c                         |   2 +\n negotiator/skipping.c                        |   2 +\n notes-cache.c                                |   2 +\n notes-merge.c                                |   8 +-\n notes-utils.c                                |   2 +\n notes.c                                      |  14 +-\n object-file-convert.c                        |   6 +-\n object-file.c                                |  19 +-\n object-name.c                                |   2 +\n object.c                                     |   2 +\n object.h                                     |   2 +-\n oid-array.c                                  |   2 +\n oidmap.h                                     |   2 +-\n oidset.c                                     |   8 +-\n oidset.h                                     |   4 +-\n oidtree.c                                    |   4 +-\n oidtree.h                                    |   2 +-\n oss-fuzz/fuzz-commit-graph.c                 |   2 +\n pack-bitmap-write.c                          |   6 +-\n pack-bitmap.c                                |   5 +-\n pack-check.c                                 |   7 +-\n pack-revindex.c                              |   2 +\n pack-write.c                                 |   5 +-\n packfile.c                                   |  20 +-\n packfile.h                                   |   2 +\n parallel-checkout.c                          |   8 +-\n parse-options-cb.c                           |   2 +\n path.c                                       |   3 +\n pathspec.c                                   |   2 +\n pretty.c                                     |   2 +\n progress.c                                   |   2 +\n promisor-remote.c                            |   2 +\n protocol-caps.c                              |   5 +-\n range-diff.c                                 |   2 +\n reachable.c                                  |   2 +\n read-cache-ll.h                              |   2 +-\n read-cache.c                                 |  21 +-\n rebase-interactive.c                         |   2 +\n ref-filter.c                                 |   2 +\n reflog-walk.c                                |   2 +\n reflog.c                                     |   2 +\n refs.c                                       |   8 +-\n refs.h                                       |   8 +-\n refs/files-backend.c                         |   8 +-\n refs/packed-backend.c                        |   8 +-\n refs/ref-cache.h                             |   2 +-\n refs/reftable-backend.c                      |  39 +-\n refspec.c                                    |   2 +\n reftable/dump.c                              |   2 +-\n reftable/reftable-record.h                   |   2 +-\n reftable/system.h                            |   2 +-\n remote-curl.c                                |   2 +\n remote.c                                     |  10 +-\n remote.h                                     |   2 +-\n replace-object.c                             |   2 +-\n repository.h                                 |   9 +-\n rerere.c                                     |   2 +\n reset.c                                      |   2 +\n reset.h                                      |   2 +-\n resolve-undo.c                               |   5 +-\n resolve-undo.h                               |   2 +-\n revision.c                                   |   2 +\n run-command.c                                |   2 +\n scalar.c                                     |   2 +\n send-pack.c                                  |   2 +\n sequencer.c                                  |   8 +-\n serve.c                                      |   4 +-\n server-info.c                                |   2 +\n setup.c                                      |   2 +\n shallow.c                                    |   2 +\n split-index.c                                |   4 +-\n split-index.h                                |   2 +-\n streaming.c                                  |   3 +\n submodule-config.c                           |   4 +-\n submodule.c                                  |   8 +-\n t/helper/test-bitmap.c                       |   2 +\n t/helper/test-bloom.c                        |   2 +\n t/helper/test-cache-tree.c                   |   2 +\n t/helper/test-dump-cache-tree.c              |   2 +\n t/helper/test-dump-fsmonitor.c               |   2 +\n t/helper/test-dump-split-index.c             |   2 +\n t/helper/test-dump-untracked-cache.c         |   2 +\n t/helper/test-find-pack.c                    |   2 +\n t/helper/test-fsmonitor-client.c             |   2 +\n t/helper/test-hash-speed.c                   |   2 +-\n t/helper/test-lazy-init-name-hash.c          |   2 +\n t/helper/test-match-trees.c                  |   2 +\n t/helper/test-oid-array.c                    |   4 +\n t/helper/test-oidmap.c                       |   2 +\n t/helper/test-pack-mtimes.c                  |   2 +\n t/helper/test-partial-clone.c                |   2 +-\n t/helper/test-proc-receive.c                 |   9 +-\n t/helper/test-reach.c                        |   2 +\n t/helper/test-read-cache.c                   |   2 +\n t/helper/test-read-graph.c                   |   2 +\n t/helper/test-read-midx.c                    |   2 +\n t/helper/test-ref-store.c                    |   2 +\n t/helper/test-repository.c                   |   2 +\n t/helper/test-revision-walking.c             |   2 +\n t/helper/test-scrap-cache-tree.c             |   2 +\n t/helper/test-sha1.c                         |   2 +-\n t/helper/test-sha256.c                       |   2 +-\n t/helper/test-submodule-config.c             |   4 +-\n t/helper/test-submodule-nested-repo-config.c |   2 +\n t/helper/test-submodule.c                    |   2 +\n t/helper/test-trace2.c                       |   2 +\n t/helper/test-write-cache.c                  |   2 +\n t/t0064-oid-array.sh                         |  18 +\n t/t5550-http-fetch-dumb.sh                   |   6 +\n t/test-lib-functions.sh                      |   5 +\n t/unit-tests/lib-oid.h                       |   2 +-\n t/unit-tests/t-example-decorate.c            |   2 +\n tag.c                                        |   2 +\n tmp-objdir.c                                 |   2 +\n transport-helper.c                           |   2 +\n transport.c                                  |   2 +\n tree-diff.c                                  |   1 +\n tree-walk.c                                  |   6 +-\n tree-walk.h                                  |   2 +-\n tree.c                                       |   2 +\n unpack-trees.c                               |   2 +\n upload-pack.c                                |   2 +\n walker.c                                     |   2 +\n worktree.c                                   |   2 +\n wt-status.c                                  |   6 +-\n xdiff-interface.c                            |   2 +\n xdiff-interface.h                            |   2 +-\n 226 files changed, 994 insertions(+), 617 deletions(-)\n delete mode 100644 hash-ll.h\n\nRange-diff against v1:\n 1:  f839013744 =  1:  d2154e8c45 hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions\n 2:  687ad9fc02 =  2:  aa468c3d88 hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()`\n 3:  346ca76a7c =  3:  403ea4485b hash: require hash algorithm in `oidread()` and `oidclr()`\n 4:  3ff28f313b =  4:  fa263d6b07 global: ensure that object IDs are always padded\n 5:  e2a0f2125d =  5:  a7df209bda hash: convert `oidcmp()` and `oideq()` to compare whole hash\n 6:  3b6ce3b26c =  6:  9058837c93 hash: make `is_null_oid()` independent of `the_repository`\n 7:  82a391acac =  7:  d26584dc8f hash: require hash algorithm in `is_empty_{blob,tree}_oid()`\n 8:  3f091dd94a =  8:  4858cca25f hash: require hash algorithm in `empty_tree_oid_hex()`\n 9:  479bebdf53 !  9:  cb3694ad0e global: introduce `USE_THE_REPOSITORY_VARIABLE` macro\n    @@ t/helper/test-dump-untracked-cache.c\n      #include \"dir.h\"\n      #include \"hex.h\"\n     \n    - ## t/helper/test-example-decorate.c ##\n    -@@\n    -+#define USE_THE_REPOSITORY_VARIABLE\n    -+\n    - #include \"test-tool.h\"\n    - #include \"git-compat-util.h\"\n    - #include \"object.h\"\n    -\n      ## t/helper/test-find-pack.c ##\n     @@\n     +#define USE_THE_REPOSITORY_VARIABLE\n    @@ t/helper/test-write-cache.c\n      #include \"lockfile.h\"\n      #include \"read-cache-ll.h\"\n     \n    + ## t/unit-tests/t-example-decorate.c ##\n    +@@\n    ++#define USE_THE_REPOSITORY_VARIABLE\n    ++\n    + #include \"test-lib.h\"\n    + #include \"object.h\"\n    + #include \"decorate.h\"\n    +\n      ## tag.c ##\n     @@\n     +#define USE_THE_REPOSITORY_VARIABLE\n10:  7e718c967a = 10:  4492548209 refs: avoid include cycle with \"repository.h\"\n11:  fb7544181a ! 11:  f3cbc4b9f9 hash-ll: merge with \"hash.h\"\n    @@ t/helper/test-sha256.c\n      int cmd__sha256(int ac, const char **av)\n      {\n     \n    + ## t/unit-tests/lib-oid.h ##\n    +@@\n    + #ifndef LIB_OID_H\n    + #define LIB_OID_H\n    + \n    +-#include \"hash-ll.h\"\n    ++#include \"hash.h\"\n    + \n    + /*\n    +  * Convert arbitrary hex string to object_id.\n    +\n      ## tree-diff.c ##\n     @@\n      #include \"tree.h\"\n12:  b47fa99f3d = 12:  9178098dd7 http-fetch: don't crash when parsing packfile without a repo\n13:  95d9b5fa3e = 13:  0b4436c32b oidset: pass hash algorithm when parsing file\n14:  c877d48f7d = 14:  c7abfbc489 protocol-caps: use hash algorithm from passed-in repository\n15:  ca5f4056fb = 15:  9ae4fdb8f1 replace-object: use hash algorithm from passed-in repository\n16:  d4e87f9d6b ! 16:  3ceb726655 compat/fsmonitor: remove dependency on `the_repository` in Darwin IPC\n    @@ Metadata\n     Author: Patrick Steinhardt <ps@pks.im>\n     \n      ## Commit message ##\n    -    compat/fsmonitor: remove dependency on `the_repository` in Darwin IPC\n    +    compat/fsmonitor: fix socket path in networked SHA256 repos\n     \n         The IPC socket used by the fsmonitor on Darwin is usually contained in\n         the Git repository itself. When the repository is hosted on a networked\n    @@ Commit message\n         directory or the socket directory. In that case, we derive the path by\n         hashing the repository path.\n     \n    -    The hashing implicitly depends on `the_repository` though via\n    -    `hash_to_hex()`. For one, this is wrong because we really should be\n    -    using the passed-in repository. But arguably, it is not sensible to\n    -    derive the path hash from the repository's object hash in the first\n    -    place -- they don't have anything to do with each other, and a\n    -    repository that is hosted in the same path should always derive the same\n    -    IPC socket path.\n    +    But while we always use SHA1 to hash the repository path, we then end up\n    +    using `hash_to_hex()` to append the computed hash to the socket path.\n    +    This is wrong because `hash_to_hex()` uses the hash algorithm configured\n    +    in `the_repository`, which may not be SHA1. The consequence is that we\n    +    may append uninitialized bytes to the path when operating in a SHA256\n    +    repository.\n     \n    -    Fix this by unconditionally using SHA1 to derive the path.\n    +    Fix this bug by using `hash_to_hex_algop()` with SHA1.\n     \n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n      ## compat/fsmonitor/fsm-ipc-darwin.c ##\n    +@@ compat/fsmonitor/fsm-ipc-darwin.c: const char *fsmonitor_ipc__get_path(struct repository *r)\n    + \tgit_SHA_CTX sha1ctx;\n    + \tchar *sock_dir = NULL;\n    + \tstruct strbuf ipc_file = STRBUF_INIT;\n    +-\tunsigned char hash[GIT_MAX_RAWSZ];\n    ++\tunsigned char hash[GIT_SHA1_RAWSZ];\n    + \n    + \tif (!r)\n    + \t\tBUG(\"No repository passed into fsmonitor_ipc__get_path\");\n     @@ compat/fsmonitor/fsm-ipc-darwin.c: const char *fsmonitor_ipc__get_path(struct repository *r)\n      \t/* Create the socket file in either socketDir or $HOME */\n      \tif (sock_dir && *sock_dir) {\n17:  5310883469 = 17:  74e5489bd0 t/helper: use correct object hash in partial-clone helper\n18:  2774b8500f = 18:  470aea1fc8 t/helper: fix segfault in \"oid-array\" command without repository\n19:  339d668da8 <  -:  ---------- t/helper: remove dependency on `the_repository` in \"oidtree\"\n20:  97fa3051fa = 19:  1f0682fc7d t/helper: remove dependency on `the_repository` in \"proc-receive\"\n21:  92c7f542d2 = 20:  16fb86c2b2 hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497058","messageId":"d2154e8c4517cbe7c981184f911bdfd06a593cee.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 01/20] hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:26Z","receivedAt":"2024-06-13T06:13:31Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The functions `is_empty_{blob,tree}_sha1()` are mostly unused, except\nfor a single callsite in \"read-cache.c\". Most callsites have long since\nbeen converted to use the equivalents that accept a `struct object_id`\ninstead of a string.\n\nAdapt the remaining callsite and drop those functions.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash.h       | 10 ----------\n read-cache.c |  2 +-\n 2 files changed, 1 insertion(+), 11 deletions(-)\n\ndiff --git a/hash.h b/hash.h\nindex e064807c17..a1161e1b22 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -84,21 +84,11 @@ static inline void oidread(struct object_id *oid, const unsigned char *hash)\n \toidread_algop(oid, hash, the_hash_algo);\n }\n \n-static inline int is_empty_blob_sha1(const unsigned char *sha1)\n-{\n-\treturn hasheq(sha1, the_hash_algo->empty_blob->hash);\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\n }\n \n-static inline int is_empty_tree_sha1(const unsigned char *sha1)\n-{\n-\treturn hasheq(sha1, the_hash_algo->empty_tree->hash);\n-}\n-\n static inline int is_empty_tree_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_tree);\ndiff --git a/read-cache.c b/read-cache.c\nindex 447109aa76..10e002ce6d 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -337,7 +337,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)\n \n \t/* Racily smudged entry? */\n \tif (!ce->ce_stat_data.sd_size) {\n-\t\tif (!is_empty_blob_sha1(ce->oid.hash))\n+\t\tif (!is_empty_blob_oid(&ce->oid))\n \t\t\tchanged |= DATA_CHANGED;\n \t}\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497059","messageId":"aa468c3d88eb673343b934d3c8e7fe991d15ba2f.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 02/20] hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:31Z","receivedAt":"2024-06-13T06:13:35Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Many of our hash functions have two variants, one receiving a `struct\ngit_hash_algo` and one that derives it via `the_repository`. Adapt all\nof those functions to always require the hash algorithm as input and\ndrop the variants that do not accept one.\n\nAs those functions are now independent of `the_repository`, we can move\nthem from \"hash.h\" to \"hash-ll.h\".\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/index-pack.c     |  6 +++---\n builtin/pack-redundant.c |  8 +++++---\n builtin/unpack-objects.c |  3 ++-\n commit-graph.c           |  3 ++-\n csum-file.c              |  6 +++---\n hash-ll.h                | 15 +++++++++++++--\n hash-lookup.c            |  3 ++-\n hash.h                   | 24 ++----------------------\n http-walker.c            |  2 +-\n match-trees.c            |  2 +-\n notes.c                  |  2 +-\n pack-bitmap-write.c      |  4 ++--\n pack-bitmap.c            |  3 ++-\n pack-check.c             |  5 +++--\n pack-write.c             |  3 ++-\n packfile.c               |  8 ++++----\n read-cache.c             |  8 ++++----\n 17 files changed, 52 insertions(+), 53 deletions(-)\n\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex 856428fef9..ea727fba16 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -1204,7 +1204,7 @@ static void parse_pack_objects(unsigned char *hash)\n \tthe_hash_algo->init_fn(&tmp_ctx);\n \tthe_hash_algo->clone_fn(&tmp_ctx, &input_ctx);\n \tthe_hash_algo->final_fn(hash, &tmp_ctx);\n-\tif (!hasheq(fill(the_hash_algo->rawsz), hash))\n+\tif (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo))\n \t\tdie(_(\"pack is corrupted (SHA1 mismatch)\"));\n \tuse(the_hash_algo->rawsz);\n \n@@ -1307,11 +1307,11 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha\n \t\tstop_progress_msg(&progress, msg.buf);\n \t\tstrbuf_release(&msg);\n \t\tfinalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0);\n-\t\thashcpy(read_hash, pack_hash);\n+\t\thashcpy(read_hash, pack_hash, the_repository->hash_algo);\n \t\tfixup_pack_header_footer(output_fd, pack_hash,\n \t\t\t\t\t curr_pack, nr_objects,\n \t\t\t\t\t read_hash, consumed_bytes-the_hash_algo->rawsz);\n-\t\tif (!hasheq(read_hash, tail_hash))\n+\t\tif (!hasheq(read_hash, tail_hash, the_repository->hash_algo))\n \t\t\tdie(_(\"Unexpected tail checksum for %s \"\n \t\t\t      \"(disk corruption?)\"), curr_pack);\n \t}\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 4c735ba069..103c11b9d3 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -155,7 +155,7 @@ static inline struct llist_item * llist_sorted_remove(struct llist *list, const\n \tl = (hint == NULL) ? list->front : hint;\n \tprev = NULL;\n \twhile (l) {\n-\t\tconst int cmp = hashcmp(l->oid.hash, oid);\n+\t\tconst int cmp = hashcmp(l->oid.hash, oid, the_repository->hash_algo);\n \t\tif (cmp > 0) /* not in list, since sorted */\n \t\t\treturn prev;\n \t\tif (!cmp) { /* found */\n@@ -258,7 +258,8 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)\n \twhile (p1_off < p1->pack->num_objects * p1_step &&\n \t       p2_off < p2->pack->num_objects * p2_step)\n \t{\n-\t\tconst int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);\n+\t\tconst int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,\n+\t\t\t\t\tthe_repository->hash_algo);\n \t\t/* cmp ~ p1 - p2 */\n \t\tif (cmp == 0) {\n \t\t\tp1_hint = llist_sorted_remove(p1->unique_objects,\n@@ -296,7 +297,8 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)\n \twhile (p1_off < p1->num_objects * p1_step &&\n \t       p2_off < p2->num_objects * p2_step)\n \t{\n-\t\tint cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);\n+\t\tint cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,\n+\t\t\t\t  the_repository->hash_algo);\n \t\t/* cmp ~ p1 - p2 */\n \t\tif (cmp == 0) {\n \t\t\tret++;\ndiff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c\nindex f1c85a00ae..0855572c27 100644\n--- a/builtin/unpack-objects.c\n+++ b/builtin/unpack-objects.c\n@@ -674,7 +674,8 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)\n \t\tif (fsck_finish(&fsck_options))\n \t\t\tdie(_(\"fsck error in pack objects\"));\n \t}\n-\tif (!hasheq(fill(the_hash_algo->rawsz), oid.hash))\n+\tif (!hasheq(fill(the_hash_algo->rawsz), oid.hash,\n+\t\t    the_repository->hash_algo))\n \t\tdie(\"final sha1 did not match\");\n \tuse(the_hash_algo->rawsz);\n \ndiff --git a/commit-graph.c b/commit-graph.c\nindex e5dd3553df..3429156b28 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -565,7 +565,8 @@ static int add_graph_to_chain(struct commit_graph *g,\n \n \t\tif (!cur_g ||\n \t\t    !oideq(&oids[n], &cur_g->oid) ||\n-\t\t    !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n))) {\n+\t\t    !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n),\n+\t\t\t    the_repository->hash_algo)) {\n \t\t\twarning(_(\"commit-graph chain does not match\"));\n \t\t\treturn 0;\n \t\t}\ndiff --git a/csum-file.c b/csum-file.c\nindex 870748e016..f4be0804b7 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -68,12 +68,12 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result,\n \thashflush(f);\n \n \tif (f->skip_hash)\n-\t\thashclr(f->buffer);\n+\t\thashclr(f->buffer, the_repository->hash_algo);\n \telse\n \t\tthe_hash_algo->final_fn(f->buffer, &f->ctx);\n \n \tif (result)\n-\t\thashcpy(result, f->buffer);\n+\t\thashcpy(result, f->buffer, the_repository->hash_algo);\n \tif (flags & CSUM_HASH_IN_STREAM)\n \t\tflush(f, f->buffer, the_hash_algo->rawsz);\n \tif (flags & CSUM_FSYNC)\n@@ -237,5 +237,5 @@ int hashfile_checksum_valid(const unsigned char *data, size_t total_len)\n \tthe_hash_algo->update_fn(&ctx, data, data_len);\n \tthe_hash_algo->final_fn(got, &ctx);\n \n-\treturn hasheq(got, data + data_len);\n+\treturn hasheq(got, data + data_len, the_repository->hash_algo);\n }\ndiff --git a/hash-ll.h b/hash-ll.h\nindex 2cfde63ae1..fabdd8ecc7 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -245,7 +245,7 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n \n const struct object_id *null_oid(void);\n \n-static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n {\n \t/*\n \t * Teach the compiler that there are only two possibilities of hash size\n@@ -256,7 +256,7 @@ static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *\n \treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n }\n \n-static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n {\n \t/*\n \t * We write this here instead of deferring to hashcmp so that the\n@@ -267,6 +267,17 @@ static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *s\n \treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n }\n \n+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(sha_dst, sha_src, algop->rawsz);\n+}\n+\n+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n+{\n+\tmemset(hash, 0, algop->rawsz);\n+}\n+\n static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n {\n \tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\ndiff --git a/hash-lookup.c b/hash-lookup.c\nindex 9f0f95e2b9..9aa6b82eb7 100644\n--- a/hash-lookup.c\n+++ b/hash-lookup.c\n@@ -112,7 +112,8 @@ int bsearch_hash(const unsigned char *hash, const uint32_t *fanout_nbo,\n \n \twhile (lo < hi) {\n \t\tunsigned mi = lo + (hi - lo) / 2;\n-\t\tint cmp = hashcmp(table + mi * stride, hash);\n+\t\tint cmp = hashcmp(table + mi * stride, hash,\n+\t\t\t\t  the_repository->hash_algo);\n \n \t\tif (!cmp) {\n \t\t\tif (result)\ndiff --git a/hash.h b/hash.h\nindex a1161e1b22..714938e2eb 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,11 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)\n-{\n-\treturn hashcmp_algop(sha1, sha2, the_hash_algo);\n-}\n-\n static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n {\n \tconst struct git_hash_algo *algop;\n@@ -18,12 +13,7 @@ static inline int oidcmp(const struct object_id *oid1, const struct object_id *o\n \t\talgop = the_hash_algo;\n \telse\n \t\talgop = &hash_algos[oid1->algo];\n-\treturn hashcmp_algop(oid1->hash, oid2->hash, algop);\n-}\n-\n-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2)\n-{\n-\treturn hasheq_algop(sha1, sha2, the_hash_algo);\n+\treturn hashcmp(oid1->hash, oid2->hash, algop);\n }\n \n static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n@@ -33,7 +23,7 @@ static inline int oideq(const struct object_id *oid1, const struct object_id *oi\n \t\talgop = the_hash_algo;\n \telse\n \t\talgop = &hash_algos[oid1->algo];\n-\treturn hasheq_algop(oid1->hash, oid2->hash, algop);\n+\treturn hasheq(oid1->hash, oid2->hash, algop);\n }\n \n static inline int is_null_oid(const struct object_id *oid)\n@@ -41,11 +31,6 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn oideq(oid, null_oid());\n }\n \n-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)\n-{\n-\tmemcpy(sha_dst, sha_src, the_hash_algo->rawsz);\n-}\n-\n /* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */\n static inline void oidcpy_with_padding(struct object_id *dst,\n \t\t\t\t       const struct object_id *src)\n@@ -62,11 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,\n \tdst->algo = src->algo;\n }\n \n-static inline void hashclr(unsigned char *hash)\n-{\n-\tmemset(hash, 0, the_hash_algo->rawsz);\n-}\n-\n static inline void oidclr(struct object_id *oid)\n {\n \tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\ndiff --git a/http-walker.c b/http-walker.c\nindex b395ef1327..cf7f8c82bc 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -485,7 +485,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)\n \n \tlist_for_each(pos, head) {\n \t\tobj_req = list_entry(pos, struct object_request, node);\n-\t\tif (hasheq(obj_req->oid.hash, hash))\n+\t\tif (hasheq(obj_req->oid.hash, hash, the_repository->hash_algo))\n \t\t\tbreak;\n \t}\n \tif (!obj_req)\ndiff --git a/match-trees.c b/match-trees.c\nindex 3412b6a140..849b391d3d 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -237,7 +237,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,\n \t} else {\n \t\trewrite_with = oid2;\n \t}\n-\thashcpy(rewrite_here, rewrite_with->hash);\n+\thashcpy(rewrite_here, rewrite_with->hash, the_repository->hash_algo);\n \tstatus = write_object_file(buf, sz, OBJ_TREE, result);\n \tfree(buf);\n \treturn status;\ndiff --git a/notes.c b/notes.c\nindex 53ca25c814..5296fd863f 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -149,7 +149,7 @@ static struct leaf_node *note_tree_find(struct notes_tree *t,\n \tvoid **p = note_tree_search(t, &tree, &n, key_sha1);\n \tif (GET_PTR_TYPE(*p) == PTR_TYPE_NOTE) {\n \t\tstruct leaf_node *l = (struct leaf_node *) CLR_PTR_TYPE(*p);\n-\t\tif (hasheq(key_sha1, l->key_oid.hash))\n+\t\tif (hasheq(key_sha1, l->key_oid.hash, the_repository->hash_algo))\n \t\t\treturn l;\n \t}\n \treturn NULL;\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 6cae670412..59d2e3a387 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -790,7 +790,7 @@ static void write_hash_cache(struct hashfile *f,\n void bitmap_writer_set_checksum(struct bitmap_writer *writer,\n \t\t\t\tconst unsigned char *sha1)\n {\n-\thashcpy(writer->pack_checksum, sha1);\n+\thashcpy(writer->pack_checksum, sha1, the_repository->hash_algo);\n }\n \n void bitmap_writer_finish(struct bitmap_writer *writer,\n@@ -816,7 +816,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,\n \theader.version = htons(default_version);\n \theader.options = htons(flags | options);\n \theader.entry_count = htonl(writer->selected_nr);\n-\thashcpy(header.checksum, writer->pack_checksum);\n+\thashcpy(header.checksum, writer->pack_checksum, the_repository->hash_algo);\n \n \thashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz);\n \tdump_bitmap(f, writer->commits);\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex fe8e8a51d3..184d28f05c 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -367,7 +367,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,\n \tif (load_bitmap_header(bitmap_git) < 0)\n \t\tgoto cleanup;\n \n-\tif (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum)) {\n+\tif (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum,\n+\t\t    the_repository->hash_algo)) {\n \t\terror(_(\"checksum doesn't match in MIDX and bitmap\"));\n \t\tgoto cleanup;\n \t}\ndiff --git a/pack-check.c b/pack-check.c\nindex 25104d5b14..288f5a3479 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -78,10 +78,11 @@ static int verify_packfile(struct repository *r,\n \t} while (offset < pack_sig_ofs);\n \tr->hash_algo->final_fn(hash, &ctx);\n \tpack_sig = use_pack(p, w_curs, pack_sig_ofs, NULL);\n-\tif (!hasheq(hash, pack_sig))\n+\tif (!hasheq(hash, pack_sig, r->hash_algo))\n \t\terr = error(\"%s pack checksum mismatch\",\n \t\t\t    p->pack_name);\n-\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig))\n+\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig,\n+\t\t    r->hash_algo))\n \t\terr = error(\"%s pack checksum does not match its index\",\n \t\t\t    p->pack_name);\n \tunuse_pack(w_curs);\ndiff --git a/pack-write.c b/pack-write.c\nindex 80ecfa544c..eef625fa5b 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -428,7 +428,8 @@ void fixup_pack_header_footer(int pack_fd,\n \t\tif (partial_pack_offset == 0) {\n \t\t\tunsigned char hash[GIT_MAX_RAWSZ];\n \t\t\tthe_hash_algo->final_fn(hash, &old_hash_ctx);\n-\t\t\tif (!hasheq(hash, partial_pack_hash))\n+\t\t\tif (!hasheq(hash, partial_pack_hash,\n+\t\t\t\t    the_repository->hash_algo))\n \t\t\t\tdie(\"Unexpected checksum for %s \"\n \t\t\t\t    \"(disk corruption?)\", pack_name);\n \t\t\t/*\ndiff --git a/packfile.c b/packfile.c\nindex d4df7fdeea..9156e9122c 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -242,7 +242,7 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)\n \tstruct packed_git *p = alloc_packed_git(alloc);\n \n \tmemcpy(p->pack_name, path, alloc); /* includes NUL */\n-\thashcpy(p->hash, sha1);\n+\thashcpy(p->hash, sha1, the_repository->hash_algo);\n \tif (check_packed_git_idx(idx_path, p)) {\n \t\tfree(p);\n \t\treturn NULL;\n@@ -596,7 +596,7 @@ static int open_packed_git_1(struct packed_git *p)\n \tif (read_result != hashsz)\n \t\treturn error(\"packfile %s signature is unavailable\", p->pack_name);\n \tidx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;\n-\tif (!hasheq(hash, idx_hash))\n+\tif (!hasheq(hash, idx_hash, the_repository->hash_algo))\n \t\treturn error(\"packfile %s does not match index\", p->pack_name);\n \treturn 0;\n }\n@@ -751,7 +751,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n \tp->mtime = st.st_mtime;\n \tif (path_len < the_hash_algo->hexsz ||\n \t    get_hash_hex(path + path_len - the_hash_algo->hexsz, p->hash))\n-\t\thashclr(p->hash);\n+\t\thashclr(p->hash, the_repository->hash_algo);\n \treturn p;\n }\n \n@@ -1971,7 +1971,7 @@ off_t find_pack_entry_one(const unsigned char *sha1,\n \t\t\treturn 0;\n \t}\n \n-\thashcpy(oid.hash, sha1);\n+\thashcpy(oid.hash, sha1, the_repository->hash_algo);\n \tif (bsearch_pack(&oid, p, &result))\n \t\treturn nth_packed_object_offset(p, result);\n \treturn 0;\ndiff --git a/read-cache.c b/read-cache.c\nindex 10e002ce6d..2642ac9558 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1735,7 +1735,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)\n \tthe_hash_algo->init_fn(&c);\n \tthe_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz);\n \tthe_hash_algo->final_fn(hash, &c);\n-\tif (!hasheq(hash, start))\n+\tif (!hasheq(hash, start, the_repository->hash_algo))\n \t\treturn error(_(\"bad index file sha1 signature\"));\n \treturn 0;\n }\n@@ -2641,7 +2641,7 @@ static void copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,\n \tondisk->uid  = htonl(ce->ce_stat_data.sd_uid);\n \tondisk->gid  = htonl(ce->ce_stat_data.sd_gid);\n \tondisk->size = htonl(ce->ce_stat_data.sd_size);\n-\thashcpy(ondisk->data, ce->oid.hash);\n+\thashcpy(ondisk->data, ce->oid.hash, the_repository->hash_algo);\n \n \tflags = ce->ce_flags & ~CE_NAMEMASK;\n \tflags |= (ce_namelen(ce) >= CE_NAMEMASK ? CE_NAMEMASK : ce_namelen(ce));\n@@ -2730,7 +2730,7 @@ static int verify_index_from(const struct index_state *istate, const char *path)\n \tif (n != the_hash_algo->rawsz)\n \t\tgoto out;\n \n-\tif (!hasheq(istate->oid.hash, hash))\n+\tif (!hasheq(istate->oid.hash, hash, the_repository->hash_algo))\n \t\tgoto out;\n \n \tclose(fd);\n@@ -3603,7 +3603,7 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size)\n \t\tsrc_offset += extsize;\n \t}\n \tthe_hash_algo->final_fn(hash, &c);\n-\tif (!hasheq(hash, (const unsigned char *)index))\n+\tif (!hasheq(hash, (const unsigned char *)index, the_repository->hash_algo))\n \t\treturn 0;\n \n \t/* Validate that the extension offsets returned us back to the eoie extension. */\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497060","messageId":"403ea4485b3aef6f0160f968336cc4d7db9f6dad.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 03/20] hash: require hash algorithm in `oidread()` and `oidclr()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:36Z","receivedAt":"2024-06-13T06:13:41Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both `oidread()` and `oidclr()` use `the_repository` to derive the hash\nfunction that shall be used. Require callers to pass in the hash\nalgorithm to get rid of this implicit dependency.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n apply.c                          |  2 +-\n blame.c                          |  2 +-\n builtin/am.c                     |  8 +++----\n builtin/fast-export.c            |  2 +-\n builtin/fast-import.c            | 39 +++++++++++++++++---------------\n builtin/fetch-pack.c             |  4 ++--\n builtin/index-pack.c             |  5 ++--\n builtin/log.c                    |  2 +-\n builtin/merge.c                  |  4 ++--\n builtin/notes.c                  |  2 +-\n builtin/pack-objects.c           |  3 ++-\n builtin/pack-redundant.c         |  2 +-\n builtin/patch-id.c               |  6 ++---\n builtin/pull.c                   |  6 ++---\n builtin/receive-pack.c           |  2 +-\n builtin/replace.c                |  2 +-\n builtin/rm.c                     |  2 +-\n builtin/tag.c                    |  2 +-\n builtin/unpack-objects.c         |  6 ++---\n builtin/update-ref.c             |  8 +++----\n cache-tree.c                     |  3 ++-\n commit-graph.c                   | 17 +++++++++-----\n diff-lib.c                       |  4 ++--\n diff.c                           |  6 ++---\n dir.c                            |  6 ++---\n hash-ll.h                        | 14 ++++++++++++\n hash.h                           | 17 --------------\n http-push.c                      |  2 +-\n http-walker.c                    |  2 +-\n match-trees.c                    |  2 +-\n midx.c                           |  3 ++-\n notes-merge.c                    |  6 ++---\n notes.c                          |  8 +++----\n object-file-convert.c            |  2 +-\n object-file.c                    |  4 ++--\n packfile.c                       | 10 ++++----\n read-cache.c                     |  8 ++++---\n refs.c                           |  6 ++---\n refs/files-backend.c             |  6 ++---\n refs/packed-backend.c            |  6 ++---\n refs/reftable-backend.c          | 37 ++++++++++++++++++------------\n remote.c                         |  8 +++----\n resolve-undo.c                   |  3 ++-\n sequencer.c                      |  4 ++--\n split-index.c                    |  2 +-\n submodule-config.c               |  2 +-\n t/helper/test-submodule-config.c |  2 +-\n tree-walk.c                      |  4 ++--\n 48 files changed, 163 insertions(+), 140 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 901b67e625..528939abb6 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -3680,7 +3680,7 @@ static int try_threeway(struct apply_state *state,\n \tif (status) {\n \t\tpatch->conflicted_threeway = 1;\n \t\tif (patch->is_new)\n-\t\t\toidclr(&patch->threeway_stage[0]);\n+\t\t\toidclr(&patch->threeway_stage[0], the_repository->hash_algo);\n \t\telse\n \t\t\toidcpy(&patch->threeway_stage[0], &pre_oid);\n \t\toidcpy(&patch->threeway_stage[1], &our_oid);\ndiff --git a/blame.c b/blame.c\nindex 33586b9777..a80f5e2e61 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -1246,7 +1246,7 @@ static int fill_blob_sha1_and_mode(struct repository *r,\n \t\tgoto error_out;\n \treturn 0;\n  error_out:\n-\toidclr(&origin->blob_oid);\n+\toidclr(&origin->blob_oid, the_repository->hash_algo);\n \torigin->mode = S_IFINVALID;\n \treturn -1;\n }\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 36839029d2..45c305ec86 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -408,7 +408,7 @@ static void am_load(struct am_state *state)\n \tread_commit_msg(state);\n \n \tif (read_state_file(&sb, state, \"original-commit\", 1) < 0)\n-\t\toidclr(&state->orig_commit);\n+\t\toidclr(&state->orig_commit, the_repository->hash_algo);\n \telse if (get_oid_hex(sb.buf, &state->orig_commit) < 0)\n \t\tdie(_(\"could not parse %s\"), am_path(state, \"original-commit\"));\n \n@@ -1121,7 +1121,7 @@ static void am_next(struct am_state *state)\n \tunlink(am_path(state, \"author-script\"));\n \tunlink(am_path(state, \"final-commit\"));\n \n-\toidclr(&state->orig_commit);\n+\toidclr(&state->orig_commit, the_repository->hash_algo);\n \tunlink(am_path(state, \"original-commit\"));\n \trefs_delete_ref(get_main_ref_store(the_repository), NULL,\n \t\t\t\"REBASE_HEAD\", NULL, REF_NO_DEREF);\n@@ -2151,11 +2151,11 @@ static int safe_to_abort(const struct am_state *state)\n \t\tif (get_oid_hex(sb.buf, &abort_safety))\n \t\t\tdie(_(\"could not parse %s\"), am_path(state, \"abort-safety\"));\n \t} else\n-\t\toidclr(&abort_safety);\n+\t\toidclr(&abort_safety, the_repository->hash_algo);\n \tstrbuf_release(&sb);\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &head))\n-\t\toidclr(&head);\n+\t\toidclr(&head, the_repository->hash_algo);\n \n \tif (oideq(&head, &abort_safety))\n \t\treturn 1;\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 4693d18cc9..4b6e8c6832 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -415,7 +415,7 @@ static char *generate_fake_oid(void)\n \tstruct object_id oid;\n \tchar *hex = xmallocz(GIT_MAX_HEXSZ);\n \n-\toidclr(&oid);\n+\toidclr(&oid, the_repository->hash_algo);\n \tput_be32(oid.hash + hashsz - 4, counter++);\n \treturn oid_to_hex_r(hex, &oid);\n }\ndiff --git a/builtin/fast-import.c b/builtin/fast-import.c\nindex d1c0243d04..12543488f3 100644\n--- a/builtin/fast-import.c\n+++ b/builtin/fast-import.c\n@@ -1279,8 +1279,10 @@ static void load_tree(struct tree_entry *root)\n \t\te->versions[0].mode = e->versions[1].mode;\n \t\te->name = to_atom(c, strlen(c));\n \t\tc += e->name->str_len + 1;\n-\t\toidread(&e->versions[0].oid, (unsigned char *)c);\n-\t\toidread(&e->versions[1].oid, (unsigned char *)c);\n+\t\toidread(&e->versions[0].oid, (unsigned char *)c,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&e->versions[1].oid, (unsigned char *)c,\n+\t\t\tthe_repository->hash_algo);\n \t\tc += the_hash_algo->rawsz;\n \t}\n \tfree(buf);\n@@ -1386,7 +1388,7 @@ static void tree_content_replace(\n {\n \tif (!S_ISDIR(mode))\n \t\tdie(\"Root cannot be a non-directory\");\n-\toidclr(&root->versions[0].oid);\n+\toidclr(&root->versions[0].oid, the_repository->hash_algo);\n \toidcpy(&root->versions[1].oid, oid);\n \tif (root->tree)\n \t\trelease_tree_content_recursive(root->tree);\n@@ -1445,7 +1447,7 @@ static int tree_content_set(\n \t\t\t\tif (S_ISDIR(e->versions[0].mode))\n \t\t\t\t\te->versions[0].mode |= NO_DELTA;\n \n-\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \t\t\t\treturn 1;\n \t\t\t}\n \t\t\tif (!S_ISDIR(e->versions[1].mode)) {\n@@ -1455,7 +1457,7 @@ static int tree_content_set(\n \t\t\tif (!e->tree)\n \t\t\t\tload_tree(e);\n \t\t\tif (tree_content_set(e, slash1 + 1, oid, mode, subtree)) {\n-\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \t\t\t\treturn 1;\n \t\t\t}\n \t\t\treturn 0;\n@@ -1467,7 +1469,7 @@ static int tree_content_set(\n \te = new_tree_entry();\n \te->name = to_atom(p, n);\n \te->versions[0].mode = 0;\n-\toidclr(&e->versions[0].oid);\n+\toidclr(&e->versions[0].oid, the_repository->hash_algo);\n \tt->entries[t->entry_count++] = e;\n \tif (*slash1) {\n \t\te->tree = new_tree_content(8);\n@@ -1478,7 +1480,7 @@ static int tree_content_set(\n \t\te->versions[1].mode = mode;\n \t\toidcpy(&e->versions[1].oid, oid);\n \t}\n-\toidclr(&root->versions[1].oid);\n+\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \treturn 1;\n }\n \n@@ -1523,7 +1525,8 @@ static int tree_content_remove(\n \t\t\tif (tree_content_remove(e, slash1 + 1, backup_leaf, 0)) {\n \t\t\t\tfor (n = 0; n < e->tree->entry_count; n++) {\n \t\t\t\t\tif (e->tree->entries[n]->versions[1].mode) {\n-\t\t\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\t\t\toidclr(&root->versions[1].oid,\n+\t\t\t\t\t\t       the_repository->hash_algo);\n \t\t\t\t\t\treturn 1;\n \t\t\t\t\t}\n \t\t\t\t}\n@@ -1542,8 +1545,8 @@ static int tree_content_remove(\n \t\trelease_tree_content_recursive(e->tree);\n \te->tree = NULL;\n \te->versions[1].mode = 0;\n-\toidclr(&e->versions[1].oid);\n-\toidclr(&root->versions[1].oid);\n+\toidclr(&e->versions[1].oid, the_repository->hash_algo);\n+\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \treturn 1;\n }\n \n@@ -1609,7 +1612,7 @@ static int update_branch(struct branch *b)\n \t\treturn 0;\n \t}\n \tif (refs_read_ref(get_main_ref_store(the_repository), b->name, &old_oid))\n-\t\toidclr(&old_oid);\n+\t\toidclr(&old_oid, the_repository->hash_algo);\n \tif (!force_update && !is_null_oid(&old_oid)) {\n \t\tstruct commit *old_cmit, *new_cmit;\n \t\tint ret;\n@@ -2550,8 +2553,8 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa\n static void file_change_deleteall(struct branch *b)\n {\n \trelease_tree_content_recursive(b->branch_tree.tree);\n-\toidclr(&b->branch_tree.versions[0].oid);\n-\toidclr(&b->branch_tree.versions[1].oid);\n+\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \tload_tree(&b->branch_tree);\n \tb->num_notes = 0;\n }\n@@ -2570,8 +2573,8 @@ static void parse_from_commit(struct branch *b, char *buf, unsigned long size)\n static void parse_from_existing(struct branch *b)\n {\n \tif (is_null_oid(&b->oid)) {\n-\t\toidclr(&b->branch_tree.versions[0].oid);\n-\t\toidclr(&b->branch_tree.versions[1].oid);\n+\t\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \t} else {\n \t\tunsigned long size;\n \t\tchar *buf;\n@@ -2894,9 +2897,9 @@ static void parse_reset_branch(const char *arg)\n \n \tb = lookup_branch(arg);\n \tif (b) {\n-\t\toidclr(&b->oid);\n-\t\toidclr(&b->branch_tree.versions[0].oid);\n-\t\toidclr(&b->branch_tree.versions[1].oid);\n+\t\toidclr(&b->oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \t\tif (b->branch_tree.tree) {\n \t\t\trelease_tree_content_recursive(b->branch_tree.tree);\n \t\t\tb->branch_tree.tree = NULL;\ndiff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c\nindex 44c05ee86c..af329e8d5c 100644\n--- a/builtin/fetch-pack.c\n+++ b/builtin/fetch-pack.c\n@@ -29,11 +29,11 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,\n \t\t\t; /* <oid>, leave oid as name */\n \t\t} else {\n \t\t\t/* <ref>, clear cruft from oid */\n-\t\t\toidclr(&oid);\n+\t\t\toidclr(&oid, the_repository->hash_algo);\n \t\t}\n \t} else {\n \t\t/* <ref>, clear cruft from get_oid_hex */\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t}\n \n \tref = alloc_ref(name);\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex ea727fba16..fd968d673d 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -528,7 +528,8 @@ static void *unpack_raw_entry(struct object_entry *obj,\n \n \tswitch (obj->type) {\n \tcase OBJ_REF_DELTA:\n-\t\toidread(ref_oid, fill(the_hash_algo->rawsz));\n+\t\toidread(ref_oid, fill(the_hash_algo->rawsz),\n+\t\t\tthe_repository->hash_algo);\n \t\tuse(the_hash_algo->rawsz);\n \t\tbreak;\n \tcase OBJ_OFS_DELTA:\n@@ -1372,7 +1373,7 @@ static struct object_entry *append_obj_to_pack(struct hashfile *f,\n \tobj[1].idx.offset += write_compressed(f, buf, size);\n \tobj[0].idx.crc32 = crc32_end(f);\n \thashflush(f);\n-\toidread(&obj->idx.oid, sha1);\n+\toidread(&obj->idx.oid, sha1, the_repository->hash_algo);\n \treturn obj;\n }\n \ndiff --git a/builtin/log.c b/builtin/log.c\nindex 78a247d8a9..ccbda8a005 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1938,7 +1938,7 @@ static void print_bases(struct base_tree_info *bases, FILE *file)\n \tfree(bases->patch_id);\n \tbases->nr_patch_id = 0;\n \tbases->alloc_patch_id = 0;\n-\toidclr(&bases->base_commit);\n+\toidclr(&bases->base_commit, the_repository->hash_algo);\n }\n \n static const char *diff_title(struct strbuf *sb,\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex daed2d4e1e..abe66311c7 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -494,7 +494,7 @@ static void merge_name(const char *remote, struct strbuf *msg)\n \tstrbuf_branchname(&bname, remote, 0);\n \tremote = bname.buf;\n \n-\toidclr(&branch_head);\n+\toidclr(&branch_head, the_repository->hash_algo);\n \tremote_head = get_merge_parent(remote);\n \tif (!remote_head)\n \t\tdie(_(\"'%s' does not point to a commit\"), remote);\n@@ -1690,7 +1690,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t * index and working tree polluted.\n \t */\n \tif (save_state(&stash))\n-\t\toidclr(&stash);\n+\t\toidclr(&stash, the_repository->hash_algo);\n \n \tfor (i = 0; i < use_strategies_nr; i++) {\n \t\tint ret, cnt;\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 7f80b3449b..d9c356e354 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -828,7 +828,7 @@ static int merge_commit(struct notes_merge_options *o)\n \tif (partial->parents)\n \t\toidcpy(&parent_oid, &partial->parents->item->object.oid);\n \telse\n-\t\toidclr(&parent_oid);\n+\t\toidclr(&parent_oid, the_repository->hash_algo);\n \n \tCALLOC_ARRAY(t, 1);\n \tinit_notes(t, \"NOTES_MERGE_PARTIAL\", combine_notes_overwrite, 0);\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 638f5c57f0..2b00983a99 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -2078,7 +2078,8 @@ static void check_object(struct object_entry *entry, uint32_t object_index)\n \t\t\t\toidread(&base_ref,\n \t\t\t\t\tuse_pack(p, &w_curs,\n \t\t\t\t\t\t entry->in_pack_offset + used,\n-\t\t\t\t\t\t NULL));\n+\t\t\t\t\t\t NULL),\n+\t\t\t\t\tthe_repository->hash_algo);\n \t\t\t\thave_base = 1;\n \t\t\t}\n \t\t\tentry->in_pack_header_size = used + the_hash_algo->rawsz;\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 103c11b9d3..dd9bf35f5b 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -100,7 +100,7 @@ static inline struct llist_item *llist_insert(struct llist *list,\n \t\t\t\t\t      const unsigned char *oid)\n {\n \tstruct llist_item *new_item = llist_item_get();\n-\toidread(&new_item->oid, oid);\n+\toidread(&new_item->oid, oid, the_repository->hash_algo);\n \tnew_item->next = NULL;\n \n \tif (after) {\ndiff --git a/builtin/patch-id.c b/builtin/patch-id.c\nindex 583099cacf..d790ae6354 100644\n--- a/builtin/patch-id.c\n+++ b/builtin/patch-id.c\n@@ -70,7 +70,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,\n \tgit_hash_ctx ctx;\n \n \tthe_hash_algo->init_fn(&ctx);\n-\toidclr(result);\n+\toidclr(result, the_repository->hash_algo);\n \n \twhile (strbuf_getwholeline(line_buf, stdin, '\\n') != EOF) {\n \t\tchar *line = line_buf->buf;\n@@ -166,7 +166,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,\n \t}\n \n \tif (!found_next)\n-\t\toidclr(next_oid);\n+\t\toidclr(next_oid, the_repository->hash_algo);\n \n \tflush_one_hunk(result, &ctx);\n \n@@ -179,7 +179,7 @@ static void generate_id_list(int stable, int verbatim)\n \tint patchlen;\n \tstruct strbuf line_buf = STRBUF_INIT;\n \n-\toidclr(&oid);\n+\toidclr(&oid, the_repository->hash_algo);\n \twhile (!feof(stdin)) {\n \t\tpatchlen = get_one_patchid(&n, &result, &line_buf, stable, verbatim);\n \t\tflush_current_id(patchlen, &oid, &result);\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex d622202bce..2a73e673f3 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1038,7 +1038,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\tdie_conclude_merge();\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &orig_head))\n-\t\toidclr(&orig_head);\n+\t\toidclr(&orig_head, the_repository->hash_algo);\n \n \tif (opt_rebase) {\n \t\tif (opt_autostash == -1)\n@@ -1053,7 +1053,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t\t\t_(\"Please commit or stash them.\"), 1, 0);\n \n \t\tif (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))\n-\t\t\toidclr(&rebase_fork_point);\n+\t\t\toidclr(&rebase_fork_point, the_repository->hash_algo);\n \t}\n \n \tif (run_fetch(repo, refspecs))\n@@ -1063,7 +1063,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\treturn 0;\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &curr_head))\n-\t\toidclr(&curr_head);\n+\t\toidclr(&curr_head, the_repository->hash_algo);\n \n \tif (!is_null_oid(&orig_head) && !is_null_oid(&curr_head) &&\n \t\t\t!oideq(&orig_head, &curr_head)) {\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 01c1f04ece..aa5ba27d17 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -741,7 +741,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)\n \t\talready_done = 1;\n \t\tif (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB,\n \t\t\t\t      &push_cert_oid))\n-\t\t\toidclr(&push_cert_oid);\n+\t\t\toidclr(&push_cert_oid, the_repository->hash_algo);\n \n \t\tmemset(&sigcheck, '\\0', sizeof(sigcheck));\n \ndiff --git a/builtin/replace.c b/builtin/replace.c\nindex ce9f6974d2..1ef833c07f 100644\n--- a/builtin/replace.c\n+++ b/builtin/replace.c\n@@ -167,7 +167,7 @@ static int check_ref_valid(struct object_id *object,\n \t\treturn error(_(\"'%s' is not a valid ref name\"), ref->buf);\n \n \tif (refs_read_ref(get_main_ref_store(the_repository), ref->buf, prev))\n-\t\toidclr(prev);\n+\t\toidclr(prev, the_repository->hash_algo);\n \telse if (!force)\n \t\treturn error(_(\"replace ref '%s' already exists\"), ref->buf);\n \treturn 0;\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex d195c16e74..0e79cbab62 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -377,7 +377,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tif (!force) {\n \t\tstruct object_id oid;\n \t\tif (repo_get_oid(the_repository, \"HEAD\", &oid))\n-\t\t\toidclr(&oid);\n+\t\t\toidclr(&oid, the_repository->hash_algo);\n \t\tif (check_local_mod(&oid, index_only))\n \t\t\texit(1);\n \t}\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 6e2c0cf342..a1fb218512 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -650,7 +650,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\tdie(_(\"'%s' is not a valid tag name.\"), tag);\n \n \tif (refs_read_ref(get_main_ref_store(the_repository), ref.buf, &prev))\n-\t\toidclr(&prev);\n+\t\toidclr(&prev, the_repository->hash_algo);\n \telse if (!force)\n \t\tdie(_(\"tag '%s' already exists\"), tag);\n \ndiff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c\nindex 0855572c27..08fa2a7a74 100644\n--- a/builtin/unpack-objects.c\n+++ b/builtin/unpack-objects.c\n@@ -439,7 +439,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \tstruct object_id base_oid;\n \n \tif (type == OBJ_REF_DELTA) {\n-\t\toidread(&base_oid, fill(the_hash_algo->rawsz));\n+\t\toidread(&base_oid, fill(the_hash_algo->rawsz), the_repository->hash_algo);\n \t\tuse(the_hash_algo->rawsz);\n \t\tdelta_data = get_data(delta_size);\n \t\tif (!delta_data)\n@@ -451,7 +451,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \t\t\treturn; /* we are done */\n \t\telse {\n \t\t\t/* cannot resolve yet --- queue it */\n-\t\t\toidclr(&obj_list[nr].oid);\n+\t\t\toidclr(&obj_list[nr].oid, the_repository->hash_algo);\n \t\t\tadd_delta_to_list(nr, &base_oid, 0, delta_data, delta_size);\n \t\t\treturn;\n \t\t}\n@@ -500,7 +500,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \t\t\t * The delta base object is itself a delta that\n \t\t\t * has not been resolved yet.\n \t\t\t */\n-\t\t\toidclr(&obj_list[nr].oid);\n+\t\t\toidclr(&obj_list[nr].oid, the_repository->hash_algo);\n \t\t\tadd_delta_to_list(nr, null_oid(), base_offset,\n \t\t\t\t\t  delta_data, delta_size);\n \t\t\treturn;\ndiff --git a/builtin/update-ref.c b/builtin/update-ref.c\nindex 6cda1c08aa..f8a5b087f8 100644\n--- a/builtin/update-ref.c\n+++ b/builtin/update-ref.c\n@@ -122,7 +122,7 @@ static int parse_next_oid(const char **next, const char *end,\n \t\t\t\tgoto invalid;\n \t\t} else {\n \t\t\t/* Without -z, an empty value means all zeros: */\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t}\n \t} else {\n \t\t/* With -z, read the next NUL-terminated line */\n@@ -142,7 +142,7 @@ static int parse_next_oid(const char **next, const char *end,\n \t\t\t/* With -z, treat an empty value as all zeros: */\n \t\t\twarning(\"%s %s: missing <new-oid>, treating as zero\",\n \t\t\t\tcommand, refname);\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t} else {\n \t\t\t/*\n \t\t\t * With -z, an empty non-required value means\n@@ -291,7 +291,7 @@ static void parse_cmd_verify(struct ref_transaction *transaction,\n \n \tif (parse_next_oid(&next, end, &old_oid, \"verify\", refname,\n \t\t\t   PARSE_SHA1_OLD))\n-\t\toidclr(&old_oid);\n+\t\toidclr(&old_oid, the_repository->hash_algo);\n \n \tif (*next != line_termination)\n \t\tdie(\"verify %s: extra input: %s\", refname, next);\n@@ -564,7 +564,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)\n \t\t\t * The empty string implies that the reference\n \t\t\t * must not already exist:\n \t\t\t */\n-\t\t\toidclr(&oldoid);\n+\t\t\toidclr(&oldoid, the_repository->hash_algo);\n \t\telse if (repo_get_oid(the_repository, oldval, &oldoid))\n \t\t\tdie(\"%s: not a valid old SHA1\", oldval);\n \t}\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 387c0a3e5b..e4255c4d02 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -578,7 +578,8 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)\n \tif (0 <= it->entry_count) {\n \t\tif (size < rawsz)\n \t\t\tgoto free_return;\n-\t\toidread(&it->oid, (const unsigned char *)buf);\n+\t\toidread(&it->oid, (const unsigned char *)buf,\n+\t\t\tthe_repository->hash_algo);\n \t\tbuf += rawsz;\n \t\tsize -= rawsz;\n \t}\ndiff --git a/commit-graph.c b/commit-graph.c\nindex 3429156b28..e4eefd83bf 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -475,7 +475,8 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,\n \t\tFREE_AND_NULL(graph->bloom_filter_settings);\n \t}\n \n-\toidread(&graph->oid, graph->data + graph->data_len - graph->hash_len);\n+\toidread(&graph->oid, graph->data + graph->data_len - graph->hash_len,\n+\t\tthe_repository->hash_algo);\n \n \tfree_chunkfile(cf);\n \treturn graph;\n@@ -838,7 +839,8 @@ static void load_oid_from_graph(struct commit_graph *g,\n \n \tlex_index = pos - g->num_commits_in_base;\n \n-\toidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index));\n+\toidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index),\n+\t\tthe_repository->hash_algo);\n }\n \n static struct commit_list **insert_parent_or_die(struct repository *r,\n@@ -1080,7 +1082,7 @@ static struct tree *load_tree_for_commit(struct repository *r,\n \tcommit_data = g->chunk_commit_data +\n \t\t\tst_mult(GRAPH_DATA_WIDTH, graph_pos - g->num_commits_in_base);\n \n-\toidread(&oid, commit_data);\n+\toidread(&oid, commit_data, r->hash_algo);\n \tset_commit_tree(c, lookup_tree(r, &oid));\n \n \treturn c->maybe_tree;\n@@ -2556,7 +2558,8 @@ int write_commit_graph(struct object_directory *odb,\n \t\tstruct commit_graph *g = ctx->r->objects->commit_graph;\n \t\tfor (i = 0; i < g->num_commits; i++) {\n \t\t\tstruct object_id oid;\n-\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\t\tr->hash_algo);\n \t\t\toid_array_append(&ctx->oids, &oid);\n \t\t}\n \t}\n@@ -2675,7 +2678,8 @@ static int verify_one_commit_graph(struct repository *r,\n \tfor (i = 0; i < g->num_commits; i++) {\n \t\tstruct commit *graph_commit;\n \n-\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\tr->hash_algo);\n \n \t\tif (i && oidcmp(&prev_oid, &cur_oid) >= 0)\n \t\t\tgraph_report(_(\"commit-graph has incorrect OID order: %s then %s\"),\n@@ -2719,7 +2723,8 @@ static int verify_one_commit_graph(struct repository *r,\n \t\ttimestamp_t generation;\n \n \t\tdisplay_progress(progress, ++(*seen));\n-\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\tthe_repository->hash_algo);\n \n \t\tgraph_commit = lookup_commit(r, &cur_oid);\n \t\todb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 5a5a50c5a1..3fb8d79fef 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -160,7 +160,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)\n \t\t\tdpath->next = NULL;\n \t\t\tmemcpy(dpath->path, ce->name, path_len);\n \t\t\tdpath->path[path_len] = '\\0';\n-\t\t\toidclr(&dpath->oid);\n+\t\t\toidclr(&dpath->oid, the_repository->hash_algo);\n \t\t\tmemset(&(dpath->parent[0]), 0,\n \t\t\t       sizeof(struct combine_diff_parent)*5);\n \n@@ -412,7 +412,7 @@ static int show_modified(struct rev_info *revs,\n \t\tmemcpy(p->path, new_entry->name, pathlen);\n \t\tp->path[pathlen] = 0;\n \t\tp->mode = mode;\n-\t\toidclr(&p->oid);\n+\t\toidclr(&p->oid, the_repository->hash_algo);\n \t\tmemset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));\n \t\tp->parent[0].status = DIFF_STATUS_MODIFIED;\n \t\tp->parent[0].mode = new_entry->ce_mode;\ndiff --git a/diff.c b/diff.c\nindex e70301df76..60d1f7be81 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4567,7 +4567,7 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is\n \t\tif (!one->oid_valid) {\n \t\t\tstruct stat st;\n \t\t\tif (one->is_stdin) {\n-\t\t\t\toidclr(&one->oid);\n+\t\t\t\toidclr(&one->oid, the_repository->hash_algo);\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tif (lstat(one->path, &st) < 0)\n@@ -4577,7 +4577,7 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is\n \t\t}\n \t}\n \telse\n-\t\toidclr(&one->oid);\n+\t\toidclr(&one->oid, the_repository->hash_algo);\n }\n \n static void strip_prefix(int prefix_length, const char **namep, const char **otherp)\n@@ -6404,7 +6404,7 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid\n \tthe_hash_algo->init_fn(&ctx);\n \tmemset(&data, 0, sizeof(struct patch_id_t));\n \tdata.ctx = &ctx;\n-\toidclr(oid);\n+\toidclr(oid, the_repository->hash_algo);\n \n \tfor (i = 0; i < q->nr; i++) {\n \t\txpparam_t xpp;\ndiff --git a/dir.c b/dir.c\nindex 45be4ad261..5de421c29c 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1687,7 +1687,7 @@ static void prep_exclude(struct dir_struct *dir,\n \t\t}\n \n \t\t/* Try to read per-directory file */\n-\t\toidclr(&oid_stat.oid);\n+\t\toidclr(&oid_stat.oid, the_repository->hash_algo);\n \t\toid_stat.valid = 0;\n \t\tif (dir->exclude_per_dir &&\n \t\t    /*\n@@ -3794,7 +3794,7 @@ static void read_oid(size_t pos, void *cb)\n \t\trd->data = rd->end + 1;\n \t\treturn;\n \t}\n-\toidread(&ud->exclude_oid, rd->data);\n+\toidread(&ud->exclude_oid, rd->data, the_repository->hash_algo);\n \trd->data += the_hash_algo->rawsz;\n }\n \n@@ -3802,7 +3802,7 @@ static void load_oid_stat(struct oid_stat *oid_stat, const unsigned char *data,\n \t\t\t  const unsigned char *sha1)\n {\n \tstat_data_from_disk(&oid_stat->stat, data);\n-\toidread(&oid_stat->oid, sha1);\n+\toidread(&oid_stat->oid, sha1, the_repository->hash_algo);\n \toid_stat->valid = 1;\n }\n \ndiff --git a/hash-ll.h b/hash-ll.h\nindex fabdd8ecc7..dbb96369fc 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -284,6 +284,20 @@ static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n \tdst->algo = src->algo;\n }\n \n+static inline void oidread(struct object_id *oid, const unsigned char *hash,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(oid->hash, hash, algop->rawsz);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline void oidclr(struct object_id *oid,\n+\t\t\t  const struct git_hash_algo *algop)\n+{\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n static inline struct object_id *oiddup(const struct object_id *src)\n {\n \tstruct object_id *dst = xmalloc(sizeof(struct object_id));\ndiff --git a/hash.h b/hash.h\nindex 714938e2eb..43623a0c86 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -47,23 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,\n \tdst->algo = src->algo;\n }\n \n-static inline void oidclr(struct object_id *oid)\n-{\n-\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n-\toid->algo = hash_algo_by_ptr(the_hash_algo);\n-}\n-\n-static inline void oidread_algop(struct object_id *oid, const unsigned char *hash, const struct git_hash_algo *algop)\n-{\n-\tmemcpy(oid->hash, hash, algop->rawsz);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline void oidread(struct object_id *oid, const unsigned char *hash)\n-{\n-\toidread_algop(oid, hash, the_hash_algo);\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\ndiff --git a/http-push.c b/http-push.c\nindex 1fe51226fd..86de238b84 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1552,7 +1552,7 @@ static void fetch_symref(const char *path, char **symref, struct object_id *oid)\n \tfree(url);\n \n \tFREE_AND_NULL(*symref);\n-\toidclr(oid);\n+\toidclr(oid, the_repository->hash_algo);\n \n \tif (buffer.len == 0)\n \t\treturn;\ndiff --git a/http-walker.c b/http-walker.c\nindex cf7f8c82bc..b7110b6f82 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -152,7 +152,7 @@ static void prefetch(struct walker *walker, unsigned char *sha1)\n \n \tnewreq = xmalloc(sizeof(*newreq));\n \tnewreq->walker = walker;\n-\toidread(&newreq->oid, sha1);\n+\toidread(&newreq->oid, sha1, the_repository->hash_algo);\n \tnewreq->repo = data->alt;\n \tnewreq->state = WAITING;\n \tnewreq->req = NULL;\ndiff --git a/match-trees.c b/match-trees.c\nindex 849b391d3d..50c42e2061 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -229,7 +229,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,\n \t\t    oid_to_hex(oid1));\n \tif (*subpath) {\n \t\tstruct object_id tree_oid;\n-\t\toidread(&tree_oid, rewrite_here);\n+\t\toidread(&tree_oid, rewrite_here, the_repository->hash_algo);\n \t\tstatus = splice_tree(&tree_oid, subpath, oid2, &subtree);\n \t\tif (status)\n \t\t\treturn status;\ndiff --git a/midx.c b/midx.c\nindex bc4797196f..1e75f1a7eb 100644\n--- a/midx.c\n+++ b/midx.c\n@@ -304,7 +304,8 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid,\n \tif (n >= m->num_objects)\n \t\treturn NULL;\n \n-\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n));\n+\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n),\n+\t\tthe_repository->hash_algo);\n \treturn oid;\n }\n \ndiff --git a/notes-merge.c b/notes-merge.c\nindex 6a9a139b12..801941c2d1 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -240,7 +240,7 @@ static void diff_tree_local(struct notes_merge_options *o,\n \t\t\t *     (will be overwritten by following addition)\n \t\t\t */\n \t\t\tif (oideq(&mp->local, &uninitialized))\n-\t\t\t\toidclr(&mp->local);\n+\t\t\t\toidclr(&mp->local, the_repository->hash_algo);\n \t\t} else if (is_null_oid(&p->one->oid)) { /* addition */\n \t\t\t/*\n \t\t\t * Either this is a true addition (1), or it is part\n@@ -556,7 +556,7 @@ int notes_merge(struct notes_merge_options *o,\n \n \tassert(o->local_ref && o->remote_ref);\n \tassert(!strcmp(o->local_ref, local_tree->ref));\n-\toidclr(result_oid);\n+\toidclr(result_oid, the_repository->hash_algo);\n \n \ttrace_printf(\"notes_merge(o->local_ref = %s, o->remote_ref = %s)\\n\",\n \t       o->local_ref, o->remote_ref);\n@@ -579,7 +579,7 @@ int notes_merge(struct notes_merge_options *o,\n \t\t * unborn ref, perform the merge using an empty notes tree.\n \t\t */\n \t\tif (!check_refname_format(o->remote_ref, 0)) {\n-\t\t\toidclr(&remote_oid);\n+\t\t\toidclr(&remote_oid, the_repository->hash_algo);\n \t\t\tremote = NULL;\n \t\t} else {\n \t\t\tdie(\"Failed to resolve remote notes ref '%s'\",\ndiff --git a/notes.c b/notes.c\nindex 5296fd863f..3a8da92fb9 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -353,7 +353,7 @@ static void add_non_note(struct notes_tree *t, char *path,\n \tn->next = NULL;\n \tn->path = path;\n \tn->mode = mode;\n-\toidread(&n->oid, sha1);\n+\toidread(&n->oid, sha1, the_repository->hash_algo);\n \tt->prev_non_note = n;\n \n \tif (!t->first_non_note) {\n@@ -1036,7 +1036,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,\n \t\tdie(\"Failed to read notes tree referenced by %s (%s)\",\n \t\t    notes_ref, oid_to_hex(&object_oid));\n \n-\toidclr(&root_tree.key_oid);\n+\toidclr(&root_tree.key_oid, the_repository->hash_algo);\n \toidcpy(&root_tree.val_oid, &oid);\n \tload_subtree(t, &root_tree, t->root, 0);\n }\n@@ -1146,8 +1146,8 @@ int remove_note(struct notes_tree *t, const unsigned char *object_sha1)\n \tif (!t)\n \t\tt = &default_notes_tree;\n \tassert(t->initialized);\n-\toidread(&l.key_oid, object_sha1);\n-\toidclr(&l.val_oid);\n+\toidread(&l.key_oid, object_sha1, the_repository->hash_algo);\n+\toidclr(&l.val_oid, the_repository->hash_algo);\n \tnote_tree_remove(t, t->root, 0, &l);\n \tif (is_null_oid(&l.val_oid)) /* no note was removed */\n \t\treturn 1;\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex 4f6189095b..f684038f7f 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -56,7 +56,7 @@ static int decode_tree_entry_raw(struct object_id *oid, const char **path,\n \t\treturn -1;\n \t*len = strlen(*path) + 1;\n \n-\toidread_algop(oid, (const unsigned char *)*path + *len, algo);\n+\toidread(oid, (const unsigned char *)*path + *len, algo);\n \treturn 0;\n }\n \ndiff --git a/object-file.c b/object-file.c\nindex a40300ce4a..c161e3e2a5 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -1446,7 +1446,7 @@ static int loose_object_info(struct repository *r,\n \tint allow_unknown = flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE;\n \n \tif (oi->delta_base_oid)\n-\t\toidclr(oi->delta_base_oid);\n+\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \n \t/*\n \t * If we don't care about type or size, then we don't\n@@ -1580,7 +1580,7 @@ static int do_oid_object_info_extended(struct repository *r,\n \t\tif (oi->disk_sizep)\n \t\t\t*(oi->disk_sizep) = 0;\n \t\tif (oi->delta_base_oid)\n-\t\t\toidclr(oi->delta_base_oid);\n+\t\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \t\tif (oi->type_name)\n \t\t\tstrbuf_addstr(oi->type_name, type_name(co->type));\n \t\tif (oi->contentp)\ndiff --git a/packfile.c b/packfile.c\nindex 9156e9122c..ec7312cd20 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1251,7 +1251,7 @@ static int get_delta_base_oid(struct packed_git *p,\n {\n \tif (type == OBJ_REF_DELTA) {\n \t\tunsigned char *base = use_pack(p, w_curs, curpos, NULL);\n-\t\toidread(oid, base);\n+\t\toidread(oid, base, the_repository->hash_algo);\n \t\treturn 0;\n \t} else if (type == OBJ_OFS_DELTA) {\n \t\tuint32_t base_pos;\n@@ -1593,7 +1593,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,\n \t\t\t\tgoto out;\n \t\t\t}\n \t\t} else\n-\t\t\toidclr(oi->delta_base_oid);\n+\t\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \t}\n \n \toi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED :\n@@ -1917,10 +1917,12 @@ int nth_packed_object_id(struct object_id *oid,\n \t\treturn -1;\n \tindex += 4 * 256;\n \tif (p->index_version == 1) {\n-\t\toidread(oid, index + st_add(st_mult(hashsz + 4, n), 4));\n+\t\toidread(oid, index + st_add(st_mult(hashsz + 4, n), 4),\n+\t\t\tthe_repository->hash_algo);\n \t} else {\n \t\tindex += 8;\n-\t\toidread(oid, index + st_mult(hashsz, n));\n+\t\toidread(oid, index + st_mult(hashsz, n),\n+\t\t\tthe_repository->hash_algo);\n \t}\n \treturn 0;\n }\ndiff --git a/read-cache.c b/read-cache.c\nindex 2642ac9558..836f1db721 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1728,7 +1728,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)\n \n \tend = (unsigned char *)hdr + size;\n \tstart = end - the_hash_algo->rawsz;\n-\toidread(&oid, start);\n+\toidread(&oid, start, the_repository->hash_algo);\n \tif (oideq(&oid, null_oid()))\n \t\treturn 0;\n \n@@ -1876,7 +1876,8 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,\n \tce->ce_flags = flags & ~CE_NAMEMASK;\n \tce->ce_namelen = len;\n \tce->index = 0;\n-\toidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data));\n+\toidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data),\n+\t\tthe_repository->hash_algo);\n \n \tif (expand_name_field) {\n \t\tif (copy_len)\n@@ -2249,7 +2250,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)\n \tif (verify_hdr(hdr, mmap_size) < 0)\n \t\tgoto unmap;\n \n-\toidread(&istate->oid, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz);\n+\toidread(&istate->oid, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz,\n+\t\tthe_repository->hash_algo);\n \tistate->version = ntohl(hdr->hdr_version);\n \tistate->cache_nr = ntohl(hdr->hdr_entries);\n \tistate->cache_alloc = alloc_nr(istate->cache_nr);\ndiff --git a/refs.c b/refs.c\nindex 1304d3dd87..6e7caefdcf 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1822,7 +1822,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \t\t\t    failure_errno != ENOTDIR)\n \t\t\t\treturn NULL;\n \n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\tif (*flags & REF_BAD_NAME)\n \t\t\t\t*flags |= REF_ISBROKEN;\n \t\t\treturn refname;\n@@ -1832,7 +1832,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \n \t\tif (!(read_flags & REF_ISSYMREF)) {\n \t\t\tif (*flags & REF_BAD_NAME) {\n-\t\t\t\toidclr(oid);\n+\t\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\t\t*flags |= REF_ISBROKEN;\n \t\t\t}\n \t\t\treturn refname;\n@@ -1840,7 +1840,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \n \t\trefname = sb_refname.buf;\n \t\tif (resolve_flags & RESOLVE_REF_NO_RECURSE) {\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\treturn refname;\n \t\t}\n \t\tif (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 4519b46171..b484b5880d 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -246,7 +246,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,\n \n \tif (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING,\n \t\t\t\t     &oid, &flag)) {\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t\tflag |= REF_ISBROKEN;\n \t} else if (is_null_oid(&oid)) {\n \t\t/*\n@@ -263,7 +263,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,\n \tif (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {\n \t\tif (!refname_is_safe(refname))\n \t\t\tdie(\"loose refname is dangerous: %s\", refname);\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t\tflag |= REF_BAD_NAME | REF_ISBROKEN;\n \t}\n \tadd_entry_to_dir(dir, create_ref_entry(refname, &oid, flag));\n@@ -1150,7 +1150,7 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,\n \n \tif (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, 0,\n \t\t\t\t     &lock->old_oid, NULL))\n-\t\toidclr(&lock->old_oid);\n+\t\toidclr(&lock->old_oid, the_repository->hash_algo);\n \tgoto out;\n \n  error_return:\ndiff --git a/refs/packed-backend.c b/refs/packed-backend.c\nindex c4c1e36aa2..5ab1b21d10 100644\n--- a/refs/packed-backend.c\n+++ b/refs/packed-backend.c\n@@ -894,7 +894,7 @@ static int next_record(struct packed_ref_iterator *iter)\n \t\tif (!refname_is_safe(iter->base.refname))\n \t\t\tdie(\"packed refname is dangerous: %s\",\n \t\t\t    iter->base.refname);\n-\t\toidclr(&iter->oid);\n+\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\titer->base.flags |= REF_BAD_NAME | REF_ISBROKEN;\n \t}\n \tif (iter->snapshot->peeled == PEELED_FULLY ||\n@@ -919,13 +919,13 @@ static int next_record(struct packed_ref_iterator *iter)\n \t\t * we suppress it if the reference is broken:\n \t\t */\n \t\tif ((iter->base.flags & REF_ISBROKEN)) {\n-\t\t\toidclr(&iter->peeled);\n+\t\t\toidclr(&iter->peeled, the_repository->hash_algo);\n \t\t\titer->base.flags &= ~REF_KNOWS_PEELED;\n \t\t} else {\n \t\t\titer->base.flags |= REF_KNOWS_PEELED;\n \t\t}\n \t} else {\n-\t\toidclr(&iter->peeled);\n+\t\toidclr(&iter->peeled, the_repository->hash_algo);\n \t}\n \n \treturn ITER_OK;\ndiff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\nindex 9886fc67a4..57df2aba66 100644\n--- a/refs/reftable-backend.c\n+++ b/refs/reftable-backend.c\n@@ -217,7 +217,8 @@ static int read_ref_without_reload(struct reftable_stack *stack,\n \t\tstrbuf_addstr(referent, ref.value.symref);\n \t\t*type |= REF_ISSYMREF;\n \t} else if (reftable_ref_record_val1(&ref)) {\n-\t\toidread(oid, reftable_ref_record_val1(&ref));\n+\t\toidread(oid, reftable_ref_record_val1(&ref),\n+\t\t\tthe_repository->hash_algo);\n \t} else {\n \t\t/* We got a tombstone, which should not happen. */\n \t\tBUG(\"unhandled reference value type %d\", ref.value_type);\n@@ -483,15 +484,17 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)\n \n \t\tswitch (iter->ref.value_type) {\n \t\tcase REFTABLE_REF_VAL1:\n-\t\t\toidread(&iter->oid, iter->ref.value.val1);\n+\t\t\toidread(&iter->oid, iter->ref.value.val1,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tbreak;\n \t\tcase REFTABLE_REF_VAL2:\n-\t\t\toidread(&iter->oid, iter->ref.value.val2.value);\n+\t\t\toidread(&iter->oid, iter->ref.value.val2.value,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tbreak;\n \t\tcase REFTABLE_REF_SYMREF:\n \t\t\tif (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname,\n \t\t\t\t\t\t     RESOLVE_REF_READING, &iter->oid, &flags))\n-\t\t\t\toidclr(&iter->oid);\n+\t\t\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tBUG(\"unhandled reference value type %d\", iter->ref.value_type);\n@@ -503,7 +506,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)\n \t\tif (check_refname_format(iter->ref.refname, REFNAME_ALLOW_ONELEVEL)) {\n \t\t\tif (!refname_is_safe(iter->ref.refname))\n \t\t\t\tdie(_(\"refname is dangerous: %s\"), iter->ref.refname);\n-\t\t\toidclr(&iter->oid);\n+\t\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\t\tflags |= REF_BAD_NAME | REF_ISBROKEN;\n \t\t}\n \n@@ -545,7 +548,8 @@ static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,\n \t\t(struct reftable_ref_iterator *)ref_iterator;\n \n \tif (iter->ref.value_type == REFTABLE_REF_VAL2) {\n-\t\toidread(peeled, iter->ref.value.val2.target_value);\n+\t\toidread(peeled, iter->ref.value.val2.target_value,\n+\t\t\tthe_repository->hash_algo);\n \t\treturn 0;\n \t}\n \n@@ -1776,8 +1780,8 @@ static int yield_log_record(struct reftable_log_record *log,\n \tstruct object_id old_oid, new_oid;\n \tconst char *full_committer;\n \n-\toidread(&old_oid, log->value.update.old_hash);\n-\toidread(&new_oid, log->value.update.new_hash);\n+\toidread(&old_oid, log->value.update.old_hash, the_repository->hash_algo);\n+\toidread(&new_oid, log->value.update.new_hash, the_repository->hash_algo);\n \n \t/*\n \t * When both the old object ID and the new object ID are null\n@@ -2178,7 +2182,8 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \tif (ret < 0)\n \t\tgoto done;\n \tif (reftable_ref_record_val1(&ref_record))\n-\t\toidread(&oid, reftable_ref_record_val1(&ref_record));\n+\t\toidread(&oid, reftable_ref_record_val1(&ref_record),\n+\t\t\tthe_repository->hash_algo);\n \tprepare_fn(refname, &oid, policy_cb_data);\n \n \twhile (1) {\n@@ -2193,8 +2198,10 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \t\t\tbreak;\n \t\t}\n \n-\t\toidread(&old_oid, log.value.update.old_hash);\n-\t\toidread(&new_oid, log.value.update.new_hash);\n+\t\toidread(&old_oid, log.value.update.old_hash,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&new_oid, log.value.update.new_hash,\n+\t\t\tthe_repository->hash_algo);\n \n \t\t/*\n \t\t * Skip over the reflog existence marker. We will add it back\n@@ -2225,8 +2232,10 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \t\tstruct object_id old_oid, new_oid;\n \n \t\t*dest = logs[i];\n-\t\toidread(&old_oid, logs[i].value.update.old_hash);\n-\t\toidread(&new_oid, logs[i].value.update.new_hash);\n+\t\toidread(&old_oid, logs[i].value.update.old_hash,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&new_oid, logs[i].value.update.new_hash,\n+\t\t\tthe_repository->hash_algo);\n \n \t\tif (should_prune_fn(&old_oid, &new_oid, logs[i].value.update.email,\n \t\t\t\t    (timestamp_t)logs[i].value.update.time,\n@@ -2243,7 +2252,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \n \tif (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash &&\n \t    reftable_ref_record_val1(&ref_record))\n-\t\toidread(&arg.update_oid, last_hash);\n+\t\toidread(&arg.update_oid, last_hash, the_repository->hash_algo);\n \n \targ.refs = refs;\n \targ.records = rewritten;\ndiff --git a/remote.c b/remote.c\nindex dcb5492c85..1064171085 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1164,7 +1164,7 @@ static void tail_link_ref(struct ref *ref, struct ref ***tail)\n static struct ref *alloc_delete_ref(void)\n {\n \tstruct ref *ref = alloc_ref(\"(delete)\");\n-\toidclr(&ref->new_oid);\n+\toidclr(&ref->new_oid, the_repository->hash_algo);\n \treturn ref;\n }\n \n@@ -2531,7 +2531,7 @@ static int parse_push_cas_option(struct push_cas_option *cas, const char *arg, i\n \tif (!*colon)\n \t\tentry->use_tracking = 1;\n \telse if (!colon[1])\n-\t\toidclr(&entry->expect);\n+\t\toidclr(&entry->expect, the_repository->hash_algo);\n \telse if (repo_get_oid(the_repository, colon + 1, &entry->expect))\n \t\treturn error(_(\"cannot parse expected object name '%s'\"),\n \t\t\t     colon + 1);\n@@ -2733,7 +2733,7 @@ static void apply_cas(struct push_cas_option *cas,\n \t\telse if (remote_tracking(remote, ref->name,\n \t\t\t\t\t &ref->old_oid_expect,\n \t\t\t\t\t &ref->tracking_ref))\n-\t\t\toidclr(&ref->old_oid_expect);\n+\t\t\toidclr(&ref->old_oid_expect, the_repository->hash_algo);\n \t\telse\n \t\t\tref->check_reachable = cas->use_force_if_includes;\n \t\treturn;\n@@ -2747,7 +2747,7 @@ static void apply_cas(struct push_cas_option *cas,\n \tif (remote_tracking(remote, ref->name,\n \t\t\t    &ref->old_oid_expect,\n \t\t\t    &ref->tracking_ref))\n-\t\toidclr(&ref->old_oid_expect);\n+\t\toidclr(&ref->old_oid_expect, the_repository->hash_algo);\n \telse\n \t\tref->check_reachable = cas->use_force_if_includes;\n }\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex cd02dc9928..4e6f0e4676 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -93,7 +93,8 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)\n \t\t\t\tcontinue;\n \t\t\tif (size < rawsz)\n \t\t\t\tgoto error;\n-\t\t\toidread(&ui->oid[i], (const unsigned char *)data);\n+\t\t\toidread(&ui->oid[i], (const unsigned char *)data,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tsize -= rawsz;\n \t\t\tdata += rawsz;\n \t\t}\ndiff --git a/sequencer.c b/sequencer.c\nindex 30513e87bf..68d62a12ff 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -3334,12 +3334,12 @@ static int rollback_is_safe(void)\n \t\tstrbuf_release(&sb);\n \t}\n \telse if (errno == ENOENT)\n-\t\toidclr(&expected_head);\n+\t\toidclr(&expected_head, the_repository->hash_algo);\n \telse\n \t\tdie_errno(_(\"could not read '%s'\"), git_path_abort_safety_file());\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &actual_head))\n-\t\toidclr(&actual_head);\n+\t\toidclr(&actual_head, the_repository->hash_algo);\n \n \treturn oideq(&actual_head, &expected_head);\n }\ndiff --git a/split-index.c b/split-index.c\nindex 8c38687c04..058a8f448e 100644\n--- a/split-index.c\n+++ b/split-index.c\n@@ -29,7 +29,7 @@ int read_link_extension(struct index_state *istate,\n \tif (sz < the_hash_algo->rawsz)\n \t\treturn error(\"corrupt link extension (too short)\");\n \tsi = init_split_index(istate);\n-\toidread(&si->base_oid, data);\n+\toidread(&si->base_oid, data, the_repository->hash_algo);\n \tdata += the_hash_algo->rawsz;\n \tsz -= the_hash_algo->rawsz;\n \tif (!sz)\ndiff --git a/submodule-config.c b/submodule-config.c\nindex ec45ea67b9..ad43a282da 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -682,7 +682,7 @@ static int gitmodule_oid_from_commit(const struct object_id *treeish_name,\n \tint ret = 0;\n \n \tif (is_null_oid(treeish_name)) {\n-\t\toidclr(gitmodules_oid);\n+\t\toidclr(gitmodules_oid, the_repository->hash_algo);\n \t\treturn 1;\n \t}\n \ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex 9df2f03ac8..4b809d9dca 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -44,7 +44,7 @@ int cmd__submodule_config(int argc, const char **argv)\n \t\tpath_or_name = arg[1];\n \n \t\tif (commit[0] == '\\0')\n-\t\t\toidclr(&commit_oid);\n+\t\t\toidclr(&commit_oid, the_repository->hash_algo);\n \t\telse if (repo_get_oid(the_repository, commit, &commit_oid) < 0)\n \t\t\tdie_usage(argc, argv, \"Commit not found.\");\n \ndiff --git a/tree-walk.c b/tree-walk.c\nindex 6565d9ad99..535a3a2539 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -38,8 +38,8 @@ static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned l\n \tdesc->entry.path = path;\n \tdesc->entry.mode = (desc->flags & TREE_DESC_RAW_MODES) ? mode : canon_mode(mode);\n \tdesc->entry.pathlen = len - 1;\n-\toidread_algop(&desc->entry.oid, (const unsigned char *)path + len,\n-\t\t      desc->algo);\n+\toidread(&desc->entry.oid, (const unsigned char *)path + len,\n+\t\tdesc->algo);\n \n \treturn 0;\n }\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497061","messageId":"fa263d6b0777ba8d157f7364507590c19069ed56.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 04/20] global: ensure that object IDs are always padded","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:40Z","receivedAt":"2024-06-13T06:13:44Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `oidcmp()` and `oideq()` functions only compare the prefix length as\nspecified by the given hash algorithm. This mandates that the object IDs\nhave a valid hash algorithm set, or otherwise we wouldn't be able to\nfigure out that prefix. As we do not have a hash algorithm in many\ncases, for example when handling null object IDs, this assumption cannot\nalways be fulfilled. We thus have a fallback in place that instead uses\n`the_repository` to derive the hash function. This implicit dependency\nis hidden away from callers and can be quite surprising, especially in\ncontexts where there may be no repository.\n\nIn theory, we can adapt those functions to always memcmp(3P) the whole\nlength of their hash arrays. But there exist a couple of sites where we\npopulate `struct object_id`s such that only the prefix of its hash that\nis actually used by the hash algorithm is populated. The remaining bytes\nare left uninitialized. The fact that those bytes are uninitialized also\nleads to warnings under Valgrind in some places where we copy those\nbytes.\n\nRefactor callsites where we populate object IDs to always initialize all\nbytes. This also allows us to get rid of `oidcpy_with_padding()`, for\none because the input is now fully initialized, and because `oidcpy()`\nwill now always copy the whole hash array.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h           |  2 ++\n hash.h              | 16 ----------------\n hex.c               |  6 +++++-\n http-push.c         |  1 +\n notes.c             |  2 ++\n object-file.c       |  2 ++\n oidtree.c           |  4 ++--\n parallel-checkout.c |  8 +-------\n 8 files changed, 15 insertions(+), 26 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex dbb96369fc..b72f84f4ae 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -288,6 +288,8 @@ static inline void oidread(struct object_id *oid, const unsigned char *hash,\n \t\t\t   const struct git_hash_algo *algop)\n {\n \tmemcpy(oid->hash, hash, algop->rawsz);\n+\tif (algop->rawsz < GIT_MAX_RAWSZ)\n+\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n \toid->algo = hash_algo_by_ptr(algop);\n }\n \ndiff --git a/hash.h b/hash.h\nindex 43623a0c86..e43e3d8b5a 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -31,22 +31,6 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn oideq(oid, null_oid());\n }\n \n-/* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */\n-static inline void oidcpy_with_padding(struct object_id *dst,\n-\t\t\t\t       const struct object_id *src)\n-{\n-\tsize_t hashsz;\n-\n-\tif (!src->algo)\n-\t\thashsz = the_hash_algo->rawsz;\n-\telse\n-\t\thashsz = hash_algos[src->algo].rawsz;\n-\n-\tmemcpy(dst->hash, src->hash, hashsz);\n-\tmemset(dst->hash + hashsz, 0, GIT_MAX_RAWSZ - hashsz);\n-\tdst->algo = src->algo;\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\ndiff --git a/hex.c b/hex.c\nindex d42262bdca..bc9e86a978 100644\n--- a/hex.c\n+++ b/hex.c\n@@ -25,8 +25,12 @@ int get_oid_hex_algop(const char *hex, struct object_id *oid,\n \t\t      const struct git_hash_algo *algop)\n {\n \tint ret = get_hash_hex_algop(hex, oid->hash, algop);\n-\tif (!ret)\n+\tif (!ret) {\n \t\toid_set_algo(oid, algop);\n+\t\tif (algop->rawsz != GIT_MAX_RAWSZ)\n+\t\t\tmemset(oid->hash + algop->rawsz, 0,\n+\t\t\t       GIT_MAX_RAWSZ - algop->rawsz);\n+\t}\n \treturn ret;\n }\n \ndiff --git a/http-push.c b/http-push.c\nindex 86de238b84..a97df4a1fb 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1016,6 +1016,7 @@ static void remote_ls(const char *path, int flags,\n /* extract hex from sharded \"xx/x{38}\" filename */\n static int get_oid_hex_from_objpath(const char *path, struct object_id *oid)\n {\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n \toid->algo = hash_algo_by_ptr(the_hash_algo);\n \n \tif (strlen(path) != the_hash_algo->hexsz + 1)\ndiff --git a/notes.c b/notes.c\nindex 3a8da92fb9..afe2e2882e 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -427,6 +427,8 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,\n \t\t\t\t\t hashsz - prefix_len))\n \t\t\t\tgoto handle_non_note; /* entry.path is not a SHA1 */\n \n+\t\t\tmemset(object_oid.hash + hashsz, 0, GIT_MAX_RAWSZ - hashsz);\n+\n \t\t\ttype = PTR_TYPE_NOTE;\n \t\t} else if (path_len == 2) {\n \t\t\t/* This is potentially an internal node */\ndiff --git a/object-file.c b/object-file.c\nindex c161e3e2a5..bb97f8a809 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2743,6 +2743,8 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,\n \t\t    !hex_to_bytes(oid.hash + 1, de->d_name,\n \t\t\t\t  the_hash_algo->rawsz - 1)) {\n \t\t\toid_set_algo(&oid, the_hash_algo);\n+\t\t\tmemset(oid.hash + the_hash_algo->rawsz, 0,\n+\t\t\t       GIT_MAX_RAWSZ - the_hash_algo->rawsz);\n \t\t\tif (obj_cb) {\n \t\t\t\tr = obj_cb(&oid, path->buf, data);\n \t\t\t\tif (r)\ndiff --git a/oidtree.c b/oidtree.c\nindex daef175dc7..92d03b52db 100644\n--- a/oidtree.c\n+++ b/oidtree.c\n@@ -42,7 +42,7 @@ void oidtree_insert(struct oidtree *ot, const struct object_id *oid)\n \t * Clear the padding and copy the result in separate steps to\n \t * respect the 4-byte alignment needed by struct object_id.\n \t */\n-\toidcpy_with_padding(&k, oid);\n+\toidcpy(&k, oid);\n \tmemcpy(on->k, &k, sizeof(k));\n \n \t/*\n@@ -60,7 +60,7 @@ int oidtree_contains(struct oidtree *ot, const struct object_id *oid)\n \tstruct object_id k;\n \tsize_t klen = sizeof(k);\n \n-\toidcpy_with_padding(&k, oid);\n+\toidcpy(&k, oid);\n \n \tif (oid->algo == GIT_HASH_UNKNOWN)\n \t\tklen -= sizeof(oid->algo);\ndiff --git a/parallel-checkout.c b/parallel-checkout.c\nindex b5a714c711..08b960aac8 100644\n--- a/parallel-checkout.c\n+++ b/parallel-checkout.c\n@@ -429,13 +429,7 @@ static void send_one_item(int fd, struct parallel_checkout_item *pc_item)\n \tfixed_portion->ident = pc_item->ca.ident;\n \tfixed_portion->name_len = name_len;\n \tfixed_portion->working_tree_encoding_len = working_tree_encoding_len;\n-\t/*\n-\t * We pad the unused bytes in the hash array because, otherwise,\n-\t * Valgrind would complain about passing uninitialized bytes to a\n-\t * write() syscall. The warning doesn't represent any real risk here,\n-\t * but it could hinder the detection of actual errors.\n-\t */\n-\toidcpy_with_padding(&fixed_portion->oid, &pc_item->ce->oid);\n+\toidcpy(&fixed_portion->oid, &pc_item->ce->oid);\n \n \tvariant = data + sizeof(*fixed_portion);\n \tif (working_tree_encoding_len) {\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497062","messageId":"a7df209bda9bacf3dc88c8a021f9162069f78867.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 05/20] hash: convert `oidcmp()` and `oideq()` to compare whole hash","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:45Z","receivedAt":"2024-06-13T06:13:49Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"With the preceding commit, the hash array of object IDs is now fully\nzero-padded even when the hash algorithm's output is smaller than the\narray length. With that, we can now adapt both `oidcmp()` and `oideq()`\nto unconditionally memcmp(3P) the whole array instead of depending on\nthe hash size.\n\nWhile it may feel inefficient to compare unused bytes for e.g. SHA-1, in\npractice the compiler should now be able to produce code that is better\noptimized both because we have no branch anymore, but also because the\nsize to compare is now known at compile time. Goldbolt spits out the\nfollowing assembly on an x86_64 platform with GCC 14.1 for the old and\nnew implementations of `oidcmp()`:\n\n    oidcmp_old:\n            movsx   rax, DWORD PTR [rdi+32]\n            test    eax, eax\n            jne     .L2\n            mov     rax, QWORD PTR the_repository[rip]\n            cmp     QWORD PTR [rax+16], 32\n            je      .L6\n    .L4:\n            mov     edx, 20\n            jmp     memcmp\n    .L2:\n            lea     rdx, [rax+rax*2]\n            lea     rax, [rax+rdx*4]\n            lea     rax, hash_algos[0+rax*8]\n            cmp     QWORD PTR [rax+16], 32\n            jne     .L4\n    .L6:\n            mov     edx, 32\n            jmp     memcmp\n\n    oidcmp_new:\n            mov     edx, 32\n            jmp     memcmp\n\nThe new implementation gets ridi of all the branches and effectively\nonly ends setting up `edx` for `memcmp()` and then calling it.\n\nAnd for `oideq()`:\n\n    oideq_old:\n            movsx   rcx, DWORD PTR [rdi+32]\n            mov     rax, rdi\n            mov     rdx, rsi\n            test    ecx, ecx\n            jne     .L2\n            mov     rcx, QWORD PTR the_repository[rip]\n            cmp     QWORD PTR [rcx+16], 32\n            mov     rcx, QWORD PTR [rax]\n            je      .L12\n    .L4:\n            mov     rsi, QWORD PTR [rax+8]\n            xor     rcx, QWORD PTR [rdx]\n            xor     rsi, QWORD PTR [rdx+8]\n            or      rcx, rsi\n            je      .L13\n    .L8:\n            mov     eax, 1\n            test    eax, eax\n            sete    al\n            movzx   eax, al\n            ret\n    .L2:\n            lea     rsi, [rcx+rcx*2]\n            lea     rcx, [rcx+rsi*4]\n            lea     rcx, hash_algos[0+rcx*8]\n            cmp     QWORD PTR [rcx+16], 32\n            mov     rcx, QWORD PTR [rax]\n            jne     .L4\n    .L12:\n            mov     rsi, QWORD PTR [rax+8]\n            xor     rcx, QWORD PTR [rdx]\n            xor     rsi, QWORD PTR [rdx+8]\n            or      rcx, rsi\n            jne     .L8\n            mov     rcx, QWORD PTR [rax+16]\n            mov     rax, QWORD PTR [rax+24]\n            xor     rcx, QWORD PTR [rdx+16]\n            xor     rax, QWORD PTR [rdx+24]\n            or      rcx, rax\n            jne     .L8\n            xor     eax, eax\n    .L14:\n            test    eax, eax\n            sete    al\n            movzx   eax, al\n            ret\n    .L13:\n            mov     edi, DWORD PTR [rdx+16]\n            cmp     DWORD PTR [rax+16], edi\n            jne     .L8\n            xor     eax, eax\n            jmp     .L14\n\n    oideq_new:\n            mov     rax, QWORD PTR [rdi]\n            mov     rdx, QWORD PTR [rdi+8]\n            xor     rax, QWORD PTR [rsi]\n            xor     rdx, QWORD PTR [rsi+8]\n            or      rax, rdx\n            je      .L5\n    .L2:\n            mov     eax, 1\n            xor     eax, 1\n            ret\n    .L5:\n            mov     rax, QWORD PTR [rdi+16]\n            mov     rdx, QWORD PTR [rdi+24]\n            xor     rax, QWORD PTR [rsi+16]\n            xor     rdx, QWORD PTR [rsi+24]\n            or      rax, rdx\n            jne     .L2\n            xor     eax, eax\n            xor     eax, 1\n            ret\n\nInterestingly, the compiler decides to split the comparisons into two so\nthat it first compares the lower half of the object ID for equality and\nthen the upper half. If the first check shows a difference, then we\nwouldn't even end up comparing the second half.\n\nIn both cases, the new generated code is significantly shorter and has\nway less branches. While I didn't benchmark the change, I'd be surprised\nif the new code was slower.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h | 10 ++++++++++\n hash.h    | 20 --------------------\n 2 files changed, 10 insertions(+), 20 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex b72f84f4ae..b04fe12aef 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -278,6 +278,16 @@ static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algo\n \tmemset(hash, 0, algop->rawsz);\n }\n \n+static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n {\n \tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\ndiff --git a/hash.h b/hash.h\nindex e43e3d8b5a..ddc2e5ca47 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,26 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\tconst struct git_hash_algo *algop;\n-\tif (!oid1->algo)\n-\t\talgop = the_hash_algo;\n-\telse\n-\t\talgop = &hash_algos[oid1->algo];\n-\treturn hashcmp(oid1->hash, oid2->hash, algop);\n-}\n-\n-static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\tconst struct git_hash_algo *algop;\n-\tif (!oid1->algo)\n-\t\talgop = the_hash_algo;\n-\telse\n-\t\talgop = &hash_algos[oid1->algo];\n-\treturn hasheq(oid1->hash, oid2->hash, algop);\n-}\n-\n static inline int is_null_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, null_oid());\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497063","messageId":"9058837c938a45504ed0cb6dfce62dfe5a595217.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 06/20] hash: make `is_null_oid()` independent of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:50Z","receivedAt":"2024-06-13T06:13:55Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The function `is_null_oid()` uses `oideq(oid, null_oid())` to check\nwhether a given object ID is the all-zero object ID. `null_oid()`\nimplicitly relies on `the_repository` though to return the correct null\nobject ID.\n\nGet rid of this dependency by always comparing the complete hash array\nfor being all-zeroes. This is possible due to the refactoring of object\nIDs so that their hash arrays are always fully initialized.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h | 6 ++++++\n hash.h    | 5 -----\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex b04fe12aef..faf6c292d2 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -341,6 +341,12 @@ static inline unsigned int oidhash(const struct object_id *oid)\n \treturn hash;\n }\n \n+static inline int is_null_oid(const struct object_id *oid)\n+{\n+\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n+\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n+}\n+\n const char *empty_tree_oid_hex(void);\n const char *empty_blob_oid_hex(void);\n \ndiff --git a/hash.h b/hash.h\nindex ddc2e5ca47..84f2296cfb 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,11 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int is_null_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, null_oid());\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497064","messageId":"d26584dc8f6f7cca5d3173c80f694b2cb0491ba7.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 07/20] hash: require hash algorithm in `is_empty_{blob,tree}_oid()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:13:55Z","receivedAt":"2024-06-13T06:13:59Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both functions `is_empty_{blob,tree}_oid()` use `the_repository` to\nderive the hash function that shall be used. Require callers to pass in\nthe hash algorithm to get rid of this implicit dependency.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/fast-import.c |  4 +++-\n cache-tree.c          |  2 +-\n diffcore-rename.c     |  4 ++--\n hash-ll.h             | 12 ++++++++++++\n hash.h                | 10 ----------\n read-cache.c          |  2 +-\n 6 files changed, 19 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/fast-import.c b/builtin/fast-import.c\nindex 12543488f3..d21c4053a7 100644\n--- a/builtin/fast-import.c\n+++ b/builtin/fast-import.c\n@@ -2361,7 +2361,9 @@ static void file_change_m(const char *p, struct branch *b)\n \tparse_path_eol(&path, p, \"path\");\n \n \t/* Git does not track empty, non-toplevel directories. */\n-\tif (S_ISDIR(mode) && is_empty_tree_oid(&oid) && *path.buf) {\n+\tif (S_ISDIR(mode) &&\n+\t    is_empty_tree_oid(&oid, the_repository->hash_algo) &&\n+\t    *path.buf) {\n \t\ttree_content_remove(&b->branch_tree, path.buf, NULL, 0);\n \t\treturn;\n \t}\ndiff --git a/cache-tree.c b/cache-tree.c\nindex e4255c4d02..3290a1b8dd 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -422,7 +422,7 @@ static int update_one(struct cache_tree *it,\n \t\t/*\n \t\t * \"sub\" can be an empty tree if all subentries are i-t-a.\n \t\t */\n-\t\tif (contains_ita && is_empty_tree_oid(oid))\n+\t\tif (contains_ita && is_empty_tree_oid(oid, the_repository->hash_algo))\n \t\t\tcontinue;\n \n \t\tstrbuf_grow(&buffer, entlen + 100);\ndiff --git a/diffcore-rename.c b/diffcore-rename.c\nindex 5a6e2bcac7..5abb958651 100644\n--- a/diffcore-rename.c\n+++ b/diffcore-rename.c\n@@ -1422,7 +1422,7 @@ void diffcore_rename_extended(struct diff_options *options,\n \t\t\t\t strcmp(options->single_follow, p->two->path))\n \t\t\t\tcontinue; /* not interested */\n \t\t\telse if (!options->flags.rename_empty &&\n-\t\t\t\t is_empty_blob_oid(&p->two->oid))\n+\t\t\t\t is_empty_blob_oid(&p->two->oid, the_repository->hash_algo))\n \t\t\t\tcontinue;\n \t\t\telse if (add_rename_dst(p) < 0) {\n \t\t\t\twarning(\"skipping rename detection, detected\"\n@@ -1432,7 +1432,7 @@ void diffcore_rename_extended(struct diff_options *options,\n \t\t\t}\n \t\t}\n \t\telse if (!options->flags.rename_empty &&\n-\t\t\t is_empty_blob_oid(&p->one->oid))\n+\t\t\t is_empty_blob_oid(&p->one->oid, the_repository->hash_algo))\n \t\t\tcontinue;\n \t\telse if (!DIFF_PAIR_UNMERGED(p) && !DIFF_FILE_VALID(p->two)) {\n \t\t\t/*\ndiff --git a/hash-ll.h b/hash-ll.h\nindex faf6c292d2..1000a9af22 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -350,4 +350,16 @@ static inline int is_null_oid(const struct object_id *oid)\n const char *empty_tree_oid_hex(void);\n const char *empty_blob_oid_hex(void);\n \n+static inline int is_empty_blob_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_blob);\n+}\n+\n+static inline int is_empty_tree_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_tree);\n+}\n+\n #endif\ndiff --git a/hash.h b/hash.h\nindex 84f2296cfb..39a0164be3 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,14 +6,4 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int is_empty_blob_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, the_hash_algo->empty_blob);\n-}\n-\n-static inline int is_empty_tree_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, the_hash_algo->empty_tree);\n-}\n-\n #endif\ndiff --git a/read-cache.c b/read-cache.c\nindex 836f1db721..085b22faf3 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -337,7 +337,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)\n \n \t/* Racily smudged entry? */\n \tif (!ce->ce_stat_data.sd_size) {\n-\t\tif (!is_empty_blob_oid(&ce->oid))\n+\t\tif (!is_empty_blob_oid(&ce->oid, the_repository->hash_algo))\n \t\t\tchanged |= DATA_CHANGED;\n \t}\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497065","messageId":"4858cca25fe9e57c984fc3181fe8498d0b7222b0.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 08/20] hash: require hash algorithm in `empty_tree_oid_hex()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:00Z","receivedAt":"2024-06-13T06:14:05Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `empty_tree_oid_hex()` function use `the_repository` to derive the\nhash function that shall be used. Require callers to pass in the hash\nalgorithm to get rid of this implicit dependency.\n\nWhile at it, remove the unused `empty_blob_oid_hex()` function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n add-interactive.c      |  2 +-\n add-patch.c            |  2 +-\n builtin/merge.c        |  3 ++-\n builtin/receive-pack.c |  2 +-\n hash-ll.h              |  3 +--\n object-file.c          | 10 ++--------\n sequencer.c            |  2 +-\n submodule.c            |  6 +++---\n wt-status.c            |  4 ++--\n 9 files changed, 14 insertions(+), 20 deletions(-)\n\ndiff --git a/add-interactive.c b/add-interactive.c\nindex b5d6cd689a..a0961096cd 100644\n--- a/add-interactive.c\n+++ b/add-interactive.c\n@@ -557,7 +557,7 @@ static int get_modified_files(struct repository *r,\n \t\ts.skip_unseen = filter && i;\n \n \t\topt.def = is_initial ?\n-\t\t\tempty_tree_oid_hex() : oid_to_hex(&head_oid);\n+\t\t\tempty_tree_oid_hex(the_repository->hash_algo) : oid_to_hex(&head_oid);\n \n \t\trepo_init_revisions(r, &rev, NULL);\n \t\tsetup_revisions(0, NULL, &rev, &opt);\ndiff --git a/add-patch.c b/add-patch.c\nindex 814de57c4a..86181770f2 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -420,7 +420,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)\n \t\t\t    /* could be on an unborn branch */\n \t\t\t    !strcmp(\"HEAD\", s->revision) &&\n \t\t\t    repo_get_oid(the_repository, \"HEAD\", &oid) ?\n-\t\t\t    empty_tree_oid_hex() : s->revision);\n+\t\t\t    empty_tree_oid_hex(the_repository->hash_algo) : s->revision);\n \t}\n \tcolor_arg_index = args.nr;\n \t/* Use `--no-color` explicitly, just in case `diff.color = always`. */\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex abe66311c7..bb94b7df21 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -330,7 +330,8 @@ static void read_empty(const struct object_id *oid)\n {\n \tstruct child_process cmd = CHILD_PROCESS_INIT;\n \n-\tstrvec_pushl(&cmd.args, \"read-tree\", \"-m\", \"-u\", empty_tree_oid_hex(),\n+\tstrvec_pushl(&cmd.args, \"read-tree\", \"-m\", \"-u\",\n+\t\t     empty_tree_oid_hex(the_repository->hash_algo),\n \t\t     oid_to_hex(oid), NULL);\n \tcmd.git_cmd = 1;\n \ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex aa5ba27d17..41d5fb8e60 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -1371,7 +1371,7 @@ static const char *push_to_deploy(unsigned char *sha1,\n \tstrvec_pushl(&child.args, \"diff-index\", \"--quiet\", \"--cached\",\n \t\t     \"--ignore-submodules\",\n \t\t     /* diff-index with either HEAD or an empty tree */\n-\t\t     head_has_history() ? \"HEAD\" : empty_tree_oid_hex(),\n+\t\t     head_has_history() ? \"HEAD\" : empty_tree_oid_hex(the_repository->hash_algo),\n \t\t     \"--\", NULL);\n \tstrvec_pushv(&child.env, env->v);\n \tchild.no_stdin = 1;\ndiff --git a/hash-ll.h b/hash-ll.h\nindex 1000a9af22..3161c778b9 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -347,8 +347,7 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n }\n \n-const char *empty_tree_oid_hex(void);\n-const char *empty_blob_oid_hex(void);\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n \n static inline int is_empty_blob_oid(const struct object_id *oid,\n \t\t\t\t    const struct git_hash_algo *algop)\ndiff --git a/object-file.c b/object-file.c\nindex bb97f8a809..72318c8dd4 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -227,16 +227,10 @@ const struct object_id *null_oid(void)\n \treturn the_hash_algo->null_oid;\n }\n \n-const char *empty_tree_oid_hex(void)\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop)\n {\n \tstatic char buf[GIT_MAX_HEXSZ + 1];\n-\treturn oid_to_hex_r(buf, the_hash_algo->empty_tree);\n-}\n-\n-const char *empty_blob_oid_hex(void)\n-{\n-\tstatic char buf[GIT_MAX_HEXSZ + 1];\n-\treturn oid_to_hex_r(buf, the_hash_algo->empty_blob);\n+\treturn oid_to_hex_r(buf, algop->empty_tree);\n }\n \n int hash_algo_by_name(const char *name)\ndiff --git a/sequencer.c b/sequencer.c\nindex 68d62a12ff..823691e379 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -2263,7 +2263,7 @@ static int do_pick_commit(struct repository *r,\n \t\t\tunborn = 1;\n \t\t} else if (unborn)\n \t\t\toidcpy(&head, the_hash_algo->empty_tree);\n-\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex() : \"HEAD\",\n+\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : \"HEAD\",\n \t\t\t\t       NULL, 0))\n \t\t\treturn error_dirty_index(r, opts);\n \t}\ndiff --git a/submodule.c b/submodule.c\nindex 759cf1e1cd..caf3aa5600 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -2119,7 +2119,7 @@ static void submodule_reset_index(const char *path, const char *super_prefix)\n \tstrvec_pushf(&cp.args, \"--super-prefix=%s%s/\",\n \t\t     (super_prefix ? super_prefix : \"\"), path);\n \n-\tstrvec_push(&cp.args, empty_tree_oid_hex());\n+\tstrvec_push(&cp.args, empty_tree_oid_hex(the_repository->hash_algo));\n \n \tif (run_command(&cp))\n \t\tdie(_(\"could not reset submodule index\"));\n@@ -2229,9 +2229,9 @@ int submodule_move_head(const char *path, const char *super_prefix,\n \t\tstrvec_push(&cp.args, \"-m\");\n \n \tif (!(flags & SUBMODULE_MOVE_HEAD_FORCE))\n-\t\tstrvec_push(&cp.args, old_head ? old_head : empty_tree_oid_hex());\n+\t\tstrvec_push(&cp.args, old_head ? old_head : empty_tree_oid_hex(the_repository->hash_algo));\n \n-\tstrvec_push(&cp.args, new_head ? new_head : empty_tree_oid_hex());\n+\tstrvec_push(&cp.args, new_head ? new_head : empty_tree_oid_hex(the_repository->hash_algo));\n \n \tif (run_command(&cp)) {\n \t\tret = error(_(\"Submodule '%s' could not be updated.\"), path);\ndiff --git a/wt-status.c b/wt-status.c\nindex ff4be071ca..5051f5e599 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -641,7 +641,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n \n \trepo_init_revisions(s->repo, &rev, NULL);\n \tmemset(&opt, 0, sizeof(opt));\n-\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n+\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n \trev.diffopt.flags.override_submodule_config = 1;\n@@ -1136,7 +1136,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)\n \trev.diffopt.ita_invisible_in_index = 1;\n \n \tmemset(&opt, 0, sizeof(opt));\n-\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n+\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n \trev.diffopt.output_format |= DIFF_FORMAT_PATCH;\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497066","messageId":"cb3694ad0eabeaf05f6fe184648740ab614cbd97.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:05Z","receivedAt":"2024-06-13T06:14:10Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Use of the `the_repository` variable is deprecated nowadays, and we\nslowly but steadily convert the codebase to not use it anymore. Instead,\ncallers should be passing down the repository to work on via parameters.\n\nIt is hard though to prove that a given code unit does not use this\nvariable anymore. The most trivial case, merely demonstrating that there\nis no direct use of `the_repository`, is already a bit of a pain during\ncode reviews as the reviewer needs to manually verify claims made by the\npatch author. The bigger problem though is that we have many interfaces\nthat implicitly rely on `the_repository`.\n\nIntroduce a new `USE_THE_REPOSITORY_VARIABLE` macro that allows code\nunits to opt into usage of `the_repository`. The intent of this macro is\nto demonstrate that a certain code unit does not use this variable\nanymore, and to keep it from new dependencies on it in future changes,\nbe it explicit or implicit\n\nFor now, the macro only guards `the_repository` itself as well as\n`the_hash_algo`. There are many more known interfaces where we have an\nimplicit dependency on `the_repository`, but those are not guarded at\nthe current point in time. Over time though, we should start to add\nguards as required (or even better, just remove them).\n\nDefine the macro as required in our code units. As expected, most of our\ncode still relies on the global variable. Nearly all of our builtins\nrely on the variable as there is no way yet to pass `the_repository` to\ntheir entry point. For now, declare the macro in \"biultin.h\" to keep the\nrequired changes at least a little bit more contained.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n add-interactive.c                            | 2 ++\n add-patch.c                                  | 2 ++\n apply.c                                      | 2 ++\n archive-tar.c                                | 3 +++\n archive-zip.c                                | 3 +++\n archive.c                                    | 2 ++\n attr.c                                       | 2 ++\n bisect.c                                     | 2 ++\n blame.c                                      | 2 ++\n branch.c                                     | 2 ++\n builtin.h                                    | 8 ++++++++\n builtin/blame.c                              | 2 +-\n builtin/log.c                                | 2 +-\n bulk-checkin.c                               | 3 +++\n bundle-uri.c                                 | 2 ++\n bundle.c                                     | 2 ++\n cache-tree.c                                 | 2 ++\n checkout.c                                   | 2 ++\n chunk-format.c                               | 2 ++\n combine-diff.c                               | 2 ++\n commit-graph.c                               | 2 ++\n commit-reach.c                               | 2 ++\n commit.c                                     | 2 ++\n common-main.c                                | 2 ++\n compat/win32/trace2_win32_process_info.c     | 2 ++\n config.c                                     | 3 +++\n connected.c                                  | 2 ++\n convert.c                                    | 2 ++\n csum-file.c                                  | 3 +++\n delta-islands.c                              | 2 ++\n diagnose.c                                   | 2 ++\n diff-lib.c                                   | 3 +++\n diff.c                                       | 3 +++\n diffcore-break.c                             | 3 +++\n diffcore-rename.c                            | 3 +++\n dir.c                                        | 3 +++\n entry.c                                      | 2 ++\n environment.c                                | 3 +++\n fetch-pack.c                                 | 2 ++\n fmt-merge-msg.c                              | 2 ++\n fsck.c                                       | 2 ++\n fsmonitor-ipc.c                              | 2 ++\n git.c                                        | 2 ++\n hash-lookup.c                                | 2 ++\n hash.h                                       | 4 +++-\n help.c                                       | 2 ++\n hex.c                                        | 2 ++\n http-backend.c                               | 2 ++\n http-push.c                                  | 2 ++\n http-walker.c                                | 2 ++\n http.c                                       | 2 ++\n list-objects-filter-options.c                | 2 ++\n list-objects-filter.c                        | 2 ++\n list-objects.c                               | 2 ++\n log-tree.c                                   | 2 ++\n loose.c                                      | 2 ++\n ls-refs.c                                    | 2 ++\n mailmap.c                                    | 2 ++\n match-trees.c                                | 2 ++\n merge-blobs.c                                | 2 ++\n merge-ort.c                                  | 2 ++\n merge-recursive.c                            | 3 +++\n merge.c                                      | 2 ++\n midx-write.c                                 | 2 ++\n midx.c                                       | 2 ++\n negotiator/default.c                         | 2 ++\n negotiator/skipping.c                        | 2 ++\n notes-cache.c                                | 2 ++\n notes-merge.c                                | 2 ++\n notes-utils.c                                | 2 ++\n notes.c                                      | 2 ++\n object-file-convert.c                        | 2 ++\n object-file.c                                | 3 +++\n object-name.c                                | 2 ++\n object.c                                     | 2 ++\n oid-array.c                                  | 2 ++\n oss-fuzz/fuzz-commit-graph.c                 | 2 ++\n pack-bitmap-write.c                          | 2 ++\n pack-bitmap.c                                | 2 ++\n pack-check.c                                 | 2 ++\n pack-revindex.c                              | 2 ++\n pack-write.c                                 | 2 ++\n packfile.c                                   | 2 ++\n parse-options-cb.c                           | 2 ++\n path.c                                       | 3 +++\n pathspec.c                                   | 2 ++\n pretty.c                                     | 2 ++\n progress.c                                   | 2 ++\n promisor-remote.c                            | 2 ++\n range-diff.c                                 | 2 ++\n reachable.c                                  | 2 ++\n read-cache.c                                 | 3 +++\n rebase-interactive.c                         | 2 ++\n ref-filter.c                                 | 2 ++\n reflog-walk.c                                | 2 ++\n reflog.c                                     | 2 ++\n refs.c                                       | 2 ++\n refs/files-backend.c                         | 2 ++\n refs/packed-backend.c                        | 2 ++\n refs/reftable-backend.c                      | 2 ++\n refspec.c                                    | 2 ++\n remote-curl.c                                | 2 ++\n remote.c                                     | 2 ++\n repository.h                                 | 2 ++\n rerere.c                                     | 2 ++\n reset.c                                      | 2 ++\n resolve-undo.c                               | 2 ++\n revision.c                                   | 2 ++\n run-command.c                                | 2 ++\n scalar.c                                     | 2 ++\n send-pack.c                                  | 2 ++\n sequencer.c                                  | 2 ++\n serve.c                                      | 2 ++\n server-info.c                                | 2 ++\n setup.c                                      | 2 ++\n shallow.c                                    | 2 ++\n split-index.c                                | 2 ++\n streaming.c                                  | 3 +++\n submodule-config.c                           | 2 ++\n submodule.c                                  | 2 ++\n t/helper/test-bitmap.c                       | 2 ++\n t/helper/test-bloom.c                        | 2 ++\n t/helper/test-cache-tree.c                   | 2 ++\n t/helper/test-dump-cache-tree.c              | 2 ++\n t/helper/test-dump-fsmonitor.c               | 2 ++\n t/helper/test-dump-split-index.c             | 2 ++\n t/helper/test-dump-untracked-cache.c         | 2 ++\n t/helper/test-find-pack.c                    | 2 ++\n t/helper/test-fsmonitor-client.c             | 2 ++\n t/helper/test-lazy-init-name-hash.c          | 2 ++\n t/helper/test-match-trees.c                  | 2 ++\n t/helper/test-oidmap.c                       | 2 ++\n t/helper/test-pack-mtimes.c                  | 2 ++\n t/helper/test-reach.c                        | 2 ++\n t/helper/test-read-cache.c                   | 2 ++\n t/helper/test-read-graph.c                   | 2 ++\n t/helper/test-read-midx.c                    | 2 ++\n t/helper/test-ref-store.c                    | 2 ++\n t/helper/test-repository.c                   | 2 ++\n t/helper/test-revision-walking.c             | 2 ++\n t/helper/test-scrap-cache-tree.c             | 2 ++\n t/helper/test-submodule-config.c             | 2 ++\n t/helper/test-submodule-nested-repo-config.c | 2 ++\n t/helper/test-submodule.c                    | 2 ++\n t/helper/test-trace2.c                       | 2 ++\n t/helper/test-write-cache.c                  | 2 ++\n t/unit-tests/t-example-decorate.c            | 2 ++\n tag.c                                        | 2 ++\n tmp-objdir.c                                 | 2 ++\n transport-helper.c                           | 2 ++\n transport.c                                  | 2 ++\n tree-walk.c                                  | 2 ++\n tree.c                                       | 2 ++\n unpack-trees.c                               | 2 ++\n upload-pack.c                                | 2 ++\n walker.c                                     | 2 ++\n worktree.c                                   | 2 ++\n wt-status.c                                  | 2 ++\n xdiff-interface.c                            | 2 ++\n 159 files changed, 339 insertions(+), 3 deletions(-)\n\ndiff --git a/add-interactive.c b/add-interactive.c\nindex a0961096cd..49042b3026 100644\n--- a/add-interactive.c\n+++ b/add-interactive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"add-interactive.h\"\n #include \"color.h\"\ndiff --git a/add-patch.c b/add-patch.c\nindex 86181770f2..99e037c1e2 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"add-interactive.h\"\n #include \"advice.h\"\ndiff --git a/apply.c b/apply.c\nindex 528939abb6..ff939f908a 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -7,6 +7,8 @@\n  *\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"base85.h\"\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 8ae30125f8..e7b3489e1e 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2005, 2006 Rene Scharfe\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\ndiff --git a/archive-zip.c b/archive-zip.c\nindex fd1d3f816d..9f32730181 100644\n--- a/archive-zip.c\n+++ b/archive-zip.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2006 Rene Scharfe\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"archive.h\"\ndiff --git a/archive.c b/archive.c\nindex 5287fcdd8e..7bd60d0632 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/attr.c b/attr.c\nindex 300f994ba6..b5ed83c90e 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -6,6 +6,8 @@\n  * an insanely large number of attributes.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/bisect.c b/bisect.c\nindex 4ea703bec1..135f94ba09 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/blame.c b/blame.c\nindex a80f5e2e61..d403c46a35 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"refs.h\"\n #include \"object-store-ll.h\"\ndiff --git a/branch.c b/branch.c\nindex df5d24fec6..c887ea2151 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/builtin.h b/builtin.h\nindex 7eda9b2486..14fa017160 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -1,6 +1,14 @@\n #ifndef BUILTIN_H\n #define BUILTIN_H\n \n+/*\n+ * TODO: Almost all of our builtins access `the_repository` by necessity\n+ * because they do not get passed a pointer to it. We should adapt the function\n+ * signature of those main functions to accept a `struct repository *` and then\n+ * remove the macro here.\n+ */\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n \n /*\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex e09ff0155a..de89fff3f8 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -5,7 +5,7 @@\n  * See COPYING for licensing conditions\n  */\n \n-#include \"git-compat-util.h\"\n+#include \"builtin.h\"\n #include \"config.h\"\n #include \"color.h\"\n #include \"builtin.h\"\ndiff --git a/builtin/log.c b/builtin/log.c\nindex ccbda8a005..00305bea51 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -4,7 +4,7 @@\n  * (C) Copyright 2006 Linus Torvalds\n  *\t\t 2006 Junio Hamano\n  */\n-#include \"git-compat-util.h\"\n+#include \"builtin.h\"\n #include \"abspath.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/bulk-checkin.c b/bulk-checkin.c\nindex eb46b88637..da8673199b 100644\n--- a/bulk-checkin.c\n+++ b/bulk-checkin.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2011, Google Inc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bulk-checkin.h\"\n #include \"environment.h\"\ndiff --git a/bundle-uri.c b/bundle-uri.c\nindex 91b3319a5c..804fbcfbfa 100644\n--- a/bundle-uri.c\n+++ b/bundle-uri.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bundle-uri.h\"\n #include \"bundle.h\"\ndiff --git a/bundle.c b/bundle.c\nindex 95367c2d0a..82c285b905 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"lockfile.h\"\n #include \"bundle.h\"\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 3290a1b8dd..50610c3f3c 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/checkout.c b/checkout.c\nindex cfaea4bd10..0b1cf8b40b 100644\n--- a/checkout.c\n+++ b/checkout.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-name.h\"\n #include \"remote.h\"\ndiff --git a/chunk-format.c b/chunk-format.c\nindex cdc7f39b70..2dde24e6a3 100644\n--- a/chunk-format.c\n+++ b/chunk-format.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"chunk-format.h\"\n #include \"csum-file.h\"\ndiff --git a/combine-diff.c b/combine-diff.c\nindex 4960d904ac..829a44e416 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-store-ll.h\"\n #include \"commit.h\"\ndiff --git a/commit-graph.c b/commit-graph.c\nindex e4eefd83bf..b6bb9df0d0 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"csum-file.h\"\ndiff --git a/commit-reach.c b/commit-reach.c\nindex 384aee1ab3..dabc2972e4 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"commit-graph.h\"\ndiff --git a/commit.c b/commit.c\nindex 1d08951007..4956803e11 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tag.h\"\n #include \"commit.h\"\ndiff --git a/common-main.c b/common-main.c\nindex b86f40600f..8e68ac9e42 100644\n--- a/common-main.c\n+++ b/common-main.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"exec-cmd.h\"\n #include \"gettext.h\"\ndiff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\nindex 3ef0936f6f..f147da706a 100644\n--- a/compat/win32/trace2_win32_process_info.c\n+++ b/compat/win32/trace2_win32_process_info.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../../git-compat-util.h\"\n #include \"../../json-writer.h\"\n #include \"../../repository.h\"\ndiff --git a/config.c b/config.c\nindex abce05b774..7951029644 100644\n--- a/config.c\n+++ b/config.c\n@@ -5,6 +5,9 @@\n  * Copyright (C) Johannes Schindelin, 2005\n  *\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"advice.h\"\ndiff --git a/connected.c b/connected.c\nindex 8f89376dbc..87cc4b57a1 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/convert.c b/convert.c\nindex f2b9f01354..d8737fe0f2 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/csum-file.c b/csum-file.c\nindex f4be0804b7..8abbf01325 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -7,6 +7,9 @@\n  * files. Useful when you write a file that you want to be\n  * able to verify hasn't been messed with afterwards.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"progress.h\"\n #include \"csum-file.h\"\ndiff --git a/delta-islands.c b/delta-islands.c\nindex 89d51b72e3..ffe1ca2814 100644\n--- a/delta-islands.c\n+++ b/delta-islands.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object.h\"\n #include \"commit.h\"\ndiff --git a/diagnose.c b/diagnose.c\nindex 4d096c857f..cc2d535b60 100644\n--- a/diagnose.c\n+++ b/diagnose.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diagnose.h\"\n #include \"compat/disk.h\"\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 3fb8d79fef..b0d0f711e8 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"diff.h\"\ndiff --git a/diff.c b/diff.c\nindex 60d1f7be81..d4579d5f76 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"base85.h\"\ndiff --git a/diffcore-break.c b/diffcore-break.c\nindex 49ba38aa7c..831b66b5c3 100644\n--- a/diffcore-break.c\n+++ b/diffcore-break.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diffcore.h\"\n #include \"hash.h\"\ndiff --git a/diffcore-rename.c b/diffcore-rename.c\nindex 5abb958651..ae504007cf 100644\n--- a/diffcore-rename.c\n+++ b/diffcore-rename.c\n@@ -2,6 +2,9 @@\n  *\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diff.h\"\n #include \"diffcore.h\"\ndiff --git a/dir.c b/dir.c\nindex 5de421c29c..b7a6625ebd 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -5,6 +5,9 @@\n  * Copyright (C) Linus Torvalds, 2005-2006\n  *\t\t Junio Hamano, 2005-2006\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/entry.c b/entry.c\nindex b8c257f6f9..fe1f74d140 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-store-ll.h\"\n #include \"dir.h\"\ndiff --git a/environment.c b/environment.c\nindex 701d515135..5cea2c9f54 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -7,6 +7,9 @@\n  * even if you might want to know where the git directory etc\n  * are.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"branch.h\"\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex eba9e420ea..e6e14b3874 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\ndiff --git a/fmt-merge-msg.c b/fmt-merge-msg.c\nindex 7d144b803a..b8bca89c0c 100644\n--- a/fmt-merge-msg.c\n+++ b/fmt-merge-msg.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/fsck.c b/fsck.c\nindex dd0a33028e..432996cbb6 100644\n--- a/fsck.c\n+++ b/fsck.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"date.h\"\n #include \"dir.h\"\ndiff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c\nindex 45471b5b74..f1b1631111 100644\n--- a/fsmonitor-ipc.c\n+++ b/fsmonitor-ipc.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"simple-ipc.h\"\ndiff --git a/git.c b/git.c\nindex 683bb69194..e35af9b0e5 100644\n--- a/git.c\n+++ b/git.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/hash-lookup.c b/hash-lookup.c\nindex 9aa6b82eb7..5f808caa51 100644\n--- a/hash-lookup.c\n+++ b/hash-lookup.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"hash-lookup.h\"\ndiff --git a/hash.h b/hash.h\nindex 39a0164be3..cb85d26a2f 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -4,6 +4,8 @@\n #include \"hash-ll.h\"\n #include \"repository.h\"\n \n-#define the_hash_algo the_repository->hash_algo\n+#ifdef USE_THE_REPOSITORY_VARIABLE\n+# define the_hash_algo the_repository->hash_algo\n+#endif\n \n #endif\ndiff --git a/help.c b/help.c\nindex 1d057aa607..10fdb1a03d 100644\n--- a/help.c\n+++ b/help.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"builtin.h\"\ndiff --git a/hex.c b/hex.c\nindex bc9e86a978..5ca78a7744 100644\n--- a/hex.c\n+++ b/hex.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"hex.h\"\ndiff --git a/http-backend.c b/http-backend.c\nindex 5b65287ac9..7c0b3be968 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/http-push.c b/http-push.c\nindex a97df4a1fb..7315a694aa 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/http-walker.c b/http-walker.c\nindex b7110b6f82..e417a7f51c 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"hex.h\"\ndiff --git a/http.c b/http.c\nindex 67cc47d28f..6536816e81 100644\n--- a/http.c\n+++ b/http.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"git-curl-compat.h\"\n #include \"hex.h\"\ndiff --git a/list-objects-filter-options.c b/list-objects-filter-options.c\nindex c5f363ca6f..00611107d2 100644\n--- a/list-objects-filter-options.c\n+++ b/list-objects-filter-options.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\ndiff --git a/list-objects-filter.c b/list-objects-filter.c\nindex 4346f8da45..49e2fa6f97 100644\n--- a/list-objects-filter.c\n+++ b/list-objects-filter.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"gettext.h\"\ndiff --git a/list-objects.c b/list-objects.c\nindex 11ad8be411..985d008799 100644\n--- a/list-objects.c\n+++ b/list-objects.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tag.h\"\n #include \"commit.h\"\ndiff --git a/log-tree.c b/log-tree.c\nindex 41416de4e3..223a4d9463 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit-reach.h\"\n #include \"config.h\"\ndiff --git a/loose.c b/loose.c\nindex f6faa6216a..a8bf772172 100644\n--- a/loose.c\n+++ b/loose.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"path.h\"\ndiff --git a/ls-refs.c b/ls-refs.c\nindex 398afe4ce3..2dd925b43d 100644\n--- a/ls-refs.c\n+++ b/ls-refs.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/mailmap.c b/mailmap.c\nindex b2efe29b3d..534a3eb4f0 100644\n--- a/mailmap.c\n+++ b/mailmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"string-list.h\"\ndiff --git a/match-trees.c b/match-trees.c\nindex 50c42e2061..f17c74d483 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"match-trees.h\"\ndiff --git a/merge-blobs.c b/merge-blobs.c\nindex 2f659fd014..0ad0390fea 100644\n--- a/merge-blobs.c\n+++ b/merge-blobs.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-ll.h\"\n #include \"blob.h\"\ndiff --git a/merge-ort.c b/merge-ort.c\nindex eaede6cead..691db9050e 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -14,6 +14,8 @@\n  * \"cale\", \"peedy\", or \"ins\" instead of \"ort\"?)\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-ort.h\"\n \ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex 8ff29ed09e..46ee364af7 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -3,6 +3,9 @@\n  * Fredrik Kuivinen.\n  * The thieves were Alex Riesen and Johannes Schindelin, in June/July 2006\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-recursive.h\"\n \ndiff --git a/merge.c b/merge.c\nindex 752a937fa9..fe3efa4b24 100644\n--- a/merge.c\n+++ b/merge.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/midx-write.c b/midx-write.c\nindex 55a6b63bac..9a194e8aac 100644\n--- a/midx-write.c\n+++ b/midx-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/midx.c b/midx.c\nindex 1e75f1a7eb..3992b05465 100644\n--- a/midx.c\n+++ b/midx.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"dir.h\"\ndiff --git a/negotiator/default.c b/negotiator/default.c\nindex 518b3c43b2..e3fa5c3324 100644\n--- a/negotiator/default.c\n+++ b/negotiator/default.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"default.h\"\n #include \"../commit.h\"\ndiff --git a/negotiator/skipping.c b/negotiator/skipping.c\nindex b7e008c2fd..f109928ad0 100644\n--- a/negotiator/skipping.c\n+++ b/negotiator/skipping.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"skipping.h\"\n #include \"../commit.h\"\ndiff --git a/notes-cache.c b/notes-cache.c\nindex 038db01ca0..ecfdf6e43b 100644\n--- a/notes-cache.c\n+++ b/notes-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"notes-cache.h\"\n #include \"object-store-ll.h\"\ndiff --git a/notes-merge.c b/notes-merge.c\nindex 801941c2d1..d95e683414 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"commit.h\"\ndiff --git a/notes-utils.c b/notes-utils.c\nindex e33aa86c4b..bca71274be 100644\n--- a/notes-utils.c\n+++ b/notes-utils.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/notes.c b/notes.c\nindex afe2e2882e..b6a13d0980 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex f684038f7f..958f61f094 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"strbuf.h\"\ndiff --git a/object-file.c b/object-file.c\nindex 72318c8dd4..a6555ed68c 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -6,6 +6,9 @@\n  * This handles basic git object files - packing, unpacking,\n  * creation etc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/object-name.c b/object-name.c\nindex 523af6f64f..d7509514bc 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-name.h\"\n #include \"advice.h\"\ndiff --git a/object.c b/object.c\nindex 93b5d97fdb..0c0fcb76c0 100644\n--- a/object.c\n+++ b/object.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/oid-array.c b/oid-array.c\nindex 1f36651754..9cac974395 100644\n--- a/oid-array.c\n+++ b/oid-array.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"oid-array.h\"\n #include \"hash-lookup.h\"\ndiff --git a/oss-fuzz/fuzz-commit-graph.c b/oss-fuzz/fuzz-commit-graph.c\nindex 75e668a057..951c9c082f 100644\n--- a/oss-fuzz/fuzz-commit-graph.c\n+++ b/oss-fuzz/fuzz-commit-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit-graph.h\"\n #include \"repository.h\"\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 59d2e3a387..37a8ad0fb3 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 184d28f05c..7eafdce4ee 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"gettext.h\"\ndiff --git a/pack-check.c b/pack-check.c\nindex 288f5a3479..d78289da3c 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/pack-revindex.c b/pack-revindex.c\nindex fc63aa76a2..de922b47d2 100644\n--- a/pack-revindex.c\n+++ b/pack-revindex.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"pack-revindex.h\"\ndiff --git a/pack-write.c b/pack-write.c\nindex eef625fa5b..d07f03d0ab 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/packfile.c b/packfile.c\nindex ec7312cd20..813584646f 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/parse-options-cb.c b/parse-options-cb.c\nindex d99d688d3c..3fb7ce68ca 100644\n--- a/parse-options-cb.c\n+++ b/parse-options-cb.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"parse-options.h\"\n #include \"branch.h\"\ndiff --git a/path.c b/path.c\nindex adfb3d3eb7..19f7684f38 100644\n--- a/path.c\n+++ b/path.c\n@@ -1,6 +1,9 @@\n /*\n  * Utilities for paths and pathnames\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"environment.h\"\ndiff --git a/pathspec.c b/pathspec.c\nindex 2133b9fe60..fe1f0f41af 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"parse.h\"\ndiff --git a/pretty.c b/pretty.c\nindex 22a81506b7..2c14a88abc 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/progress.c b/progress.c\nindex c83cb60bf1..0d44c18edc 100644\n--- a/progress.c\n+++ b/progress.c\n@@ -9,6 +9,8 @@\n  */\n \n #define GIT_TEST_PROGRESS_ONLY\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"pager.h\"\n #include \"progress.h\"\ndiff --git a/promisor-remote.c b/promisor-remote.c\nindex 2ca7c2ae48..317e1b127f 100644\n--- a/promisor-remote.c\n+++ b/promisor-remote.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/range-diff.c b/range-diff.c\nindex c45b6d849c..5f01605550 100644\n--- a/range-diff.c\n+++ b/range-diff.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/reachable.c b/reachable.c\nindex 1224b30008..46613a6bb6 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/read-cache.c b/read-cache.c\nindex 085b22faf3..48bf24f87c 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -3,6 +3,9 @@\n  *\n  * Copyright (C) Linus Torvalds, 2005\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bulk-checkin.h\"\n #include \"config.h\"\ndiff --git a/rebase-interactive.c b/rebase-interactive.c\nindex c343e16fcd..e93b385523 100644\n--- a/rebase-interactive.c\n+++ b/rebase-interactive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"editor.h\"\ndiff --git a/ref-filter.c b/ref-filter.c\nindex f7fb0c7e0e..8c5e673fc0 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 5f09552c5c..c7070b13b0 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"refs.h\"\ndiff --git a/reflog.c b/reflog.c\nindex 3c80950186..5ca944529b 100644\n--- a/reflog.c\n+++ b/reflog.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"object-store-ll.h\"\ndiff --git a/refs.c b/refs.c\nindex 6e7caefdcf..727ed6c1d6 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2,6 +2,8 @@\n  * The backend-independent part of the reference module.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex b484b5880d..35931bc71e 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../copy.h\"\n #include \"../environment.h\"\ndiff --git a/refs/packed-backend.c b/refs/packed-backend.c\nindex 5ab1b21d10..a0666407cd 100644\n--- a/refs/packed-backend.c\n+++ b/refs/packed-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../config.h\"\n #include \"../dir.h\"\ndiff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\nindex 57df2aba66..6e34eb2188 100644\n--- a/refs/reftable-backend.c\n+++ b/refs/reftable-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../abspath.h\"\n #include \"../chdir-notify.h\"\ndiff --git a/refspec.c b/refspec.c\nindex d60932f4de..c2e3e24351 100644\n--- a/refspec.c\n+++ b/refspec.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 6008d7e87c..1930f83cc7 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"git-curl-compat.h\"\n #include \"config.h\"\ndiff --git a/remote.c b/remote.c\nindex 1064171085..5fab7f0970 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/repository.h b/repository.h\nindex a35cd77c35..29727edec6 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -197,7 +197,9 @@ struct repository {\n \tunsigned different_commondir:1;\n };\n \n+#ifdef USE_THE_REPOSITORY_VARIABLE\n extern struct repository *the_repository;\n+#endif\n \n /*\n  * Define a custom repository layout. Any field can be NULL, which\ndiff --git a/rerere.c b/rerere.c\nindex c7e1f8fd25..597256fa5b 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/reset.c b/reset.c\nindex 937f11c0f4..9550dea03d 100644\n--- a/reset.c\n+++ b/reset.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"cache-tree.h\"\n #include \"gettext.h\"\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex 4e6f0e4676..8c9911affb 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"hash.h\"\ndiff --git a/revision.c b/revision.c\nindex 7ddf0f151a..40da255953 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/run-command.c b/run-command.c\nindex 31b20123d8..f5fde92b7c 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"run-command.h\"\n #include \"environment.h\"\ndiff --git a/scalar.c b/scalar.c\nindex 331b91dbdb..a1cb4b45b5 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -2,6 +2,8 @@\n  * The Scalar command-line interface.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"gettext.h\"\ndiff --git a/send-pack.c b/send-pack.c\nindex 37f59d4f66..b42e6986df 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/sequencer.c b/sequencer.c\nindex 823691e379..8083fe20bf 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"advice.h\"\ndiff --git a/serve.c b/serve.c\nindex aa651b73e9..33608ea4d5 100644\n--- a/serve.c\n+++ b/serve.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\ndiff --git a/server-info.c b/server-info.c\nindex 6feaa457c5..97e839c33d 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"environment.h\"\ndiff --git a/setup.c b/setup.c\nindex 20f380825b..7e1169eb86 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"copy.h\"\ndiff --git a/shallow.c b/shallow.c\nindex a0b181ba8a..31a6ca40fe 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"repository.h\"\ndiff --git a/split-index.c b/split-index.c\nindex 058a8f448e..120c8190b1 100644\n--- a/split-index.c\n+++ b/split-index.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/streaming.c b/streaming.c\nindex 10adf625b2..38839511af 100644\n--- a/streaming.c\n+++ b/streaming.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2011, Google Inc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"convert.h\"\n #include \"environment.h\"\ndiff --git a/submodule-config.c b/submodule-config.c\nindex ad43a282da..9b0bb0b9f4 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"environment.h\"\ndiff --git a/submodule.c b/submodule.c\nindex caf3aa5600..ab99a30253 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c\nindex af43ee1cb5..1f18d57007 100644\n--- a/t/helper/test-bitmap.c\n+++ b/t/helper/test-bitmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"git-compat-util.h\"\n #include \"pack-bitmap.h\"\ndiff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c\nindex 1281e66876..f7f9b62002 100644\n--- a/t/helper/test-bloom.c\n+++ b/t/helper/test-bloom.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"bloom.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c\nindex dc89ecfd71..5cdef3ebef 100644\n--- a/t/helper/test-cache-tree.c\n+++ b/t/helper/test-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c\nindex 02b0b46c3f..3f0c7d0ed0 100644\n--- a/t/helper/test-dump-cache-tree.c\n+++ b/t/helper/test-dump-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hash.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c\nindex 4f215fea02..1b7f37a84f 100644\n--- a/t/helper/test-dump-fsmonitor.c\n+++ b/t/helper/test-dump-fsmonitor.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"read-cache-ll.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c\nindex f472691a3c..a6720faf9c 100644\n--- a/t/helper/test-dump-split-index.c\n+++ b/t/helper/test-dump-split-index.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c\nindex 9ff67c3967..4f010d5324 100644\n--- a/t/helper/test-dump-untracked-cache.c\n+++ b/t/helper/test-dump-untracked-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"dir.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c\nindex e8bd793e58..14b2b0c12c 100644\n--- a/t/helper/test-find-pack.c\n+++ b/t/helper/test-find-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"object-name.h\"\n #include \"object-store.h\"\ndiff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\nindex 8280984d08..02bfe92e8d 100644\n--- a/t/helper/test-fsmonitor-client.c\n+++ b/t/helper/test-fsmonitor-client.c\n@@ -3,6 +3,8 @@\n  * a `git fsmonitor--daemon` daemon.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"parse-options.h\"\n #include \"fsmonitor-ipc.h\"\ndiff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c\nindex 5f33bb7b8f..40f5df4412 100644\n--- a/t/helper/test-lazy-init-name-hash.c\n+++ b/t/helper/test-lazy-init-name-hash.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"environment.h\"\n #include \"name-hash.h\"\ndiff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c\nindex d0db5ff26f..e0e2048320 100644\n--- a/t/helper/test-match-trees.c\n+++ b/t/helper/test-match-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"match-trees.h\"\ndiff --git a/t/helper/test-oidmap.c b/t/helper/test-oidmap.c\nindex bd30244a54..c03cfa5ecf 100644\n--- a/t/helper/test-oidmap.c\n+++ b/t/helper/test-oidmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"object-name.h\"\ndiff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c\nindex 67a964ef90..f8f9afbb5b 100644\n--- a/t/helper/test-pack-mtimes.c\n+++ b/t/helper/test-pack-mtimes.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"strbuf.h\"\ndiff --git a/t/helper/test-reach.c b/t/helper/test-reach.c\nindex 1ba226f1f9..5dd374379c 100644\n--- a/t/helper/test-reach.c\n+++ b/t/helper/test-reach.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit.h\"\n #include \"commit-reach.h\"\ndiff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c\nindex e803c43ece..d285c656bd 100644\n--- a/t/helper/test-read-cache.c\n+++ b/t/helper/test-read-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"config.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c\nindex 8c7a83f578..d9e980d04c 100644\n--- a/t/helper/test-read-graph.c\n+++ b/t/helper/test-read-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit-graph.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c\nindex 4acae41bb9..83effc2b5f 100644\n--- a/t/helper/test-read-midx.c\n+++ b/t/helper/test-read-midx.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"midx.h\"\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex ad24300170..637b8b294e 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"refs.h\"\ndiff --git a/t/helper/test-repository.c b/t/helper/test-repository.c\nindex 0c7c5aa4dd..c6a074df3d 100644\n--- a/t/helper/test-repository.c\n+++ b/t/helper/test-repository.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit-graph.h\"\n #include \"commit.h\"\ndiff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c\nindex f346951bc2..071f5bd1e2 100644\n--- a/t/helper/test-revision-walking.c\n+++ b/t/helper/test-revision-walking.c\n@@ -8,6 +8,8 @@\n  * published by the Free Software Foundation.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit.h\"\n #include \"diff.h\"\ndiff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c\nindex 737cbe475b..64fff6e9e3 100644\n--- a/t/helper/test-scrap-cache-tree.c\n+++ b/t/helper/test-scrap-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"lockfile.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex 4b809d9dca..cbe93f2f9e 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"config.h\"\n #include \"hash.h\"\ndiff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c\nindex ecd40ded99..6ca069ce63 100644\n--- a/t/helper/test-submodule-nested-repo-config.c\n+++ b/t/helper/test-submodule-nested-repo-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"repository.h\"\n #include \"setup.h\"\ndiff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c\nindex 7197969a08..22e518d229 100644\n--- a/t/helper/test-submodule.c\n+++ b/t/helper/test-submodule.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"test-tool-utils.h\"\n #include \"parse-options.h\"\ndiff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c\nindex 1adac29a57..cd955ec63e 100644\n--- a/t/helper/test-trace2.c\n+++ b/t/helper/test-trace2.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"strvec.h\"\n #include \"run-command.h\"\ndiff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c\nindex 7e3da380a9..b37dd2c5d6 100644\n--- a/t/helper/test-write-cache.c\n+++ b/t/helper/test-write-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"lockfile.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/unit-tests/t-example-decorate.c b/t/unit-tests/t-example-decorate.c\nindex 3c856a8cf2..a4a75db735 100644\n--- a/t/unit-tests/t-example-decorate.c\n+++ b/t/unit-tests/t-example-decorate.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-lib.h\"\n #include \"object.h\"\n #include \"decorate.h\"\ndiff --git a/tag.c b/tag.c\nindex 52bbe50819..d24170e340 100644\n--- a/tag.c\n+++ b/tag.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"tag.h\"\ndiff --git a/tmp-objdir.c b/tmp-objdir.c\nindex 3509258be5..a8e4553f27 100644\n--- a/tmp-objdir.c\n+++ b/tmp-objdir.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tmp-objdir.h\"\n #include \"abspath.h\"\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 9820947ab2..09b3560ffd 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"transport.h\"\n #include \"quote.h\"\ndiff --git a/transport.c b/transport.c\nindex 83ddea8fbc..b9c8827ed9 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/tree-walk.c b/tree-walk.c\nindex 535a3a2539..a033397965 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tree-walk.h\"\n #include \"dir.h\"\ndiff --git a/tree.c b/tree.c\nindex 7973d3f9a8..ad86ad1ba9 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"tree.h\"\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 304ea2ed86..7dc884fafd 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"strvec.h\"\ndiff --git a/upload-pack.c b/upload-pack.c\nindex b726f7a57d..0052c6a4dc 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/walker.c b/walker.c\nindex 946d86b04e..0fafdc97cf 100644\n--- a/walker.c\n+++ b/walker.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/worktree.c b/worktree.c\nindex 70844d023a..f3c4c8ec54 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"environment.h\"\ndiff --git a/wt-status.c b/wt-status.c\nindex 5051f5e599..8815df419e 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"wt-status.h\"\ndiff --git a/xdiff-interface.c b/xdiff-interface.c\nindex 16ed8ac492..d5dc88661e 100644\n--- a/xdiff-interface.c\n+++ b/xdiff-interface.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"config.h\"\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497067","messageId":"4492548209bde9e43ed01d012a3bfaadf9e2ab04.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 10/20] refs: avoid include cycle with \"repository.h\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:10Z","receivedAt":"2024-06-13T06:14:15Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"There is an include cycle between \"refs.h\" and \"repository.h\" via\n\"commit.h\", \"object.h\" and \"hash.h\". This has the effect that several\ndefinitions of structs and enums will not be visible once we merge\n\"hash-ll.h\" back into \"hash.h\" in the next commit.\n\nThe only reason that \"repository.h\" includes \"refs.h\" is the definition\nof `enum ref_storage_format`. Move it into \"repository.h\" and have\n\"refs.h\" include \"repository.h\" instead to fix the cycle.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n refs.h       | 8 +-------\n repository.h | 7 ++++++-\n 2 files changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/refs.h b/refs.h\nindex 76d25df4de..a9716e5d25 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -2,21 +2,15 @@\n #define REFS_H\n \n #include \"commit.h\"\n+#include \"repository.h\"\n \n struct object_id;\n struct ref_store;\n-struct repository;\n struct strbuf;\n struct string_list;\n struct string_list_item;\n struct worktree;\n \n-enum ref_storage_format {\n-\tREF_STORAGE_FORMAT_UNKNOWN,\n-\tREF_STORAGE_FORMAT_FILES,\n-\tREF_STORAGE_FORMAT_REFTABLE,\n-};\n-\n enum ref_storage_format ref_storage_format_by_name(const char *name);\n const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format);\n \ndiff --git a/repository.h b/repository.h\nindex 29727edec6..6ce6826c26 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -1,7 +1,6 @@\n #ifndef REPOSITORY_H\n #define REPOSITORY_H\n \n-#include \"refs.h\"\n #include \"strmap.h\"\n \n struct config_set;\n@@ -27,6 +26,12 @@ enum fetch_negotiation_setting {\n \tFETCH_NEGOTIATION_NOOP,\n };\n \n+enum ref_storage_format {\n+\tREF_STORAGE_FORMAT_UNKNOWN,\n+\tREF_STORAGE_FORMAT_FILES,\n+\tREF_STORAGE_FORMAT_REFTABLE,\n+};\n+\n struct repo_settings {\n \tint initialized;\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497068","messageId":"f3cbc4b9f91a19e06949c26a05ebf917bc5b5514.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 11/20] hash-ll: merge with \"hash.h\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:15Z","receivedAt":"2024-06-13T06:14:20Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"hash-ll.h\" header was introduced via d1cbe1e6d8 (hash-ll.h: split\nout of hash.h to remove dependency on repository.h, 2023-04-22) to make\nexplicit the split between hash-related functions that rely on the\nglobal `the_repository`, and those that don't. This split is no longer\nnecessary now that we we have removed the reliance on `the_repository`.\n\nMerge \"hash-ll.h\" back into \"hash.h\". This causes some code units to not\ninclude \"repository.h\" anymore, which requires us to add some forward\ndeclarations.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n apply.h                    |   2 +-\n bloom.c                    |   1 +\n checkout.h                 |   2 +-\n chunk-format.h             |   2 +-\n commit-graph.h             |   2 +\n compat/sha1-chunked.c      |   2 +-\n convert.h                  |   2 +-\n csum-file.h                |   2 +-\n diff.h                     |   2 +-\n diffcore.h                 |   2 +-\n dir.h                      |   2 +-\n hash-ll.h                  | 364 -------------------------------------\n hash.h                     | 362 +++++++++++++++++++++++++++++++++++-\n hex.h                      |   2 +-\n loose.h                    |   2 +\n merge-ort.h                |   2 +-\n object-file-convert.c      |   2 +-\n object.h                   |   2 +-\n oidmap.h                   |   2 +-\n oidtree.h                  |   2 +-\n packfile.h                 |   2 +\n protocol-caps.c            |   2 +-\n read-cache-ll.h            |   2 +-\n refs/ref-cache.h           |   2 +-\n reftable/dump.c            |   2 +-\n reftable/reftable-record.h |   2 +-\n reftable/system.h          |   2 +-\n remote.h                   |   2 +-\n reset.h                    |   2 +-\n resolve-undo.h             |   2 +-\n serve.c                    |   2 +-\n split-index.h              |   2 +-\n t/helper/test-hash-speed.c |   2 +-\n t/helper/test-sha1.c       |   2 +-\n t/helper/test-sha256.c     |   2 +-\n t/unit-tests/lib-oid.h     |   2 +-\n tree-diff.c                |   1 +\n tree-walk.h                |   2 +-\n xdiff-interface.h          |   2 +-\n 39 files changed, 400 insertions(+), 398 deletions(-)\n delete mode 100644 hash-ll.h\n\ndiff --git a/apply.h b/apply.h\nindex 7cd38b1443..b9f18ce87d 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -1,7 +1,7 @@\n #ifndef APPLY_H\n #define APPLY_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"lockfile.h\"\n #include \"string-list.h\"\n #include \"strmap.h\"\ndiff --git a/bloom.c b/bloom.c\nindex e529f7605c..bbf146fc30 100644\n--- a/bloom.c\n+++ b/bloom.c\n@@ -6,6 +6,7 @@\n #include \"commit-graph.h\"\n #include \"commit.h\"\n #include \"commit-slab.h\"\n+#include \"repository.h\"\n \n define_commit_slab(bloom_filter_slab, struct bloom_filter);\n \ndiff --git a/checkout.h b/checkout.h\nindex ba15a13fb3..55920e7aeb 100644\n--- a/checkout.h\n+++ b/checkout.h\n@@ -1,7 +1,7 @@\n #ifndef CHECKOUT_H\n #define CHECKOUT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n /*\n  * Check if the branch name uniquely matches a branch name on a remote\ndiff --git a/chunk-format.h b/chunk-format.h\nindex 14b76180ef..212a0a6af1 100644\n--- a/chunk-format.h\n+++ b/chunk-format.h\n@@ -1,7 +1,7 @@\n #ifndef CHUNK_FORMAT_H\n #define CHUNK_FORMAT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct hashfile;\n struct chunkfile;\ndiff --git a/commit-graph.h b/commit-graph.h\nindex e519cb81cb..6781940195 100644\n--- a/commit-graph.h\n+++ b/commit-graph.h\n@@ -122,6 +122,8 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,\n struct commit_graph *read_commit_graph_one(struct repository *r,\n \t\t\t\t\t   struct object_directory *odb);\n \n+struct repo_settings;\n+\n /*\n  * Callers should initialize the repo_settings with prepare_repo_settings()\n  * prior to calling parse_commit_graph().\ndiff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c\nindex a4a6f930d7..0446f9983f 100644\n--- a/compat/sha1-chunked.c\n+++ b/compat/sha1-chunked.c\n@@ -1,5 +1,5 @@\n #include \"git-compat-util.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)\n {\ndiff --git a/convert.h b/convert.h\nindex d925589444..0a6e4086b8 100644\n--- a/convert.h\n+++ b/convert.h\n@@ -4,7 +4,7 @@\n #ifndef CONVERT_H\n #define CONVERT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"string-list.h\"\n \n struct index_state;\ndiff --git a/csum-file.h b/csum-file.h\nindex bc5bec27ac..566e05cbd2 100644\n--- a/csum-file.h\n+++ b/csum-file.h\n@@ -1,7 +1,7 @@\n #ifndef CSUM_FILE_H\n #define CSUM_FILE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"write-or-die.h\"\n \n struct progress;\ndiff --git a/diff.h b/diff.h\nindex 66bd8aeb29..9901c8ca8c 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -4,7 +4,7 @@\n #ifndef DIFF_H\n #define DIFF_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"pathspec.h\"\n #include \"strbuf.h\"\n \ndiff --git a/diffcore.h b/diffcore.h\nindex 5ffe4ec788..1701ed50b9 100644\n--- a/diffcore.h\n+++ b/diffcore.h\n@@ -4,7 +4,7 @@\n #ifndef DIFFCORE_H\n #define DIFFCORE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct diff_options;\n struct mem_pool;\ndiff --git a/dir.h b/dir.h\nindex 1398a53fb4..69a76d8bdd 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -1,7 +1,7 @@\n #ifndef DIR_H\n #define DIR_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"pathspec.h\"\n #include \"statinfo.h\"\ndiff --git a/hash-ll.h b/hash-ll.h\ndeleted file mode 100644\nindex 3161c778b9..0000000000\n--- a/hash-ll.h\n+++ /dev/null\n@@ -1,364 +0,0 @@\n-#ifndef HASH_LL_H\n-#define HASH_LL_H\n-\n-#if defined(SHA1_APPLE)\n-#include <CommonCrypto/CommonDigest.h>\n-#elif defined(SHA1_OPENSSL)\n-#  include <openssl/sha.h>\n-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n-#    define SHA1_NEEDS_CLONE_HELPER\n-#    include \"sha1/openssl.h\"\n-#  endif\n-#elif defined(SHA1_DC)\n-#include \"sha1dc_git.h\"\n-#else /* SHA1_BLK */\n-#include \"block-sha1/sha1.h\"\n-#endif\n-\n-#if defined(SHA256_NETTLE)\n-#include \"sha256/nettle.h\"\n-#elif defined(SHA256_GCRYPT)\n-#define SHA256_NEEDS_CLONE_HELPER\n-#include \"sha256/gcrypt.h\"\n-#elif defined(SHA256_OPENSSL)\n-#  include <openssl/sha.h>\n-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n-#    define SHA256_NEEDS_CLONE_HELPER\n-#    include \"sha256/openssl.h\"\n-#  endif\n-#else\n-#include \"sha256/block/sha256.h\"\n-#endif\n-\n-#ifndef platform_SHA_CTX\n-/*\n- * platform's underlying implementation of SHA-1; could be OpenSSL,\n- * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant\n- * SHA-1 header may have already defined platform_SHA_CTX for our\n- * own implementations like block-sha1, so we list\n- * the default for OpenSSL compatible SHA-1 implementations here.\n- */\n-#define platform_SHA_CTX\tSHA_CTX\n-#define platform_SHA1_Init\tSHA1_Init\n-#define platform_SHA1_Update\tSHA1_Update\n-#define platform_SHA1_Final    \tSHA1_Final\n-#endif\n-\n-#define git_SHA_CTX\t\tplatform_SHA_CTX\n-#define git_SHA1_Init\t\tplatform_SHA1_Init\n-#define git_SHA1_Update\t\tplatform_SHA1_Update\n-#define git_SHA1_Final\t\tplatform_SHA1_Final\n-\n-#ifdef platform_SHA1_Clone\n-#define git_SHA1_Clone\tplatform_SHA1_Clone\n-#endif\n-\n-#ifndef platform_SHA256_CTX\n-#define platform_SHA256_CTX\tSHA256_CTX\n-#define platform_SHA256_Init\tSHA256_Init\n-#define platform_SHA256_Update\tSHA256_Update\n-#define platform_SHA256_Final\tSHA256_Final\n-#endif\n-\n-#define git_SHA256_CTX\t\tplatform_SHA256_CTX\n-#define git_SHA256_Init\t\tplatform_SHA256_Init\n-#define git_SHA256_Update\tplatform_SHA256_Update\n-#define git_SHA256_Final\tplatform_SHA256_Final\n-\n-#ifdef platform_SHA256_Clone\n-#define git_SHA256_Clone\tplatform_SHA256_Clone\n-#endif\n-\n-#ifdef SHA1_MAX_BLOCK_SIZE\n-#include \"compat/sha1-chunked.h\"\n-#undef git_SHA1_Update\n-#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n-#endif\n-\n-#ifndef SHA1_NEEDS_CLONE_HELPER\n-static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)\n-{\n-\tmemcpy(dst, src, sizeof(*dst));\n-}\n-#endif\n-\n-#ifndef SHA256_NEEDS_CLONE_HELPER\n-static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)\n-{\n-\tmemcpy(dst, src, sizeof(*dst));\n-}\n-#endif\n-\n-/*\n- * Note that these constants are suitable for indexing the hash_algos array and\n- * comparing against each other, but are otherwise arbitrary, so they should not\n- * be exposed to the user or serialized to disk.  To know whether a\n- * git_hash_algo struct points to some usable hash function, test the format_id\n- * field for being non-zero.  Use the name field for user-visible situations and\n- * the format_id field for fixed-length fields on disk.\n- */\n-/* An unknown hash function. */\n-#define GIT_HASH_UNKNOWN 0\n-/* SHA-1 */\n-#define GIT_HASH_SHA1 1\n-/* SHA-256  */\n-#define GIT_HASH_SHA256 2\n-/* Number of algorithms supported (including unknown). */\n-#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)\n-\n-/* \"sha1\", big-endian */\n-#define GIT_SHA1_FORMAT_ID 0x73686131\n-\n-/* The length in bytes and in hex digits of an object name (SHA-1 value). */\n-#define GIT_SHA1_RAWSZ 20\n-#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)\n-/* The block size of SHA-1. */\n-#define GIT_SHA1_BLKSZ 64\n-\n-/* \"s256\", big-endian */\n-#define GIT_SHA256_FORMAT_ID 0x73323536\n-\n-/* The length in bytes and in hex digits of an object name (SHA-256 value). */\n-#define GIT_SHA256_RAWSZ 32\n-#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)\n-/* The block size of SHA-256. */\n-#define GIT_SHA256_BLKSZ 64\n-\n-/* The length in byte and in hex digits of the largest possible hash value. */\n-#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ\n-#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ\n-/* The largest possible block size for any supported hash. */\n-#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ\n-\n-struct object_id {\n-\tunsigned char hash[GIT_MAX_RAWSZ];\n-\tint algo;\t/* XXX requires 4-byte alignment */\n-};\n-\n-#define GET_OID_QUIETLY           01\n-#define GET_OID_COMMIT            02\n-#define GET_OID_COMMITTISH        04\n-#define GET_OID_TREE             010\n-#define GET_OID_TREEISH          020\n-#define GET_OID_BLOB             040\n-#define GET_OID_FOLLOW_SYMLINKS 0100\n-#define GET_OID_RECORD_PATH     0200\n-#define GET_OID_ONLY_TO_DIE    04000\n-#define GET_OID_REQUIRE_PATH  010000\n-#define GET_OID_HASH_ANY      020000\n-\n-#define GET_OID_DISAMBIGUATORS \\\n-\t(GET_OID_COMMIT | GET_OID_COMMITTISH | \\\n-\tGET_OID_TREE | GET_OID_TREEISH | \\\n-\tGET_OID_BLOB)\n-\n-enum get_oid_result {\n-\tFOUND = 0,\n-\tMISSING_OBJECT = -1, /* The requested object is missing */\n-\tSHORT_NAME_AMBIGUOUS = -2,\n-\t/* The following only apply when symlinks are followed */\n-\tDANGLING_SYMLINK = -4, /*\n-\t\t\t\t* The initial symlink is there, but\n-\t\t\t\t* (transitively) points to a missing\n-\t\t\t\t* in-tree file\n-\t\t\t\t*/\n-\tSYMLINK_LOOP = -5,\n-\tNOT_DIR = -6, /*\n-\t\t       * Somewhere along the symlink chain, a path is\n-\t\t       * requested which contains a file as a\n-\t\t       * non-final element.\n-\t\t       */\n-};\n-\n-/* A suitably aligned type for stack allocations of hash contexts. */\n-union git_hash_ctx {\n-\tgit_SHA_CTX sha1;\n-\tgit_SHA256_CTX sha256;\n-};\n-typedef union git_hash_ctx git_hash_ctx;\n-\n-typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);\n-typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);\n-typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);\n-typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);\n-typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);\n-\n-struct git_hash_algo {\n-\t/*\n-\t * The name of the algorithm, as appears in the config file and in\n-\t * messages.\n-\t */\n-\tconst char *name;\n-\n-\t/* A four-byte version identifier, used in pack indices. */\n-\tuint32_t format_id;\n-\n-\t/* The length of the hash in binary. */\n-\tsize_t rawsz;\n-\n-\t/* The length of the hash in hex characters. */\n-\tsize_t hexsz;\n-\n-\t/* The block size of the hash. */\n-\tsize_t blksz;\n-\n-\t/* The hash initialization function. */\n-\tgit_hash_init_fn init_fn;\n-\n-\t/* The hash context cloning function. */\n-\tgit_hash_clone_fn clone_fn;\n-\n-\t/* The hash update function. */\n-\tgit_hash_update_fn update_fn;\n-\n-\t/* The hash finalization function. */\n-\tgit_hash_final_fn final_fn;\n-\n-\t/* The hash finalization function for object IDs. */\n-\tgit_hash_final_oid_fn final_oid_fn;\n-\n-\t/* The OID of the empty tree. */\n-\tconst struct object_id *empty_tree;\n-\n-\t/* The OID of the empty blob. */\n-\tconst struct object_id *empty_blob;\n-\n-\t/* The all-zeros OID. */\n-\tconst struct object_id *null_oid;\n-};\n-extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];\n-\n-/*\n- * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if\n- * the name doesn't match a known algorithm.\n- */\n-int hash_algo_by_name(const char *name);\n-/* Identical, except based on the format ID. */\n-int hash_algo_by_id(uint32_t format_id);\n-/* Identical, except based on the length. */\n-int hash_algo_by_length(int len);\n-/* Identical, except for a pointer to struct git_hash_algo. */\n-static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n-{\n-\treturn p - hash_algos;\n-}\n-\n-const struct object_id *null_oid(void);\n-\n-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n-{\n-\t/*\n-\t * Teach the compiler that there are only two possibilities of hash size\n-\t * here, so that it can optimize for this case as much as possible.\n-\t */\n-\tif (algop->rawsz == GIT_MAX_RAWSZ)\n-\t\treturn memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n-\treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n-}\n-\n-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n-{\n-\t/*\n-\t * We write this here instead of deferring to hashcmp so that the\n-\t * compiler can properly inline it and avoid calling memcmp.\n-\t */\n-\tif (algop->rawsz == GIT_MAX_RAWSZ)\n-\t\treturn !memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n-\treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n-}\n-\n-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n-\t\t\t   const struct git_hash_algo *algop)\n-{\n-\tmemcpy(sha_dst, sha_src, algop->rawsz);\n-}\n-\n-static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n-{\n-\tmemset(hash, 0, algop->rawsz);\n-}\n-\n-static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n-}\n-\n-static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n-}\n-\n-static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n-{\n-\tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\n-\tdst->algo = src->algo;\n-}\n-\n-static inline void oidread(struct object_id *oid, const unsigned char *hash,\n-\t\t\t   const struct git_hash_algo *algop)\n-{\n-\tmemcpy(oid->hash, hash, algop->rawsz);\n-\tif (algop->rawsz < GIT_MAX_RAWSZ)\n-\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline void oidclr(struct object_id *oid,\n-\t\t\t  const struct git_hash_algo *algop)\n-{\n-\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline struct object_id *oiddup(const struct object_id *src)\n-{\n-\tstruct object_id *dst = xmalloc(sizeof(struct object_id));\n-\toidcpy(dst, src);\n-\treturn dst;\n-}\n-\n-static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)\n-{\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-/*\n- * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code\n- * for use in hash tables. Cryptographic hashes are supposed to have\n- * uniform distribution, so in contrast to `memhash()`, this just copies\n- * the first `sizeof(int)` bytes without shuffling any bits. Note that\n- * the results will be different on big-endian and little-endian\n- * platforms, so they should not be stored or transferred over the net.\n- */\n-static inline unsigned int oidhash(const struct object_id *oid)\n-{\n-\t/*\n-\t * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on\n-\t * platforms that don't support unaligned reads.\n-\t */\n-\tunsigned int hash;\n-\tmemcpy(&hash, oid->hash, sizeof(hash));\n-\treturn hash;\n-}\n-\n-static inline int is_null_oid(const struct object_id *oid)\n-{\n-\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n-\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n-}\n-\n-const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n-\n-static inline int is_empty_blob_oid(const struct object_id *oid,\n-\t\t\t\t    const struct git_hash_algo *algop)\n-{\n-\treturn oideq(oid, algop->empty_blob);\n-}\n-\n-static inline int is_empty_tree_oid(const struct object_id *oid,\n-\t\t\t\t    const struct git_hash_algo *algop)\n-{\n-\treturn oideq(oid, algop->empty_tree);\n-}\n-\n-#endif\ndiff --git a/hash.h b/hash.h\nindex cb85d26a2f..72ffbc862e 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -1,11 +1,369 @@\n #ifndef HASH_H\n #define HASH_H\n \n-#include \"hash-ll.h\"\n-#include \"repository.h\"\n+#if defined(SHA1_APPLE)\n+#include <CommonCrypto/CommonDigest.h>\n+#elif defined(SHA1_OPENSSL)\n+#  include <openssl/sha.h>\n+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n+#    define SHA1_NEEDS_CLONE_HELPER\n+#    include \"sha1/openssl.h\"\n+#  endif\n+#elif defined(SHA1_DC)\n+#include \"sha1dc_git.h\"\n+#else /* SHA1_BLK */\n+#include \"block-sha1/sha1.h\"\n+#endif\n+\n+#if defined(SHA256_NETTLE)\n+#include \"sha256/nettle.h\"\n+#elif defined(SHA256_GCRYPT)\n+#define SHA256_NEEDS_CLONE_HELPER\n+#include \"sha256/gcrypt.h\"\n+#elif defined(SHA256_OPENSSL)\n+#  include <openssl/sha.h>\n+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n+#    define SHA256_NEEDS_CLONE_HELPER\n+#    include \"sha256/openssl.h\"\n+#  endif\n+#else\n+#include \"sha256/block/sha256.h\"\n+#endif\n+\n+#ifndef platform_SHA_CTX\n+/*\n+ * platform's underlying implementation of SHA-1; could be OpenSSL,\n+ * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant\n+ * SHA-1 header may have already defined platform_SHA_CTX for our\n+ * own implementations like block-sha1, so we list\n+ * the default for OpenSSL compatible SHA-1 implementations here.\n+ */\n+#define platform_SHA_CTX\tSHA_CTX\n+#define platform_SHA1_Init\tSHA1_Init\n+#define platform_SHA1_Update\tSHA1_Update\n+#define platform_SHA1_Final    \tSHA1_Final\n+#endif\n+\n+#define git_SHA_CTX\t\tplatform_SHA_CTX\n+#define git_SHA1_Init\t\tplatform_SHA1_Init\n+#define git_SHA1_Update\t\tplatform_SHA1_Update\n+#define git_SHA1_Final\t\tplatform_SHA1_Final\n+\n+#ifdef platform_SHA1_Clone\n+#define git_SHA1_Clone\tplatform_SHA1_Clone\n+#endif\n+\n+#ifndef platform_SHA256_CTX\n+#define platform_SHA256_CTX\tSHA256_CTX\n+#define platform_SHA256_Init\tSHA256_Init\n+#define platform_SHA256_Update\tSHA256_Update\n+#define platform_SHA256_Final\tSHA256_Final\n+#endif\n+\n+#define git_SHA256_CTX\t\tplatform_SHA256_CTX\n+#define git_SHA256_Init\t\tplatform_SHA256_Init\n+#define git_SHA256_Update\tplatform_SHA256_Update\n+#define git_SHA256_Final\tplatform_SHA256_Final\n+\n+#ifdef platform_SHA256_Clone\n+#define git_SHA256_Clone\tplatform_SHA256_Clone\n+#endif\n+\n+#ifdef SHA1_MAX_BLOCK_SIZE\n+#include \"compat/sha1-chunked.h\"\n+#undef git_SHA1_Update\n+#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n+#endif\n+\n+#ifndef SHA1_NEEDS_CLONE_HELPER\n+static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)\n+{\n+\tmemcpy(dst, src, sizeof(*dst));\n+}\n+#endif\n+\n+#ifndef SHA256_NEEDS_CLONE_HELPER\n+static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)\n+{\n+\tmemcpy(dst, src, sizeof(*dst));\n+}\n+#endif\n+\n+/*\n+ * Note that these constants are suitable for indexing the hash_algos array and\n+ * comparing against each other, but are otherwise arbitrary, so they should not\n+ * be exposed to the user or serialized to disk.  To know whether a\n+ * git_hash_algo struct points to some usable hash function, test the format_id\n+ * field for being non-zero.  Use the name field for user-visible situations and\n+ * the format_id field for fixed-length fields on disk.\n+ */\n+/* An unknown hash function. */\n+#define GIT_HASH_UNKNOWN 0\n+/* SHA-1 */\n+#define GIT_HASH_SHA1 1\n+/* SHA-256  */\n+#define GIT_HASH_SHA256 2\n+/* Number of algorithms supported (including unknown). */\n+#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)\n+\n+/* \"sha1\", big-endian */\n+#define GIT_SHA1_FORMAT_ID 0x73686131\n+\n+/* The length in bytes and in hex digits of an object name (SHA-1 value). */\n+#define GIT_SHA1_RAWSZ 20\n+#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)\n+/* The block size of SHA-1. */\n+#define GIT_SHA1_BLKSZ 64\n+\n+/* \"s256\", big-endian */\n+#define GIT_SHA256_FORMAT_ID 0x73323536\n+\n+/* The length in bytes and in hex digits of an object name (SHA-256 value). */\n+#define GIT_SHA256_RAWSZ 32\n+#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)\n+/* The block size of SHA-256. */\n+#define GIT_SHA256_BLKSZ 64\n+\n+/* The length in byte and in hex digits of the largest possible hash value. */\n+#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ\n+#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ\n+/* The largest possible block size for any supported hash. */\n+#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ\n+\n+struct object_id {\n+\tunsigned char hash[GIT_MAX_RAWSZ];\n+\tint algo;\t/* XXX requires 4-byte alignment */\n+};\n+\n+#define GET_OID_QUIETLY           01\n+#define GET_OID_COMMIT            02\n+#define GET_OID_COMMITTISH        04\n+#define GET_OID_TREE             010\n+#define GET_OID_TREEISH          020\n+#define GET_OID_BLOB             040\n+#define GET_OID_FOLLOW_SYMLINKS 0100\n+#define GET_OID_RECORD_PATH     0200\n+#define GET_OID_ONLY_TO_DIE    04000\n+#define GET_OID_REQUIRE_PATH  010000\n+#define GET_OID_HASH_ANY      020000\n+\n+#define GET_OID_DISAMBIGUATORS \\\n+\t(GET_OID_COMMIT | GET_OID_COMMITTISH | \\\n+\tGET_OID_TREE | GET_OID_TREEISH | \\\n+\tGET_OID_BLOB)\n+\n+enum get_oid_result {\n+\tFOUND = 0,\n+\tMISSING_OBJECT = -1, /* The requested object is missing */\n+\tSHORT_NAME_AMBIGUOUS = -2,\n+\t/* The following only apply when symlinks are followed */\n+\tDANGLING_SYMLINK = -4, /*\n+\t\t\t\t* The initial symlink is there, but\n+\t\t\t\t* (transitively) points to a missing\n+\t\t\t\t* in-tree file\n+\t\t\t\t*/\n+\tSYMLINK_LOOP = -5,\n+\tNOT_DIR = -6, /*\n+\t\t       * Somewhere along the symlink chain, a path is\n+\t\t       * requested which contains a file as a\n+\t\t       * non-final element.\n+\t\t       */\n+};\n \n #ifdef USE_THE_REPOSITORY_VARIABLE\n+# include \"repository.h\"\n # define the_hash_algo the_repository->hash_algo\n #endif\n \n+/* A suitably aligned type for stack allocations of hash contexts. */\n+union git_hash_ctx {\n+\tgit_SHA_CTX sha1;\n+\tgit_SHA256_CTX sha256;\n+};\n+typedef union git_hash_ctx git_hash_ctx;\n+\n+typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);\n+typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);\n+typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);\n+typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);\n+typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);\n+\n+struct git_hash_algo {\n+\t/*\n+\t * The name of the algorithm, as appears in the config file and in\n+\t * messages.\n+\t */\n+\tconst char *name;\n+\n+\t/* A four-byte version identifier, used in pack indices. */\n+\tuint32_t format_id;\n+\n+\t/* The length of the hash in binary. */\n+\tsize_t rawsz;\n+\n+\t/* The length of the hash in hex characters. */\n+\tsize_t hexsz;\n+\n+\t/* The block size of the hash. */\n+\tsize_t blksz;\n+\n+\t/* The hash initialization function. */\n+\tgit_hash_init_fn init_fn;\n+\n+\t/* The hash context cloning function. */\n+\tgit_hash_clone_fn clone_fn;\n+\n+\t/* The hash update function. */\n+\tgit_hash_update_fn update_fn;\n+\n+\t/* The hash finalization function. */\n+\tgit_hash_final_fn final_fn;\n+\n+\t/* The hash finalization function for object IDs. */\n+\tgit_hash_final_oid_fn final_oid_fn;\n+\n+\t/* The OID of the empty tree. */\n+\tconst struct object_id *empty_tree;\n+\n+\t/* The OID of the empty blob. */\n+\tconst struct object_id *empty_blob;\n+\n+\t/* The all-zeros OID. */\n+\tconst struct object_id *null_oid;\n+};\n+extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];\n+\n+/*\n+ * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if\n+ * the name doesn't match a known algorithm.\n+ */\n+int hash_algo_by_name(const char *name);\n+/* Identical, except based on the format ID. */\n+int hash_algo_by_id(uint32_t format_id);\n+/* Identical, except based on the length. */\n+int hash_algo_by_length(int len);\n+/* Identical, except for a pointer to struct git_hash_algo. */\n+static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n+{\n+\treturn p - hash_algos;\n+}\n+\n+const struct object_id *null_oid(void);\n+\n+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+{\n+\t/*\n+\t * Teach the compiler that there are only two possibilities of hash size\n+\t * here, so that it can optimize for this case as much as possible.\n+\t */\n+\tif (algop->rawsz == GIT_MAX_RAWSZ)\n+\t\treturn memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n+\treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n+}\n+\n+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+{\n+\t/*\n+\t * We write this here instead of deferring to hashcmp so that the\n+\t * compiler can properly inline it and avoid calling memcmp.\n+\t */\n+\tif (algop->rawsz == GIT_MAX_RAWSZ)\n+\t\treturn !memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n+\treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n+}\n+\n+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(sha_dst, sha_src, algop->rawsz);\n+}\n+\n+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n+{\n+\tmemset(hash, 0, algop->rawsz);\n+}\n+\n+static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n+{\n+\tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\n+\tdst->algo = src->algo;\n+}\n+\n+static inline void oidread(struct object_id *oid, const unsigned char *hash,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(oid->hash, hash, algop->rawsz);\n+\tif (algop->rawsz < GIT_MAX_RAWSZ)\n+\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline void oidclr(struct object_id *oid,\n+\t\t\t  const struct git_hash_algo *algop)\n+{\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline struct object_id *oiddup(const struct object_id *src)\n+{\n+\tstruct object_id *dst = xmalloc(sizeof(struct object_id));\n+\toidcpy(dst, src);\n+\treturn dst;\n+}\n+\n+static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)\n+{\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+/*\n+ * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code\n+ * for use in hash tables. Cryptographic hashes are supposed to have\n+ * uniform distribution, so in contrast to `memhash()`, this just copies\n+ * the first `sizeof(int)` bytes without shuffling any bits. Note that\n+ * the results will be different on big-endian and little-endian\n+ * platforms, so they should not be stored or transferred over the net.\n+ */\n+static inline unsigned int oidhash(const struct object_id *oid)\n+{\n+\t/*\n+\t * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on\n+\t * platforms that don't support unaligned reads.\n+\t */\n+\tunsigned int hash;\n+\tmemcpy(&hash, oid->hash, sizeof(hash));\n+\treturn hash;\n+}\n+\n+static inline int is_null_oid(const struct object_id *oid)\n+{\n+\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n+\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n+}\n+\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n+\n+static inline int is_empty_blob_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_blob);\n+}\n+\n+static inline int is_empty_tree_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_tree);\n+}\n+\n #endif\ndiff --git a/hex.h b/hex.h\nindex e0b83f776f..9809667f33 100644\n--- a/hex.h\n+++ b/hex.h\n@@ -1,7 +1,7 @@\n #ifndef HEX_H\n #define HEX_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hex-ll.h\"\n \n /*\ndiff --git a/loose.h b/loose.h\nindex 2c2957072c..28512306e5 100644\n--- a/loose.h\n+++ b/loose.h\n@@ -3,6 +3,8 @@\n \n #include \"khash.h\"\n \n+struct repository;\n+\n struct loose_object_map {\n \tkh_oid_map_t *to_compat;\n \tkh_oid_map_t *to_storage;\ndiff --git a/merge-ort.h b/merge-ort.h\nindex ce56ec1a78..a994c9a5fc 100644\n--- a/merge-ort.h\n+++ b/merge-ort.h\n@@ -2,7 +2,7 @@\n #define MERGE_ORT_H\n \n #include \"merge-recursive.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct commit;\n struct tree;\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex 958f61f094..3887d6d57b 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -5,7 +5,7 @@\n #include \"strbuf.h\"\n #include \"hex.h\"\n #include \"repository.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hash.h\"\n #include \"object.h\"\n #include \"loose.h\"\ndiff --git a/object.h b/object.h\nindex 73b4ec3904..9fa42d51d9 100644\n--- a/object.h\n+++ b/object.h\n@@ -1,7 +1,7 @@\n #ifndef OBJECT_H\n #define OBJECT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct buffer_slab;\n struct repository;\ndiff --git a/oidmap.h b/oidmap.h\nindex 05c673eb7c..fad412827a 100644\n--- a/oidmap.h\n+++ b/oidmap.h\n@@ -1,7 +1,7 @@\n #ifndef OIDMAP_H\n #define OIDMAP_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n \n /*\ndiff --git a/oidtree.h b/oidtree.h\nindex 55c83513fd..77898f510a 100644\n--- a/oidtree.h\n+++ b/oidtree.h\n@@ -2,7 +2,7 @@\n #define OIDTREE_H\n \n #include \"cbtree.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"mem-pool.h\"\n \n struct oidtree {\ndiff --git a/packfile.h b/packfile.h\nindex 28c8fd3e39..eb18ec15db 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -101,6 +101,8 @@ int close_pack_fd(struct packed_git *p);\n \n uint32_t get_pack_fanout(struct packed_git *p, uint32_t value);\n \n+struct raw_object_store;\n+\n unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);\n void close_pack_windows(struct packed_git *);\n void close_pack(struct packed_git *);\ndiff --git a/protocol-caps.c b/protocol-caps.c\nindex 75f4cbb0a7..fe8d1d5c63 100644\n--- a/protocol-caps.c\n+++ b/protocol-caps.c\n@@ -3,7 +3,7 @@\n #include \"gettext.h\"\n #include \"hex.h\"\n #include \"pkt-line.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hex.h\"\n #include \"object.h\"\n #include \"object-store-ll.h\"\ndiff --git a/read-cache-ll.h b/read-cache-ll.h\nindex 09414afd04..e0e39607ef 100644\n--- a/read-cache-ll.h\n+++ b/read-cache-ll.h\n@@ -1,7 +1,7 @@\n #ifndef READ_CACHE_LL_H\n #define READ_CACHE_LL_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"statinfo.h\"\n \ndiff --git a/refs/ref-cache.h b/refs/ref-cache.h\nindex 95c76e27c8..31ebe24f6c 100644\n--- a/refs/ref-cache.h\n+++ b/refs/ref-cache.h\n@@ -1,7 +1,7 @@\n #ifndef REFS_REF_CACHE_H\n #define REFS_REF_CACHE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct ref_dir;\n struct ref_store;\ndiff --git a/reftable/dump.c b/reftable/dump.c\nindex 41abbb8ecf..dd65d9e8bb 100644\n--- a/reftable/dump.c\n+++ b/reftable/dump.c\n@@ -7,7 +7,7 @@ license that can be found in the LICENSE file or at\n */\n \n #include \"git-compat-util.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n #include \"reftable-blocksource.h\"\n #include \"reftable-error.h\"\ndiff --git a/reftable/reftable-record.h b/reftable/reftable-record.h\nindex 2a2943cd13..ff486eb1f7 100644\n--- a/reftable/reftable-record.h\n+++ b/reftable/reftable-record.h\n@@ -9,7 +9,7 @@ license that can be found in the LICENSE file or at\n #ifndef REFTABLE_RECORD_H\n #define REFTABLE_RECORD_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include <stdint.h>\n \n /*\ndiff --git a/reftable/system.h b/reftable/system.h\nindex 5d8b6dede5..d0cabd5d17 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -15,7 +15,7 @@ license that can be found in the LICENSE file or at\n #include \"lockfile.h\"\n #include \"strbuf.h\"\n #include \"tempfile.h\"\n-#include \"hash-ll.h\" /* hash ID, sizes.*/\n+#include \"hash.h\" /* hash ID, sizes.*/\n #include \"dir.h\" /* remove_dir_recursively, for tests.*/\n \n int hash_size(uint32_t id);\ndiff --git a/remote.h b/remote.h\nindex e8c6655e42..7d04e1be1b 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -1,7 +1,7 @@\n #ifndef REMOTE_H\n #define REMOTE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"refspec.h\"\n \ndiff --git a/reset.h b/reset.h\nindex 10708d8ddc..a28f81829d 100644\n--- a/reset.h\n+++ b/reset.h\n@@ -1,7 +1,7 @@\n #ifndef RESET_H\n #define RESET_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"repository.h\"\n \n #define GIT_REFLOG_ACTION_ENVIRONMENT \"GIT_REFLOG_ACTION\"\ndiff --git a/resolve-undo.h b/resolve-undo.h\nindex f3f8462751..89a3227262 100644\n--- a/resolve-undo.h\n+++ b/resolve-undo.h\n@@ -6,7 +6,7 @@ struct index_state;\n struct pathspec;\n struct string_list;\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct resolve_undo_info {\n \tunsigned int mode[3];\ndiff --git a/serve.c b/serve.c\nindex 33608ea4d5..884cd84ca8 100644\n--- a/serve.c\n+++ b/serve.c\n@@ -3,7 +3,7 @@\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"pkt-line.h\"\n #include \"version.h\"\n #include \"ls-refs.h\"\ndiff --git a/split-index.h b/split-index.h\nindex 15a29cd08c..1a153f47ba 100644\n--- a/split-index.h\n+++ b/split-index.h\n@@ -1,7 +1,7 @@\n #ifndef SPLIT_INDEX_H\n #define SPLIT_INDEX_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct index_state;\n struct strbuf;\ndiff --git a/t/helper/test-hash-speed.c b/t/helper/test-hash-speed.c\nindex b235da594f..7de822af51 100644\n--- a/t/helper/test-hash-speed.c\n+++ b/t/helper/test-hash-speed.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n #define NUM_SECONDS 3\n \ndiff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c\nindex dcb7f6c003..e60d000c03 100644\n--- a/t/helper/test-sha1.c\n+++ b/t/helper/test-sha1.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int cmd__sha1(int ac, const char **av)\n {\ndiff --git a/t/helper/test-sha256.c b/t/helper/test-sha256.c\nindex 08cf149001..2fb20438f3 100644\n--- a/t/helper/test-sha256.c\n+++ b/t/helper/test-sha256.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int cmd__sha256(int ac, const char **av)\n {\ndiff --git a/t/unit-tests/lib-oid.h b/t/unit-tests/lib-oid.h\nindex bfde639190..8d2acca768 100644\n--- a/t/unit-tests/lib-oid.h\n+++ b/t/unit-tests/lib-oid.h\n@@ -1,7 +1,7 @@\n #ifndef LIB_OID_H\n #define LIB_OID_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n /*\n  * Convert arbitrary hex string to object_id.\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 46107772d1..9252481df3 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -8,6 +8,7 @@\n #include \"tree.h\"\n #include \"tree-walk.h\"\n #include \"environment.h\"\n+#include \"repository.h\"\n \n /*\n  * Some mode bits are also used internally for computations.\ndiff --git a/tree-walk.h b/tree-walk.h\nindex 0b1067fbc5..aaea689f9a 100644\n--- a/tree-walk.h\n+++ b/tree-walk.h\n@@ -1,7 +1,7 @@\n #ifndef TREE_WALK_H\n #define TREE_WALK_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct index_state;\n struct repository;\ndiff --git a/xdiff-interface.h b/xdiff-interface.h\nindex 38537169b7..1ed430b622 100644\n--- a/xdiff-interface.h\n+++ b/xdiff-interface.h\n@@ -1,7 +1,7 @@\n #ifndef XDIFF_INTERFACE_H\n #define XDIFF_INTERFACE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"xdiff/xdiff.h\"\n \n /*\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497069","messageId":"9178098dd7ae60883c93ace78973c4c0e73bd143.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 12/20] http-fetch: don't crash when parsing packfile without a repo","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:19Z","receivedAt":"2024-06-13T06:14:24Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The git-http-fetch(1) command accepts a `--packfile=` option, which\nallows the user to specify that it shall fetch a specific packfile,\nonly. The parameter here is the hash of the packfile, which is specific\nto the object hash used by the repository. This requirement is implicit\nthough via our use of `parse_oid_hex()`, which internally uses\n`the_repository`.\n\nThe git-http-fetch(1) command allows for there to be no repository\nthough, which only exists such that we can show usage via the \"-h\"\noption. In that case though, starting with c8aed5e8da (repository: stop\nsetting SHA1 as the default object hash, 2024-05-07), `the_repository`\ndoes not have its object hash initialized anymore and thus we would\ncrash when trying to parse the object ID outside of a repository.\n\nFix this issue by dying immediately when we see a \"--packfile=\"\nparameter when outside a Git repository. This is not a functional\nregression as we would die later on with the same error anyway.\n\nAdd a test to detect the segfault. We use the \"nongit\" function to do\nso, which we need to allow-list in `test_must_fail ()`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n http-fetch.c               | 8 +++++++-\n t/t5550-http-fetch-dumb.sh | 6 ++++++\n t/test-lib-functions.sh    | 5 +++++\n 3 files changed, 18 insertions(+), 1 deletion(-)\n\ndiff --git a/http-fetch.c b/http-fetch.c\nindex bec94988bb..d460bb1837 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\n@@ -127,8 +129,12 @@ int cmd_main(int argc, const char **argv)\n \t\t} else if (skip_prefix(argv[arg], \"--packfile=\", &p)) {\n \t\t\tconst char *end;\n \n+\t\t\tif (nongit)\n+\t\t\t\tdie(_(\"not a git repository\"));\n+\n \t\t\tpackfile = 1;\n-\t\t\tif (parse_oid_hex(p, &packfile_hash, &end) || *end)\n+\t\t\tif (parse_oid_hex_algop(p, &packfile_hash, &end,\n+\t\t\t\t\t\tthe_repository->hash_algo) || *end)\n \t\t\t\tdie(_(\"argument to --packfile must be a valid hash (got '%s')\"), p);\n \t\t} else if (skip_prefix(argv[arg], \"--index-pack-arg=\", &p)) {\n \t\t\tstrvec_push(&index_pack_args, p);\ndiff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh\nindex 5f16cbc58d..ea8e48f627 100755\n--- a/t/t5550-http-fetch-dumb.sh\n+++ b/t/t5550-http-fetch-dumb.sh\n@@ -25,6 +25,12 @@ test_expect_success 'setup repository' '\n \tgit commit -m two\n '\n \n+test_expect_success 'packfile without repository does not crash' '\n+\techo \"fatal: not a git repository\" >expect &&\n+\ttest_must_fail nongit git http-fetch --packfile=abc 2>err &&\n+\ttest_cmp expect err\n+'\n+\n setup_post_update_server_info_hook () {\n \ttest_hook --setup -C \"$1\" post-update <<-\\EOF &&\n \texec git update-server-info\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nindex 862d80c974..34bc7d7da4 100644\n--- a/t/test-lib-functions.sh\n+++ b/t/test-lib-functions.sh\n@@ -1096,6 +1096,11 @@ test_must_fail_acceptable () {\n \t\tdone\n \tfi\n \n+\tif test \"$1\" = \"nongit\"\n+\tthen\n+\t\tshift\n+\tfi\n+\n \tcase \"$1\" in\n \tgit|__git*|scalar|test-tool|test_terminal)\n \t\treturn 0\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497070","messageId":"0b4436c32baf17525cc203bd0b816fd04f586c17.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 13/20] oidset: pass hash algorithm when parsing file","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:24Z","receivedAt":"2024-06-13T06:14:28Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `oidset_parse_file_carefully()` function implicitly depends on\n`the_repository` when parsing object IDs. Fix this by having callers\npass in the hash algorithm to use.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/blame.c | 1 +\n fsck.c          | 3 ++-\n oidset.c        | 8 +++++---\n oidset.h        | 4 +++-\n 4 files changed, 11 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex de89fff3f8..18f1a3cea0 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -852,6 +852,7 @@ static void build_ignorelist(struct blame_scoreboard *sb,\n \t\t\toidset_clear(&sb->ignore_list);\n \t\telse\n \t\t\toidset_parse_file_carefully(&sb->ignore_list, i->string,\n+\t\t\t\t\t\t    the_repository->hash_algo,\n \t\t\t\t\t\t    peel_to_commit_oid, sb);\n \t}\n \tfor_each_string_list_item(i, ignore_rev_list) {\ndiff --git a/fsck.c b/fsck.c\nindex 432996cbb6..304f4a17ec 100644\n--- a/fsck.c\n+++ b/fsck.c\n@@ -205,7 +205,8 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values)\n \t\tif (!strcmp(buf, \"skiplist\")) {\n \t\t\tif (equal == len)\n \t\t\t\tdie(\"skiplist requires a path\");\n-\t\t\toidset_parse_file(&options->skiplist, buf + equal + 1);\n+\t\t\toidset_parse_file(&options->skiplist, buf + equal + 1,\n+\t\t\t\t\t  the_repository->hash_algo);\n \t\t\tbuf += len + 1;\n \t\t\tcontinue;\n \t\t}\ndiff --git a/oidset.c b/oidset.c\nindex 91d1385910..8d36aef8dc 100644\n--- a/oidset.c\n+++ b/oidset.c\n@@ -48,12 +48,14 @@ void oidset_clear(struct oidset *set)\n \toidset_init(set, 0);\n }\n \n-void oidset_parse_file(struct oidset *set, const char *path)\n+void oidset_parse_file(struct oidset *set, const char *path,\n+\t\t       const struct git_hash_algo *algop)\n {\n-\toidset_parse_file_carefully(set, path, NULL, NULL);\n+\toidset_parse_file_carefully(set, path, algop, NULL, NULL);\n }\n \n void oidset_parse_file_carefully(struct oidset *set, const char *path,\n+\t\t\t\t const struct git_hash_algo *algop,\n \t\t\t\t oidset_parse_tweak_fn fn, void *cbdata)\n {\n \tFILE *fp;\n@@ -79,7 +81,7 @@ void oidset_parse_file_carefully(struct oidset *set, const char *path,\n \t\tif (!sb.len)\n \t\t\tcontinue;\n \n-\t\tif (parse_oid_hex(sb.buf, &oid, &p) || *p != '\\0')\n+\t\tif (parse_oid_hex_algop(sb.buf, &oid, &p, algop) || *p != '\\0')\n \t\t\tdie(\"invalid object name: %s\", sb.buf);\n \t\tif (fn && fn(&oid, cbdata))\n \t\t\tcontinue;\ndiff --git a/oidset.h b/oidset.h\nindex 262f4256d6..0106b6f278 100644\n--- a/oidset.h\n+++ b/oidset.h\n@@ -80,7 +80,8 @@ void oidset_clear(struct oidset *set);\n  * are allowed.  Leading whitespace and empty or white-space only lines are\n  * ignored.\n  */\n-void oidset_parse_file(struct oidset *set, const char *path);\n+void oidset_parse_file(struct oidset *set, const char *path,\n+\t\t       const struct git_hash_algo *algop);\n \n /*\n  * Similar to the above, but with a callback which can (1) return non-zero to\n@@ -89,6 +90,7 @@ void oidset_parse_file(struct oidset *set, const char *path);\n  */\n typedef int (*oidset_parse_tweak_fn)(struct object_id *, void *);\n void oidset_parse_file_carefully(struct oidset *set, const char *path,\n+\t\t\t\t const struct git_hash_algo *algop,\n \t\t\t\t oidset_parse_tweak_fn fn, void *cbdata);\n \n struct oidset_iter {\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497071","messageId":"c7abfbc48994515fa19350e80309d8d0f4798470.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 14/20] protocol-caps: use hash algorithm from passed-in repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:29Z","receivedAt":"2024-06-13T06:14:34Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In `send_info()`, we pass in a repository but then use `get_oid_hex()`\nto parse passed-in object IDs, which implicitly uses `the_repository`.\nFix this by using the hash algorithm from the passed-in repository\ninstead.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n protocol-caps.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/protocol-caps.c b/protocol-caps.c\nindex fe8d1d5c63..855f279c2f 100644\n--- a/protocol-caps.c\n+++ b/protocol-caps.c\n@@ -7,6 +7,7 @@\n #include \"hex.h\"\n #include \"object.h\"\n #include \"object-store-ll.h\"\n+#include \"repository.h\"\n #include \"string-list.h\"\n #include \"strbuf.h\"\n \n@@ -52,7 +53,7 @@ static void send_info(struct repository *r, struct packet_writer *writer,\n \t\tstruct object_id oid;\n \t\tunsigned long object_size;\n \n-\t\tif (get_oid_hex(oid_str, &oid) < 0) {\n+\t\tif (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {\n \t\t\tpacket_writer_error(\n \t\t\t\twriter,\n \t\t\t\t\"object-info: protocol error, expected to get oid, not '%s'\",\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497072","messageId":"9ae4fdb8f1cd7dee969a6f813289d100a003c099.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 15/20] replace-object: use hash algorithm from passed-in repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:34Z","receivedAt":"2024-06-13T06:14:38Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In `register_replace_ref()`, we pass in a repository but then use\n`get_oid_hex()` to parse passed-in object IDs, which implicitly uses\n`the_repository`. Fix this by using the hash algorithm from the\npassed-in repository instead.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n replace-object.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/replace-object.c b/replace-object.c\nindex 73f5acbcd9..59252d565e 100644\n--- a/replace-object.c\n+++ b/replace-object.c\n@@ -20,7 +20,7 @@ static int register_replace_ref(const char *refname,\n \tconst char *hash = slash ? slash + 1 : refname;\n \tstruct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));\n \n-\tif (get_oid_hex(hash, &repl_obj->original.oid)) {\n+\tif (get_oid_hex_algop(hash, &repl_obj->original.oid, r->hash_algo)) {\n \t\tfree(repl_obj);\n \t\twarning(_(\"bad replace ref name: %s\"), refname);\n \t\treturn 0;\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497073","messageId":"3ceb726655e72f8bca0864b5bc3978df5b011e19.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 16/20] compat/fsmonitor: fix socket path in networked SHA256 repos","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:39Z","receivedAt":"2024-06-13T06:14:43Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The IPC socket used by the fsmonitor on Darwin is usually contained in\nthe Git repository itself. When the repository is hosted on a networked\nfilesystem though, we instead create the socket path in the user's home\ndirectory or the socket directory. In that case, we derive the path by\nhashing the repository path.\n\nBut while we always use SHA1 to hash the repository path, we then end up\nusing `hash_to_hex()` to append the computed hash to the socket path.\nThis is wrong because `hash_to_hex()` uses the hash algorithm configured\nin `the_repository`, which may not be SHA1. The consequence is that we\nmay append uninitialized bytes to the path when operating in a SHA256\nrepository.\n\nFix this bug by using `hash_to_hex_algop()` with SHA1.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n compat/fsmonitor/fsm-ipc-darwin.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/compat/fsmonitor/fsm-ipc-darwin.c b/compat/fsmonitor/fsm-ipc-darwin.c\nindex 6f3a95410c..52f4f29720 100644\n--- a/compat/fsmonitor/fsm-ipc-darwin.c\n+++ b/compat/fsmonitor/fsm-ipc-darwin.c\n@@ -17,7 +17,7 @@ const char *fsmonitor_ipc__get_path(struct repository *r)\n \tgit_SHA_CTX sha1ctx;\n \tchar *sock_dir = NULL;\n \tstruct strbuf ipc_file = STRBUF_INIT;\n-\tunsigned char hash[GIT_MAX_RAWSZ];\n+\tunsigned char hash[GIT_SHA1_RAWSZ];\n \n \tif (!r)\n \t\tBUG(\"No repository passed into fsmonitor_ipc__get_path\");\n@@ -41,9 +41,10 @@ const char *fsmonitor_ipc__get_path(struct repository *r)\n \t/* Create the socket file in either socketDir or $HOME */\n \tif (sock_dir && *sock_dir) {\n \t\tstrbuf_addf(&ipc_file, \"%s/.git-fsmonitor-%s\",\n-\t\t\t\t\tsock_dir, hash_to_hex(hash));\n+\t\t\t    sock_dir, hash_to_hex_algop(hash, &hash_algos[GIT_HASH_SHA1]));\n \t} else {\n-\t\tstrbuf_addf(&ipc_file, \"~/.git-fsmonitor-%s\", hash_to_hex(hash));\n+\t\tstrbuf_addf(&ipc_file, \"~/.git-fsmonitor-%s\",\n+\t\t\t    hash_to_hex_algop(hash, &hash_algos[GIT_HASH_SHA1]));\n \t}\n \tfree(sock_dir);\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497074","messageId":"74e5489bd077ee60b08fd4631c8113669bbc2b25.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 17/20] t/helper: use correct object hash in partial-clone helper","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:44Z","receivedAt":"2024-06-13T06:14:48Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `object_info()` function of the partial-clone helper is responsible\nfor checking the object ID of a repository other than `the_repository`.\nWe use `parse_oid_hex()` in this function though, which means that we\nstill depend on `the_repository->hash_algo`.\n\nFix this by using the object hash of the function-local repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-partial-clone.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c\nindex 910a128614..0ead529167 100644\n--- a/t/helper/test-partial-clone.c\n+++ b/t/helper/test-partial-clone.c\n@@ -21,7 +21,7 @@ static void object_info(const char *gitdir, const char *oid_hex)\n \n \tif (repo_init(&r, gitdir, NULL))\n \t\tdie(\"could not init repo\");\n-\tif (parse_oid_hex(oid_hex, &oid, &p))\n+\tif (parse_oid_hex_algop(oid_hex, &oid, &p, r.hash_algo))\n \t\tdie(\"could not parse oid\");\n \tif (oid_object_info_extended(&r, &oid, &oi, 0))\n \t\tdie(\"could not obtain object info\");\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497075","messageId":"470aea1fc85b0dce983ce5a81aeac28df62e8ea7.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 18/20] t/helper: fix segfault in \"oid-array\" command without repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:49Z","receivedAt":"2024-06-13T06:14:53Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"oid-array\" test helper can supposedly work without a Git\nrepository, but will in fact crash because `the_repository->hash_algo`\nis not initialized. This is because `oid_pos()`, which is used by\n`oid_array_lookup()`, depends on `the_hash_algo->rawsz`.\n\nIdeally, we'd adapt `oid_pos()` to not depend on `the_hash_algo`\nanymore. That is a bigger untertaking though, so instead we fall back to\nSHA1 when there is no repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-oid-array.c |  4 ++++\n t/t0064-oid-array.sh      | 18 ++++++++++++++++++\n 2 files changed, 22 insertions(+)\n\ndiff --git a/t/helper/test-oid-array.c b/t/helper/test-oid-array.c\nindex aafe398ef0..076b849cbf 100644\n--- a/t/helper/test-oid-array.c\n+++ b/t/helper/test-oid-array.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"oid-array.h\"\n@@ -17,6 +19,8 @@ int cmd__oid_array(int argc UNUSED, const char **argv UNUSED)\n \tint nongit_ok;\n \n \tsetup_git_directory_gently(&nongit_ok);\n+\tif (nongit_ok)\n+\t\trepo_set_hash_algo(the_repository, GIT_HASH_SHA1);\n \n \twhile (strbuf_getline(&line, stdin) != EOF) {\n \t\tconst char *arg;\ndiff --git a/t/t0064-oid-array.sh b/t/t0064-oid-array.sh\nindex 88c89e8f48..de74b692d0 100755\n--- a/t/t0064-oid-array.sh\n+++ b/t/t0064-oid-array.sh\n@@ -15,6 +15,24 @@ echoid () {\n \tdone\n }\n \n+test_expect_success 'without repository' '\n+\tcat >expect <<-EOF &&\n+\t4444444444444444444444444444444444444444\n+\t5555555555555555555555555555555555555555\n+\t8888888888888888888888888888888888888888\n+\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n+\tEOF\n+\tcat >input <<-EOF &&\n+\tappend 4444444444444444444444444444444444444444\n+\tappend 5555555555555555555555555555555555555555\n+\tappend 8888888888888888888888888888888888888888\n+\tappend aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n+\tfor_each_unique\n+\tEOF\n+\tnongit test-tool oid-array <input >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'ordered enumeration' '\n \techoid \"\" 44 55 88 aa >expect &&\n \t{\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497076","messageId":"1f0682fc7dfa63a50838316bb85717b576274289.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 19/20] t/helper: remove dependency on `the_repository` in \"proc-receive\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:54Z","receivedAt":"2024-06-13T06:14:58Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"proc-receive\" test helper implicitly relies on `the_repository` via\n`parse_oid_hex()`. This isn't necessary though, and in fact the whole\ncommand does not depend on `the_repository` at all.\n\nStop setting up `the_repository` and use `parse_oid_hex_any()` to parse\nobject IDs.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-proc-receive.c | 9 +++------\n 1 file changed, 3 insertions(+), 6 deletions(-)\n\ndiff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c\nindex f30022d222..29361c7aab 100644\n--- a/t/helper/test-proc-receive.c\n+++ b/t/helper/test-proc-receive.c\n@@ -3,8 +3,8 @@\n #include \"hex.h\"\n #include \"parse-options.h\"\n #include \"pkt-line.h\"\n-#include \"setup.h\"\n #include \"sigchain.h\"\n+#include \"string-list.h\"\n \n static const char *proc_receive_usage[] = {\n \t\"test-tool proc-receive [<options>]\",\n@@ -92,9 +92,9 @@ static void proc_receive_read_commands(struct packet_reader *reader,\n \t\tif (die_read_commands)\n \t\t\tdie(\"die with the --die-read-commands option\");\n \n-\t\tif (parse_oid_hex(reader->line, &old_oid, &p) ||\n+\t\tif (parse_oid_hex_any(reader->line, &old_oid, &p) == GIT_HASH_UNKNOWN ||\n \t\t    *p++ != ' ' ||\n-\t\t    parse_oid_hex(p, &new_oid, &p) ||\n+\t\t    parse_oid_hex_any(p, &new_oid, &p) == GIT_HASH_UNKNOWN ||\n \t\t    *p++ != ' ')\n \t\t\tdie(\"protocol error: expected 'old new ref', got '%s'\",\n \t\t\t    reader->line);\n@@ -128,7 +128,6 @@ static void proc_receive_read_push_options(struct packet_reader *reader,\n \n int cmd__proc_receive(int argc, const char **argv)\n {\n-\tint nongit_ok = 0;\n \tstruct packet_reader reader;\n \tstruct command *commands = NULL;\n \tstruct string_list push_options = STRING_LIST_INIT_DUP;\n@@ -154,8 +153,6 @@ int cmd__proc_receive(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n-\tsetup_git_directory_gently(&nongit_ok);\n-\n \targc = parse_options(argc, argv, \"test-tools\", options, proc_receive_usage, 0);\n \tif (argc > 0)\n \t\tusage_msg_opt(\"Too many arguments.\", proc_receive_usage, options);\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497077","messageId":"16fb86c2b296d6d3803fbdb25ac69b2acaf5a4aa.1718259125.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"[PATCH v2 20/20] hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-13T06:14:59Z","receivedAt":"2024-06-13T06:15:03Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Guard declarations of functions that implicitly use `the_repository`\nwith `USE_THE_REPOSITORY_VARIABLE` such that callers don't accidentally\nrely on that global variable.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hex.h | 26 ++++++++++++++++----------\n 1 file changed, 16 insertions(+), 10 deletions(-)\n\ndiff --git a/hex.h b/hex.h\nindex 9809667f33..e9ccb54065 100644\n--- a/hex.h\n+++ b/hex.h\n@@ -13,10 +13,6 @@\n  * input, so it is safe to pass this function an arbitrary\n  * null-terminated string.\n  */\n-int get_hash_hex(const char *hex, unsigned char *hash);\n-int get_oid_hex(const char *hex, struct object_id *oid);\n-\n-/* Like get_oid_hex, but for an arbitrary hash algorithm. */\n int get_oid_hex_algop(const char *hex, struct object_id *oid, const struct git_hash_algo *algop);\n \n /*\n@@ -35,7 +31,6 @@ int get_oid_hex_algop(const char *hex, struct object_id *oid, const struct git_h\n char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash, const struct git_hash_algo *);\n char *oid_to_hex_r(char *out, const struct object_id *oid);\n char *hash_to_hex_algop(const unsigned char *hash, const struct git_hash_algo *);\t/* static buffer result! */\n-char *hash_to_hex(const unsigned char *hash);\t\t\t\t\t\t/* same static buffer */\n char *oid_to_hex(const struct object_id *oid);\t\t\t\t\t\t/* same static buffer */\n \n /*\n@@ -45,13 +40,9 @@ char *oid_to_hex(const struct object_id *oid);\t\t\t\t\t\t/* same static buffer */\n  * other invalid character.  end is only updated on success; otherwise, it is\n  * unmodified.\n  */\n-int parse_oid_hex(const char *hex, struct object_id *oid, const char **end);\n-\n-/* Like parse_oid_hex, but for an arbitrary hash algorithm. */\n int parse_oid_hex_algop(const char *hex, struct object_id *oid, const char **end,\n \t\t\tconst struct git_hash_algo *algo);\n \n-\n /*\n  * These functions work like get_oid_hex and parse_oid_hex, but they will parse\n  * a hex value for any algorithm. The algorithm is detected based on the length\n@@ -61,4 +52,19 @@ int parse_oid_hex_algop(const char *hex, struct object_id *oid, const char **end\n int get_oid_hex_any(const char *hex, struct object_id *oid);\n int parse_oid_hex_any(const char *hex, struct object_id *oid, const char **end);\n \n-#endif\n+#ifdef USE_THE_REPOSITORY_VARIABLE\n+\n+/* Like get_oid_hex_algop, but for `the_hash_algo`. */\n+int get_hash_hex(const char *hex, unsigned char *hash);\n+int get_oid_hex(const char *hex, struct object_id *oid);\n+\n+/* Like parse_oid_hex_algop, but uses `the_hash_algo`. */\n+int parse_oid_hex(const char *hex, struct object_id *oid, const char **end);\n+\n+/*\n+ * Same as `hash_to_hex_algop()`, but uses `the_hash_algo`.\n+ */\n+char *hash_to_hex(const unsigned char *hash);\n+\n+#endif /* USE_THE_REPOSITORY_VARIABLE */\n+#endif /* HEX_H */\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497084","messageId":"66763b5a-3ea6-481f-b4d3-5fad76f5da0c@gmail.com","threadId":"61621","inReplyTo":"4858cca25fe9e57c984fc3181fe8498d0b7222b0.1718259125.git.ps@pks.im","subject":"Re: [PATCH v2 08/20] hash: require hash algorithm in `empty_tree_oid_hex()`","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-06-13T10:01:35Z","receivedAt":"2024-06-13T10:01:38Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 13/06/2024 07:14, Patrick Steinhardt wrote:\n> The `empty_tree_oid_hex()` function use `the_repository` to derive the\n> hash function that shall be used. Require callers to pass in the hash\n> algorithm to get rid of this implicit dependency.\n\nMany of these call sites already have a repository instance available so \ndon't need to use \"the_repository\". I haven't checked but with these \nchanges it might be possible to remove some of these files from the next \npatch.\n\nI've only really looked at this patch in this series as I was just \nchecking for changes to the sequencer code. As for the series as a whole \nI think adding USE_THE_REPOSITORY_VARIABLE is a good direction.\n\n> While at it, remove the unused `empty_blob_oid_hex()` function.\n> \n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>   add-interactive.c      |  2 +-\n>   add-patch.c            |  2 +-\n>   builtin/merge.c        |  3 ++-\n>   builtin/receive-pack.c |  2 +-\n>   hash-ll.h              |  3 +--\n>   object-file.c          | 10 ++--------\n>   sequencer.c            |  2 +-\n>   submodule.c            |  6 +++---\n>   wt-status.c            |  4 ++--\n>   9 files changed, 14 insertions(+), 20 deletions(-)\n> \n> diff --git a/add-interactive.c b/add-interactive.c\n> index b5d6cd689a..a0961096cd 100644\n> --- a/add-interactive.c\n> +++ b/add-interactive.c\n> @@ -557,7 +557,7 @@ static int get_modified_files(struct repository *r,\n>   \t\ts.skip_unseen = filter && i;\n>   \n>   \t\topt.def = is_initial ?\n> -\t\t\tempty_tree_oid_hex() : oid_to_hex(&head_oid);\n> +\t\t\tempty_tree_oid_hex(the_repository->hash_algo) : oid_to_hex(&head_oid);\n\nThe hunk fragment shows that we already have a struct repository \ninstance in this function which we should use instead of \"the_repository\"\n\n> diff --git a/add-patch.c b/add-patch.c\n> index 814de57c4a..86181770f2 100644\n> --- a/add-patch.c\n> +++ b/add-patch.c\n> @@ -420,7 +420,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)\n>   \t\t\t    /* could be on an unborn branch */\n>   \t\t\t    !strcmp(\"HEAD\", s->revision) &&\n>   \t\t\t    repo_get_oid(the_repository, \"HEAD\", &oid) ?\n> -\t\t\t    empty_tree_oid_hex() : s->revision);\n> +\t\t\t    empty_tree_oid_hex(the_repository->hash_algo) : s->revision);\n\nIt's not obvious from this hunk but there is a repository instance in \n\"s->s->r\" which we should use instead of \"the_repository\"\n\n> diff --git a/sequencer.c b/sequencer.c\n> index 68d62a12ff..823691e379 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -2263,7 +2263,7 @@ static int do_pick_commit(struct repository *r,\n>   \t\t\tunborn = 1;\n>   \t\t} else if (unborn)\n>   \t\t\toidcpy(&head, the_hash_algo->empty_tree);\n> -\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex() : \"HEAD\",\n> +\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : \"HEAD\",\n\nThe hunk fragment shows that we already have a struct repository \ninstance in \"r\" which we should use instead of \"the_repository\" here.\n\n> diff --git a/wt-status.c b/wt-status.c\n> index ff4be071ca..5051f5e599 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -641,7 +641,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n>   \n>   \trepo_init_revisions(s->repo, &rev, NULL);\n>   \tmemset(&opt, 0, sizeof(opt));\n> -\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n> +\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n\nThe context line above shows us that we have a repository instance \navailable so we should use \"s->repo\" instead of \"the_repository\"\n\n> @@ -1136,7 +1136,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)\n>   \trev.diffopt.ita_invisible_in_index = 1;\n>   \n>   \tmemset(&opt, 0, sizeof(opt));\n> -\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n> +\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n\nWe should use \"s->repo\" here as well\n\nBest Wishes\n\nPhillip\n\n"},{"id":"497093","messageId":"xmqqv82cn97d.fsf@gitster.g","threadId":"61621","inReplyTo":"66763b5a-3ea6-481f-b4d3-5fad76f5da0c@gmail.com","subject":"Re: [PATCH v2 08/20] hash: require hash algorithm in `empty_tree_oid_hex()`","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-13T15:39:18Z","receivedAt":"2024-06-13T15:39:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n>> diff --git a/add-interactive.c b/add-interactive.c\n>> index b5d6cd689a..a0961096cd 100644\n>> --- a/add-interactive.c\n>> +++ b/add-interactive.c\n>> @@ -557,7 +557,7 @@ static int get_modified_files(struct repository *r,\n>>   \t\ts.skip_unseen = filter && i;\n>>     \t\topt.def = is_initial ?\n>> -\t\t\tempty_tree_oid_hex() : oid_to_hex(&head_oid);\n>> +\t\t\tempty_tree_oid_hex(the_repository->hash_algo) : oid_to_hex(&head_oid);\n>\n> The hunk fragment shows that we already have a struct repository\n> instance in this function which we should use instead of\n> \"the_repository\"\n\nAs an internal helper function in add-interactive.c, all of whose\ncallers deal with \"struct add_i_state *\", it probably should not\neven take \"struct repository *\" as a parameter.  The state knows\nwhat repository we are working with.\n\n>> diff --git a/add-patch.c b/add-patch.c\n>> index 814de57c4a..86181770f2 100644\n>> --- a/add-patch.c\n>> +++ b/add-patch.c\n>> @@ -420,7 +420,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)\n>>   \t\t\t    /* could be on an unborn branch */\n>>   \t\t\t    !strcmp(\"HEAD\", s->revision) &&\n>>   \t\t\t    repo_get_oid(the_repository, \"HEAD\", &oid) ?\n>> -\t\t\t    empty_tree_oid_hex() : s->revision);\n>> +\t\t\t    empty_tree_oid_hex(the_repository->hash_algo) : s->revision);\n>\n> It's not obvious from this hunk but there is a repository instance in\n> \"s->s->r\" which we should use instead of \"the_repository\"\n\nI agree it is the same issue.\n\nJust like a previous effort, making a \"faithful\" conversion from the\noriginal that used the_repository implicitly by explicitly passing\nthe_repository in one patch, and then making semantics corrections\nof the original (if we were ever working on a repository in s->r\nthat is different from the_repository, the existing code is already\nbuggy) in a separate patch, is a reasonable approach to limit the\ncognitive load while reviewing the first step, I would say.\n\n> diff --git a/sequencer.c b/sequencer.c\n>> index 68d62a12ff..823691e379 100644\n>> --- a/sequencer.c\n>> +++ b/sequencer.c\n>> @@ -2263,7 +2263,7 @@ static int do_pick_commit(struct repository *r,\n>>   \t\t\tunborn = 1;\n>>   \t\t} else if (unborn)\n>>   \t\t\toidcpy(&head, the_hash_algo->empty_tree);\n>> -\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex() : \"HEAD\",\n>> +\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : \"HEAD\",\n>\n> The hunk fragment shows that we already have a struct repository\n> instance in \"r\" which we should use instead of \"the_repository\" here.\n\nYes, but the same \"it is better to make a faithful conversion first,\ncorrections separately in a later step\" would apply.\n\nAs the sequencer machinery is inherently stateful, I wonder if we\nshould pass around not \"repository\" but a sequencer state object\nthat may have a pointer to a repository in use.  But that of course\nbelongs to the latter, i.e., \"making corrections\", theme.\n"},{"id":"497098","messageId":"xmqqcyoklo26.fsf@gitster.g","threadId":"61621","inReplyTo":"cover.1718259125.git.ps@pks.im","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-13T18:01:21Z","receivedAt":"2024-06-13T18:01:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> this is the second version of my patch series that introduce a new\n> `USE_THE_REPOSITORY_VARIABLE` macro. If undefined, then declarations\n> like `the_repository`, `the_hash_algo` and a subset of functions that\n> implicitly depend on either of these are hidden away.\n\n;-)\n"},{"id":"497100","messageId":"xmqqfrtgk7ah.fsf@gitster.g","threadId":"61621","inReplyTo":"xmqqcyoklo26.fsf@gitster.g","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-13T18:48:54Z","receivedAt":"2024-06-13T18:48:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Patrick Steinhardt <ps@pks.im> writes:\n>\n>> this is the second version of my patch series that introduce a new\n>> `USE_THE_REPOSITORY_VARIABLE` macro. If undefined, then declarations\n>> like `the_repository`, `the_hash_algo` and a subset of functions that\n>> implicitly depend on either of these are hidden away.\n>\n> ;-)\n\nTwo things.\n\n(1) This stupid change was needed to please \"make sparse\", or we'd\n    get this:\n\n    repository.c:21:19: error: symbol 'the_repository' was not declared. Should it be static?\n    gmake: *** [Makefile:3259: repository.sp] Error 1\n\n repository.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git c/repository.c w/repository.c\nindex 95d10cc4a0..22ef85b0b3 100644\n--- c/repository.c\n+++ w/repository.c\n@@ -18,6 +18,8 @@\n \n /* The main repository */\n static struct repository the_repo;\n+\n+extern struct repository *the_repository;\n struct repository *the_repository = &the_repo;\n \n /*\n\n\n(2) Aside from a few trivial and expected textual conflicts to be\n    resolved, there were a few new files added that needed\n    merge-fixes, with which I have this topic at the tip of the\n    'seen' branch.\n\n index-info.c   | 2 ++\n pseudo-merge.c | 2 ++\n 2 files changed, 4 insertions(+)\n\ndiff --git a/index-info.c b/index-info.c\nindex 5d61e61e28..791380f910 100644\n--- a/index-info.c\n+++ b/index-info.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"index-info.h\"\n #include \"hash.h\"\ndiff --git a/pseudo-merge.c b/pseudo-merge.c\nindex e3e0393f11..f0fde13c47 100644\n--- a/pseudo-merge.c\n+++ b/pseudo-merge.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"pseudo-merge.h\"\n #include \"date.h\"\n-- \n2.45.2-683-gddb3e810f1\n\n"},{"id":"497116","messageId":"b69449d0-46f4-448e-b80e-002a8b5c4e1f@ramsayjones.plus.com","threadId":"61621","inReplyTo":"xmqqfrtgk7ah.fsf@gitster.g","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Ramsay Jones","fromEmail":"ramsay@ramsayjones.plus.com","sentAt":"2024-06-13T23:14:59Z","receivedAt":"2024-06-13T23:18:09Z","isPatch":true,"sender":{"key":"ramsay@ramsayjones.plus.com","avatar":"https://avatars.githubusercontent.com/u/33702710?v=4"},"body":"\n\nOn 13/06/2024 19:48, Junio C Hamano wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>> Patrick Steinhardt <ps@pks.im> writes:\n>>\n>>> this is the second version of my patch series that introduce a new\n>>> `USE_THE_REPOSITORY_VARIABLE` macro. If undefined, then declarations\n>>> like `the_repository`, `the_hash_algo` and a subset of functions that\n>>> implicitly depend on either of these are hidden away.\n>>\n>> ;-)\n> \n> Two things.\n> \n> (1) This stupid change was needed to please \"make sparse\", or we'd\n>     get this:\n> \n>     repository.c:21:19: error: symbol 'the_repository' was not declared. Should it be static?\n>     gmake: *** [Makefile:3259: repository.sp] Error 1\n> \n>  repository.c | 2 ++\n>  1 file changed, 2 insertions(+)\n> \n> diff --git c/repository.c w/repository.c\n> index 95d10cc4a0..22ef85b0b3 100644\n> --- c/repository.c\n> +++ w/repository.c\n> @@ -18,6 +18,8 @@\n>  \n>  /* The main repository */\n>  static struct repository the_repo;\n> +\n> +extern struct repository *the_repository;\n>  struct repository *the_repository = &the_repo;\n>  \n\nHmm, odd; isn't the declaration of 'the_repository' from\nthe \"repository.h\" header file visible at this point?\n\npuzzled.\n\nATB,\nRamsay Jones\n\n\n"},{"id":"497117","messageId":"CAPc5daUpzc+FDTH4-ajjf6ctnchE5Z6mHVvpm0qnbPLup18ykg@mail.gmail.com","threadId":"61621","inReplyTo":"b69449d0-46f4-448e-b80e-002a8b5c4e1f@ramsayjones.plus.com","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-13T23:18:29Z","receivedAt":"2024-06-13T23:18:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"On Thu, Jun 13, 2024 at 4:15 PM Ramsay Jones\n<ramsay@ramsayjones.plus.com> wrote:\n>\n> Hmm, odd; isn't the declaration of 'the_repository' from\n> the \"repository.h\" header file visible at this point?\n\nNo. The declaration is guarded with USE_THE_REPOSITORY_VARIABLE CPP macro\nin the header, and repository.c does not define it.\n"},{"id":"497118","messageId":"9d085d3f-5fdf-4a28-b31c-458ba68ebcd4@ramsayjones.plus.com","threadId":"61621","inReplyTo":"CAPc5daUpzc+FDTH4-ajjf6ctnchE5Z6mHVvpm0qnbPLup18ykg@mail.gmail.com","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Ramsay Jones","fromEmail":"ramsay@ramsayjones.plus.com","sentAt":"2024-06-13T23:55:38Z","receivedAt":"2024-06-13T23:55:41Z","isPatch":true,"sender":{"key":"ramsay@ramsayjones.plus.com","avatar":"https://avatars.githubusercontent.com/u/33702710?v=4"},"body":"\n\nOn 14/06/2024 00:18, Junio C Hamano wrote:\n> On Thu, Jun 13, 2024 at 4:15 PM Ramsay Jones\n> <ramsay@ramsayjones.plus.com> wrote:\n>>\n>> Hmm, odd; isn't the declaration of 'the_repository' from\n>> the \"repository.h\" header file visible at this point?\n> \n> No. The declaration is guarded with USE_THE_REPOSITORY_VARIABLE CPP macro\n> in the header, and repository.c does not define it.\n> \n\nAh, OK. I haven't been following too closely and didn't\nnotice that the declaration in the header file was now\nconditional. :(\n\nBut that does beg the question - why is repository.c not\ndefining the USE_THE_REPOSITORY_VARIABLE?\n\nATB,\nRamsay Jones\n"},{"id":"497119","messageId":"xmqqfrtgjs3f.fsf@gitster.g","threadId":"61621","inReplyTo":"9d085d3f-5fdf-4a28-b31c-458ba68ebcd4@ramsayjones.plus.com","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-14T00:17:08Z","receivedAt":"2024-06-14T00:17:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramsay Jones <ramsay@ramsayjones.plus.com> writes:\n\n> On 14/06/2024 00:18, Junio C Hamano wrote:\n>> On Thu, Jun 13, 2024 at 4:15 PM Ramsay Jones\n>> <ramsay@ramsayjones.plus.com> wrote:\n>>>\n>>> Hmm, odd; isn't the declaration of 'the_repository' from\n>>> the \"repository.h\" header file visible at this point?\n>> \n>> No. The declaration is guarded with USE_THE_REPOSITORY_VARIABLE CPP macro\n>> in the header, and repository.c does not define it.\n>> \n>\n> Ah, OK. I haven't been following too closely and didn't\n> notice that the declaration in the header file was now\n> conditional. :(\n>\n> But that does beg the question - why is repository.c not\n> defining the USE_THE_REPOSITORY_VARIABLE?\n\nI think the goal of the series is to eventually get to the point\nwhere nobody uses the_repository variable.  If repository.c, which\nconsists of a set of service routines that work on a repository\ninstance, defined it, showing willingness to implicitly rely on\nthe_repository through things like get_oid_hex() (which would rely\non the_repository->hash_algo), that would go the opposite direction,\nso everything, other than the definition of the_repository variable\nitself that allows other files that still do rely implicitly on the\nvariable to link with it, in repository.c would actively want to\nrefuse to use services only available to those who define USE_THE_*\nmacro.\n\nIt is a similar pattern we took when we weaned ourselves off of\nthe_index compatibility macros.  The read-cache.c was the central\nthing that defined the in-core index services, and it was the first\nthing that lost the_index compatibility macros like read_cache(),\nadd_file_to_cache(), etc. that implicitly worked on the singleton\nthe_index instance, while everybody else still relied on the\nsingleton and services that implicitly worked on the singleton.\n\n"},{"id":"497123","messageId":"ZmvTvtYXIfvzVc5e@tanuki","threadId":"61621","inReplyTo":"xmqqv82cn97d.fsf@gitster.g","subject":"Re: [PATCH v2 08/20] hash: require hash algorithm in `empty_tree_oid_hex()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T05:23:10Z","receivedAt":"2024-06-14T05:23:17Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Jun 13, 2024 at 08:39:18AM -0700, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n> > diff --git a/sequencer.c b/sequencer.c\n> >> index 68d62a12ff..823691e379 100644\n> >> --- a/sequencer.c\n> >> +++ b/sequencer.c\n> >> @@ -2263,7 +2263,7 @@ static int do_pick_commit(struct repository *r,\n> >>   \t\t\tunborn = 1;\n> >>   \t\t} else if (unborn)\n> >>   \t\t\toidcpy(&head, the_hash_algo->empty_tree);\n> >> -\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex() : \"HEAD\",\n> >> +\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : \"HEAD\",\n> >\n> > The hunk fragment shows that we already have a struct repository\n> > instance in \"r\" which we should use instead of \"the_repository\" here.\n> \n> Yes, but the same \"it is better to make a faithful conversion first,\n> corrections separately in a later step\" would apply.\n\nYeah, this is what I'm aiming for. In large patch series like this I\nthink it increases the risk of regression quite significantly if we also\ntry to deviate from the preceding code and do the \"right\" thing, even if\nit is seemingly obvious. So I rather do a faithful conversion that does\nnot change the behaviour and leave conversion away from `the_repository`\nto later steps after this series.\n\nI can amend the commit message to say so.\n\nPatrick\n"},{"id":"497124","messageId":"ZmvVBwLEb0qofY2m@tanuki","threadId":"61621","inReplyTo":"xmqqfrtgjs3f.fsf@gitster.g","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T05:28:39Z","receivedAt":"2024-06-14T05:28:45Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Jun 13, 2024 at 05:17:08PM -0700, Junio C Hamano wrote:\n> Ramsay Jones <ramsay@ramsayjones.plus.com> writes:\n> \n> > On 14/06/2024 00:18, Junio C Hamano wrote:\n> >> On Thu, Jun 13, 2024 at 4:15 PM Ramsay Jones\n> >> <ramsay@ramsayjones.plus.com> wrote:\n> >>>\n> >>> Hmm, odd; isn't the declaration of 'the_repository' from\n> >>> the \"repository.h\" header file visible at this point?\n> >> \n> >> No. The declaration is guarded with USE_THE_REPOSITORY_VARIABLE CPP macro\n> >> in the header, and repository.c does not define it.\n> >> \n> >\n> > Ah, OK. I haven't been following too closely and didn't\n> > notice that the declaration in the header file was now\n> > conditional. :(\n> >\n> > But that does beg the question - why is repository.c not\n> > defining the USE_THE_REPOSITORY_VARIABLE?\n> \n> I think the goal of the series is to eventually get to the point\n> where nobody uses the_repository variable.  If repository.c, which\n> consists of a set of service routines that work on a repository\n> instance, defined it, showing willingness to implicitly rely on\n> the_repository through things like get_oid_hex() (which would rely\n> on the_repository->hash_algo), that would go the opposite direction,\n> so everything, other than the definition of the_repository variable\n> itself that allows other files that still do rely implicitly on the\n> variable to link with it, in repository.c would actively want to\n> refuse to use services only available to those who define USE_THE_*\n> macro.\n\nExactly, that's why it doesn't declare `USE_THE_REPOSITORY_VARIABLE`.\nThe macro doesn't only guard use of `the_repository`, but does also\nguards other functions that implicitly relies on it, and we do not want\nto use these in \"repository.c\". So even though the added `extern`\ndeclaration is somewhat ugly, I think it is preferable over defining the\nmacro.\n\nPatrick\n"},{"id":"497131","messageId":"cover.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718106284.git.ps@pks.im","subject":"[PATCH v3 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:49:40Z","receivedAt":"2024-06-14T06:49:46Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nthis is the third version of my patch series that introduces the\n`USE_THE_REPOSITORY_VARIABLE` macro. When unset, this will cause us to\nhide `the_repository`, `the_hash_algo` and several other functions that\nimplicitly rely on those global variables from our headers. This is a\nfirst step towards fully getting rid of this global state in favor of\npassing it down explicitly via function parameters.\n\nChanges compared to v2:\n\n  - Note in a commit message that we aim to have a faithful conversion\n    when introducing a `struct git_hash_algo` parameter to functions. So\n    even in case the calling context has a `struct git_hash_algo`\n    available via a local repository, we still use `the_repository` such\n    that there cannot be a change in behaviour here. Fixing those sites\n    will be left for a future patch series such that we can avoid any\n    kind of regressions caused by this comparatively large refactoring.\n    I also adapted some conversions to fully follow through with this\n    intent.\n\n  - Fix an issue with sparse by adding another `extern` declaration of\n    `the_repository` to \"repository.c\".\n\nThanks!\n\nPatrick\n\nPatrick Steinhardt (20):\n  hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions\n  hash: require hash algorithm in `hasheq()`, `hashcmp()` and\n    `hashclr()`\n  hash: require hash algorithm in `oidread()` and `oidclr()`\n  global: ensure that object IDs are always padded\n  hash: convert `oidcmp()` and `oideq()` to compare whole hash\n  hash: make `is_null_oid()` independent of `the_repository`\n  hash: require hash algorithm in `is_empty_{blob,tree}_oid()`\n  hash: require hash algorithm in `empty_tree_oid_hex()`\n  global: introduce `USE_THE_REPOSITORY_VARIABLE` macro\n  refs: avoid include cycle with \"repository.h\"\n  hash-ll: merge with \"hash.h\"\n  http-fetch: don't crash when parsing packfile without a repo\n  oidset: pass hash algorithm when parsing file\n  protocol-caps: use hash algorithm from passed-in repository\n  replace-object: use hash algorithm from passed-in repository\n  compat/fsmonitor: fix socket path in networked SHA256 repos\n  t/helper: use correct object hash in partial-clone helper\n  t/helper: fix segfault in \"oid-array\" command without repository\n  t/helper: remove dependency on `the_repository` in \"proc-receive\"\n  hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`\n\n add-interactive.c                            |   4 +-\n add-patch.c                                  |   4 +-\n apply.c                                      |   4 +-\n apply.h                                      |   2 +-\n archive-tar.c                                |   3 +\n archive-zip.c                                |   3 +\n archive.c                                    |   2 +\n attr.c                                       |   2 +\n bisect.c                                     |   2 +\n blame.c                                      |   4 +-\n bloom.c                                      |   1 +\n branch.c                                     |   2 +\n builtin.h                                    |   8 +\n builtin/am.c                                 |   8 +-\n builtin/blame.c                              |   3 +-\n builtin/fast-export.c                        |   2 +-\n builtin/fast-import.c                        |  43 ++-\n builtin/fetch-pack.c                         |   4 +-\n builtin/index-pack.c                         |  11 +-\n builtin/log.c                                |   4 +-\n builtin/merge.c                              |   7 +-\n builtin/notes.c                              |   2 +-\n builtin/pack-objects.c                       |   3 +-\n builtin/pack-redundant.c                     |  10 +-\n builtin/patch-id.c                           |   6 +-\n builtin/pull.c                               |   6 +-\n builtin/receive-pack.c                       |   4 +-\n builtin/replace.c                            |   2 +-\n builtin/rm.c                                 |   2 +-\n builtin/tag.c                                |   2 +-\n builtin/unpack-objects.c                     |   9 +-\n builtin/update-ref.c                         |   8 +-\n bulk-checkin.c                               |   3 +\n bundle-uri.c                                 |   2 +\n bundle.c                                     |   2 +\n cache-tree.c                                 |   7 +-\n checkout.c                                   |   2 +\n checkout.h                                   |   2 +-\n chunk-format.c                               |   2 +\n chunk-format.h                               |   2 +-\n combine-diff.c                               |   2 +\n commit-graph.c                               |  22 +-\n commit-graph.h                               |   2 +\n commit-reach.c                               |   2 +\n commit.c                                     |   2 +\n common-main.c                                |   2 +\n compat/fsmonitor/fsm-ipc-darwin.c            |   7 +-\n compat/sha1-chunked.c                        |   2 +-\n compat/win32/trace2_win32_process_info.c     |   2 +\n config.c                                     |   3 +\n connected.c                                  |   2 +\n convert.c                                    |   2 +\n convert.h                                    |   2 +-\n csum-file.c                                  |   9 +-\n csum-file.h                                  |   2 +-\n delta-islands.c                              |   2 +\n diagnose.c                                   |   2 +\n diff-lib.c                                   |   7 +-\n diff.c                                       |   9 +-\n diff.h                                       |   2 +-\n diffcore-break.c                             |   3 +\n diffcore-rename.c                            |   7 +-\n diffcore.h                                   |   2 +-\n dir.c                                        |   9 +-\n dir.h                                        |   2 +-\n entry.c                                      |   2 +\n environment.c                                |   3 +\n fetch-pack.c                                 |   2 +\n fmt-merge-msg.c                              |   2 +\n fsck.c                                       |   5 +-\n fsmonitor-ipc.c                              |   2 +\n git.c                                        |   2 +\n hash-ll.h                                    | 310 ----------------\n hash-lookup.c                                |   5 +-\n hash.h                                       | 366 ++++++++++++++++---\n help.c                                       |   2 +\n hex.c                                        |   8 +-\n hex.h                                        |  28 +-\n http-backend.c                               |   2 +\n http-fetch.c                                 |   8 +-\n http-push.c                                  |   5 +-\n http-walker.c                                |   6 +-\n http.c                                       |   2 +\n list-objects-filter-options.c                |   2 +\n list-objects-filter.c                        |   2 +\n list-objects.c                               |   2 +\n log-tree.c                                   |   2 +\n loose.c                                      |   2 +\n loose.h                                      |   2 +\n ls-refs.c                                    |   2 +\n mailmap.c                                    |   2 +\n match-trees.c                                |   6 +-\n merge-blobs.c                                |   2 +\n merge-ort.c                                  |   2 +\n merge-ort.h                                  |   2 +-\n merge-recursive.c                            |   3 +\n merge.c                                      |   2 +\n midx-write.c                                 |   2 +\n midx.c                                       |   5 +-\n negotiator/default.c                         |   2 +\n negotiator/skipping.c                        |   2 +\n notes-cache.c                                |   2 +\n notes-merge.c                                |   8 +-\n notes-utils.c                                |   2 +\n notes.c                                      |  14 +-\n object-file-convert.c                        |   6 +-\n object-file.c                                |  19 +-\n object-name.c                                |   2 +\n object.c                                     |   2 +\n object.h                                     |   2 +-\n oid-array.c                                  |   2 +\n oidmap.h                                     |   2 +-\n oidset.c                                     |   8 +-\n oidset.h                                     |   4 +-\n oidtree.c                                    |   4 +-\n oidtree.h                                    |   2 +-\n oss-fuzz/fuzz-commit-graph.c                 |   2 +\n pack-bitmap-write.c                          |   6 +-\n pack-bitmap.c                                |   5 +-\n pack-check.c                                 |   7 +-\n pack-revindex.c                              |   2 +\n pack-write.c                                 |   5 +-\n packfile.c                                   |  20 +-\n packfile.h                                   |   2 +\n parallel-checkout.c                          |   8 +-\n parse-options-cb.c                           |   2 +\n path.c                                       |   3 +\n pathspec.c                                   |   2 +\n pretty.c                                     |   2 +\n progress.c                                   |   2 +\n promisor-remote.c                            |   2 +\n protocol-caps.c                              |   5 +-\n range-diff.c                                 |   2 +\n reachable.c                                  |   2 +\n read-cache-ll.h                              |   2 +-\n read-cache.c                                 |  21 +-\n rebase-interactive.c                         |   2 +\n ref-filter.c                                 |   2 +\n reflog-walk.c                                |   2 +\n reflog.c                                     |   2 +\n refs.c                                       |   8 +-\n refs.h                                       |   8 +-\n refs/files-backend.c                         |   8 +-\n refs/packed-backend.c                        |   8 +-\n refs/ref-cache.h                             |   2 +-\n refs/reftable-backend.c                      |  39 +-\n refspec.c                                    |   2 +\n reftable/dump.c                              |   2 +-\n reftable/reftable-record.h                   |   2 +-\n reftable/system.h                            |   2 +-\n remote-curl.c                                |   2 +\n remote.c                                     |  10 +-\n remote.h                                     |   2 +-\n replace-object.c                             |   2 +-\n repository.c                                 |   8 +\n repository.h                                 |   9 +-\n rerere.c                                     |   2 +\n reset.c                                      |   2 +\n reset.h                                      |   2 +-\n resolve-undo.c                               |   5 +-\n resolve-undo.h                               |   2 +-\n revision.c                                   |   2 +\n run-command.c                                |   2 +\n scalar.c                                     |   2 +\n send-pack.c                                  |   2 +\n sequencer.c                                  |   8 +-\n serve.c                                      |   4 +-\n server-info.c                                |   2 +\n setup.c                                      |   2 +\n shallow.c                                    |   2 +\n split-index.c                                |   4 +-\n split-index.h                                |   2 +-\n streaming.c                                  |   3 +\n submodule-config.c                           |   4 +-\n submodule.c                                  |   8 +-\n t/helper/test-bitmap.c                       |   2 +\n t/helper/test-bloom.c                        |   2 +\n t/helper/test-cache-tree.c                   |   2 +\n t/helper/test-dump-cache-tree.c              |   2 +\n t/helper/test-dump-fsmonitor.c               |   2 +\n t/helper/test-dump-split-index.c             |   2 +\n t/helper/test-dump-untracked-cache.c         |   2 +\n t/helper/test-find-pack.c                    |   2 +\n t/helper/test-fsmonitor-client.c             |   2 +\n t/helper/test-hash-speed.c                   |   2 +-\n t/helper/test-lazy-init-name-hash.c          |   2 +\n t/helper/test-match-trees.c                  |   2 +\n t/helper/test-oid-array.c                    |   4 +\n t/helper/test-oidmap.c                       |   2 +\n t/helper/test-pack-mtimes.c                  |   2 +\n t/helper/test-partial-clone.c                |   2 +-\n t/helper/test-proc-receive.c                 |   9 +-\n t/helper/test-reach.c                        |   2 +\n t/helper/test-read-cache.c                   |   2 +\n t/helper/test-read-graph.c                   |   2 +\n t/helper/test-read-midx.c                    |   2 +\n t/helper/test-ref-store.c                    |   2 +\n t/helper/test-repository.c                   |   2 +\n t/helper/test-revision-walking.c             |   2 +\n t/helper/test-scrap-cache-tree.c             |   2 +\n t/helper/test-sha1.c                         |   2 +-\n t/helper/test-sha256.c                       |   2 +-\n t/helper/test-submodule-config.c             |   4 +-\n t/helper/test-submodule-nested-repo-config.c |   2 +\n t/helper/test-submodule.c                    |   2 +\n t/helper/test-trace2.c                       |   2 +\n t/helper/test-write-cache.c                  |   2 +\n t/t0064-oid-array.sh                         |  18 +\n t/t5550-http-fetch-dumb.sh                   |   6 +\n t/test-lib-functions.sh                      |   5 +\n t/unit-tests/lib-oid.h                       |   2 +-\n t/unit-tests/t-example-decorate.c            |   2 +\n tag.c                                        |   2 +\n tmp-objdir.c                                 |   2 +\n transport-helper.c                           |   2 +\n transport.c                                  |   2 +\n tree-diff.c                                  |   1 +\n tree-walk.c                                  |   6 +-\n tree-walk.h                                  |   2 +-\n tree.c                                       |   2 +\n unpack-trees.c                               |   2 +\n upload-pack.c                                |   2 +\n walker.c                                     |   2 +\n worktree.c                                   |   2 +\n wt-status.c                                  |   6 +-\n xdiff-interface.c                            |   2 +\n xdiff-interface.h                            |   2 +-\n 227 files changed, 1002 insertions(+), 617 deletions(-)\n delete mode 100644 hash-ll.h\n\nRange-diff against v2:\n 1:  d2154e8c45 =  1:  d2154e8c45 hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions\n 2:  aa468c3d88 !  2:  c481479598 hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()`\n    @@ Commit message\n         As those functions are now independent of `the_repository`, we can move\n         them from \"hash.h\" to \"hash-ll.h\".\n     \n    +    Note that both in this and subsequent commits in this series we always\n    +    just pass `the_repository->hash_algo` as input even if it is obvious\n    +    that there is a repository in the context that we should be using the\n    +    hash from instead. This is done to be on the safe side and not introduce\n    +    any regressions. All callsites should eventually be amended to use a\n    +    repo passed via parameters, but this is outside the scope of this patch\n    +    series.\n    +\n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n      ## builtin/index-pack.c ##\n    @@ pack-check.c: static int verify_packfile(struct repository *r,\n      \tr->hash_algo->final_fn(hash, &ctx);\n      \tpack_sig = use_pack(p, w_curs, pack_sig_ofs, NULL);\n     -\tif (!hasheq(hash, pack_sig))\n    -+\tif (!hasheq(hash, pack_sig, r->hash_algo))\n    ++\tif (!hasheq(hash, pack_sig, the_repository->hash_algo))\n      \t\terr = error(\"%s pack checksum mismatch\",\n      \t\t\t    p->pack_name);\n     -\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig))\n     +\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig,\n    -+\t\t    r->hash_algo))\n    ++\t\t    the_repository->hash_algo))\n      \t\terr = error(\"%s pack checksum does not match its index\",\n      \t\t\t    p->pack_name);\n      \tunuse_pack(w_curs);\n 3:  403ea4485b !  3:  226173a92b hash: require hash algorithm in `oidread()` and `oidclr()`\n    @@ commit-graph.c: static struct tree *load_tree_for_commit(struct repository *r,\n      \t\t\tst_mult(GRAPH_DATA_WIDTH, graph_pos - g->num_commits_in_base);\n      \n     -\toidread(&oid, commit_data);\n    -+\toidread(&oid, commit_data, r->hash_algo);\n    ++\toidread(&oid, commit_data, the_repository->hash_algo);\n      \tset_commit_tree(c, lookup_tree(r, &oid));\n      \n      \treturn c->maybe_tree;\n    @@ commit-graph.c: int write_commit_graph(struct object_directory *odb,\n      \t\t\tstruct object_id oid;\n     -\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n     +\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n    -+\t\t\t\tr->hash_algo);\n    ++\t\t\t\tthe_repository->hash_algo);\n      \t\t\toid_array_append(&ctx->oids, &oid);\n      \t\t}\n      \t}\n    @@ commit-graph.c: static int verify_one_commit_graph(struct repository *r,\n      \n     -\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n     +\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n    -+\t\t\tr->hash_algo);\n    ++\t\t\tthe_repository->hash_algo);\n      \n      \t\tif (i && oidcmp(&prev_oid, &cur_oid) >= 0)\n      \t\t\tgraph_report(_(\"commit-graph has incorrect OID order: %s then %s\"),\n 4:  fa263d6b07 =  4:  3947c0c04d global: ensure that object IDs are always padded\n 5:  a7df209bda =  5:  91eb94bc0b hash: convert `oidcmp()` and `oideq()` to compare whole hash\n 6:  9058837c93 =  6:  9ae29e1912 hash: make `is_null_oid()` independent of `the_repository`\n 7:  d26584dc8f =  7:  da48d5fdea hash: require hash algorithm in `is_empty_{blob,tree}_oid()`\n 8:  4858cca25f =  8:  1cf25bec3e hash: require hash algorithm in `empty_tree_oid_hex()`\n 9:  cb3694ad0e !  9:  7e023a335f global: introduce `USE_THE_REPOSITORY_VARIABLE` macro\n    @@ remote.c\n      #include \"abspath.h\"\n      #include \"config.h\"\n     \n    + ## repository.c ##\n    +@@\n    + #include \"promisor-remote.h\"\n    + #include \"refs.h\"\n    + \n    ++/*\n    ++ * We do not define `USE_THE_REPOSITORY_VARIABLE` in this file because we do\n    ++ * not want to rely on functions that implicitly use `the_repository`. This\n    ++ * means that the `extern` declaration of `the_repository` isn't visible here,\n    ++ * which makes sparse unhappy. We thus declare it here.\n    ++ */\n    ++extern struct repository *the_repository;\n    ++\n    + /* The main repository */\n    + static struct repository the_repo;\n    + struct repository *the_repository = &the_repo;\n    +\n      ## repository.h ##\n     @@ repository.h: struct repository {\n      \tunsigned different_commondir:1;\n10:  4492548209 = 10:  74c88ebc39 refs: avoid include cycle with \"repository.h\"\n11:  f3cbc4b9f9 = 11:  fe4550ba0c hash-ll: merge with \"hash.h\"\n12:  9178098dd7 = 12:  30babd8a67 http-fetch: don't crash when parsing packfile without a repo\n13:  0b4436c32b = 13:  fa41a85c7e oidset: pass hash algorithm when parsing file\n14:  c7abfbc489 = 14:  0b42208e2f protocol-caps: use hash algorithm from passed-in repository\n15:  9ae4fdb8f1 = 15:  e1f4bffea1 replace-object: use hash algorithm from passed-in repository\n16:  3ceb726655 = 16:  5b8f981ea2 compat/fsmonitor: fix socket path in networked SHA256 repos\n17:  74e5489bd0 = 17:  ad83b17ad0 t/helper: use correct object hash in partial-clone helper\n18:  470aea1fc8 = 18:  a488363bcb t/helper: fix segfault in \"oid-array\" command without repository\n19:  1f0682fc7d = 19:  5de7a01af5 t/helper: remove dependency on `the_repository` in \"proc-receive\"\n20:  16fb86c2b2 = 20:  436ffc0570 hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497132","messageId":"d2154e8c4517cbe7c981184f911bdfd06a593cee.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 01/20] hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:49:45Z","receivedAt":"2024-06-14T06:49:49Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The functions `is_empty_{blob,tree}_sha1()` are mostly unused, except\nfor a single callsite in \"read-cache.c\". Most callsites have long since\nbeen converted to use the equivalents that accept a `struct object_id`\ninstead of a string.\n\nAdapt the remaining callsite and drop those functions.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash.h       | 10 ----------\n read-cache.c |  2 +-\n 2 files changed, 1 insertion(+), 11 deletions(-)\n\ndiff --git a/hash.h b/hash.h\nindex e064807c17..a1161e1b22 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -84,21 +84,11 @@ static inline void oidread(struct object_id *oid, const unsigned char *hash)\n \toidread_algop(oid, hash, the_hash_algo);\n }\n \n-static inline int is_empty_blob_sha1(const unsigned char *sha1)\n-{\n-\treturn hasheq(sha1, the_hash_algo->empty_blob->hash);\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\n }\n \n-static inline int is_empty_tree_sha1(const unsigned char *sha1)\n-{\n-\treturn hasheq(sha1, the_hash_algo->empty_tree->hash);\n-}\n-\n static inline int is_empty_tree_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_tree);\ndiff --git a/read-cache.c b/read-cache.c\nindex 447109aa76..10e002ce6d 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -337,7 +337,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)\n \n \t/* Racily smudged entry? */\n \tif (!ce->ce_stat_data.sd_size) {\n-\t\tif (!is_empty_blob_sha1(ce->oid.hash))\n+\t\tif (!is_empty_blob_oid(&ce->oid))\n \t\t\tchanged |= DATA_CHANGED;\n \t}\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497133","messageId":"c481479598411894283c300dfeae78cdeb15f130.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 02/20] hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:49:50Z","receivedAt":"2024-06-14T06:49:54Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Many of our hash functions have two variants, one receiving a `struct\ngit_hash_algo` and one that derives it via `the_repository`. Adapt all\nof those functions to always require the hash algorithm as input and\ndrop the variants that do not accept one.\n\nAs those functions are now independent of `the_repository`, we can move\nthem from \"hash.h\" to \"hash-ll.h\".\n\nNote that both in this and subsequent commits in this series we always\njust pass `the_repository->hash_algo` as input even if it is obvious\nthat there is a repository in the context that we should be using the\nhash from instead. This is done to be on the safe side and not introduce\nany regressions. All callsites should eventually be amended to use a\nrepo passed via parameters, but this is outside the scope of this patch\nseries.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/index-pack.c     |  6 +++---\n builtin/pack-redundant.c |  8 +++++---\n builtin/unpack-objects.c |  3 ++-\n commit-graph.c           |  3 ++-\n csum-file.c              |  6 +++---\n hash-ll.h                | 15 +++++++++++++--\n hash-lookup.c            |  3 ++-\n hash.h                   | 24 ++----------------------\n http-walker.c            |  2 +-\n match-trees.c            |  2 +-\n notes.c                  |  2 +-\n pack-bitmap-write.c      |  4 ++--\n pack-bitmap.c            |  3 ++-\n pack-check.c             |  5 +++--\n pack-write.c             |  3 ++-\n packfile.c               |  8 ++++----\n read-cache.c             |  8 ++++----\n 17 files changed, 52 insertions(+), 53 deletions(-)\n\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex 856428fef9..ea727fba16 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -1204,7 +1204,7 @@ static void parse_pack_objects(unsigned char *hash)\n \tthe_hash_algo->init_fn(&tmp_ctx);\n \tthe_hash_algo->clone_fn(&tmp_ctx, &input_ctx);\n \tthe_hash_algo->final_fn(hash, &tmp_ctx);\n-\tif (!hasheq(fill(the_hash_algo->rawsz), hash))\n+\tif (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo))\n \t\tdie(_(\"pack is corrupted (SHA1 mismatch)\"));\n \tuse(the_hash_algo->rawsz);\n \n@@ -1307,11 +1307,11 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha\n \t\tstop_progress_msg(&progress, msg.buf);\n \t\tstrbuf_release(&msg);\n \t\tfinalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0);\n-\t\thashcpy(read_hash, pack_hash);\n+\t\thashcpy(read_hash, pack_hash, the_repository->hash_algo);\n \t\tfixup_pack_header_footer(output_fd, pack_hash,\n \t\t\t\t\t curr_pack, nr_objects,\n \t\t\t\t\t read_hash, consumed_bytes-the_hash_algo->rawsz);\n-\t\tif (!hasheq(read_hash, tail_hash))\n+\t\tif (!hasheq(read_hash, tail_hash, the_repository->hash_algo))\n \t\t\tdie(_(\"Unexpected tail checksum for %s \"\n \t\t\t      \"(disk corruption?)\"), curr_pack);\n \t}\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 4c735ba069..103c11b9d3 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -155,7 +155,7 @@ static inline struct llist_item * llist_sorted_remove(struct llist *list, const\n \tl = (hint == NULL) ? list->front : hint;\n \tprev = NULL;\n \twhile (l) {\n-\t\tconst int cmp = hashcmp(l->oid.hash, oid);\n+\t\tconst int cmp = hashcmp(l->oid.hash, oid, the_repository->hash_algo);\n \t\tif (cmp > 0) /* not in list, since sorted */\n \t\t\treturn prev;\n \t\tif (!cmp) { /* found */\n@@ -258,7 +258,8 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)\n \twhile (p1_off < p1->pack->num_objects * p1_step &&\n \t       p2_off < p2->pack->num_objects * p2_step)\n \t{\n-\t\tconst int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);\n+\t\tconst int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,\n+\t\t\t\t\tthe_repository->hash_algo);\n \t\t/* cmp ~ p1 - p2 */\n \t\tif (cmp == 0) {\n \t\t\tp1_hint = llist_sorted_remove(p1->unique_objects,\n@@ -296,7 +297,8 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)\n \twhile (p1_off < p1->num_objects * p1_step &&\n \t       p2_off < p2->num_objects * p2_step)\n \t{\n-\t\tint cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);\n+\t\tint cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,\n+\t\t\t\t  the_repository->hash_algo);\n \t\t/* cmp ~ p1 - p2 */\n \t\tif (cmp == 0) {\n \t\t\tret++;\ndiff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c\nindex f1c85a00ae..0855572c27 100644\n--- a/builtin/unpack-objects.c\n+++ b/builtin/unpack-objects.c\n@@ -674,7 +674,8 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)\n \t\tif (fsck_finish(&fsck_options))\n \t\t\tdie(_(\"fsck error in pack objects\"));\n \t}\n-\tif (!hasheq(fill(the_hash_algo->rawsz), oid.hash))\n+\tif (!hasheq(fill(the_hash_algo->rawsz), oid.hash,\n+\t\t    the_repository->hash_algo))\n \t\tdie(\"final sha1 did not match\");\n \tuse(the_hash_algo->rawsz);\n \ndiff --git a/commit-graph.c b/commit-graph.c\nindex e5dd3553df..3429156b28 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -565,7 +565,8 @@ static int add_graph_to_chain(struct commit_graph *g,\n \n \t\tif (!cur_g ||\n \t\t    !oideq(&oids[n], &cur_g->oid) ||\n-\t\t    !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n))) {\n+\t\t    !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n),\n+\t\t\t    the_repository->hash_algo)) {\n \t\t\twarning(_(\"commit-graph chain does not match\"));\n \t\t\treturn 0;\n \t\t}\ndiff --git a/csum-file.c b/csum-file.c\nindex 870748e016..f4be0804b7 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -68,12 +68,12 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result,\n \thashflush(f);\n \n \tif (f->skip_hash)\n-\t\thashclr(f->buffer);\n+\t\thashclr(f->buffer, the_repository->hash_algo);\n \telse\n \t\tthe_hash_algo->final_fn(f->buffer, &f->ctx);\n \n \tif (result)\n-\t\thashcpy(result, f->buffer);\n+\t\thashcpy(result, f->buffer, the_repository->hash_algo);\n \tif (flags & CSUM_HASH_IN_STREAM)\n \t\tflush(f, f->buffer, the_hash_algo->rawsz);\n \tif (flags & CSUM_FSYNC)\n@@ -237,5 +237,5 @@ int hashfile_checksum_valid(const unsigned char *data, size_t total_len)\n \tthe_hash_algo->update_fn(&ctx, data, data_len);\n \tthe_hash_algo->final_fn(got, &ctx);\n \n-\treturn hasheq(got, data + data_len);\n+\treturn hasheq(got, data + data_len, the_repository->hash_algo);\n }\ndiff --git a/hash-ll.h b/hash-ll.h\nindex 2cfde63ae1..fabdd8ecc7 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -245,7 +245,7 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n \n const struct object_id *null_oid(void);\n \n-static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n {\n \t/*\n \t * Teach the compiler that there are only two possibilities of hash size\n@@ -256,7 +256,7 @@ static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *\n \treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n }\n \n-static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n {\n \t/*\n \t * We write this here instead of deferring to hashcmp so that the\n@@ -267,6 +267,17 @@ static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *s\n \treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n }\n \n+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(sha_dst, sha_src, algop->rawsz);\n+}\n+\n+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n+{\n+\tmemset(hash, 0, algop->rawsz);\n+}\n+\n static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n {\n \tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\ndiff --git a/hash-lookup.c b/hash-lookup.c\nindex 9f0f95e2b9..9aa6b82eb7 100644\n--- a/hash-lookup.c\n+++ b/hash-lookup.c\n@@ -112,7 +112,8 @@ int bsearch_hash(const unsigned char *hash, const uint32_t *fanout_nbo,\n \n \twhile (lo < hi) {\n \t\tunsigned mi = lo + (hi - lo) / 2;\n-\t\tint cmp = hashcmp(table + mi * stride, hash);\n+\t\tint cmp = hashcmp(table + mi * stride, hash,\n+\t\t\t\t  the_repository->hash_algo);\n \n \t\tif (!cmp) {\n \t\t\tif (result)\ndiff --git a/hash.h b/hash.h\nindex a1161e1b22..714938e2eb 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,11 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)\n-{\n-\treturn hashcmp_algop(sha1, sha2, the_hash_algo);\n-}\n-\n static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n {\n \tconst struct git_hash_algo *algop;\n@@ -18,12 +13,7 @@ static inline int oidcmp(const struct object_id *oid1, const struct object_id *o\n \t\talgop = the_hash_algo;\n \telse\n \t\talgop = &hash_algos[oid1->algo];\n-\treturn hashcmp_algop(oid1->hash, oid2->hash, algop);\n-}\n-\n-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2)\n-{\n-\treturn hasheq_algop(sha1, sha2, the_hash_algo);\n+\treturn hashcmp(oid1->hash, oid2->hash, algop);\n }\n \n static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n@@ -33,7 +23,7 @@ static inline int oideq(const struct object_id *oid1, const struct object_id *oi\n \t\talgop = the_hash_algo;\n \telse\n \t\talgop = &hash_algos[oid1->algo];\n-\treturn hasheq_algop(oid1->hash, oid2->hash, algop);\n+\treturn hasheq(oid1->hash, oid2->hash, algop);\n }\n \n static inline int is_null_oid(const struct object_id *oid)\n@@ -41,11 +31,6 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn oideq(oid, null_oid());\n }\n \n-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)\n-{\n-\tmemcpy(sha_dst, sha_src, the_hash_algo->rawsz);\n-}\n-\n /* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */\n static inline void oidcpy_with_padding(struct object_id *dst,\n \t\t\t\t       const struct object_id *src)\n@@ -62,11 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,\n \tdst->algo = src->algo;\n }\n \n-static inline void hashclr(unsigned char *hash)\n-{\n-\tmemset(hash, 0, the_hash_algo->rawsz);\n-}\n-\n static inline void oidclr(struct object_id *oid)\n {\n \tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\ndiff --git a/http-walker.c b/http-walker.c\nindex b395ef1327..cf7f8c82bc 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -485,7 +485,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)\n \n \tlist_for_each(pos, head) {\n \t\tobj_req = list_entry(pos, struct object_request, node);\n-\t\tif (hasheq(obj_req->oid.hash, hash))\n+\t\tif (hasheq(obj_req->oid.hash, hash, the_repository->hash_algo))\n \t\t\tbreak;\n \t}\n \tif (!obj_req)\ndiff --git a/match-trees.c b/match-trees.c\nindex 3412b6a140..849b391d3d 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -237,7 +237,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,\n \t} else {\n \t\trewrite_with = oid2;\n \t}\n-\thashcpy(rewrite_here, rewrite_with->hash);\n+\thashcpy(rewrite_here, rewrite_with->hash, the_repository->hash_algo);\n \tstatus = write_object_file(buf, sz, OBJ_TREE, result);\n \tfree(buf);\n \treturn status;\ndiff --git a/notes.c b/notes.c\nindex 53ca25c814..5296fd863f 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -149,7 +149,7 @@ static struct leaf_node *note_tree_find(struct notes_tree *t,\n \tvoid **p = note_tree_search(t, &tree, &n, key_sha1);\n \tif (GET_PTR_TYPE(*p) == PTR_TYPE_NOTE) {\n \t\tstruct leaf_node *l = (struct leaf_node *) CLR_PTR_TYPE(*p);\n-\t\tif (hasheq(key_sha1, l->key_oid.hash))\n+\t\tif (hasheq(key_sha1, l->key_oid.hash, the_repository->hash_algo))\n \t\t\treturn l;\n \t}\n \treturn NULL;\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 6cae670412..59d2e3a387 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -790,7 +790,7 @@ static void write_hash_cache(struct hashfile *f,\n void bitmap_writer_set_checksum(struct bitmap_writer *writer,\n \t\t\t\tconst unsigned char *sha1)\n {\n-\thashcpy(writer->pack_checksum, sha1);\n+\thashcpy(writer->pack_checksum, sha1, the_repository->hash_algo);\n }\n \n void bitmap_writer_finish(struct bitmap_writer *writer,\n@@ -816,7 +816,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,\n \theader.version = htons(default_version);\n \theader.options = htons(flags | options);\n \theader.entry_count = htonl(writer->selected_nr);\n-\thashcpy(header.checksum, writer->pack_checksum);\n+\thashcpy(header.checksum, writer->pack_checksum, the_repository->hash_algo);\n \n \thashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz);\n \tdump_bitmap(f, writer->commits);\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex fe8e8a51d3..184d28f05c 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -367,7 +367,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,\n \tif (load_bitmap_header(bitmap_git) < 0)\n \t\tgoto cleanup;\n \n-\tif (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum)) {\n+\tif (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum,\n+\t\t    the_repository->hash_algo)) {\n \t\terror(_(\"checksum doesn't match in MIDX and bitmap\"));\n \t\tgoto cleanup;\n \t}\ndiff --git a/pack-check.c b/pack-check.c\nindex 25104d5b14..e7b214fcbd 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -78,10 +78,11 @@ static int verify_packfile(struct repository *r,\n \t} while (offset < pack_sig_ofs);\n \tr->hash_algo->final_fn(hash, &ctx);\n \tpack_sig = use_pack(p, w_curs, pack_sig_ofs, NULL);\n-\tif (!hasheq(hash, pack_sig))\n+\tif (!hasheq(hash, pack_sig, the_repository->hash_algo))\n \t\terr = error(\"%s pack checksum mismatch\",\n \t\t\t    p->pack_name);\n-\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig))\n+\tif (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig,\n+\t\t    the_repository->hash_algo))\n \t\terr = error(\"%s pack checksum does not match its index\",\n \t\t\t    p->pack_name);\n \tunuse_pack(w_curs);\ndiff --git a/pack-write.c b/pack-write.c\nindex 80ecfa544c..eef625fa5b 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -428,7 +428,8 @@ void fixup_pack_header_footer(int pack_fd,\n \t\tif (partial_pack_offset == 0) {\n \t\t\tunsigned char hash[GIT_MAX_RAWSZ];\n \t\t\tthe_hash_algo->final_fn(hash, &old_hash_ctx);\n-\t\t\tif (!hasheq(hash, partial_pack_hash))\n+\t\t\tif (!hasheq(hash, partial_pack_hash,\n+\t\t\t\t    the_repository->hash_algo))\n \t\t\t\tdie(\"Unexpected checksum for %s \"\n \t\t\t\t    \"(disk corruption?)\", pack_name);\n \t\t\t/*\ndiff --git a/packfile.c b/packfile.c\nindex d4df7fdeea..9156e9122c 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -242,7 +242,7 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)\n \tstruct packed_git *p = alloc_packed_git(alloc);\n \n \tmemcpy(p->pack_name, path, alloc); /* includes NUL */\n-\thashcpy(p->hash, sha1);\n+\thashcpy(p->hash, sha1, the_repository->hash_algo);\n \tif (check_packed_git_idx(idx_path, p)) {\n \t\tfree(p);\n \t\treturn NULL;\n@@ -596,7 +596,7 @@ static int open_packed_git_1(struct packed_git *p)\n \tif (read_result != hashsz)\n \t\treturn error(\"packfile %s signature is unavailable\", p->pack_name);\n \tidx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;\n-\tif (!hasheq(hash, idx_hash))\n+\tif (!hasheq(hash, idx_hash, the_repository->hash_algo))\n \t\treturn error(\"packfile %s does not match index\", p->pack_name);\n \treturn 0;\n }\n@@ -751,7 +751,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n \tp->mtime = st.st_mtime;\n \tif (path_len < the_hash_algo->hexsz ||\n \t    get_hash_hex(path + path_len - the_hash_algo->hexsz, p->hash))\n-\t\thashclr(p->hash);\n+\t\thashclr(p->hash, the_repository->hash_algo);\n \treturn p;\n }\n \n@@ -1971,7 +1971,7 @@ off_t find_pack_entry_one(const unsigned char *sha1,\n \t\t\treturn 0;\n \t}\n \n-\thashcpy(oid.hash, sha1);\n+\thashcpy(oid.hash, sha1, the_repository->hash_algo);\n \tif (bsearch_pack(&oid, p, &result))\n \t\treturn nth_packed_object_offset(p, result);\n \treturn 0;\ndiff --git a/read-cache.c b/read-cache.c\nindex 10e002ce6d..2642ac9558 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1735,7 +1735,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)\n \tthe_hash_algo->init_fn(&c);\n \tthe_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz);\n \tthe_hash_algo->final_fn(hash, &c);\n-\tif (!hasheq(hash, start))\n+\tif (!hasheq(hash, start, the_repository->hash_algo))\n \t\treturn error(_(\"bad index file sha1 signature\"));\n \treturn 0;\n }\n@@ -2641,7 +2641,7 @@ static void copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,\n \tondisk->uid  = htonl(ce->ce_stat_data.sd_uid);\n \tondisk->gid  = htonl(ce->ce_stat_data.sd_gid);\n \tondisk->size = htonl(ce->ce_stat_data.sd_size);\n-\thashcpy(ondisk->data, ce->oid.hash);\n+\thashcpy(ondisk->data, ce->oid.hash, the_repository->hash_algo);\n \n \tflags = ce->ce_flags & ~CE_NAMEMASK;\n \tflags |= (ce_namelen(ce) >= CE_NAMEMASK ? CE_NAMEMASK : ce_namelen(ce));\n@@ -2730,7 +2730,7 @@ static int verify_index_from(const struct index_state *istate, const char *path)\n \tif (n != the_hash_algo->rawsz)\n \t\tgoto out;\n \n-\tif (!hasheq(istate->oid.hash, hash))\n+\tif (!hasheq(istate->oid.hash, hash, the_repository->hash_algo))\n \t\tgoto out;\n \n \tclose(fd);\n@@ -3603,7 +3603,7 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size)\n \t\tsrc_offset += extsize;\n \t}\n \tthe_hash_algo->final_fn(hash, &c);\n-\tif (!hasheq(hash, (const unsigned char *)index))\n+\tif (!hasheq(hash, (const unsigned char *)index, the_repository->hash_algo))\n \t\treturn 0;\n \n \t/* Validate that the extension offsets returned us back to the eoie extension. */\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497134","messageId":"226173a92b7bc35b13b7b6cde272bd36d1128529.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 03/20] hash: require hash algorithm in `oidread()` and `oidclr()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:49:54Z","receivedAt":"2024-06-14T06:49:59Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both `oidread()` and `oidclr()` use `the_repository` to derive the hash\nfunction that shall be used. Require callers to pass in the hash\nalgorithm to get rid of this implicit dependency.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n apply.c                          |  2 +-\n blame.c                          |  2 +-\n builtin/am.c                     |  8 +++----\n builtin/fast-export.c            |  2 +-\n builtin/fast-import.c            | 39 +++++++++++++++++---------------\n builtin/fetch-pack.c             |  4 ++--\n builtin/index-pack.c             |  5 ++--\n builtin/log.c                    |  2 +-\n builtin/merge.c                  |  4 ++--\n builtin/notes.c                  |  2 +-\n builtin/pack-objects.c           |  3 ++-\n builtin/pack-redundant.c         |  2 +-\n builtin/patch-id.c               |  6 ++---\n builtin/pull.c                   |  6 ++---\n builtin/receive-pack.c           |  2 +-\n builtin/replace.c                |  2 +-\n builtin/rm.c                     |  2 +-\n builtin/tag.c                    |  2 +-\n builtin/unpack-objects.c         |  6 ++---\n builtin/update-ref.c             |  8 +++----\n cache-tree.c                     |  3 ++-\n commit-graph.c                   | 17 +++++++++-----\n diff-lib.c                       |  4 ++--\n diff.c                           |  6 ++---\n dir.c                            |  6 ++---\n hash-ll.h                        | 14 ++++++++++++\n hash.h                           | 17 --------------\n http-push.c                      |  2 +-\n http-walker.c                    |  2 +-\n match-trees.c                    |  2 +-\n midx.c                           |  3 ++-\n notes-merge.c                    |  6 ++---\n notes.c                          |  8 +++----\n object-file-convert.c            |  2 +-\n object-file.c                    |  4 ++--\n packfile.c                       | 10 ++++----\n read-cache.c                     |  8 ++++---\n refs.c                           |  6 ++---\n refs/files-backend.c             |  6 ++---\n refs/packed-backend.c            |  6 ++---\n refs/reftable-backend.c          | 37 ++++++++++++++++++------------\n remote.c                         |  8 +++----\n resolve-undo.c                   |  3 ++-\n sequencer.c                      |  4 ++--\n split-index.c                    |  2 +-\n submodule-config.c               |  2 +-\n t/helper/test-submodule-config.c |  2 +-\n tree-walk.c                      |  4 ++--\n 48 files changed, 163 insertions(+), 140 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 901b67e625..528939abb6 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -3680,7 +3680,7 @@ static int try_threeway(struct apply_state *state,\n \tif (status) {\n \t\tpatch->conflicted_threeway = 1;\n \t\tif (patch->is_new)\n-\t\t\toidclr(&patch->threeway_stage[0]);\n+\t\t\toidclr(&patch->threeway_stage[0], the_repository->hash_algo);\n \t\telse\n \t\t\toidcpy(&patch->threeway_stage[0], &pre_oid);\n \t\toidcpy(&patch->threeway_stage[1], &our_oid);\ndiff --git a/blame.c b/blame.c\nindex 33586b9777..a80f5e2e61 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -1246,7 +1246,7 @@ static int fill_blob_sha1_and_mode(struct repository *r,\n \t\tgoto error_out;\n \treturn 0;\n  error_out:\n-\toidclr(&origin->blob_oid);\n+\toidclr(&origin->blob_oid, the_repository->hash_algo);\n \torigin->mode = S_IFINVALID;\n \treturn -1;\n }\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 36839029d2..45c305ec86 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -408,7 +408,7 @@ static void am_load(struct am_state *state)\n \tread_commit_msg(state);\n \n \tif (read_state_file(&sb, state, \"original-commit\", 1) < 0)\n-\t\toidclr(&state->orig_commit);\n+\t\toidclr(&state->orig_commit, the_repository->hash_algo);\n \telse if (get_oid_hex(sb.buf, &state->orig_commit) < 0)\n \t\tdie(_(\"could not parse %s\"), am_path(state, \"original-commit\"));\n \n@@ -1121,7 +1121,7 @@ static void am_next(struct am_state *state)\n \tunlink(am_path(state, \"author-script\"));\n \tunlink(am_path(state, \"final-commit\"));\n \n-\toidclr(&state->orig_commit);\n+\toidclr(&state->orig_commit, the_repository->hash_algo);\n \tunlink(am_path(state, \"original-commit\"));\n \trefs_delete_ref(get_main_ref_store(the_repository), NULL,\n \t\t\t\"REBASE_HEAD\", NULL, REF_NO_DEREF);\n@@ -2151,11 +2151,11 @@ static int safe_to_abort(const struct am_state *state)\n \t\tif (get_oid_hex(sb.buf, &abort_safety))\n \t\t\tdie(_(\"could not parse %s\"), am_path(state, \"abort-safety\"));\n \t} else\n-\t\toidclr(&abort_safety);\n+\t\toidclr(&abort_safety, the_repository->hash_algo);\n \tstrbuf_release(&sb);\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &head))\n-\t\toidclr(&head);\n+\t\toidclr(&head, the_repository->hash_algo);\n \n \tif (oideq(&head, &abort_safety))\n \t\treturn 1;\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 4693d18cc9..4b6e8c6832 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -415,7 +415,7 @@ static char *generate_fake_oid(void)\n \tstruct object_id oid;\n \tchar *hex = xmallocz(GIT_MAX_HEXSZ);\n \n-\toidclr(&oid);\n+\toidclr(&oid, the_repository->hash_algo);\n \tput_be32(oid.hash + hashsz - 4, counter++);\n \treturn oid_to_hex_r(hex, &oid);\n }\ndiff --git a/builtin/fast-import.c b/builtin/fast-import.c\nindex d1c0243d04..12543488f3 100644\n--- a/builtin/fast-import.c\n+++ b/builtin/fast-import.c\n@@ -1279,8 +1279,10 @@ static void load_tree(struct tree_entry *root)\n \t\te->versions[0].mode = e->versions[1].mode;\n \t\te->name = to_atom(c, strlen(c));\n \t\tc += e->name->str_len + 1;\n-\t\toidread(&e->versions[0].oid, (unsigned char *)c);\n-\t\toidread(&e->versions[1].oid, (unsigned char *)c);\n+\t\toidread(&e->versions[0].oid, (unsigned char *)c,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&e->versions[1].oid, (unsigned char *)c,\n+\t\t\tthe_repository->hash_algo);\n \t\tc += the_hash_algo->rawsz;\n \t}\n \tfree(buf);\n@@ -1386,7 +1388,7 @@ static void tree_content_replace(\n {\n \tif (!S_ISDIR(mode))\n \t\tdie(\"Root cannot be a non-directory\");\n-\toidclr(&root->versions[0].oid);\n+\toidclr(&root->versions[0].oid, the_repository->hash_algo);\n \toidcpy(&root->versions[1].oid, oid);\n \tif (root->tree)\n \t\trelease_tree_content_recursive(root->tree);\n@@ -1445,7 +1447,7 @@ static int tree_content_set(\n \t\t\t\tif (S_ISDIR(e->versions[0].mode))\n \t\t\t\t\te->versions[0].mode |= NO_DELTA;\n \n-\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \t\t\t\treturn 1;\n \t\t\t}\n \t\t\tif (!S_ISDIR(e->versions[1].mode)) {\n@@ -1455,7 +1457,7 @@ static int tree_content_set(\n \t\t\tif (!e->tree)\n \t\t\t\tload_tree(e);\n \t\t\tif (tree_content_set(e, slash1 + 1, oid, mode, subtree)) {\n-\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \t\t\t\treturn 1;\n \t\t\t}\n \t\t\treturn 0;\n@@ -1467,7 +1469,7 @@ static int tree_content_set(\n \te = new_tree_entry();\n \te->name = to_atom(p, n);\n \te->versions[0].mode = 0;\n-\toidclr(&e->versions[0].oid);\n+\toidclr(&e->versions[0].oid, the_repository->hash_algo);\n \tt->entries[t->entry_count++] = e;\n \tif (*slash1) {\n \t\te->tree = new_tree_content(8);\n@@ -1478,7 +1480,7 @@ static int tree_content_set(\n \t\te->versions[1].mode = mode;\n \t\toidcpy(&e->versions[1].oid, oid);\n \t}\n-\toidclr(&root->versions[1].oid);\n+\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \treturn 1;\n }\n \n@@ -1523,7 +1525,8 @@ static int tree_content_remove(\n \t\t\tif (tree_content_remove(e, slash1 + 1, backup_leaf, 0)) {\n \t\t\t\tfor (n = 0; n < e->tree->entry_count; n++) {\n \t\t\t\t\tif (e->tree->entries[n]->versions[1].mode) {\n-\t\t\t\t\t\toidclr(&root->versions[1].oid);\n+\t\t\t\t\t\toidclr(&root->versions[1].oid,\n+\t\t\t\t\t\t       the_repository->hash_algo);\n \t\t\t\t\t\treturn 1;\n \t\t\t\t\t}\n \t\t\t\t}\n@@ -1542,8 +1545,8 @@ static int tree_content_remove(\n \t\trelease_tree_content_recursive(e->tree);\n \te->tree = NULL;\n \te->versions[1].mode = 0;\n-\toidclr(&e->versions[1].oid);\n-\toidclr(&root->versions[1].oid);\n+\toidclr(&e->versions[1].oid, the_repository->hash_algo);\n+\toidclr(&root->versions[1].oid, the_repository->hash_algo);\n \treturn 1;\n }\n \n@@ -1609,7 +1612,7 @@ static int update_branch(struct branch *b)\n \t\treturn 0;\n \t}\n \tif (refs_read_ref(get_main_ref_store(the_repository), b->name, &old_oid))\n-\t\toidclr(&old_oid);\n+\t\toidclr(&old_oid, the_repository->hash_algo);\n \tif (!force_update && !is_null_oid(&old_oid)) {\n \t\tstruct commit *old_cmit, *new_cmit;\n \t\tint ret;\n@@ -2550,8 +2553,8 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa\n static void file_change_deleteall(struct branch *b)\n {\n \trelease_tree_content_recursive(b->branch_tree.tree);\n-\toidclr(&b->branch_tree.versions[0].oid);\n-\toidclr(&b->branch_tree.versions[1].oid);\n+\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \tload_tree(&b->branch_tree);\n \tb->num_notes = 0;\n }\n@@ -2570,8 +2573,8 @@ static void parse_from_commit(struct branch *b, char *buf, unsigned long size)\n static void parse_from_existing(struct branch *b)\n {\n \tif (is_null_oid(&b->oid)) {\n-\t\toidclr(&b->branch_tree.versions[0].oid);\n-\t\toidclr(&b->branch_tree.versions[1].oid);\n+\t\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \t} else {\n \t\tunsigned long size;\n \t\tchar *buf;\n@@ -2894,9 +2897,9 @@ static void parse_reset_branch(const char *arg)\n \n \tb = lookup_branch(arg);\n \tif (b) {\n-\t\toidclr(&b->oid);\n-\t\toidclr(&b->branch_tree.versions[0].oid);\n-\t\toidclr(&b->branch_tree.versions[1].oid);\n+\t\toidclr(&b->oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[0].oid, the_repository->hash_algo);\n+\t\toidclr(&b->branch_tree.versions[1].oid, the_repository->hash_algo);\n \t\tif (b->branch_tree.tree) {\n \t\t\trelease_tree_content_recursive(b->branch_tree.tree);\n \t\t\tb->branch_tree.tree = NULL;\ndiff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c\nindex 44c05ee86c..af329e8d5c 100644\n--- a/builtin/fetch-pack.c\n+++ b/builtin/fetch-pack.c\n@@ -29,11 +29,11 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,\n \t\t\t; /* <oid>, leave oid as name */\n \t\t} else {\n \t\t\t/* <ref>, clear cruft from oid */\n-\t\t\toidclr(&oid);\n+\t\t\toidclr(&oid, the_repository->hash_algo);\n \t\t}\n \t} else {\n \t\t/* <ref>, clear cruft from get_oid_hex */\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t}\n \n \tref = alloc_ref(name);\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex ea727fba16..fd968d673d 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -528,7 +528,8 @@ static void *unpack_raw_entry(struct object_entry *obj,\n \n \tswitch (obj->type) {\n \tcase OBJ_REF_DELTA:\n-\t\toidread(ref_oid, fill(the_hash_algo->rawsz));\n+\t\toidread(ref_oid, fill(the_hash_algo->rawsz),\n+\t\t\tthe_repository->hash_algo);\n \t\tuse(the_hash_algo->rawsz);\n \t\tbreak;\n \tcase OBJ_OFS_DELTA:\n@@ -1372,7 +1373,7 @@ static struct object_entry *append_obj_to_pack(struct hashfile *f,\n \tobj[1].idx.offset += write_compressed(f, buf, size);\n \tobj[0].idx.crc32 = crc32_end(f);\n \thashflush(f);\n-\toidread(&obj->idx.oid, sha1);\n+\toidread(&obj->idx.oid, sha1, the_repository->hash_algo);\n \treturn obj;\n }\n \ndiff --git a/builtin/log.c b/builtin/log.c\nindex 78a247d8a9..ccbda8a005 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1938,7 +1938,7 @@ static void print_bases(struct base_tree_info *bases, FILE *file)\n \tfree(bases->patch_id);\n \tbases->nr_patch_id = 0;\n \tbases->alloc_patch_id = 0;\n-\toidclr(&bases->base_commit);\n+\toidclr(&bases->base_commit, the_repository->hash_algo);\n }\n \n static const char *diff_title(struct strbuf *sb,\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex daed2d4e1e..abe66311c7 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -494,7 +494,7 @@ static void merge_name(const char *remote, struct strbuf *msg)\n \tstrbuf_branchname(&bname, remote, 0);\n \tremote = bname.buf;\n \n-\toidclr(&branch_head);\n+\toidclr(&branch_head, the_repository->hash_algo);\n \tremote_head = get_merge_parent(remote);\n \tif (!remote_head)\n \t\tdie(_(\"'%s' does not point to a commit\"), remote);\n@@ -1690,7 +1690,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t * index and working tree polluted.\n \t */\n \tif (save_state(&stash))\n-\t\toidclr(&stash);\n+\t\toidclr(&stash, the_repository->hash_algo);\n \n \tfor (i = 0; i < use_strategies_nr; i++) {\n \t\tint ret, cnt;\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 7f80b3449b..d9c356e354 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -828,7 +828,7 @@ static int merge_commit(struct notes_merge_options *o)\n \tif (partial->parents)\n \t\toidcpy(&parent_oid, &partial->parents->item->object.oid);\n \telse\n-\t\toidclr(&parent_oid);\n+\t\toidclr(&parent_oid, the_repository->hash_algo);\n \n \tCALLOC_ARRAY(t, 1);\n \tinit_notes(t, \"NOTES_MERGE_PARTIAL\", combine_notes_overwrite, 0);\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 638f5c57f0..2b00983a99 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -2078,7 +2078,8 @@ static void check_object(struct object_entry *entry, uint32_t object_index)\n \t\t\t\toidread(&base_ref,\n \t\t\t\t\tuse_pack(p, &w_curs,\n \t\t\t\t\t\t entry->in_pack_offset + used,\n-\t\t\t\t\t\t NULL));\n+\t\t\t\t\t\t NULL),\n+\t\t\t\t\tthe_repository->hash_algo);\n \t\t\t\thave_base = 1;\n \t\t\t}\n \t\t\tentry->in_pack_header_size = used + the_hash_algo->rawsz;\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 103c11b9d3..dd9bf35f5b 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -100,7 +100,7 @@ static inline struct llist_item *llist_insert(struct llist *list,\n \t\t\t\t\t      const unsigned char *oid)\n {\n \tstruct llist_item *new_item = llist_item_get();\n-\toidread(&new_item->oid, oid);\n+\toidread(&new_item->oid, oid, the_repository->hash_algo);\n \tnew_item->next = NULL;\n \n \tif (after) {\ndiff --git a/builtin/patch-id.c b/builtin/patch-id.c\nindex 583099cacf..d790ae6354 100644\n--- a/builtin/patch-id.c\n+++ b/builtin/patch-id.c\n@@ -70,7 +70,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,\n \tgit_hash_ctx ctx;\n \n \tthe_hash_algo->init_fn(&ctx);\n-\toidclr(result);\n+\toidclr(result, the_repository->hash_algo);\n \n \twhile (strbuf_getwholeline(line_buf, stdin, '\\n') != EOF) {\n \t\tchar *line = line_buf->buf;\n@@ -166,7 +166,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,\n \t}\n \n \tif (!found_next)\n-\t\toidclr(next_oid);\n+\t\toidclr(next_oid, the_repository->hash_algo);\n \n \tflush_one_hunk(result, &ctx);\n \n@@ -179,7 +179,7 @@ static void generate_id_list(int stable, int verbatim)\n \tint patchlen;\n \tstruct strbuf line_buf = STRBUF_INIT;\n \n-\toidclr(&oid);\n+\toidclr(&oid, the_repository->hash_algo);\n \twhile (!feof(stdin)) {\n \t\tpatchlen = get_one_patchid(&n, &result, &line_buf, stable, verbatim);\n \t\tflush_current_id(patchlen, &oid, &result);\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex d622202bce..2a73e673f3 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -1038,7 +1038,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\tdie_conclude_merge();\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &orig_head))\n-\t\toidclr(&orig_head);\n+\t\toidclr(&orig_head, the_repository->hash_algo);\n \n \tif (opt_rebase) {\n \t\tif (opt_autostash == -1)\n@@ -1053,7 +1053,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\t\t\t_(\"Please commit or stash them.\"), 1, 0);\n \n \t\tif (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))\n-\t\t\toidclr(&rebase_fork_point);\n+\t\t\toidclr(&rebase_fork_point, the_repository->hash_algo);\n \t}\n \n \tif (run_fetch(repo, refspecs))\n@@ -1063,7 +1063,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)\n \t\treturn 0;\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &curr_head))\n-\t\toidclr(&curr_head);\n+\t\toidclr(&curr_head, the_repository->hash_algo);\n \n \tif (!is_null_oid(&orig_head) && !is_null_oid(&curr_head) &&\n \t\t\t!oideq(&orig_head, &curr_head)) {\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 01c1f04ece..aa5ba27d17 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -741,7 +741,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)\n \t\talready_done = 1;\n \t\tif (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB,\n \t\t\t\t      &push_cert_oid))\n-\t\t\toidclr(&push_cert_oid);\n+\t\t\toidclr(&push_cert_oid, the_repository->hash_algo);\n \n \t\tmemset(&sigcheck, '\\0', sizeof(sigcheck));\n \ndiff --git a/builtin/replace.c b/builtin/replace.c\nindex ce9f6974d2..1ef833c07f 100644\n--- a/builtin/replace.c\n+++ b/builtin/replace.c\n@@ -167,7 +167,7 @@ static int check_ref_valid(struct object_id *object,\n \t\treturn error(_(\"'%s' is not a valid ref name\"), ref->buf);\n \n \tif (refs_read_ref(get_main_ref_store(the_repository), ref->buf, prev))\n-\t\toidclr(prev);\n+\t\toidclr(prev, the_repository->hash_algo);\n \telse if (!force)\n \t\treturn error(_(\"replace ref '%s' already exists\"), ref->buf);\n \treturn 0;\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex d195c16e74..0e79cbab62 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -377,7 +377,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tif (!force) {\n \t\tstruct object_id oid;\n \t\tif (repo_get_oid(the_repository, \"HEAD\", &oid))\n-\t\t\toidclr(&oid);\n+\t\t\toidclr(&oid, the_repository->hash_algo);\n \t\tif (check_local_mod(&oid, index_only))\n \t\t\texit(1);\n \t}\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 6e2c0cf342..a1fb218512 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -650,7 +650,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\tdie(_(\"'%s' is not a valid tag name.\"), tag);\n \n \tif (refs_read_ref(get_main_ref_store(the_repository), ref.buf, &prev))\n-\t\toidclr(&prev);\n+\t\toidclr(&prev, the_repository->hash_algo);\n \telse if (!force)\n \t\tdie(_(\"tag '%s' already exists\"), tag);\n \ndiff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c\nindex 0855572c27..08fa2a7a74 100644\n--- a/builtin/unpack-objects.c\n+++ b/builtin/unpack-objects.c\n@@ -439,7 +439,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \tstruct object_id base_oid;\n \n \tif (type == OBJ_REF_DELTA) {\n-\t\toidread(&base_oid, fill(the_hash_algo->rawsz));\n+\t\toidread(&base_oid, fill(the_hash_algo->rawsz), the_repository->hash_algo);\n \t\tuse(the_hash_algo->rawsz);\n \t\tdelta_data = get_data(delta_size);\n \t\tif (!delta_data)\n@@ -451,7 +451,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \t\t\treturn; /* we are done */\n \t\telse {\n \t\t\t/* cannot resolve yet --- queue it */\n-\t\t\toidclr(&obj_list[nr].oid);\n+\t\t\toidclr(&obj_list[nr].oid, the_repository->hash_algo);\n \t\t\tadd_delta_to_list(nr, &base_oid, 0, delta_data, delta_size);\n \t\t\treturn;\n \t\t}\n@@ -500,7 +500,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,\n \t\t\t * The delta base object is itself a delta that\n \t\t\t * has not been resolved yet.\n \t\t\t */\n-\t\t\toidclr(&obj_list[nr].oid);\n+\t\t\toidclr(&obj_list[nr].oid, the_repository->hash_algo);\n \t\t\tadd_delta_to_list(nr, null_oid(), base_offset,\n \t\t\t\t\t  delta_data, delta_size);\n \t\t\treturn;\ndiff --git a/builtin/update-ref.c b/builtin/update-ref.c\nindex 6cda1c08aa..f8a5b087f8 100644\n--- a/builtin/update-ref.c\n+++ b/builtin/update-ref.c\n@@ -122,7 +122,7 @@ static int parse_next_oid(const char **next, const char *end,\n \t\t\t\tgoto invalid;\n \t\t} else {\n \t\t\t/* Without -z, an empty value means all zeros: */\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t}\n \t} else {\n \t\t/* With -z, read the next NUL-terminated line */\n@@ -142,7 +142,7 @@ static int parse_next_oid(const char **next, const char *end,\n \t\t\t/* With -z, treat an empty value as all zeros: */\n \t\t\twarning(\"%s %s: missing <new-oid>, treating as zero\",\n \t\t\t\tcommand, refname);\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t} else {\n \t\t\t/*\n \t\t\t * With -z, an empty non-required value means\n@@ -291,7 +291,7 @@ static void parse_cmd_verify(struct ref_transaction *transaction,\n \n \tif (parse_next_oid(&next, end, &old_oid, \"verify\", refname,\n \t\t\t   PARSE_SHA1_OLD))\n-\t\toidclr(&old_oid);\n+\t\toidclr(&old_oid, the_repository->hash_algo);\n \n \tif (*next != line_termination)\n \t\tdie(\"verify %s: extra input: %s\", refname, next);\n@@ -564,7 +564,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)\n \t\t\t * The empty string implies that the reference\n \t\t\t * must not already exist:\n \t\t\t */\n-\t\t\toidclr(&oldoid);\n+\t\t\toidclr(&oldoid, the_repository->hash_algo);\n \t\telse if (repo_get_oid(the_repository, oldval, &oldoid))\n \t\t\tdie(\"%s: not a valid old SHA1\", oldval);\n \t}\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 387c0a3e5b..e4255c4d02 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -578,7 +578,8 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)\n \tif (0 <= it->entry_count) {\n \t\tif (size < rawsz)\n \t\t\tgoto free_return;\n-\t\toidread(&it->oid, (const unsigned char *)buf);\n+\t\toidread(&it->oid, (const unsigned char *)buf,\n+\t\t\tthe_repository->hash_algo);\n \t\tbuf += rawsz;\n \t\tsize -= rawsz;\n \t}\ndiff --git a/commit-graph.c b/commit-graph.c\nindex 3429156b28..98cbd53eea 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -475,7 +475,8 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,\n \t\tFREE_AND_NULL(graph->bloom_filter_settings);\n \t}\n \n-\toidread(&graph->oid, graph->data + graph->data_len - graph->hash_len);\n+\toidread(&graph->oid, graph->data + graph->data_len - graph->hash_len,\n+\t\tthe_repository->hash_algo);\n \n \tfree_chunkfile(cf);\n \treturn graph;\n@@ -838,7 +839,8 @@ static void load_oid_from_graph(struct commit_graph *g,\n \n \tlex_index = pos - g->num_commits_in_base;\n \n-\toidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index));\n+\toidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index),\n+\t\tthe_repository->hash_algo);\n }\n \n static struct commit_list **insert_parent_or_die(struct repository *r,\n@@ -1080,7 +1082,7 @@ static struct tree *load_tree_for_commit(struct repository *r,\n \tcommit_data = g->chunk_commit_data +\n \t\t\tst_mult(GRAPH_DATA_WIDTH, graph_pos - g->num_commits_in_base);\n \n-\toidread(&oid, commit_data);\n+\toidread(&oid, commit_data, the_repository->hash_algo);\n \tset_commit_tree(c, lookup_tree(r, &oid));\n \n \treturn c->maybe_tree;\n@@ -2556,7 +2558,8 @@ int write_commit_graph(struct object_directory *odb,\n \t\tstruct commit_graph *g = ctx->r->objects->commit_graph;\n \t\tfor (i = 0; i < g->num_commits; i++) {\n \t\t\tstruct object_id oid;\n-\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\t\toidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\toid_array_append(&ctx->oids, &oid);\n \t\t}\n \t}\n@@ -2675,7 +2678,8 @@ static int verify_one_commit_graph(struct repository *r,\n \tfor (i = 0; i < g->num_commits; i++) {\n \t\tstruct commit *graph_commit;\n \n-\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\tthe_repository->hash_algo);\n \n \t\tif (i && oidcmp(&prev_oid, &cur_oid) >= 0)\n \t\t\tgraph_report(_(\"commit-graph has incorrect OID order: %s then %s\"),\n@@ -2719,7 +2723,8 @@ static int verify_one_commit_graph(struct repository *r,\n \t\ttimestamp_t generation;\n \n \t\tdisplay_progress(progress, ++(*seen));\n-\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i));\n+\t\toidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),\n+\t\t\tthe_repository->hash_algo);\n \n \t\tgraph_commit = lookup_commit(r, &cur_oid);\n \t\todb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 5a5a50c5a1..3fb8d79fef 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -160,7 +160,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)\n \t\t\tdpath->next = NULL;\n \t\t\tmemcpy(dpath->path, ce->name, path_len);\n \t\t\tdpath->path[path_len] = '\\0';\n-\t\t\toidclr(&dpath->oid);\n+\t\t\toidclr(&dpath->oid, the_repository->hash_algo);\n \t\t\tmemset(&(dpath->parent[0]), 0,\n \t\t\t       sizeof(struct combine_diff_parent)*5);\n \n@@ -412,7 +412,7 @@ static int show_modified(struct rev_info *revs,\n \t\tmemcpy(p->path, new_entry->name, pathlen);\n \t\tp->path[pathlen] = 0;\n \t\tp->mode = mode;\n-\t\toidclr(&p->oid);\n+\t\toidclr(&p->oid, the_repository->hash_algo);\n \t\tmemset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));\n \t\tp->parent[0].status = DIFF_STATUS_MODIFIED;\n \t\tp->parent[0].mode = new_entry->ce_mode;\ndiff --git a/diff.c b/diff.c\nindex e70301df76..60d1f7be81 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4567,7 +4567,7 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is\n \t\tif (!one->oid_valid) {\n \t\t\tstruct stat st;\n \t\t\tif (one->is_stdin) {\n-\t\t\t\toidclr(&one->oid);\n+\t\t\t\toidclr(&one->oid, the_repository->hash_algo);\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tif (lstat(one->path, &st) < 0)\n@@ -4577,7 +4577,7 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is\n \t\t}\n \t}\n \telse\n-\t\toidclr(&one->oid);\n+\t\toidclr(&one->oid, the_repository->hash_algo);\n }\n \n static void strip_prefix(int prefix_length, const char **namep, const char **otherp)\n@@ -6404,7 +6404,7 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid\n \tthe_hash_algo->init_fn(&ctx);\n \tmemset(&data, 0, sizeof(struct patch_id_t));\n \tdata.ctx = &ctx;\n-\toidclr(oid);\n+\toidclr(oid, the_repository->hash_algo);\n \n \tfor (i = 0; i < q->nr; i++) {\n \t\txpparam_t xpp;\ndiff --git a/dir.c b/dir.c\nindex 45be4ad261..5de421c29c 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1687,7 +1687,7 @@ static void prep_exclude(struct dir_struct *dir,\n \t\t}\n \n \t\t/* Try to read per-directory file */\n-\t\toidclr(&oid_stat.oid);\n+\t\toidclr(&oid_stat.oid, the_repository->hash_algo);\n \t\toid_stat.valid = 0;\n \t\tif (dir->exclude_per_dir &&\n \t\t    /*\n@@ -3794,7 +3794,7 @@ static void read_oid(size_t pos, void *cb)\n \t\trd->data = rd->end + 1;\n \t\treturn;\n \t}\n-\toidread(&ud->exclude_oid, rd->data);\n+\toidread(&ud->exclude_oid, rd->data, the_repository->hash_algo);\n \trd->data += the_hash_algo->rawsz;\n }\n \n@@ -3802,7 +3802,7 @@ static void load_oid_stat(struct oid_stat *oid_stat, const unsigned char *data,\n \t\t\t  const unsigned char *sha1)\n {\n \tstat_data_from_disk(&oid_stat->stat, data);\n-\toidread(&oid_stat->oid, sha1);\n+\toidread(&oid_stat->oid, sha1, the_repository->hash_algo);\n \toid_stat->valid = 1;\n }\n \ndiff --git a/hash-ll.h b/hash-ll.h\nindex fabdd8ecc7..dbb96369fc 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -284,6 +284,20 @@ static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n \tdst->algo = src->algo;\n }\n \n+static inline void oidread(struct object_id *oid, const unsigned char *hash,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(oid->hash, hash, algop->rawsz);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline void oidclr(struct object_id *oid,\n+\t\t\t  const struct git_hash_algo *algop)\n+{\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n static inline struct object_id *oiddup(const struct object_id *src)\n {\n \tstruct object_id *dst = xmalloc(sizeof(struct object_id));\ndiff --git a/hash.h b/hash.h\nindex 714938e2eb..43623a0c86 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -47,23 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,\n \tdst->algo = src->algo;\n }\n \n-static inline void oidclr(struct object_id *oid)\n-{\n-\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n-\toid->algo = hash_algo_by_ptr(the_hash_algo);\n-}\n-\n-static inline void oidread_algop(struct object_id *oid, const unsigned char *hash, const struct git_hash_algo *algop)\n-{\n-\tmemcpy(oid->hash, hash, algop->rawsz);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline void oidread(struct object_id *oid, const unsigned char *hash)\n-{\n-\toidread_algop(oid, hash, the_hash_algo);\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\ndiff --git a/http-push.c b/http-push.c\nindex 1fe51226fd..86de238b84 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1552,7 +1552,7 @@ static void fetch_symref(const char *path, char **symref, struct object_id *oid)\n \tfree(url);\n \n \tFREE_AND_NULL(*symref);\n-\toidclr(oid);\n+\toidclr(oid, the_repository->hash_algo);\n \n \tif (buffer.len == 0)\n \t\treturn;\ndiff --git a/http-walker.c b/http-walker.c\nindex cf7f8c82bc..b7110b6f82 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -152,7 +152,7 @@ static void prefetch(struct walker *walker, unsigned char *sha1)\n \n \tnewreq = xmalloc(sizeof(*newreq));\n \tnewreq->walker = walker;\n-\toidread(&newreq->oid, sha1);\n+\toidread(&newreq->oid, sha1, the_repository->hash_algo);\n \tnewreq->repo = data->alt;\n \tnewreq->state = WAITING;\n \tnewreq->req = NULL;\ndiff --git a/match-trees.c b/match-trees.c\nindex 849b391d3d..50c42e2061 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -229,7 +229,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,\n \t\t    oid_to_hex(oid1));\n \tif (*subpath) {\n \t\tstruct object_id tree_oid;\n-\t\toidread(&tree_oid, rewrite_here);\n+\t\toidread(&tree_oid, rewrite_here, the_repository->hash_algo);\n \t\tstatus = splice_tree(&tree_oid, subpath, oid2, &subtree);\n \t\tif (status)\n \t\t\treturn status;\ndiff --git a/midx.c b/midx.c\nindex bc4797196f..1e75f1a7eb 100644\n--- a/midx.c\n+++ b/midx.c\n@@ -304,7 +304,8 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid,\n \tif (n >= m->num_objects)\n \t\treturn NULL;\n \n-\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n));\n+\toidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n),\n+\t\tthe_repository->hash_algo);\n \treturn oid;\n }\n \ndiff --git a/notes-merge.c b/notes-merge.c\nindex 6a9a139b12..801941c2d1 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -240,7 +240,7 @@ static void diff_tree_local(struct notes_merge_options *o,\n \t\t\t *     (will be overwritten by following addition)\n \t\t\t */\n \t\t\tif (oideq(&mp->local, &uninitialized))\n-\t\t\t\toidclr(&mp->local);\n+\t\t\t\toidclr(&mp->local, the_repository->hash_algo);\n \t\t} else if (is_null_oid(&p->one->oid)) { /* addition */\n \t\t\t/*\n \t\t\t * Either this is a true addition (1), or it is part\n@@ -556,7 +556,7 @@ int notes_merge(struct notes_merge_options *o,\n \n \tassert(o->local_ref && o->remote_ref);\n \tassert(!strcmp(o->local_ref, local_tree->ref));\n-\toidclr(result_oid);\n+\toidclr(result_oid, the_repository->hash_algo);\n \n \ttrace_printf(\"notes_merge(o->local_ref = %s, o->remote_ref = %s)\\n\",\n \t       o->local_ref, o->remote_ref);\n@@ -579,7 +579,7 @@ int notes_merge(struct notes_merge_options *o,\n \t\t * unborn ref, perform the merge using an empty notes tree.\n \t\t */\n \t\tif (!check_refname_format(o->remote_ref, 0)) {\n-\t\t\toidclr(&remote_oid);\n+\t\t\toidclr(&remote_oid, the_repository->hash_algo);\n \t\t\tremote = NULL;\n \t\t} else {\n \t\t\tdie(\"Failed to resolve remote notes ref '%s'\",\ndiff --git a/notes.c b/notes.c\nindex 5296fd863f..3a8da92fb9 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -353,7 +353,7 @@ static void add_non_note(struct notes_tree *t, char *path,\n \tn->next = NULL;\n \tn->path = path;\n \tn->mode = mode;\n-\toidread(&n->oid, sha1);\n+\toidread(&n->oid, sha1, the_repository->hash_algo);\n \tt->prev_non_note = n;\n \n \tif (!t->first_non_note) {\n@@ -1036,7 +1036,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,\n \t\tdie(\"Failed to read notes tree referenced by %s (%s)\",\n \t\t    notes_ref, oid_to_hex(&object_oid));\n \n-\toidclr(&root_tree.key_oid);\n+\toidclr(&root_tree.key_oid, the_repository->hash_algo);\n \toidcpy(&root_tree.val_oid, &oid);\n \tload_subtree(t, &root_tree, t->root, 0);\n }\n@@ -1146,8 +1146,8 @@ int remove_note(struct notes_tree *t, const unsigned char *object_sha1)\n \tif (!t)\n \t\tt = &default_notes_tree;\n \tassert(t->initialized);\n-\toidread(&l.key_oid, object_sha1);\n-\toidclr(&l.val_oid);\n+\toidread(&l.key_oid, object_sha1, the_repository->hash_algo);\n+\toidclr(&l.val_oid, the_repository->hash_algo);\n \tnote_tree_remove(t, t->root, 0, &l);\n \tif (is_null_oid(&l.val_oid)) /* no note was removed */\n \t\treturn 1;\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex 4f6189095b..f684038f7f 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -56,7 +56,7 @@ static int decode_tree_entry_raw(struct object_id *oid, const char **path,\n \t\treturn -1;\n \t*len = strlen(*path) + 1;\n \n-\toidread_algop(oid, (const unsigned char *)*path + *len, algo);\n+\toidread(oid, (const unsigned char *)*path + *len, algo);\n \treturn 0;\n }\n \ndiff --git a/object-file.c b/object-file.c\nindex a40300ce4a..c161e3e2a5 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -1446,7 +1446,7 @@ static int loose_object_info(struct repository *r,\n \tint allow_unknown = flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE;\n \n \tif (oi->delta_base_oid)\n-\t\toidclr(oi->delta_base_oid);\n+\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \n \t/*\n \t * If we don't care about type or size, then we don't\n@@ -1580,7 +1580,7 @@ static int do_oid_object_info_extended(struct repository *r,\n \t\tif (oi->disk_sizep)\n \t\t\t*(oi->disk_sizep) = 0;\n \t\tif (oi->delta_base_oid)\n-\t\t\toidclr(oi->delta_base_oid);\n+\t\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \t\tif (oi->type_name)\n \t\t\tstrbuf_addstr(oi->type_name, type_name(co->type));\n \t\tif (oi->contentp)\ndiff --git a/packfile.c b/packfile.c\nindex 9156e9122c..ec7312cd20 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1251,7 +1251,7 @@ static int get_delta_base_oid(struct packed_git *p,\n {\n \tif (type == OBJ_REF_DELTA) {\n \t\tunsigned char *base = use_pack(p, w_curs, curpos, NULL);\n-\t\toidread(oid, base);\n+\t\toidread(oid, base, the_repository->hash_algo);\n \t\treturn 0;\n \t} else if (type == OBJ_OFS_DELTA) {\n \t\tuint32_t base_pos;\n@@ -1593,7 +1593,7 @@ int packed_object_info(struct repository *r, struct packed_git *p,\n \t\t\t\tgoto out;\n \t\t\t}\n \t\t} else\n-\t\t\toidclr(oi->delta_base_oid);\n+\t\t\toidclr(oi->delta_base_oid, the_repository->hash_algo);\n \t}\n \n \toi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED :\n@@ -1917,10 +1917,12 @@ int nth_packed_object_id(struct object_id *oid,\n \t\treturn -1;\n \tindex += 4 * 256;\n \tif (p->index_version == 1) {\n-\t\toidread(oid, index + st_add(st_mult(hashsz + 4, n), 4));\n+\t\toidread(oid, index + st_add(st_mult(hashsz + 4, n), 4),\n+\t\t\tthe_repository->hash_algo);\n \t} else {\n \t\tindex += 8;\n-\t\toidread(oid, index + st_mult(hashsz, n));\n+\t\toidread(oid, index + st_mult(hashsz, n),\n+\t\t\tthe_repository->hash_algo);\n \t}\n \treturn 0;\n }\ndiff --git a/read-cache.c b/read-cache.c\nindex 2642ac9558..836f1db721 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1728,7 +1728,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)\n \n \tend = (unsigned char *)hdr + size;\n \tstart = end - the_hash_algo->rawsz;\n-\toidread(&oid, start);\n+\toidread(&oid, start, the_repository->hash_algo);\n \tif (oideq(&oid, null_oid()))\n \t\treturn 0;\n \n@@ -1876,7 +1876,8 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,\n \tce->ce_flags = flags & ~CE_NAMEMASK;\n \tce->ce_namelen = len;\n \tce->index = 0;\n-\toidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data));\n+\toidread(&ce->oid, (const unsigned char *)ondisk + offsetof(struct ondisk_cache_entry, data),\n+\t\tthe_repository->hash_algo);\n \n \tif (expand_name_field) {\n \t\tif (copy_len)\n@@ -2249,7 +2250,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)\n \tif (verify_hdr(hdr, mmap_size) < 0)\n \t\tgoto unmap;\n \n-\toidread(&istate->oid, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz);\n+\toidread(&istate->oid, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz,\n+\t\tthe_repository->hash_algo);\n \tistate->version = ntohl(hdr->hdr_version);\n \tistate->cache_nr = ntohl(hdr->hdr_entries);\n \tistate->cache_alloc = alloc_nr(istate->cache_nr);\ndiff --git a/refs.c b/refs.c\nindex 1304d3dd87..6e7caefdcf 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1822,7 +1822,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \t\t\t    failure_errno != ENOTDIR)\n \t\t\t\treturn NULL;\n \n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\tif (*flags & REF_BAD_NAME)\n \t\t\t\t*flags |= REF_ISBROKEN;\n \t\t\treturn refname;\n@@ -1832,7 +1832,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \n \t\tif (!(read_flags & REF_ISSYMREF)) {\n \t\t\tif (*flags & REF_BAD_NAME) {\n-\t\t\t\toidclr(oid);\n+\t\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\t\t*flags |= REF_ISBROKEN;\n \t\t\t}\n \t\t\treturn refname;\n@@ -1840,7 +1840,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,\n \n \t\trefname = sb_refname.buf;\n \t\tif (resolve_flags & RESOLVE_REF_NO_RECURSE) {\n-\t\t\toidclr(oid);\n+\t\t\toidclr(oid, the_repository->hash_algo);\n \t\t\treturn refname;\n \t\t}\n \t\tif (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 4519b46171..b484b5880d 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -246,7 +246,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,\n \n \tif (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING,\n \t\t\t\t     &oid, &flag)) {\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t\tflag |= REF_ISBROKEN;\n \t} else if (is_null_oid(&oid)) {\n \t\t/*\n@@ -263,7 +263,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs,\n \tif (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {\n \t\tif (!refname_is_safe(refname))\n \t\t\tdie(\"loose refname is dangerous: %s\", refname);\n-\t\toidclr(&oid);\n+\t\toidclr(&oid, the_repository->hash_algo);\n \t\tflag |= REF_BAD_NAME | REF_ISBROKEN;\n \t}\n \tadd_entry_to_dir(dir, create_ref_entry(refname, &oid, flag));\n@@ -1150,7 +1150,7 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,\n \n \tif (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, 0,\n \t\t\t\t     &lock->old_oid, NULL))\n-\t\toidclr(&lock->old_oid);\n+\t\toidclr(&lock->old_oid, the_repository->hash_algo);\n \tgoto out;\n \n  error_return:\ndiff --git a/refs/packed-backend.c b/refs/packed-backend.c\nindex c4c1e36aa2..5ab1b21d10 100644\n--- a/refs/packed-backend.c\n+++ b/refs/packed-backend.c\n@@ -894,7 +894,7 @@ static int next_record(struct packed_ref_iterator *iter)\n \t\tif (!refname_is_safe(iter->base.refname))\n \t\t\tdie(\"packed refname is dangerous: %s\",\n \t\t\t    iter->base.refname);\n-\t\toidclr(&iter->oid);\n+\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\titer->base.flags |= REF_BAD_NAME | REF_ISBROKEN;\n \t}\n \tif (iter->snapshot->peeled == PEELED_FULLY ||\n@@ -919,13 +919,13 @@ static int next_record(struct packed_ref_iterator *iter)\n \t\t * we suppress it if the reference is broken:\n \t\t */\n \t\tif ((iter->base.flags & REF_ISBROKEN)) {\n-\t\t\toidclr(&iter->peeled);\n+\t\t\toidclr(&iter->peeled, the_repository->hash_algo);\n \t\t\titer->base.flags &= ~REF_KNOWS_PEELED;\n \t\t} else {\n \t\t\titer->base.flags |= REF_KNOWS_PEELED;\n \t\t}\n \t} else {\n-\t\toidclr(&iter->peeled);\n+\t\toidclr(&iter->peeled, the_repository->hash_algo);\n \t}\n \n \treturn ITER_OK;\ndiff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\nindex 9886fc67a4..57df2aba66 100644\n--- a/refs/reftable-backend.c\n+++ b/refs/reftable-backend.c\n@@ -217,7 +217,8 @@ static int read_ref_without_reload(struct reftable_stack *stack,\n \t\tstrbuf_addstr(referent, ref.value.symref);\n \t\t*type |= REF_ISSYMREF;\n \t} else if (reftable_ref_record_val1(&ref)) {\n-\t\toidread(oid, reftable_ref_record_val1(&ref));\n+\t\toidread(oid, reftable_ref_record_val1(&ref),\n+\t\t\tthe_repository->hash_algo);\n \t} else {\n \t\t/* We got a tombstone, which should not happen. */\n \t\tBUG(\"unhandled reference value type %d\", ref.value_type);\n@@ -483,15 +484,17 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)\n \n \t\tswitch (iter->ref.value_type) {\n \t\tcase REFTABLE_REF_VAL1:\n-\t\t\toidread(&iter->oid, iter->ref.value.val1);\n+\t\t\toidread(&iter->oid, iter->ref.value.val1,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tbreak;\n \t\tcase REFTABLE_REF_VAL2:\n-\t\t\toidread(&iter->oid, iter->ref.value.val2.value);\n+\t\t\toidread(&iter->oid, iter->ref.value.val2.value,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tbreak;\n \t\tcase REFTABLE_REF_SYMREF:\n \t\t\tif (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname,\n \t\t\t\t\t\t     RESOLVE_REF_READING, &iter->oid, &flags))\n-\t\t\t\toidclr(&iter->oid);\n+\t\t\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tBUG(\"unhandled reference value type %d\", iter->ref.value_type);\n@@ -503,7 +506,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)\n \t\tif (check_refname_format(iter->ref.refname, REFNAME_ALLOW_ONELEVEL)) {\n \t\t\tif (!refname_is_safe(iter->ref.refname))\n \t\t\t\tdie(_(\"refname is dangerous: %s\"), iter->ref.refname);\n-\t\t\toidclr(&iter->oid);\n+\t\t\toidclr(&iter->oid, the_repository->hash_algo);\n \t\t\tflags |= REF_BAD_NAME | REF_ISBROKEN;\n \t\t}\n \n@@ -545,7 +548,8 @@ static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator,\n \t\t(struct reftable_ref_iterator *)ref_iterator;\n \n \tif (iter->ref.value_type == REFTABLE_REF_VAL2) {\n-\t\toidread(peeled, iter->ref.value.val2.target_value);\n+\t\toidread(peeled, iter->ref.value.val2.target_value,\n+\t\t\tthe_repository->hash_algo);\n \t\treturn 0;\n \t}\n \n@@ -1776,8 +1780,8 @@ static int yield_log_record(struct reftable_log_record *log,\n \tstruct object_id old_oid, new_oid;\n \tconst char *full_committer;\n \n-\toidread(&old_oid, log->value.update.old_hash);\n-\toidread(&new_oid, log->value.update.new_hash);\n+\toidread(&old_oid, log->value.update.old_hash, the_repository->hash_algo);\n+\toidread(&new_oid, log->value.update.new_hash, the_repository->hash_algo);\n \n \t/*\n \t * When both the old object ID and the new object ID are null\n@@ -2178,7 +2182,8 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \tif (ret < 0)\n \t\tgoto done;\n \tif (reftable_ref_record_val1(&ref_record))\n-\t\toidread(&oid, reftable_ref_record_val1(&ref_record));\n+\t\toidread(&oid, reftable_ref_record_val1(&ref_record),\n+\t\t\tthe_repository->hash_algo);\n \tprepare_fn(refname, &oid, policy_cb_data);\n \n \twhile (1) {\n@@ -2193,8 +2198,10 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \t\t\tbreak;\n \t\t}\n \n-\t\toidread(&old_oid, log.value.update.old_hash);\n-\t\toidread(&new_oid, log.value.update.new_hash);\n+\t\toidread(&old_oid, log.value.update.old_hash,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&new_oid, log.value.update.new_hash,\n+\t\t\tthe_repository->hash_algo);\n \n \t\t/*\n \t\t * Skip over the reflog existence marker. We will add it back\n@@ -2225,8 +2232,10 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \t\tstruct object_id old_oid, new_oid;\n \n \t\t*dest = logs[i];\n-\t\toidread(&old_oid, logs[i].value.update.old_hash);\n-\t\toidread(&new_oid, logs[i].value.update.new_hash);\n+\t\toidread(&old_oid, logs[i].value.update.old_hash,\n+\t\t\tthe_repository->hash_algo);\n+\t\toidread(&new_oid, logs[i].value.update.new_hash,\n+\t\t\tthe_repository->hash_algo);\n \n \t\tif (should_prune_fn(&old_oid, &new_oid, logs[i].value.update.email,\n \t\t\t\t    (timestamp_t)logs[i].value.update.time,\n@@ -2243,7 +2252,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,\n \n \tif (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash &&\n \t    reftable_ref_record_val1(&ref_record))\n-\t\toidread(&arg.update_oid, last_hash);\n+\t\toidread(&arg.update_oid, last_hash, the_repository->hash_algo);\n \n \targ.refs = refs;\n \targ.records = rewritten;\ndiff --git a/remote.c b/remote.c\nindex dcb5492c85..1064171085 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1164,7 +1164,7 @@ static void tail_link_ref(struct ref *ref, struct ref ***tail)\n static struct ref *alloc_delete_ref(void)\n {\n \tstruct ref *ref = alloc_ref(\"(delete)\");\n-\toidclr(&ref->new_oid);\n+\toidclr(&ref->new_oid, the_repository->hash_algo);\n \treturn ref;\n }\n \n@@ -2531,7 +2531,7 @@ static int parse_push_cas_option(struct push_cas_option *cas, const char *arg, i\n \tif (!*colon)\n \t\tentry->use_tracking = 1;\n \telse if (!colon[1])\n-\t\toidclr(&entry->expect);\n+\t\toidclr(&entry->expect, the_repository->hash_algo);\n \telse if (repo_get_oid(the_repository, colon + 1, &entry->expect))\n \t\treturn error(_(\"cannot parse expected object name '%s'\"),\n \t\t\t     colon + 1);\n@@ -2733,7 +2733,7 @@ static void apply_cas(struct push_cas_option *cas,\n \t\telse if (remote_tracking(remote, ref->name,\n \t\t\t\t\t &ref->old_oid_expect,\n \t\t\t\t\t &ref->tracking_ref))\n-\t\t\toidclr(&ref->old_oid_expect);\n+\t\t\toidclr(&ref->old_oid_expect, the_repository->hash_algo);\n \t\telse\n \t\t\tref->check_reachable = cas->use_force_if_includes;\n \t\treturn;\n@@ -2747,7 +2747,7 @@ static void apply_cas(struct push_cas_option *cas,\n \tif (remote_tracking(remote, ref->name,\n \t\t\t    &ref->old_oid_expect,\n \t\t\t    &ref->tracking_ref))\n-\t\toidclr(&ref->old_oid_expect);\n+\t\toidclr(&ref->old_oid_expect, the_repository->hash_algo);\n \telse\n \t\tref->check_reachable = cas->use_force_if_includes;\n }\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex cd02dc9928..4e6f0e4676 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -93,7 +93,8 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)\n \t\t\t\tcontinue;\n \t\t\tif (size < rawsz)\n \t\t\t\tgoto error;\n-\t\t\toidread(&ui->oid[i], (const unsigned char *)data);\n+\t\t\toidread(&ui->oid[i], (const unsigned char *)data,\n+\t\t\t\tthe_repository->hash_algo);\n \t\t\tsize -= rawsz;\n \t\t\tdata += rawsz;\n \t\t}\ndiff --git a/sequencer.c b/sequencer.c\nindex 30513e87bf..68d62a12ff 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -3334,12 +3334,12 @@ static int rollback_is_safe(void)\n \t\tstrbuf_release(&sb);\n \t}\n \telse if (errno == ENOENT)\n-\t\toidclr(&expected_head);\n+\t\toidclr(&expected_head, the_repository->hash_algo);\n \telse\n \t\tdie_errno(_(\"could not read '%s'\"), git_path_abort_safety_file());\n \n \tif (repo_get_oid(the_repository, \"HEAD\", &actual_head))\n-\t\toidclr(&actual_head);\n+\t\toidclr(&actual_head, the_repository->hash_algo);\n \n \treturn oideq(&actual_head, &expected_head);\n }\ndiff --git a/split-index.c b/split-index.c\nindex 8c38687c04..058a8f448e 100644\n--- a/split-index.c\n+++ b/split-index.c\n@@ -29,7 +29,7 @@ int read_link_extension(struct index_state *istate,\n \tif (sz < the_hash_algo->rawsz)\n \t\treturn error(\"corrupt link extension (too short)\");\n \tsi = init_split_index(istate);\n-\toidread(&si->base_oid, data);\n+\toidread(&si->base_oid, data, the_repository->hash_algo);\n \tdata += the_hash_algo->rawsz;\n \tsz -= the_hash_algo->rawsz;\n \tif (!sz)\ndiff --git a/submodule-config.c b/submodule-config.c\nindex ec45ea67b9..ad43a282da 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -682,7 +682,7 @@ static int gitmodule_oid_from_commit(const struct object_id *treeish_name,\n \tint ret = 0;\n \n \tif (is_null_oid(treeish_name)) {\n-\t\toidclr(gitmodules_oid);\n+\t\toidclr(gitmodules_oid, the_repository->hash_algo);\n \t\treturn 1;\n \t}\n \ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex 9df2f03ac8..4b809d9dca 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -44,7 +44,7 @@ int cmd__submodule_config(int argc, const char **argv)\n \t\tpath_or_name = arg[1];\n \n \t\tif (commit[0] == '\\0')\n-\t\t\toidclr(&commit_oid);\n+\t\t\toidclr(&commit_oid, the_repository->hash_algo);\n \t\telse if (repo_get_oid(the_repository, commit, &commit_oid) < 0)\n \t\t\tdie_usage(argc, argv, \"Commit not found.\");\n \ndiff --git a/tree-walk.c b/tree-walk.c\nindex 6565d9ad99..535a3a2539 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -38,8 +38,8 @@ static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned l\n \tdesc->entry.path = path;\n \tdesc->entry.mode = (desc->flags & TREE_DESC_RAW_MODES) ? mode : canon_mode(mode);\n \tdesc->entry.pathlen = len - 1;\n-\toidread_algop(&desc->entry.oid, (const unsigned char *)path + len,\n-\t\t      desc->algo);\n+\toidread(&desc->entry.oid, (const unsigned char *)path + len,\n+\t\tdesc->algo);\n \n \treturn 0;\n }\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497135","messageId":"3947c0c04dafa470facb7c9dd03133d69d09a161.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 04/20] global: ensure that object IDs are always padded","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:49:59Z","receivedAt":"2024-06-14T06:50:03Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `oidcmp()` and `oideq()` functions only compare the prefix length as\nspecified by the given hash algorithm. This mandates that the object IDs\nhave a valid hash algorithm set, or otherwise we wouldn't be able to\nfigure out that prefix. As we do not have a hash algorithm in many\ncases, for example when handling null object IDs, this assumption cannot\nalways be fulfilled. We thus have a fallback in place that instead uses\n`the_repository` to derive the hash function. This implicit dependency\nis hidden away from callers and can be quite surprising, especially in\ncontexts where there may be no repository.\n\nIn theory, we can adapt those functions to always memcmp(3P) the whole\nlength of their hash arrays. But there exist a couple of sites where we\npopulate `struct object_id`s such that only the prefix of its hash that\nis actually used by the hash algorithm is populated. The remaining bytes\nare left uninitialized. The fact that those bytes are uninitialized also\nleads to warnings under Valgrind in some places where we copy those\nbytes.\n\nRefactor callsites where we populate object IDs to always initialize all\nbytes. This also allows us to get rid of `oidcpy_with_padding()`, for\none because the input is now fully initialized, and because `oidcpy()`\nwill now always copy the whole hash array.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h           |  2 ++\n hash.h              | 16 ----------------\n hex.c               |  6 +++++-\n http-push.c         |  1 +\n notes.c             |  2 ++\n object-file.c       |  2 ++\n oidtree.c           |  4 ++--\n parallel-checkout.c |  8 +-------\n 8 files changed, 15 insertions(+), 26 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex dbb96369fc..b72f84f4ae 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -288,6 +288,8 @@ static inline void oidread(struct object_id *oid, const unsigned char *hash,\n \t\t\t   const struct git_hash_algo *algop)\n {\n \tmemcpy(oid->hash, hash, algop->rawsz);\n+\tif (algop->rawsz < GIT_MAX_RAWSZ)\n+\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n \toid->algo = hash_algo_by_ptr(algop);\n }\n \ndiff --git a/hash.h b/hash.h\nindex 43623a0c86..e43e3d8b5a 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -31,22 +31,6 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn oideq(oid, null_oid());\n }\n \n-/* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */\n-static inline void oidcpy_with_padding(struct object_id *dst,\n-\t\t\t\t       const struct object_id *src)\n-{\n-\tsize_t hashsz;\n-\n-\tif (!src->algo)\n-\t\thashsz = the_hash_algo->rawsz;\n-\telse\n-\t\thashsz = hash_algos[src->algo].rawsz;\n-\n-\tmemcpy(dst->hash, src->hash, hashsz);\n-\tmemset(dst->hash + hashsz, 0, GIT_MAX_RAWSZ - hashsz);\n-\tdst->algo = src->algo;\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\ndiff --git a/hex.c b/hex.c\nindex d42262bdca..bc9e86a978 100644\n--- a/hex.c\n+++ b/hex.c\n@@ -25,8 +25,12 @@ int get_oid_hex_algop(const char *hex, struct object_id *oid,\n \t\t      const struct git_hash_algo *algop)\n {\n \tint ret = get_hash_hex_algop(hex, oid->hash, algop);\n-\tif (!ret)\n+\tif (!ret) {\n \t\toid_set_algo(oid, algop);\n+\t\tif (algop->rawsz != GIT_MAX_RAWSZ)\n+\t\t\tmemset(oid->hash + algop->rawsz, 0,\n+\t\t\t       GIT_MAX_RAWSZ - algop->rawsz);\n+\t}\n \treturn ret;\n }\n \ndiff --git a/http-push.c b/http-push.c\nindex 86de238b84..a97df4a1fb 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1016,6 +1016,7 @@ static void remote_ls(const char *path, int flags,\n /* extract hex from sharded \"xx/x{38}\" filename */\n static int get_oid_hex_from_objpath(const char *path, struct object_id *oid)\n {\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n \toid->algo = hash_algo_by_ptr(the_hash_algo);\n \n \tif (strlen(path) != the_hash_algo->hexsz + 1)\ndiff --git a/notes.c b/notes.c\nindex 3a8da92fb9..afe2e2882e 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -427,6 +427,8 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,\n \t\t\t\t\t hashsz - prefix_len))\n \t\t\t\tgoto handle_non_note; /* entry.path is not a SHA1 */\n \n+\t\t\tmemset(object_oid.hash + hashsz, 0, GIT_MAX_RAWSZ - hashsz);\n+\n \t\t\ttype = PTR_TYPE_NOTE;\n \t\t} else if (path_len == 2) {\n \t\t\t/* This is potentially an internal node */\ndiff --git a/object-file.c b/object-file.c\nindex c161e3e2a5..bb97f8a809 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2743,6 +2743,8 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,\n \t\t    !hex_to_bytes(oid.hash + 1, de->d_name,\n \t\t\t\t  the_hash_algo->rawsz - 1)) {\n \t\t\toid_set_algo(&oid, the_hash_algo);\n+\t\t\tmemset(oid.hash + the_hash_algo->rawsz, 0,\n+\t\t\t       GIT_MAX_RAWSZ - the_hash_algo->rawsz);\n \t\t\tif (obj_cb) {\n \t\t\t\tr = obj_cb(&oid, path->buf, data);\n \t\t\t\tif (r)\ndiff --git a/oidtree.c b/oidtree.c\nindex daef175dc7..92d03b52db 100644\n--- a/oidtree.c\n+++ b/oidtree.c\n@@ -42,7 +42,7 @@ void oidtree_insert(struct oidtree *ot, const struct object_id *oid)\n \t * Clear the padding and copy the result in separate steps to\n \t * respect the 4-byte alignment needed by struct object_id.\n \t */\n-\toidcpy_with_padding(&k, oid);\n+\toidcpy(&k, oid);\n \tmemcpy(on->k, &k, sizeof(k));\n \n \t/*\n@@ -60,7 +60,7 @@ int oidtree_contains(struct oidtree *ot, const struct object_id *oid)\n \tstruct object_id k;\n \tsize_t klen = sizeof(k);\n \n-\toidcpy_with_padding(&k, oid);\n+\toidcpy(&k, oid);\n \n \tif (oid->algo == GIT_HASH_UNKNOWN)\n \t\tklen -= sizeof(oid->algo);\ndiff --git a/parallel-checkout.c b/parallel-checkout.c\nindex b5a714c711..08b960aac8 100644\n--- a/parallel-checkout.c\n+++ b/parallel-checkout.c\n@@ -429,13 +429,7 @@ static void send_one_item(int fd, struct parallel_checkout_item *pc_item)\n \tfixed_portion->ident = pc_item->ca.ident;\n \tfixed_portion->name_len = name_len;\n \tfixed_portion->working_tree_encoding_len = working_tree_encoding_len;\n-\t/*\n-\t * We pad the unused bytes in the hash array because, otherwise,\n-\t * Valgrind would complain about passing uninitialized bytes to a\n-\t * write() syscall. The warning doesn't represent any real risk here,\n-\t * but it could hinder the detection of actual errors.\n-\t */\n-\toidcpy_with_padding(&fixed_portion->oid, &pc_item->ce->oid);\n+\toidcpy(&fixed_portion->oid, &pc_item->ce->oid);\n \n \tvariant = data + sizeof(*fixed_portion);\n \tif (working_tree_encoding_len) {\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497136","messageId":"91eb94bc0b91c8d1bda7f8fd776d94113acf8cd3.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 05/20] hash: convert `oidcmp()` and `oideq()` to compare whole hash","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:03Z","receivedAt":"2024-06-14T06:50:08Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"With the preceding commit, the hash array of object IDs is now fully\nzero-padded even when the hash algorithm's output is smaller than the\narray length. With that, we can now adapt both `oidcmp()` and `oideq()`\nto unconditionally memcmp(3P) the whole array instead of depending on\nthe hash size.\n\nWhile it may feel inefficient to compare unused bytes for e.g. SHA-1, in\npractice the compiler should now be able to produce code that is better\noptimized both because we have no branch anymore, but also because the\nsize to compare is now known at compile time. Goldbolt spits out the\nfollowing assembly on an x86_64 platform with GCC 14.1 for the old and\nnew implementations of `oidcmp()`:\n\n    oidcmp_old:\n            movsx   rax, DWORD PTR [rdi+32]\n            test    eax, eax\n            jne     .L2\n            mov     rax, QWORD PTR the_repository[rip]\n            cmp     QWORD PTR [rax+16], 32\n            je      .L6\n    .L4:\n            mov     edx, 20\n            jmp     memcmp\n    .L2:\n            lea     rdx, [rax+rax*2]\n            lea     rax, [rax+rdx*4]\n            lea     rax, hash_algos[0+rax*8]\n            cmp     QWORD PTR [rax+16], 32\n            jne     .L4\n    .L6:\n            mov     edx, 32\n            jmp     memcmp\n\n    oidcmp_new:\n            mov     edx, 32\n            jmp     memcmp\n\nThe new implementation gets ridi of all the branches and effectively\nonly ends setting up `edx` for `memcmp()` and then calling it.\n\nAnd for `oideq()`:\n\n    oideq_old:\n            movsx   rcx, DWORD PTR [rdi+32]\n            mov     rax, rdi\n            mov     rdx, rsi\n            test    ecx, ecx\n            jne     .L2\n            mov     rcx, QWORD PTR the_repository[rip]\n            cmp     QWORD PTR [rcx+16], 32\n            mov     rcx, QWORD PTR [rax]\n            je      .L12\n    .L4:\n            mov     rsi, QWORD PTR [rax+8]\n            xor     rcx, QWORD PTR [rdx]\n            xor     rsi, QWORD PTR [rdx+8]\n            or      rcx, rsi\n            je      .L13\n    .L8:\n            mov     eax, 1\n            test    eax, eax\n            sete    al\n            movzx   eax, al\n            ret\n    .L2:\n            lea     rsi, [rcx+rcx*2]\n            lea     rcx, [rcx+rsi*4]\n            lea     rcx, hash_algos[0+rcx*8]\n            cmp     QWORD PTR [rcx+16], 32\n            mov     rcx, QWORD PTR [rax]\n            jne     .L4\n    .L12:\n            mov     rsi, QWORD PTR [rax+8]\n            xor     rcx, QWORD PTR [rdx]\n            xor     rsi, QWORD PTR [rdx+8]\n            or      rcx, rsi\n            jne     .L8\n            mov     rcx, QWORD PTR [rax+16]\n            mov     rax, QWORD PTR [rax+24]\n            xor     rcx, QWORD PTR [rdx+16]\n            xor     rax, QWORD PTR [rdx+24]\n            or      rcx, rax\n            jne     .L8\n            xor     eax, eax\n    .L14:\n            test    eax, eax\n            sete    al\n            movzx   eax, al\n            ret\n    .L13:\n            mov     edi, DWORD PTR [rdx+16]\n            cmp     DWORD PTR [rax+16], edi\n            jne     .L8\n            xor     eax, eax\n            jmp     .L14\n\n    oideq_new:\n            mov     rax, QWORD PTR [rdi]\n            mov     rdx, QWORD PTR [rdi+8]\n            xor     rax, QWORD PTR [rsi]\n            xor     rdx, QWORD PTR [rsi+8]\n            or      rax, rdx\n            je      .L5\n    .L2:\n            mov     eax, 1\n            xor     eax, 1\n            ret\n    .L5:\n            mov     rax, QWORD PTR [rdi+16]\n            mov     rdx, QWORD PTR [rdi+24]\n            xor     rax, QWORD PTR [rsi+16]\n            xor     rdx, QWORD PTR [rsi+24]\n            or      rax, rdx\n            jne     .L2\n            xor     eax, eax\n            xor     eax, 1\n            ret\n\nInterestingly, the compiler decides to split the comparisons into two so\nthat it first compares the lower half of the object ID for equality and\nthen the upper half. If the first check shows a difference, then we\nwouldn't even end up comparing the second half.\n\nIn both cases, the new generated code is significantly shorter and has\nway less branches. While I didn't benchmark the change, I'd be surprised\nif the new code was slower.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h | 10 ++++++++++\n hash.h    | 20 --------------------\n 2 files changed, 10 insertions(+), 20 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex b72f84f4ae..b04fe12aef 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -278,6 +278,16 @@ static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algo\n \tmemset(hash, 0, algop->rawsz);\n }\n \n+static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n {\n \tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\ndiff --git a/hash.h b/hash.h\nindex e43e3d8b5a..ddc2e5ca47 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,26 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\tconst struct git_hash_algo *algop;\n-\tif (!oid1->algo)\n-\t\talgop = the_hash_algo;\n-\telse\n-\t\talgop = &hash_algos[oid1->algo];\n-\treturn hashcmp(oid1->hash, oid2->hash, algop);\n-}\n-\n-static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\tconst struct git_hash_algo *algop;\n-\tif (!oid1->algo)\n-\t\talgop = the_hash_algo;\n-\telse\n-\t\talgop = &hash_algos[oid1->algo];\n-\treturn hasheq(oid1->hash, oid2->hash, algop);\n-}\n-\n static inline int is_null_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, null_oid());\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497137","messageId":"9ae29e1912a661fa0539b0e03421a24566ed611a.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 06/20] hash: make `is_null_oid()` independent of `the_repository`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:08Z","receivedAt":"2024-06-14T06:50:13Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The function `is_null_oid()` uses `oideq(oid, null_oid())` to check\nwhether a given object ID is the all-zero object ID. `null_oid()`\nimplicitly relies on `the_repository` though to return the correct null\nobject ID.\n\nGet rid of this dependency by always comparing the complete hash array\nfor being all-zeroes. This is possible due to the refactoring of object\nIDs so that their hash arrays are always fully initialized.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hash-ll.h | 6 ++++++\n hash.h    | 5 -----\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/hash-ll.h b/hash-ll.h\nindex b04fe12aef..faf6c292d2 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -341,6 +341,12 @@ static inline unsigned int oidhash(const struct object_id *oid)\n \treturn hash;\n }\n \n+static inline int is_null_oid(const struct object_id *oid)\n+{\n+\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n+\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n+}\n+\n const char *empty_tree_oid_hex(void);\n const char *empty_blob_oid_hex(void);\n \ndiff --git a/hash.h b/hash.h\nindex ddc2e5ca47..84f2296cfb 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,11 +6,6 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int is_null_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, null_oid());\n-}\n-\n static inline int is_empty_blob_oid(const struct object_id *oid)\n {\n \treturn oideq(oid, the_hash_algo->empty_blob);\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497138","messageId":"da48d5fdeaff49c702d016e3e1123eebf32c229e.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 07/20] hash: require hash algorithm in `is_empty_{blob,tree}_oid()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:13Z","receivedAt":"2024-06-14T06:50:17Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both functions `is_empty_{blob,tree}_oid()` use `the_repository` to\nderive the hash function that shall be used. Require callers to pass in\nthe hash algorithm to get rid of this implicit dependency.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/fast-import.c |  4 +++-\n cache-tree.c          |  2 +-\n diffcore-rename.c     |  4 ++--\n hash-ll.h             | 12 ++++++++++++\n hash.h                | 10 ----------\n read-cache.c          |  2 +-\n 6 files changed, 19 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/fast-import.c b/builtin/fast-import.c\nindex 12543488f3..d21c4053a7 100644\n--- a/builtin/fast-import.c\n+++ b/builtin/fast-import.c\n@@ -2361,7 +2361,9 @@ static void file_change_m(const char *p, struct branch *b)\n \tparse_path_eol(&path, p, \"path\");\n \n \t/* Git does not track empty, non-toplevel directories. */\n-\tif (S_ISDIR(mode) && is_empty_tree_oid(&oid) && *path.buf) {\n+\tif (S_ISDIR(mode) &&\n+\t    is_empty_tree_oid(&oid, the_repository->hash_algo) &&\n+\t    *path.buf) {\n \t\ttree_content_remove(&b->branch_tree, path.buf, NULL, 0);\n \t\treturn;\n \t}\ndiff --git a/cache-tree.c b/cache-tree.c\nindex e4255c4d02..3290a1b8dd 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -422,7 +422,7 @@ static int update_one(struct cache_tree *it,\n \t\t/*\n \t\t * \"sub\" can be an empty tree if all subentries are i-t-a.\n \t\t */\n-\t\tif (contains_ita && is_empty_tree_oid(oid))\n+\t\tif (contains_ita && is_empty_tree_oid(oid, the_repository->hash_algo))\n \t\t\tcontinue;\n \n \t\tstrbuf_grow(&buffer, entlen + 100);\ndiff --git a/diffcore-rename.c b/diffcore-rename.c\nindex 5a6e2bcac7..5abb958651 100644\n--- a/diffcore-rename.c\n+++ b/diffcore-rename.c\n@@ -1422,7 +1422,7 @@ void diffcore_rename_extended(struct diff_options *options,\n \t\t\t\t strcmp(options->single_follow, p->two->path))\n \t\t\t\tcontinue; /* not interested */\n \t\t\telse if (!options->flags.rename_empty &&\n-\t\t\t\t is_empty_blob_oid(&p->two->oid))\n+\t\t\t\t is_empty_blob_oid(&p->two->oid, the_repository->hash_algo))\n \t\t\t\tcontinue;\n \t\t\telse if (add_rename_dst(p) < 0) {\n \t\t\t\twarning(\"skipping rename detection, detected\"\n@@ -1432,7 +1432,7 @@ void diffcore_rename_extended(struct diff_options *options,\n \t\t\t}\n \t\t}\n \t\telse if (!options->flags.rename_empty &&\n-\t\t\t is_empty_blob_oid(&p->one->oid))\n+\t\t\t is_empty_blob_oid(&p->one->oid, the_repository->hash_algo))\n \t\t\tcontinue;\n \t\telse if (!DIFF_PAIR_UNMERGED(p) && !DIFF_FILE_VALID(p->two)) {\n \t\t\t/*\ndiff --git a/hash-ll.h b/hash-ll.h\nindex faf6c292d2..1000a9af22 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -350,4 +350,16 @@ static inline int is_null_oid(const struct object_id *oid)\n const char *empty_tree_oid_hex(void);\n const char *empty_blob_oid_hex(void);\n \n+static inline int is_empty_blob_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_blob);\n+}\n+\n+static inline int is_empty_tree_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_tree);\n+}\n+\n #endif\ndiff --git a/hash.h b/hash.h\nindex 84f2296cfb..39a0164be3 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -6,14 +6,4 @@\n \n #define the_hash_algo the_repository->hash_algo\n \n-static inline int is_empty_blob_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, the_hash_algo->empty_blob);\n-}\n-\n-static inline int is_empty_tree_oid(const struct object_id *oid)\n-{\n-\treturn oideq(oid, the_hash_algo->empty_tree);\n-}\n-\n #endif\ndiff --git a/read-cache.c b/read-cache.c\nindex 836f1db721..085b22faf3 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -337,7 +337,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)\n \n \t/* Racily smudged entry? */\n \tif (!ce->ce_stat_data.sd_size) {\n-\t\tif (!is_empty_blob_oid(&ce->oid))\n+\t\tif (!is_empty_blob_oid(&ce->oid, the_repository->hash_algo))\n \t\t\tchanged |= DATA_CHANGED;\n \t}\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497139","messageId":"1cf25bec3eef9f590abc7ae2a84845a8312e9a4b.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 08/20] hash: require hash algorithm in `empty_tree_oid_hex()`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:18Z","receivedAt":"2024-06-14T06:50:22Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `empty_tree_oid_hex()` function use `the_repository` to derive the\nhash function that shall be used. Require callers to pass in the hash\nalgorithm to get rid of this implicit dependency.\n\nWhile at it, remove the unused `empty_blob_oid_hex()` function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n add-interactive.c      |  2 +-\n add-patch.c            |  2 +-\n builtin/merge.c        |  3 ++-\n builtin/receive-pack.c |  2 +-\n hash-ll.h              |  3 +--\n object-file.c          | 10 ++--------\n sequencer.c            |  2 +-\n submodule.c            |  6 +++---\n wt-status.c            |  4 ++--\n 9 files changed, 14 insertions(+), 20 deletions(-)\n\ndiff --git a/add-interactive.c b/add-interactive.c\nindex b5d6cd689a..a0961096cd 100644\n--- a/add-interactive.c\n+++ b/add-interactive.c\n@@ -557,7 +557,7 @@ static int get_modified_files(struct repository *r,\n \t\ts.skip_unseen = filter && i;\n \n \t\topt.def = is_initial ?\n-\t\t\tempty_tree_oid_hex() : oid_to_hex(&head_oid);\n+\t\t\tempty_tree_oid_hex(the_repository->hash_algo) : oid_to_hex(&head_oid);\n \n \t\trepo_init_revisions(r, &rev, NULL);\n \t\tsetup_revisions(0, NULL, &rev, &opt);\ndiff --git a/add-patch.c b/add-patch.c\nindex 814de57c4a..86181770f2 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -420,7 +420,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)\n \t\t\t    /* could be on an unborn branch */\n \t\t\t    !strcmp(\"HEAD\", s->revision) &&\n \t\t\t    repo_get_oid(the_repository, \"HEAD\", &oid) ?\n-\t\t\t    empty_tree_oid_hex() : s->revision);\n+\t\t\t    empty_tree_oid_hex(the_repository->hash_algo) : s->revision);\n \t}\n \tcolor_arg_index = args.nr;\n \t/* Use `--no-color` explicitly, just in case `diff.color = always`. */\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex abe66311c7..bb94b7df21 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -330,7 +330,8 @@ static void read_empty(const struct object_id *oid)\n {\n \tstruct child_process cmd = CHILD_PROCESS_INIT;\n \n-\tstrvec_pushl(&cmd.args, \"read-tree\", \"-m\", \"-u\", empty_tree_oid_hex(),\n+\tstrvec_pushl(&cmd.args, \"read-tree\", \"-m\", \"-u\",\n+\t\t     empty_tree_oid_hex(the_repository->hash_algo),\n \t\t     oid_to_hex(oid), NULL);\n \tcmd.git_cmd = 1;\n \ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex aa5ba27d17..41d5fb8e60 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -1371,7 +1371,7 @@ static const char *push_to_deploy(unsigned char *sha1,\n \tstrvec_pushl(&child.args, \"diff-index\", \"--quiet\", \"--cached\",\n \t\t     \"--ignore-submodules\",\n \t\t     /* diff-index with either HEAD or an empty tree */\n-\t\t     head_has_history() ? \"HEAD\" : empty_tree_oid_hex(),\n+\t\t     head_has_history() ? \"HEAD\" : empty_tree_oid_hex(the_repository->hash_algo),\n \t\t     \"--\", NULL);\n \tstrvec_pushv(&child.env, env->v);\n \tchild.no_stdin = 1;\ndiff --git a/hash-ll.h b/hash-ll.h\nindex 1000a9af22..3161c778b9 100644\n--- a/hash-ll.h\n+++ b/hash-ll.h\n@@ -347,8 +347,7 @@ static inline int is_null_oid(const struct object_id *oid)\n \treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n }\n \n-const char *empty_tree_oid_hex(void);\n-const char *empty_blob_oid_hex(void);\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n \n static inline int is_empty_blob_oid(const struct object_id *oid,\n \t\t\t\t    const struct git_hash_algo *algop)\ndiff --git a/object-file.c b/object-file.c\nindex bb97f8a809..72318c8dd4 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -227,16 +227,10 @@ const struct object_id *null_oid(void)\n \treturn the_hash_algo->null_oid;\n }\n \n-const char *empty_tree_oid_hex(void)\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop)\n {\n \tstatic char buf[GIT_MAX_HEXSZ + 1];\n-\treturn oid_to_hex_r(buf, the_hash_algo->empty_tree);\n-}\n-\n-const char *empty_blob_oid_hex(void)\n-{\n-\tstatic char buf[GIT_MAX_HEXSZ + 1];\n-\treturn oid_to_hex_r(buf, the_hash_algo->empty_blob);\n+\treturn oid_to_hex_r(buf, algop->empty_tree);\n }\n \n int hash_algo_by_name(const char *name)\ndiff --git a/sequencer.c b/sequencer.c\nindex 68d62a12ff..823691e379 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -2263,7 +2263,7 @@ static int do_pick_commit(struct repository *r,\n \t\t\tunborn = 1;\n \t\t} else if (unborn)\n \t\t\toidcpy(&head, the_hash_algo->empty_tree);\n-\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex() : \"HEAD\",\n+\t\tif (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : \"HEAD\",\n \t\t\t\t       NULL, 0))\n \t\t\treturn error_dirty_index(r, opts);\n \t}\ndiff --git a/submodule.c b/submodule.c\nindex 759cf1e1cd..caf3aa5600 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -2119,7 +2119,7 @@ static void submodule_reset_index(const char *path, const char *super_prefix)\n \tstrvec_pushf(&cp.args, \"--super-prefix=%s%s/\",\n \t\t     (super_prefix ? super_prefix : \"\"), path);\n \n-\tstrvec_push(&cp.args, empty_tree_oid_hex());\n+\tstrvec_push(&cp.args, empty_tree_oid_hex(the_repository->hash_algo));\n \n \tif (run_command(&cp))\n \t\tdie(_(\"could not reset submodule index\"));\n@@ -2229,9 +2229,9 @@ int submodule_move_head(const char *path, const char *super_prefix,\n \t\tstrvec_push(&cp.args, \"-m\");\n \n \tif (!(flags & SUBMODULE_MOVE_HEAD_FORCE))\n-\t\tstrvec_push(&cp.args, old_head ? old_head : empty_tree_oid_hex());\n+\t\tstrvec_push(&cp.args, old_head ? old_head : empty_tree_oid_hex(the_repository->hash_algo));\n \n-\tstrvec_push(&cp.args, new_head ? new_head : empty_tree_oid_hex());\n+\tstrvec_push(&cp.args, new_head ? new_head : empty_tree_oid_hex(the_repository->hash_algo));\n \n \tif (run_command(&cp)) {\n \t\tret = error(_(\"Submodule '%s' could not be updated.\"), path);\ndiff --git a/wt-status.c b/wt-status.c\nindex ff4be071ca..5051f5e599 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -641,7 +641,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n \n \trepo_init_revisions(s->repo, &rev, NULL);\n \tmemset(&opt, 0, sizeof(opt));\n-\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n+\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n \trev.diffopt.flags.override_submodule_config = 1;\n@@ -1136,7 +1136,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)\n \trev.diffopt.ita_invisible_in_index = 1;\n \n \tmemset(&opt, 0, sizeof(opt));\n-\topt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;\n+\topt.def = s->is_initial ? empty_tree_oid_hex(the_repository->hash_algo) : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n \trev.diffopt.output_format |= DIFF_FORMAT_PATCH;\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497140","messageId":"7e023a335f500658b09a0037aee48eff06c668f8.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:23Z","receivedAt":"2024-06-14T06:50:27Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Use of the `the_repository` variable is deprecated nowadays, and we\nslowly but steadily convert the codebase to not use it anymore. Instead,\ncallers should be passing down the repository to work on via parameters.\n\nIt is hard though to prove that a given code unit does not use this\nvariable anymore. The most trivial case, merely demonstrating that there\nis no direct use of `the_repository`, is already a bit of a pain during\ncode reviews as the reviewer needs to manually verify claims made by the\npatch author. The bigger problem though is that we have many interfaces\nthat implicitly rely on `the_repository`.\n\nIntroduce a new `USE_THE_REPOSITORY_VARIABLE` macro that allows code\nunits to opt into usage of `the_repository`. The intent of this macro is\nto demonstrate that a certain code unit does not use this variable\nanymore, and to keep it from new dependencies on it in future changes,\nbe it explicit or implicit\n\nFor now, the macro only guards `the_repository` itself as well as\n`the_hash_algo`. There are many more known interfaces where we have an\nimplicit dependency on `the_repository`, but those are not guarded at\nthe current point in time. Over time though, we should start to add\nguards as required (or even better, just remove them).\n\nDefine the macro as required in our code units. As expected, most of our\ncode still relies on the global variable. Nearly all of our builtins\nrely on the variable as there is no way yet to pass `the_repository` to\ntheir entry point. For now, declare the macro in \"biultin.h\" to keep the\nrequired changes at least a little bit more contained.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n add-interactive.c                            | 2 ++\n add-patch.c                                  | 2 ++\n apply.c                                      | 2 ++\n archive-tar.c                                | 3 +++\n archive-zip.c                                | 3 +++\n archive.c                                    | 2 ++\n attr.c                                       | 2 ++\n bisect.c                                     | 2 ++\n blame.c                                      | 2 ++\n branch.c                                     | 2 ++\n builtin.h                                    | 8 ++++++++\n builtin/blame.c                              | 2 +-\n builtin/log.c                                | 2 +-\n bulk-checkin.c                               | 3 +++\n bundle-uri.c                                 | 2 ++\n bundle.c                                     | 2 ++\n cache-tree.c                                 | 2 ++\n checkout.c                                   | 2 ++\n chunk-format.c                               | 2 ++\n combine-diff.c                               | 2 ++\n commit-graph.c                               | 2 ++\n commit-reach.c                               | 2 ++\n commit.c                                     | 2 ++\n common-main.c                                | 2 ++\n compat/win32/trace2_win32_process_info.c     | 2 ++\n config.c                                     | 3 +++\n connected.c                                  | 2 ++\n convert.c                                    | 2 ++\n csum-file.c                                  | 3 +++\n delta-islands.c                              | 2 ++\n diagnose.c                                   | 2 ++\n diff-lib.c                                   | 3 +++\n diff.c                                       | 3 +++\n diffcore-break.c                             | 3 +++\n diffcore-rename.c                            | 3 +++\n dir.c                                        | 3 +++\n entry.c                                      | 2 ++\n environment.c                                | 3 +++\n fetch-pack.c                                 | 2 ++\n fmt-merge-msg.c                              | 2 ++\n fsck.c                                       | 2 ++\n fsmonitor-ipc.c                              | 2 ++\n git.c                                        | 2 ++\n hash-lookup.c                                | 2 ++\n hash.h                                       | 4 +++-\n help.c                                       | 2 ++\n hex.c                                        | 2 ++\n http-backend.c                               | 2 ++\n http-push.c                                  | 2 ++\n http-walker.c                                | 2 ++\n http.c                                       | 2 ++\n list-objects-filter-options.c                | 2 ++\n list-objects-filter.c                        | 2 ++\n list-objects.c                               | 2 ++\n log-tree.c                                   | 2 ++\n loose.c                                      | 2 ++\n ls-refs.c                                    | 2 ++\n mailmap.c                                    | 2 ++\n match-trees.c                                | 2 ++\n merge-blobs.c                                | 2 ++\n merge-ort.c                                  | 2 ++\n merge-recursive.c                            | 3 +++\n merge.c                                      | 2 ++\n midx-write.c                                 | 2 ++\n midx.c                                       | 2 ++\n negotiator/default.c                         | 2 ++\n negotiator/skipping.c                        | 2 ++\n notes-cache.c                                | 2 ++\n notes-merge.c                                | 2 ++\n notes-utils.c                                | 2 ++\n notes.c                                      | 2 ++\n object-file-convert.c                        | 2 ++\n object-file.c                                | 3 +++\n object-name.c                                | 2 ++\n object.c                                     | 2 ++\n oid-array.c                                  | 2 ++\n oss-fuzz/fuzz-commit-graph.c                 | 2 ++\n pack-bitmap-write.c                          | 2 ++\n pack-bitmap.c                                | 2 ++\n pack-check.c                                 | 2 ++\n pack-revindex.c                              | 2 ++\n pack-write.c                                 | 2 ++\n packfile.c                                   | 2 ++\n parse-options-cb.c                           | 2 ++\n path.c                                       | 3 +++\n pathspec.c                                   | 2 ++\n pretty.c                                     | 2 ++\n progress.c                                   | 2 ++\n promisor-remote.c                            | 2 ++\n range-diff.c                                 | 2 ++\n reachable.c                                  | 2 ++\n read-cache.c                                 | 3 +++\n rebase-interactive.c                         | 2 ++\n ref-filter.c                                 | 2 ++\n reflog-walk.c                                | 2 ++\n reflog.c                                     | 2 ++\n refs.c                                       | 2 ++\n refs/files-backend.c                         | 2 ++\n refs/packed-backend.c                        | 2 ++\n refs/reftable-backend.c                      | 2 ++\n refspec.c                                    | 2 ++\n remote-curl.c                                | 2 ++\n remote.c                                     | 2 ++\n repository.c                                 | 8 ++++++++\n repository.h                                 | 2 ++\n rerere.c                                     | 2 ++\n reset.c                                      | 2 ++\n resolve-undo.c                               | 2 ++\n revision.c                                   | 2 ++\n run-command.c                                | 2 ++\n scalar.c                                     | 2 ++\n send-pack.c                                  | 2 ++\n sequencer.c                                  | 2 ++\n serve.c                                      | 2 ++\n server-info.c                                | 2 ++\n setup.c                                      | 2 ++\n shallow.c                                    | 2 ++\n split-index.c                                | 2 ++\n streaming.c                                  | 3 +++\n submodule-config.c                           | 2 ++\n submodule.c                                  | 2 ++\n t/helper/test-bitmap.c                       | 2 ++\n t/helper/test-bloom.c                        | 2 ++\n t/helper/test-cache-tree.c                   | 2 ++\n t/helper/test-dump-cache-tree.c              | 2 ++\n t/helper/test-dump-fsmonitor.c               | 2 ++\n t/helper/test-dump-split-index.c             | 2 ++\n t/helper/test-dump-untracked-cache.c         | 2 ++\n t/helper/test-find-pack.c                    | 2 ++\n t/helper/test-fsmonitor-client.c             | 2 ++\n t/helper/test-lazy-init-name-hash.c          | 2 ++\n t/helper/test-match-trees.c                  | 2 ++\n t/helper/test-oidmap.c                       | 2 ++\n t/helper/test-pack-mtimes.c                  | 2 ++\n t/helper/test-reach.c                        | 2 ++\n t/helper/test-read-cache.c                   | 2 ++\n t/helper/test-read-graph.c                   | 2 ++\n t/helper/test-read-midx.c                    | 2 ++\n t/helper/test-ref-store.c                    | 2 ++\n t/helper/test-repository.c                   | 2 ++\n t/helper/test-revision-walking.c             | 2 ++\n t/helper/test-scrap-cache-tree.c             | 2 ++\n t/helper/test-submodule-config.c             | 2 ++\n t/helper/test-submodule-nested-repo-config.c | 2 ++\n t/helper/test-submodule.c                    | 2 ++\n t/helper/test-trace2.c                       | 2 ++\n t/helper/test-write-cache.c                  | 2 ++\n t/unit-tests/t-example-decorate.c            | 2 ++\n tag.c                                        | 2 ++\n tmp-objdir.c                                 | 2 ++\n transport-helper.c                           | 2 ++\n transport.c                                  | 2 ++\n tree-walk.c                                  | 2 ++\n tree.c                                       | 2 ++\n unpack-trees.c                               | 2 ++\n upload-pack.c                                | 2 ++\n walker.c                                     | 2 ++\n worktree.c                                   | 2 ++\n wt-status.c                                  | 2 ++\n xdiff-interface.c                            | 2 ++\n 160 files changed, 347 insertions(+), 3 deletions(-)\n\ndiff --git a/add-interactive.c b/add-interactive.c\nindex a0961096cd..49042b3026 100644\n--- a/add-interactive.c\n+++ b/add-interactive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"add-interactive.h\"\n #include \"color.h\"\ndiff --git a/add-patch.c b/add-patch.c\nindex 86181770f2..99e037c1e2 100644\n--- a/add-patch.c\n+++ b/add-patch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"add-interactive.h\"\n #include \"advice.h\"\ndiff --git a/apply.c b/apply.c\nindex 528939abb6..ff939f908a 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -7,6 +7,8 @@\n  *\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"base85.h\"\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 8ae30125f8..e7b3489e1e 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2005, 2006 Rene Scharfe\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\ndiff --git a/archive-zip.c b/archive-zip.c\nindex fd1d3f816d..9f32730181 100644\n--- a/archive-zip.c\n+++ b/archive-zip.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2006 Rene Scharfe\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"archive.h\"\ndiff --git a/archive.c b/archive.c\nindex 5287fcdd8e..7bd60d0632 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/attr.c b/attr.c\nindex 300f994ba6..b5ed83c90e 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -6,6 +6,8 @@\n  * an insanely large number of attributes.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/bisect.c b/bisect.c\nindex 4ea703bec1..135f94ba09 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/blame.c b/blame.c\nindex a80f5e2e61..d403c46a35 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"refs.h\"\n #include \"object-store-ll.h\"\ndiff --git a/branch.c b/branch.c\nindex df5d24fec6..c887ea2151 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/builtin.h b/builtin.h\nindex 7eda9b2486..14fa017160 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -1,6 +1,14 @@\n #ifndef BUILTIN_H\n #define BUILTIN_H\n \n+/*\n+ * TODO: Almost all of our builtins access `the_repository` by necessity\n+ * because they do not get passed a pointer to it. We should adapt the function\n+ * signature of those main functions to accept a `struct repository *` and then\n+ * remove the macro here.\n+ */\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n \n /*\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex e09ff0155a..de89fff3f8 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -5,7 +5,7 @@\n  * See COPYING for licensing conditions\n  */\n \n-#include \"git-compat-util.h\"\n+#include \"builtin.h\"\n #include \"config.h\"\n #include \"color.h\"\n #include \"builtin.h\"\ndiff --git a/builtin/log.c b/builtin/log.c\nindex ccbda8a005..00305bea51 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -4,7 +4,7 @@\n  * (C) Copyright 2006 Linus Torvalds\n  *\t\t 2006 Junio Hamano\n  */\n-#include \"git-compat-util.h\"\n+#include \"builtin.h\"\n #include \"abspath.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/bulk-checkin.c b/bulk-checkin.c\nindex eb46b88637..da8673199b 100644\n--- a/bulk-checkin.c\n+++ b/bulk-checkin.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2011, Google Inc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bulk-checkin.h\"\n #include \"environment.h\"\ndiff --git a/bundle-uri.c b/bundle-uri.c\nindex 91b3319a5c..804fbcfbfa 100644\n--- a/bundle-uri.c\n+++ b/bundle-uri.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bundle-uri.h\"\n #include \"bundle.h\"\ndiff --git a/bundle.c b/bundle.c\nindex 95367c2d0a..82c285b905 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"lockfile.h\"\n #include \"bundle.h\"\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 3290a1b8dd..50610c3f3c 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/checkout.c b/checkout.c\nindex cfaea4bd10..0b1cf8b40b 100644\n--- a/checkout.c\n+++ b/checkout.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-name.h\"\n #include \"remote.h\"\ndiff --git a/chunk-format.c b/chunk-format.c\nindex cdc7f39b70..2dde24e6a3 100644\n--- a/chunk-format.c\n+++ b/chunk-format.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"chunk-format.h\"\n #include \"csum-file.h\"\ndiff --git a/combine-diff.c b/combine-diff.c\nindex 4960d904ac..829a44e416 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-store-ll.h\"\n #include \"commit.h\"\ndiff --git a/commit-graph.c b/commit-graph.c\nindex 98cbd53eea..e1070ee6e7 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"csum-file.h\"\ndiff --git a/commit-reach.c b/commit-reach.c\nindex 384aee1ab3..dabc2972e4 100644\n--- a/commit-reach.c\n+++ b/commit-reach.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"commit-graph.h\"\ndiff --git a/commit.c b/commit.c\nindex 1d08951007..4956803e11 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tag.h\"\n #include \"commit.h\"\ndiff --git a/common-main.c b/common-main.c\nindex b86f40600f..8e68ac9e42 100644\n--- a/common-main.c\n+++ b/common-main.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"exec-cmd.h\"\n #include \"gettext.h\"\ndiff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c\nindex 3ef0936f6f..f147da706a 100644\n--- a/compat/win32/trace2_win32_process_info.c\n+++ b/compat/win32/trace2_win32_process_info.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../../git-compat-util.h\"\n #include \"../../json-writer.h\"\n #include \"../../repository.h\"\ndiff --git a/config.c b/config.c\nindex abce05b774..7951029644 100644\n--- a/config.c\n+++ b/config.c\n@@ -5,6 +5,9 @@\n  * Copyright (C) Johannes Schindelin, 2005\n  *\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"advice.h\"\ndiff --git a/connected.c b/connected.c\nindex 8f89376dbc..87cc4b57a1 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/convert.c b/convert.c\nindex f2b9f01354..d8737fe0f2 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/csum-file.c b/csum-file.c\nindex f4be0804b7..8abbf01325 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -7,6 +7,9 @@\n  * files. Useful when you write a file that you want to be\n  * able to verify hasn't been messed with afterwards.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"progress.h\"\n #include \"csum-file.h\"\ndiff --git a/delta-islands.c b/delta-islands.c\nindex 89d51b72e3..ffe1ca2814 100644\n--- a/delta-islands.c\n+++ b/delta-islands.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object.h\"\n #include \"commit.h\"\ndiff --git a/diagnose.c b/diagnose.c\nindex 4d096c857f..cc2d535b60 100644\n--- a/diagnose.c\n+++ b/diagnose.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diagnose.h\"\n #include \"compat/disk.h\"\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 3fb8d79fef..b0d0f711e8 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"diff.h\"\ndiff --git a/diff.c b/diff.c\nindex 60d1f7be81..d4579d5f76 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"base85.h\"\ndiff --git a/diffcore-break.c b/diffcore-break.c\nindex 49ba38aa7c..831b66b5c3 100644\n--- a/diffcore-break.c\n+++ b/diffcore-break.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diffcore.h\"\n #include \"hash.h\"\ndiff --git a/diffcore-rename.c b/diffcore-rename.c\nindex 5abb958651..ae504007cf 100644\n--- a/diffcore-rename.c\n+++ b/diffcore-rename.c\n@@ -2,6 +2,9 @@\n  *\n  * Copyright (C) 2005 Junio C Hamano\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"diff.h\"\n #include \"diffcore.h\"\ndiff --git a/dir.c b/dir.c\nindex 5de421c29c..b7a6625ebd 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -5,6 +5,9 @@\n  * Copyright (C) Linus Torvalds, 2005-2006\n  *\t\t Junio Hamano, 2005-2006\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/entry.c b/entry.c\nindex b8c257f6f9..fe1f74d140 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-store-ll.h\"\n #include \"dir.h\"\ndiff --git a/environment.c b/environment.c\nindex 701d515135..5cea2c9f54 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -7,6 +7,9 @@\n  * even if you might want to know where the git directory etc\n  * are.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"branch.h\"\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex eba9e420ea..e6e14b3874 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\ndiff --git a/fmt-merge-msg.c b/fmt-merge-msg.c\nindex 7d144b803a..b8bca89c0c 100644\n--- a/fmt-merge-msg.c\n+++ b/fmt-merge-msg.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/fsck.c b/fsck.c\nindex dd0a33028e..432996cbb6 100644\n--- a/fsck.c\n+++ b/fsck.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"date.h\"\n #include \"dir.h\"\ndiff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c\nindex 45471b5b74..f1b1631111 100644\n--- a/fsmonitor-ipc.c\n+++ b/fsmonitor-ipc.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"simple-ipc.h\"\ndiff --git a/git.c b/git.c\nindex 683bb69194..e35af9b0e5 100644\n--- a/git.c\n+++ b/git.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/hash-lookup.c b/hash-lookup.c\nindex 9aa6b82eb7..5f808caa51 100644\n--- a/hash-lookup.c\n+++ b/hash-lookup.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"hash-lookup.h\"\ndiff --git a/hash.h b/hash.h\nindex 39a0164be3..cb85d26a2f 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -4,6 +4,8 @@\n #include \"hash-ll.h\"\n #include \"repository.h\"\n \n-#define the_hash_algo the_repository->hash_algo\n+#ifdef USE_THE_REPOSITORY_VARIABLE\n+# define the_hash_algo the_repository->hash_algo\n+#endif\n \n #endif\ndiff --git a/help.c b/help.c\nindex 1d057aa607..10fdb1a03d 100644\n--- a/help.c\n+++ b/help.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"builtin.h\"\ndiff --git a/hex.c b/hex.c\nindex bc9e86a978..5ca78a7744 100644\n--- a/hex.c\n+++ b/hex.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"hex.h\"\ndiff --git a/http-backend.c b/http-backend.c\nindex 5b65287ac9..7c0b3be968 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/http-push.c b/http-push.c\nindex a97df4a1fb..7315a694aa 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/http-walker.c b/http-walker.c\nindex b7110b6f82..e417a7f51c 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"hex.h\"\ndiff --git a/http.c b/http.c\nindex 67cc47d28f..6536816e81 100644\n--- a/http.c\n+++ b/http.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"git-curl-compat.h\"\n #include \"hex.h\"\ndiff --git a/list-objects-filter-options.c b/list-objects-filter-options.c\nindex c5f363ca6f..00611107d2 100644\n--- a/list-objects-filter-options.c\n+++ b/list-objects-filter-options.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\ndiff --git a/list-objects-filter.c b/list-objects-filter.c\nindex 4346f8da45..49e2fa6f97 100644\n--- a/list-objects-filter.c\n+++ b/list-objects-filter.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"gettext.h\"\ndiff --git a/list-objects.c b/list-objects.c\nindex 11ad8be411..985d008799 100644\n--- a/list-objects.c\n+++ b/list-objects.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tag.h\"\n #include \"commit.h\"\ndiff --git a/log-tree.c b/log-tree.c\nindex 41416de4e3..223a4d9463 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit-reach.h\"\n #include \"config.h\"\ndiff --git a/loose.c b/loose.c\nindex f6faa6216a..a8bf772172 100644\n--- a/loose.c\n+++ b/loose.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hash.h\"\n #include \"path.h\"\ndiff --git a/ls-refs.c b/ls-refs.c\nindex 398afe4ce3..2dd925b43d 100644\n--- a/ls-refs.c\n+++ b/ls-refs.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/mailmap.c b/mailmap.c\nindex b2efe29b3d..534a3eb4f0 100644\n--- a/mailmap.c\n+++ b/mailmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"string-list.h\"\ndiff --git a/match-trees.c b/match-trees.c\nindex 50c42e2061..f17c74d483 100644\n--- a/match-trees.c\n+++ b/match-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"match-trees.h\"\ndiff --git a/merge-blobs.c b/merge-blobs.c\nindex 2f659fd014..0ad0390fea 100644\n--- a/merge-blobs.c\n+++ b/merge-blobs.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-ll.h\"\n #include \"blob.h\"\ndiff --git a/merge-ort.c b/merge-ort.c\nindex eaede6cead..691db9050e 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -14,6 +14,8 @@\n  * \"cale\", \"peedy\", or \"ins\" instead of \"ort\"?)\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-ort.h\"\n \ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex 8ff29ed09e..46ee364af7 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -3,6 +3,9 @@\n  * Fredrik Kuivinen.\n  * The thieves were Alex Riesen and Johannes Schindelin, in June/July 2006\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"merge-recursive.h\"\n \ndiff --git a/merge.c b/merge.c\nindex 752a937fa9..fe3efa4b24 100644\n--- a/merge.c\n+++ b/merge.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/midx-write.c b/midx-write.c\nindex 55a6b63bac..9a194e8aac 100644\n--- a/midx-write.c\n+++ b/midx-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/midx.c b/midx.c\nindex 1e75f1a7eb..3992b05465 100644\n--- a/midx.c\n+++ b/midx.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"dir.h\"\ndiff --git a/negotiator/default.c b/negotiator/default.c\nindex 518b3c43b2..e3fa5c3324 100644\n--- a/negotiator/default.c\n+++ b/negotiator/default.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"default.h\"\n #include \"../commit.h\"\ndiff --git a/negotiator/skipping.c b/negotiator/skipping.c\nindex b7e008c2fd..f109928ad0 100644\n--- a/negotiator/skipping.c\n+++ b/negotiator/skipping.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"skipping.h\"\n #include \"../commit.h\"\ndiff --git a/notes-cache.c b/notes-cache.c\nindex 038db01ca0..ecfdf6e43b 100644\n--- a/notes-cache.c\n+++ b/notes-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"notes-cache.h\"\n #include \"object-store-ll.h\"\ndiff --git a/notes-merge.c b/notes-merge.c\nindex 801941c2d1..d95e683414 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"commit.h\"\ndiff --git a/notes-utils.c b/notes-utils.c\nindex e33aa86c4b..bca71274be 100644\n--- a/notes-utils.c\n+++ b/notes-utils.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/notes.c b/notes.c\nindex afe2e2882e..b6a13d0980 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex f684038f7f..958f61f094 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"strbuf.h\"\ndiff --git a/object-file.c b/object-file.c\nindex 72318c8dd4..a6555ed68c 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -6,6 +6,9 @@\n  * This handles basic git object files - packing, unpacking,\n  * creation etc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/object-name.c b/object-name.c\nindex 523af6f64f..d7509514bc 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"object-name.h\"\n #include \"advice.h\"\ndiff --git a/object.c b/object.c\nindex 93b5d97fdb..0c0fcb76c0 100644\n--- a/object.c\n+++ b/object.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/oid-array.c b/oid-array.c\nindex 1f36651754..9cac974395 100644\n--- a/oid-array.c\n+++ b/oid-array.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"oid-array.h\"\n #include \"hash-lookup.h\"\ndiff --git a/oss-fuzz/fuzz-commit-graph.c b/oss-fuzz/fuzz-commit-graph.c\nindex 75e668a057..951c9c082f 100644\n--- a/oss-fuzz/fuzz-commit-graph.c\n+++ b/oss-fuzz/fuzz-commit-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit-graph.h\"\n #include \"repository.h\"\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 59d2e3a387..37a8ad0fb3 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 184d28f05c..7eafdce4ee 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"gettext.h\"\ndiff --git a/pack-check.c b/pack-check.c\nindex e7b214fcbd..e883dae3f2 100644\n--- a/pack-check.c\n+++ b/pack-check.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"hex.h\"\ndiff --git a/pack-revindex.c b/pack-revindex.c\nindex fc63aa76a2..de922b47d2 100644\n--- a/pack-revindex.c\n+++ b/pack-revindex.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"pack-revindex.h\"\ndiff --git a/pack-write.c b/pack-write.c\nindex eef625fa5b..d07f03d0ab 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/packfile.c b/packfile.c\nindex ec7312cd20..813584646f 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/parse-options-cb.c b/parse-options-cb.c\nindex d99d688d3c..3fb7ce68ca 100644\n--- a/parse-options-cb.c\n+++ b/parse-options-cb.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"parse-options.h\"\n #include \"branch.h\"\ndiff --git a/path.c b/path.c\nindex adfb3d3eb7..19f7684f38 100644\n--- a/path.c\n+++ b/path.c\n@@ -1,6 +1,9 @@\n /*\n  * Utilities for paths and pathnames\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"environment.h\"\ndiff --git a/pathspec.c b/pathspec.c\nindex 2133b9fe60..fe1f0f41af 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"parse.h\"\ndiff --git a/pretty.c b/pretty.c\nindex 22a81506b7..2c14a88abc 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/progress.c b/progress.c\nindex c83cb60bf1..0d44c18edc 100644\n--- a/progress.c\n+++ b/progress.c\n@@ -9,6 +9,8 @@\n  */\n \n #define GIT_TEST_PROGRESS_ONLY\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"pager.h\"\n #include \"progress.h\"\ndiff --git a/promisor-remote.c b/promisor-remote.c\nindex 2ca7c2ae48..317e1b127f 100644\n--- a/promisor-remote.c\n+++ b/promisor-remote.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/range-diff.c b/range-diff.c\nindex c45b6d849c..5f01605550 100644\n--- a/range-diff.c\n+++ b/range-diff.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/reachable.c b/reachable.c\nindex 1224b30008..46613a6bb6 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/read-cache.c b/read-cache.c\nindex 085b22faf3..48bf24f87c 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -3,6 +3,9 @@\n  *\n  * Copyright (C) Linus Torvalds, 2005\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"bulk-checkin.h\"\n #include \"config.h\"\ndiff --git a/rebase-interactive.c b/rebase-interactive.c\nindex c343e16fcd..e93b385523 100644\n--- a/rebase-interactive.c\n+++ b/rebase-interactive.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"editor.h\"\ndiff --git a/ref-filter.c b/ref-filter.c\nindex f7fb0c7e0e..8c5e673fc0 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"gettext.h\"\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 5f09552c5c..c7070b13b0 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"commit.h\"\n #include \"refs.h\"\ndiff --git a/reflog.c b/reflog.c\nindex 3c80950186..5ca944529b 100644\n--- a/reflog.c\n+++ b/reflog.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"object-store-ll.h\"\ndiff --git a/refs.c b/refs.c\nindex 6e7caefdcf..727ed6c1d6 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2,6 +2,8 @@\n  * The backend-independent part of the reference module.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex b484b5880d..35931bc71e 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../copy.h\"\n #include \"../environment.h\"\ndiff --git a/refs/packed-backend.c b/refs/packed-backend.c\nindex 5ab1b21d10..a0666407cd 100644\n--- a/refs/packed-backend.c\n+++ b/refs/packed-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../config.h\"\n #include \"../dir.h\"\ndiff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\nindex 57df2aba66..6e34eb2188 100644\n--- a/refs/reftable-backend.c\n+++ b/refs/reftable-backend.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"../git-compat-util.h\"\n #include \"../abspath.h\"\n #include \"../chdir-notify.h\"\ndiff --git a/refspec.c b/refspec.c\nindex d60932f4de..c2e3e24351 100644\n--- a/refspec.c\n+++ b/refspec.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 6008d7e87c..1930f83cc7 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"git-curl-compat.h\"\n #include \"config.h\"\ndiff --git a/remote.c b/remote.c\nindex 1064171085..5fab7f0970 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/repository.c b/repository.c\nindex 95d10cc4a0..9825a30899 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -16,6 +16,14 @@\n #include \"promisor-remote.h\"\n #include \"refs.h\"\n \n+/*\n+ * We do not define `USE_THE_REPOSITORY_VARIABLE` in this file because we do\n+ * not want to rely on functions that implicitly use `the_repository`. This\n+ * means that the `extern` declaration of `the_repository` isn't visible here,\n+ * which makes sparse unhappy. We thus declare it here.\n+ */\n+extern struct repository *the_repository;\n+\n /* The main repository */\n static struct repository the_repo;\n struct repository *the_repository = &the_repo;\ndiff --git a/repository.h b/repository.h\nindex a35cd77c35..29727edec6 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -197,7 +197,9 @@ struct repository {\n \tunsigned different_commondir:1;\n };\n \n+#ifdef USE_THE_REPOSITORY_VARIABLE\n extern struct repository *the_repository;\n+#endif\n \n /*\n  * Define a custom repository layout. Any field can be NULL, which\ndiff --git a/rerere.c b/rerere.c\nindex c7e1f8fd25..597256fa5b 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"config.h\"\ndiff --git a/reset.c b/reset.c\nindex 937f11c0f4..9550dea03d 100644\n--- a/reset.c\n+++ b/reset.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"cache-tree.h\"\n #include \"gettext.h\"\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex 4e6f0e4676..8c9911affb 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"hash.h\"\ndiff --git a/revision.c b/revision.c\nindex 7ddf0f151a..40da255953 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/run-command.c b/run-command.c\nindex 31b20123d8..f5fde92b7c 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"run-command.h\"\n #include \"environment.h\"\ndiff --git a/scalar.c b/scalar.c\nindex 331b91dbdb..a1cb4b45b5 100644\n--- a/scalar.c\n+++ b/scalar.c\n@@ -2,6 +2,8 @@\n  * The Scalar command-line interface.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"gettext.h\"\ndiff --git a/send-pack.c b/send-pack.c\nindex 37f59d4f66..b42e6986df 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"commit.h\"\ndiff --git a/sequencer.c b/sequencer.c\nindex 823691e379..8083fe20bf 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"advice.h\"\ndiff --git a/serve.c b/serve.c\nindex aa651b73e9..33608ea4d5 100644\n--- a/serve.c\n+++ b/serve.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\ndiff --git a/server-info.c b/server-info.c\nindex 6feaa457c5..97e839c33d 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"environment.h\"\ndiff --git a/setup.c b/setup.c\nindex 20f380825b..7e1169eb86 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"copy.h\"\ndiff --git a/shallow.c b/shallow.c\nindex a0b181ba8a..31a6ca40fe 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"repository.h\"\ndiff --git a/split-index.c b/split-index.c\nindex 058a8f448e..120c8190b1 100644\n--- a/split-index.c\n+++ b/split-index.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hash.h\"\ndiff --git a/streaming.c b/streaming.c\nindex 10adf625b2..38839511af 100644\n--- a/streaming.c\n+++ b/streaming.c\n@@ -1,6 +1,9 @@\n /*\n  * Copyright (c) 2011, Google Inc.\n  */\n+\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"convert.h\"\n #include \"environment.h\"\ndiff --git a/submodule-config.c b/submodule-config.c\nindex ad43a282da..9b0bb0b9f4 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"dir.h\"\n #include \"environment.h\"\ndiff --git a/submodule.c b/submodule.c\nindex caf3aa5600..ab99a30253 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c\nindex af43ee1cb5..1f18d57007 100644\n--- a/t/helper/test-bitmap.c\n+++ b/t/helper/test-bitmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"git-compat-util.h\"\n #include \"pack-bitmap.h\"\ndiff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c\nindex 1281e66876..f7f9b62002 100644\n--- a/t/helper/test-bloom.c\n+++ b/t/helper/test-bloom.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"bloom.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c\nindex dc89ecfd71..5cdef3ebef 100644\n--- a/t/helper/test-cache-tree.c\n+++ b/t/helper/test-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c\nindex 02b0b46c3f..3f0c7d0ed0 100644\n--- a/t/helper/test-dump-cache-tree.c\n+++ b/t/helper/test-dump-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hash.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c\nindex 4f215fea02..1b7f37a84f 100644\n--- a/t/helper/test-dump-fsmonitor.c\n+++ b/t/helper/test-dump-fsmonitor.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"read-cache-ll.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c\nindex f472691a3c..a6720faf9c 100644\n--- a/t/helper/test-dump-split-index.c\n+++ b/t/helper/test-dump-split-index.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c\nindex 9ff67c3967..4f010d5324 100644\n--- a/t/helper/test-dump-untracked-cache.c\n+++ b/t/helper/test-dump-untracked-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"dir.h\"\n #include \"hex.h\"\ndiff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c\nindex e8bd793e58..14b2b0c12c 100644\n--- a/t/helper/test-find-pack.c\n+++ b/t/helper/test-find-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"object-name.h\"\n #include \"object-store.h\"\ndiff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\nindex 8280984d08..02bfe92e8d 100644\n--- a/t/helper/test-fsmonitor-client.c\n+++ b/t/helper/test-fsmonitor-client.c\n@@ -3,6 +3,8 @@\n  * a `git fsmonitor--daemon` daemon.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"parse-options.h\"\n #include \"fsmonitor-ipc.h\"\ndiff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c\nindex 5f33bb7b8f..40f5df4412 100644\n--- a/t/helper/test-lazy-init-name-hash.c\n+++ b/t/helper/test-lazy-init-name-hash.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"environment.h\"\n #include \"name-hash.h\"\ndiff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c\nindex d0db5ff26f..e0e2048320 100644\n--- a/t/helper/test-match-trees.c\n+++ b/t/helper/test-match-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"match-trees.h\"\ndiff --git a/t/helper/test-oidmap.c b/t/helper/test-oidmap.c\nindex bd30244a54..c03cfa5ecf 100644\n--- a/t/helper/test-oidmap.c\n+++ b/t/helper/test-oidmap.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"object-name.h\"\ndiff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c\nindex 67a964ef90..f8f9afbb5b 100644\n--- a/t/helper/test-pack-mtimes.c\n+++ b/t/helper/test-pack-mtimes.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"strbuf.h\"\ndiff --git a/t/helper/test-reach.c b/t/helper/test-reach.c\nindex 1ba226f1f9..5dd374379c 100644\n--- a/t/helper/test-reach.c\n+++ b/t/helper/test-reach.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit.h\"\n #include \"commit-reach.h\"\ndiff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c\nindex e803c43ece..d285c656bd 100644\n--- a/t/helper/test-read-cache.c\n+++ b/t/helper/test-read-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"config.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c\nindex 8c7a83f578..d9e980d04c 100644\n--- a/t/helper/test-read-graph.c\n+++ b/t/helper/test-read-graph.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit-graph.h\"\n #include \"repository.h\"\ndiff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c\nindex 4acae41bb9..83effc2b5f 100644\n--- a/t/helper/test-read-midx.c\n+++ b/t/helper/test-read-midx.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"midx.h\"\ndiff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c\nindex ad24300170..637b8b294e 100644\n--- a/t/helper/test-ref-store.c\n+++ b/t/helper/test-ref-store.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"refs.h\"\ndiff --git a/t/helper/test-repository.c b/t/helper/test-repository.c\nindex 0c7c5aa4dd..c6a074df3d 100644\n--- a/t/helper/test-repository.c\n+++ b/t/helper/test-repository.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit-graph.h\"\n #include \"commit.h\"\ndiff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c\nindex f346951bc2..071f5bd1e2 100644\n--- a/t/helper/test-revision-walking.c\n+++ b/t/helper/test-revision-walking.c\n@@ -8,6 +8,8 @@\n  * published by the Free Software Foundation.\n  */\n \n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"commit.h\"\n #include \"diff.h\"\ndiff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c\nindex 737cbe475b..64fff6e9e3 100644\n--- a/t/helper/test-scrap-cache-tree.c\n+++ b/t/helper/test-scrap-cache-tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"lockfile.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex 4b809d9dca..cbe93f2f9e 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"config.h\"\n #include \"hash.h\"\ndiff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c\nindex ecd40ded99..6ca069ce63 100644\n--- a/t/helper/test-submodule-nested-repo-config.c\n+++ b/t/helper/test-submodule-nested-repo-config.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"repository.h\"\n #include \"setup.h\"\ndiff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c\nindex 7197969a08..22e518d229 100644\n--- a/t/helper/test-submodule.c\n+++ b/t/helper/test-submodule.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"test-tool-utils.h\"\n #include \"parse-options.h\"\ndiff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c\nindex 1adac29a57..cd955ec63e 100644\n--- a/t/helper/test-trace2.c\n+++ b/t/helper/test-trace2.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"strvec.h\"\n #include \"run-command.h\"\ndiff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c\nindex 7e3da380a9..b37dd2c5d6 100644\n--- a/t/helper/test-write-cache.c\n+++ b/t/helper/test-write-cache.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"lockfile.h\"\n #include \"read-cache-ll.h\"\ndiff --git a/t/unit-tests/t-example-decorate.c b/t/unit-tests/t-example-decorate.c\nindex 3c856a8cf2..a4a75db735 100644\n--- a/t/unit-tests/t-example-decorate.c\n+++ b/t/unit-tests/t-example-decorate.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-lib.h\"\n #include \"object.h\"\n #include \"decorate.h\"\ndiff --git a/tag.c b/tag.c\nindex 52bbe50819..d24170e340 100644\n--- a/tag.c\n+++ b/tag.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"environment.h\"\n #include \"tag.h\"\ndiff --git a/tmp-objdir.c b/tmp-objdir.c\nindex 3509258be5..a8e4553f27 100644\n--- a/tmp-objdir.c\n+++ b/tmp-objdir.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tmp-objdir.h\"\n #include \"abspath.h\"\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 9820947ab2..09b3560ffd 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"transport.h\"\n #include \"quote.h\"\ndiff --git a/transport.c b/transport.c\nindex 83ddea8fbc..b9c8827ed9 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"config.h\"\ndiff --git a/tree-walk.c b/tree-walk.c\nindex 535a3a2539..a033397965 100644\n--- a/tree-walk.c\n+++ b/tree-walk.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"tree-walk.h\"\n #include \"dir.h\"\ndiff --git a/tree.c b/tree.c\nindex 7973d3f9a8..ad86ad1ba9 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"hex.h\"\n #include \"tree.h\"\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 304ea2ed86..7dc884fafd 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"strvec.h\"\ndiff --git a/upload-pack.c b/upload-pack.c\nindex b726f7a57d..0052c6a4dc 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"environment.h\"\ndiff --git a/walker.c b/walker.c\nindex 946d86b04e..0fafdc97cf 100644\n--- a/walker.c\n+++ b/walker.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"hex.h\"\ndiff --git a/worktree.c b/worktree.c\nindex 70844d023a..f3c4c8ec54 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"abspath.h\"\n #include \"environment.h\"\ndiff --git a/wt-status.c b/wt-status.c\nindex 5051f5e599..8815df419e 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"advice.h\"\n #include \"wt-status.h\"\ndiff --git a/xdiff-interface.c b/xdiff-interface.c\nindex 16ed8ac492..d5dc88661e 100644\n--- a/xdiff-interface.c\n+++ b/xdiff-interface.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"gettext.h\"\n #include \"config.h\"\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497141","messageId":"74c88ebc39e345fef8eaf49311df89dc8d27250f.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 10/20] refs: avoid include cycle with \"repository.h\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:28Z","receivedAt":"2024-06-14T06:50:31Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"There is an include cycle between \"refs.h\" and \"repository.h\" via\n\"commit.h\", \"object.h\" and \"hash.h\". This has the effect that several\ndefinitions of structs and enums will not be visible once we merge\n\"hash-ll.h\" back into \"hash.h\" in the next commit.\n\nThe only reason that \"repository.h\" includes \"refs.h\" is the definition\nof `enum ref_storage_format`. Move it into \"repository.h\" and have\n\"refs.h\" include \"repository.h\" instead to fix the cycle.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n refs.h       | 8 +-------\n repository.h | 7 ++++++-\n 2 files changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/refs.h b/refs.h\nindex 76d25df4de..a9716e5d25 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -2,21 +2,15 @@\n #define REFS_H\n \n #include \"commit.h\"\n+#include \"repository.h\"\n \n struct object_id;\n struct ref_store;\n-struct repository;\n struct strbuf;\n struct string_list;\n struct string_list_item;\n struct worktree;\n \n-enum ref_storage_format {\n-\tREF_STORAGE_FORMAT_UNKNOWN,\n-\tREF_STORAGE_FORMAT_FILES,\n-\tREF_STORAGE_FORMAT_REFTABLE,\n-};\n-\n enum ref_storage_format ref_storage_format_by_name(const char *name);\n const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format);\n \ndiff --git a/repository.h b/repository.h\nindex 29727edec6..6ce6826c26 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -1,7 +1,6 @@\n #ifndef REPOSITORY_H\n #define REPOSITORY_H\n \n-#include \"refs.h\"\n #include \"strmap.h\"\n \n struct config_set;\n@@ -27,6 +26,12 @@ enum fetch_negotiation_setting {\n \tFETCH_NEGOTIATION_NOOP,\n };\n \n+enum ref_storage_format {\n+\tREF_STORAGE_FORMAT_UNKNOWN,\n+\tREF_STORAGE_FORMAT_FILES,\n+\tREF_STORAGE_FORMAT_REFTABLE,\n+};\n+\n struct repo_settings {\n \tint initialized;\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497142","messageId":"fe4550ba0cc90f1be3863312089078912a26d588.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 11/20] hash-ll: merge with \"hash.h\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:32Z","receivedAt":"2024-06-14T06:50:37Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"hash-ll.h\" header was introduced via d1cbe1e6d8 (hash-ll.h: split\nout of hash.h to remove dependency on repository.h, 2023-04-22) to make\nexplicit the split between hash-related functions that rely on the\nglobal `the_repository`, and those that don't. This split is no longer\nnecessary now that we we have removed the reliance on `the_repository`.\n\nMerge \"hash-ll.h\" back into \"hash.h\". This causes some code units to not\ninclude \"repository.h\" anymore, which requires us to add some forward\ndeclarations.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n apply.h                    |   2 +-\n bloom.c                    |   1 +\n checkout.h                 |   2 +-\n chunk-format.h             |   2 +-\n commit-graph.h             |   2 +\n compat/sha1-chunked.c      |   2 +-\n convert.h                  |   2 +-\n csum-file.h                |   2 +-\n diff.h                     |   2 +-\n diffcore.h                 |   2 +-\n dir.h                      |   2 +-\n hash-ll.h                  | 364 -------------------------------------\n hash.h                     | 362 +++++++++++++++++++++++++++++++++++-\n hex.h                      |   2 +-\n loose.h                    |   2 +\n merge-ort.h                |   2 +-\n object-file-convert.c      |   2 +-\n object.h                   |   2 +-\n oidmap.h                   |   2 +-\n oidtree.h                  |   2 +-\n packfile.h                 |   2 +\n protocol-caps.c            |   2 +-\n read-cache-ll.h            |   2 +-\n refs/ref-cache.h           |   2 +-\n reftable/dump.c            |   2 +-\n reftable/reftable-record.h |   2 +-\n reftable/system.h          |   2 +-\n remote.h                   |   2 +-\n reset.h                    |   2 +-\n resolve-undo.h             |   2 +-\n serve.c                    |   2 +-\n split-index.h              |   2 +-\n t/helper/test-hash-speed.c |   2 +-\n t/helper/test-sha1.c       |   2 +-\n t/helper/test-sha256.c     |   2 +-\n t/unit-tests/lib-oid.h     |   2 +-\n tree-diff.c                |   1 +\n tree-walk.h                |   2 +-\n xdiff-interface.h          |   2 +-\n 39 files changed, 400 insertions(+), 398 deletions(-)\n delete mode 100644 hash-ll.h\n\ndiff --git a/apply.h b/apply.h\nindex 7cd38b1443..b9f18ce87d 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -1,7 +1,7 @@\n #ifndef APPLY_H\n #define APPLY_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"lockfile.h\"\n #include \"string-list.h\"\n #include \"strmap.h\"\ndiff --git a/bloom.c b/bloom.c\nindex e529f7605c..bbf146fc30 100644\n--- a/bloom.c\n+++ b/bloom.c\n@@ -6,6 +6,7 @@\n #include \"commit-graph.h\"\n #include \"commit.h\"\n #include \"commit-slab.h\"\n+#include \"repository.h\"\n \n define_commit_slab(bloom_filter_slab, struct bloom_filter);\n \ndiff --git a/checkout.h b/checkout.h\nindex ba15a13fb3..55920e7aeb 100644\n--- a/checkout.h\n+++ b/checkout.h\n@@ -1,7 +1,7 @@\n #ifndef CHECKOUT_H\n #define CHECKOUT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n /*\n  * Check if the branch name uniquely matches a branch name on a remote\ndiff --git a/chunk-format.h b/chunk-format.h\nindex 14b76180ef..212a0a6af1 100644\n--- a/chunk-format.h\n+++ b/chunk-format.h\n@@ -1,7 +1,7 @@\n #ifndef CHUNK_FORMAT_H\n #define CHUNK_FORMAT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct hashfile;\n struct chunkfile;\ndiff --git a/commit-graph.h b/commit-graph.h\nindex e519cb81cb..6781940195 100644\n--- a/commit-graph.h\n+++ b/commit-graph.h\n@@ -122,6 +122,8 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,\n struct commit_graph *read_commit_graph_one(struct repository *r,\n \t\t\t\t\t   struct object_directory *odb);\n \n+struct repo_settings;\n+\n /*\n  * Callers should initialize the repo_settings with prepare_repo_settings()\n  * prior to calling parse_commit_graph().\ndiff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c\nindex a4a6f930d7..0446f9983f 100644\n--- a/compat/sha1-chunked.c\n+++ b/compat/sha1-chunked.c\n@@ -1,5 +1,5 @@\n #include \"git-compat-util.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)\n {\ndiff --git a/convert.h b/convert.h\nindex d925589444..0a6e4086b8 100644\n--- a/convert.h\n+++ b/convert.h\n@@ -4,7 +4,7 @@\n #ifndef CONVERT_H\n #define CONVERT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"string-list.h\"\n \n struct index_state;\ndiff --git a/csum-file.h b/csum-file.h\nindex bc5bec27ac..566e05cbd2 100644\n--- a/csum-file.h\n+++ b/csum-file.h\n@@ -1,7 +1,7 @@\n #ifndef CSUM_FILE_H\n #define CSUM_FILE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"write-or-die.h\"\n \n struct progress;\ndiff --git a/diff.h b/diff.h\nindex 66bd8aeb29..9901c8ca8c 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -4,7 +4,7 @@\n #ifndef DIFF_H\n #define DIFF_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"pathspec.h\"\n #include \"strbuf.h\"\n \ndiff --git a/diffcore.h b/diffcore.h\nindex 5ffe4ec788..1701ed50b9 100644\n--- a/diffcore.h\n+++ b/diffcore.h\n@@ -4,7 +4,7 @@\n #ifndef DIFFCORE_H\n #define DIFFCORE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct diff_options;\n struct mem_pool;\ndiff --git a/dir.h b/dir.h\nindex 1398a53fb4..69a76d8bdd 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -1,7 +1,7 @@\n #ifndef DIR_H\n #define DIR_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"pathspec.h\"\n #include \"statinfo.h\"\ndiff --git a/hash-ll.h b/hash-ll.h\ndeleted file mode 100644\nindex 3161c778b9..0000000000\n--- a/hash-ll.h\n+++ /dev/null\n@@ -1,364 +0,0 @@\n-#ifndef HASH_LL_H\n-#define HASH_LL_H\n-\n-#if defined(SHA1_APPLE)\n-#include <CommonCrypto/CommonDigest.h>\n-#elif defined(SHA1_OPENSSL)\n-#  include <openssl/sha.h>\n-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n-#    define SHA1_NEEDS_CLONE_HELPER\n-#    include \"sha1/openssl.h\"\n-#  endif\n-#elif defined(SHA1_DC)\n-#include \"sha1dc_git.h\"\n-#else /* SHA1_BLK */\n-#include \"block-sha1/sha1.h\"\n-#endif\n-\n-#if defined(SHA256_NETTLE)\n-#include \"sha256/nettle.h\"\n-#elif defined(SHA256_GCRYPT)\n-#define SHA256_NEEDS_CLONE_HELPER\n-#include \"sha256/gcrypt.h\"\n-#elif defined(SHA256_OPENSSL)\n-#  include <openssl/sha.h>\n-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n-#    define SHA256_NEEDS_CLONE_HELPER\n-#    include \"sha256/openssl.h\"\n-#  endif\n-#else\n-#include \"sha256/block/sha256.h\"\n-#endif\n-\n-#ifndef platform_SHA_CTX\n-/*\n- * platform's underlying implementation of SHA-1; could be OpenSSL,\n- * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant\n- * SHA-1 header may have already defined platform_SHA_CTX for our\n- * own implementations like block-sha1, so we list\n- * the default for OpenSSL compatible SHA-1 implementations here.\n- */\n-#define platform_SHA_CTX\tSHA_CTX\n-#define platform_SHA1_Init\tSHA1_Init\n-#define platform_SHA1_Update\tSHA1_Update\n-#define platform_SHA1_Final    \tSHA1_Final\n-#endif\n-\n-#define git_SHA_CTX\t\tplatform_SHA_CTX\n-#define git_SHA1_Init\t\tplatform_SHA1_Init\n-#define git_SHA1_Update\t\tplatform_SHA1_Update\n-#define git_SHA1_Final\t\tplatform_SHA1_Final\n-\n-#ifdef platform_SHA1_Clone\n-#define git_SHA1_Clone\tplatform_SHA1_Clone\n-#endif\n-\n-#ifndef platform_SHA256_CTX\n-#define platform_SHA256_CTX\tSHA256_CTX\n-#define platform_SHA256_Init\tSHA256_Init\n-#define platform_SHA256_Update\tSHA256_Update\n-#define platform_SHA256_Final\tSHA256_Final\n-#endif\n-\n-#define git_SHA256_CTX\t\tplatform_SHA256_CTX\n-#define git_SHA256_Init\t\tplatform_SHA256_Init\n-#define git_SHA256_Update\tplatform_SHA256_Update\n-#define git_SHA256_Final\tplatform_SHA256_Final\n-\n-#ifdef platform_SHA256_Clone\n-#define git_SHA256_Clone\tplatform_SHA256_Clone\n-#endif\n-\n-#ifdef SHA1_MAX_BLOCK_SIZE\n-#include \"compat/sha1-chunked.h\"\n-#undef git_SHA1_Update\n-#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n-#endif\n-\n-#ifndef SHA1_NEEDS_CLONE_HELPER\n-static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)\n-{\n-\tmemcpy(dst, src, sizeof(*dst));\n-}\n-#endif\n-\n-#ifndef SHA256_NEEDS_CLONE_HELPER\n-static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)\n-{\n-\tmemcpy(dst, src, sizeof(*dst));\n-}\n-#endif\n-\n-/*\n- * Note that these constants are suitable for indexing the hash_algos array and\n- * comparing against each other, but are otherwise arbitrary, so they should not\n- * be exposed to the user or serialized to disk.  To know whether a\n- * git_hash_algo struct points to some usable hash function, test the format_id\n- * field for being non-zero.  Use the name field for user-visible situations and\n- * the format_id field for fixed-length fields on disk.\n- */\n-/* An unknown hash function. */\n-#define GIT_HASH_UNKNOWN 0\n-/* SHA-1 */\n-#define GIT_HASH_SHA1 1\n-/* SHA-256  */\n-#define GIT_HASH_SHA256 2\n-/* Number of algorithms supported (including unknown). */\n-#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)\n-\n-/* \"sha1\", big-endian */\n-#define GIT_SHA1_FORMAT_ID 0x73686131\n-\n-/* The length in bytes and in hex digits of an object name (SHA-1 value). */\n-#define GIT_SHA1_RAWSZ 20\n-#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)\n-/* The block size of SHA-1. */\n-#define GIT_SHA1_BLKSZ 64\n-\n-/* \"s256\", big-endian */\n-#define GIT_SHA256_FORMAT_ID 0x73323536\n-\n-/* The length in bytes and in hex digits of an object name (SHA-256 value). */\n-#define GIT_SHA256_RAWSZ 32\n-#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)\n-/* The block size of SHA-256. */\n-#define GIT_SHA256_BLKSZ 64\n-\n-/* The length in byte and in hex digits of the largest possible hash value. */\n-#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ\n-#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ\n-/* The largest possible block size for any supported hash. */\n-#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ\n-\n-struct object_id {\n-\tunsigned char hash[GIT_MAX_RAWSZ];\n-\tint algo;\t/* XXX requires 4-byte alignment */\n-};\n-\n-#define GET_OID_QUIETLY           01\n-#define GET_OID_COMMIT            02\n-#define GET_OID_COMMITTISH        04\n-#define GET_OID_TREE             010\n-#define GET_OID_TREEISH          020\n-#define GET_OID_BLOB             040\n-#define GET_OID_FOLLOW_SYMLINKS 0100\n-#define GET_OID_RECORD_PATH     0200\n-#define GET_OID_ONLY_TO_DIE    04000\n-#define GET_OID_REQUIRE_PATH  010000\n-#define GET_OID_HASH_ANY      020000\n-\n-#define GET_OID_DISAMBIGUATORS \\\n-\t(GET_OID_COMMIT | GET_OID_COMMITTISH | \\\n-\tGET_OID_TREE | GET_OID_TREEISH | \\\n-\tGET_OID_BLOB)\n-\n-enum get_oid_result {\n-\tFOUND = 0,\n-\tMISSING_OBJECT = -1, /* The requested object is missing */\n-\tSHORT_NAME_AMBIGUOUS = -2,\n-\t/* The following only apply when symlinks are followed */\n-\tDANGLING_SYMLINK = -4, /*\n-\t\t\t\t* The initial symlink is there, but\n-\t\t\t\t* (transitively) points to a missing\n-\t\t\t\t* in-tree file\n-\t\t\t\t*/\n-\tSYMLINK_LOOP = -5,\n-\tNOT_DIR = -6, /*\n-\t\t       * Somewhere along the symlink chain, a path is\n-\t\t       * requested which contains a file as a\n-\t\t       * non-final element.\n-\t\t       */\n-};\n-\n-/* A suitably aligned type for stack allocations of hash contexts. */\n-union git_hash_ctx {\n-\tgit_SHA_CTX sha1;\n-\tgit_SHA256_CTX sha256;\n-};\n-typedef union git_hash_ctx git_hash_ctx;\n-\n-typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);\n-typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);\n-typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);\n-typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);\n-typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);\n-\n-struct git_hash_algo {\n-\t/*\n-\t * The name of the algorithm, as appears in the config file and in\n-\t * messages.\n-\t */\n-\tconst char *name;\n-\n-\t/* A four-byte version identifier, used in pack indices. */\n-\tuint32_t format_id;\n-\n-\t/* The length of the hash in binary. */\n-\tsize_t rawsz;\n-\n-\t/* The length of the hash in hex characters. */\n-\tsize_t hexsz;\n-\n-\t/* The block size of the hash. */\n-\tsize_t blksz;\n-\n-\t/* The hash initialization function. */\n-\tgit_hash_init_fn init_fn;\n-\n-\t/* The hash context cloning function. */\n-\tgit_hash_clone_fn clone_fn;\n-\n-\t/* The hash update function. */\n-\tgit_hash_update_fn update_fn;\n-\n-\t/* The hash finalization function. */\n-\tgit_hash_final_fn final_fn;\n-\n-\t/* The hash finalization function for object IDs. */\n-\tgit_hash_final_oid_fn final_oid_fn;\n-\n-\t/* The OID of the empty tree. */\n-\tconst struct object_id *empty_tree;\n-\n-\t/* The OID of the empty blob. */\n-\tconst struct object_id *empty_blob;\n-\n-\t/* The all-zeros OID. */\n-\tconst struct object_id *null_oid;\n-};\n-extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];\n-\n-/*\n- * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if\n- * the name doesn't match a known algorithm.\n- */\n-int hash_algo_by_name(const char *name);\n-/* Identical, except based on the format ID. */\n-int hash_algo_by_id(uint32_t format_id);\n-/* Identical, except based on the length. */\n-int hash_algo_by_length(int len);\n-/* Identical, except for a pointer to struct git_hash_algo. */\n-static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n-{\n-\treturn p - hash_algos;\n-}\n-\n-const struct object_id *null_oid(void);\n-\n-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n-{\n-\t/*\n-\t * Teach the compiler that there are only two possibilities of hash size\n-\t * here, so that it can optimize for this case as much as possible.\n-\t */\n-\tif (algop->rawsz == GIT_MAX_RAWSZ)\n-\t\treturn memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n-\treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n-}\n-\n-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n-{\n-\t/*\n-\t * We write this here instead of deferring to hashcmp so that the\n-\t * compiler can properly inline it and avoid calling memcmp.\n-\t */\n-\tif (algop->rawsz == GIT_MAX_RAWSZ)\n-\t\treturn !memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n-\treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n-}\n-\n-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n-\t\t\t   const struct git_hash_algo *algop)\n-{\n-\tmemcpy(sha_dst, sha_src, algop->rawsz);\n-}\n-\n-static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n-{\n-\tmemset(hash, 0, algop->rawsz);\n-}\n-\n-static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n-}\n-\n-static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n-{\n-\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n-}\n-\n-static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n-{\n-\tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\n-\tdst->algo = src->algo;\n-}\n-\n-static inline void oidread(struct object_id *oid, const unsigned char *hash,\n-\t\t\t   const struct git_hash_algo *algop)\n-{\n-\tmemcpy(oid->hash, hash, algop->rawsz);\n-\tif (algop->rawsz < GIT_MAX_RAWSZ)\n-\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline void oidclr(struct object_id *oid,\n-\t\t\t  const struct git_hash_algo *algop)\n-{\n-\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-static inline struct object_id *oiddup(const struct object_id *src)\n-{\n-\tstruct object_id *dst = xmalloc(sizeof(struct object_id));\n-\toidcpy(dst, src);\n-\treturn dst;\n-}\n-\n-static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)\n-{\n-\toid->algo = hash_algo_by_ptr(algop);\n-}\n-\n-/*\n- * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code\n- * for use in hash tables. Cryptographic hashes are supposed to have\n- * uniform distribution, so in contrast to `memhash()`, this just copies\n- * the first `sizeof(int)` bytes without shuffling any bits. Note that\n- * the results will be different on big-endian and little-endian\n- * platforms, so they should not be stored or transferred over the net.\n- */\n-static inline unsigned int oidhash(const struct object_id *oid)\n-{\n-\t/*\n-\t * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on\n-\t * platforms that don't support unaligned reads.\n-\t */\n-\tunsigned int hash;\n-\tmemcpy(&hash, oid->hash, sizeof(hash));\n-\treturn hash;\n-}\n-\n-static inline int is_null_oid(const struct object_id *oid)\n-{\n-\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n-\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n-}\n-\n-const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n-\n-static inline int is_empty_blob_oid(const struct object_id *oid,\n-\t\t\t\t    const struct git_hash_algo *algop)\n-{\n-\treturn oideq(oid, algop->empty_blob);\n-}\n-\n-static inline int is_empty_tree_oid(const struct object_id *oid,\n-\t\t\t\t    const struct git_hash_algo *algop)\n-{\n-\treturn oideq(oid, algop->empty_tree);\n-}\n-\n-#endif\ndiff --git a/hash.h b/hash.h\nindex cb85d26a2f..72ffbc862e 100644\n--- a/hash.h\n+++ b/hash.h\n@@ -1,11 +1,369 @@\n #ifndef HASH_H\n #define HASH_H\n \n-#include \"hash-ll.h\"\n-#include \"repository.h\"\n+#if defined(SHA1_APPLE)\n+#include <CommonCrypto/CommonDigest.h>\n+#elif defined(SHA1_OPENSSL)\n+#  include <openssl/sha.h>\n+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n+#    define SHA1_NEEDS_CLONE_HELPER\n+#    include \"sha1/openssl.h\"\n+#  endif\n+#elif defined(SHA1_DC)\n+#include \"sha1dc_git.h\"\n+#else /* SHA1_BLK */\n+#include \"block-sha1/sha1.h\"\n+#endif\n+\n+#if defined(SHA256_NETTLE)\n+#include \"sha256/nettle.h\"\n+#elif defined(SHA256_GCRYPT)\n+#define SHA256_NEEDS_CLONE_HELPER\n+#include \"sha256/gcrypt.h\"\n+#elif defined(SHA256_OPENSSL)\n+#  include <openssl/sha.h>\n+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3\n+#    define SHA256_NEEDS_CLONE_HELPER\n+#    include \"sha256/openssl.h\"\n+#  endif\n+#else\n+#include \"sha256/block/sha256.h\"\n+#endif\n+\n+#ifndef platform_SHA_CTX\n+/*\n+ * platform's underlying implementation of SHA-1; could be OpenSSL,\n+ * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant\n+ * SHA-1 header may have already defined platform_SHA_CTX for our\n+ * own implementations like block-sha1, so we list\n+ * the default for OpenSSL compatible SHA-1 implementations here.\n+ */\n+#define platform_SHA_CTX\tSHA_CTX\n+#define platform_SHA1_Init\tSHA1_Init\n+#define platform_SHA1_Update\tSHA1_Update\n+#define platform_SHA1_Final    \tSHA1_Final\n+#endif\n+\n+#define git_SHA_CTX\t\tplatform_SHA_CTX\n+#define git_SHA1_Init\t\tplatform_SHA1_Init\n+#define git_SHA1_Update\t\tplatform_SHA1_Update\n+#define git_SHA1_Final\t\tplatform_SHA1_Final\n+\n+#ifdef platform_SHA1_Clone\n+#define git_SHA1_Clone\tplatform_SHA1_Clone\n+#endif\n+\n+#ifndef platform_SHA256_CTX\n+#define platform_SHA256_CTX\tSHA256_CTX\n+#define platform_SHA256_Init\tSHA256_Init\n+#define platform_SHA256_Update\tSHA256_Update\n+#define platform_SHA256_Final\tSHA256_Final\n+#endif\n+\n+#define git_SHA256_CTX\t\tplatform_SHA256_CTX\n+#define git_SHA256_Init\t\tplatform_SHA256_Init\n+#define git_SHA256_Update\tplatform_SHA256_Update\n+#define git_SHA256_Final\tplatform_SHA256_Final\n+\n+#ifdef platform_SHA256_Clone\n+#define git_SHA256_Clone\tplatform_SHA256_Clone\n+#endif\n+\n+#ifdef SHA1_MAX_BLOCK_SIZE\n+#include \"compat/sha1-chunked.h\"\n+#undef git_SHA1_Update\n+#define git_SHA1_Update\t\tgit_SHA1_Update_Chunked\n+#endif\n+\n+#ifndef SHA1_NEEDS_CLONE_HELPER\n+static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)\n+{\n+\tmemcpy(dst, src, sizeof(*dst));\n+}\n+#endif\n+\n+#ifndef SHA256_NEEDS_CLONE_HELPER\n+static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)\n+{\n+\tmemcpy(dst, src, sizeof(*dst));\n+}\n+#endif\n+\n+/*\n+ * Note that these constants are suitable for indexing the hash_algos array and\n+ * comparing against each other, but are otherwise arbitrary, so they should not\n+ * be exposed to the user or serialized to disk.  To know whether a\n+ * git_hash_algo struct points to some usable hash function, test the format_id\n+ * field for being non-zero.  Use the name field for user-visible situations and\n+ * the format_id field for fixed-length fields on disk.\n+ */\n+/* An unknown hash function. */\n+#define GIT_HASH_UNKNOWN 0\n+/* SHA-1 */\n+#define GIT_HASH_SHA1 1\n+/* SHA-256  */\n+#define GIT_HASH_SHA256 2\n+/* Number of algorithms supported (including unknown). */\n+#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)\n+\n+/* \"sha1\", big-endian */\n+#define GIT_SHA1_FORMAT_ID 0x73686131\n+\n+/* The length in bytes and in hex digits of an object name (SHA-1 value). */\n+#define GIT_SHA1_RAWSZ 20\n+#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)\n+/* The block size of SHA-1. */\n+#define GIT_SHA1_BLKSZ 64\n+\n+/* \"s256\", big-endian */\n+#define GIT_SHA256_FORMAT_ID 0x73323536\n+\n+/* The length in bytes and in hex digits of an object name (SHA-256 value). */\n+#define GIT_SHA256_RAWSZ 32\n+#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)\n+/* The block size of SHA-256. */\n+#define GIT_SHA256_BLKSZ 64\n+\n+/* The length in byte and in hex digits of the largest possible hash value. */\n+#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ\n+#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ\n+/* The largest possible block size for any supported hash. */\n+#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ\n+\n+struct object_id {\n+\tunsigned char hash[GIT_MAX_RAWSZ];\n+\tint algo;\t/* XXX requires 4-byte alignment */\n+};\n+\n+#define GET_OID_QUIETLY           01\n+#define GET_OID_COMMIT            02\n+#define GET_OID_COMMITTISH        04\n+#define GET_OID_TREE             010\n+#define GET_OID_TREEISH          020\n+#define GET_OID_BLOB             040\n+#define GET_OID_FOLLOW_SYMLINKS 0100\n+#define GET_OID_RECORD_PATH     0200\n+#define GET_OID_ONLY_TO_DIE    04000\n+#define GET_OID_REQUIRE_PATH  010000\n+#define GET_OID_HASH_ANY      020000\n+\n+#define GET_OID_DISAMBIGUATORS \\\n+\t(GET_OID_COMMIT | GET_OID_COMMITTISH | \\\n+\tGET_OID_TREE | GET_OID_TREEISH | \\\n+\tGET_OID_BLOB)\n+\n+enum get_oid_result {\n+\tFOUND = 0,\n+\tMISSING_OBJECT = -1, /* The requested object is missing */\n+\tSHORT_NAME_AMBIGUOUS = -2,\n+\t/* The following only apply when symlinks are followed */\n+\tDANGLING_SYMLINK = -4, /*\n+\t\t\t\t* The initial symlink is there, but\n+\t\t\t\t* (transitively) points to a missing\n+\t\t\t\t* in-tree file\n+\t\t\t\t*/\n+\tSYMLINK_LOOP = -5,\n+\tNOT_DIR = -6, /*\n+\t\t       * Somewhere along the symlink chain, a path is\n+\t\t       * requested which contains a file as a\n+\t\t       * non-final element.\n+\t\t       */\n+};\n \n #ifdef USE_THE_REPOSITORY_VARIABLE\n+# include \"repository.h\"\n # define the_hash_algo the_repository->hash_algo\n #endif\n \n+/* A suitably aligned type for stack allocations of hash contexts. */\n+union git_hash_ctx {\n+\tgit_SHA_CTX sha1;\n+\tgit_SHA256_CTX sha256;\n+};\n+typedef union git_hash_ctx git_hash_ctx;\n+\n+typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);\n+typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);\n+typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);\n+typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);\n+typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);\n+\n+struct git_hash_algo {\n+\t/*\n+\t * The name of the algorithm, as appears in the config file and in\n+\t * messages.\n+\t */\n+\tconst char *name;\n+\n+\t/* A four-byte version identifier, used in pack indices. */\n+\tuint32_t format_id;\n+\n+\t/* The length of the hash in binary. */\n+\tsize_t rawsz;\n+\n+\t/* The length of the hash in hex characters. */\n+\tsize_t hexsz;\n+\n+\t/* The block size of the hash. */\n+\tsize_t blksz;\n+\n+\t/* The hash initialization function. */\n+\tgit_hash_init_fn init_fn;\n+\n+\t/* The hash context cloning function. */\n+\tgit_hash_clone_fn clone_fn;\n+\n+\t/* The hash update function. */\n+\tgit_hash_update_fn update_fn;\n+\n+\t/* The hash finalization function. */\n+\tgit_hash_final_fn final_fn;\n+\n+\t/* The hash finalization function for object IDs. */\n+\tgit_hash_final_oid_fn final_oid_fn;\n+\n+\t/* The OID of the empty tree. */\n+\tconst struct object_id *empty_tree;\n+\n+\t/* The OID of the empty blob. */\n+\tconst struct object_id *empty_blob;\n+\n+\t/* The all-zeros OID. */\n+\tconst struct object_id *null_oid;\n+};\n+extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];\n+\n+/*\n+ * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if\n+ * the name doesn't match a known algorithm.\n+ */\n+int hash_algo_by_name(const char *name);\n+/* Identical, except based on the format ID. */\n+int hash_algo_by_id(uint32_t format_id);\n+/* Identical, except based on the length. */\n+int hash_algo_by_length(int len);\n+/* Identical, except for a pointer to struct git_hash_algo. */\n+static inline int hash_algo_by_ptr(const struct git_hash_algo *p)\n+{\n+\treturn p - hash_algos;\n+}\n+\n+const struct object_id *null_oid(void);\n+\n+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+{\n+\t/*\n+\t * Teach the compiler that there are only two possibilities of hash size\n+\t * here, so that it can optimize for this case as much as possible.\n+\t */\n+\tif (algop->rawsz == GIT_MAX_RAWSZ)\n+\t\treturn memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n+\treturn memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n+}\n+\n+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)\n+{\n+\t/*\n+\t * We write this here instead of deferring to hashcmp so that the\n+\t * compiler can properly inline it and avoid calling memcmp.\n+\t */\n+\tif (algop->rawsz == GIT_MAX_RAWSZ)\n+\t\treturn !memcmp(sha1, sha2, GIT_MAX_RAWSZ);\n+\treturn !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);\n+}\n+\n+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(sha_dst, sha_src, algop->rawsz);\n+}\n+\n+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)\n+{\n+\tmemset(hash, 0, algop->rawsz);\n+}\n+\n+static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n+{\n+\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n+}\n+\n+static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n+{\n+\tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\n+\tdst->algo = src->algo;\n+}\n+\n+static inline void oidread(struct object_id *oid, const unsigned char *hash,\n+\t\t\t   const struct git_hash_algo *algop)\n+{\n+\tmemcpy(oid->hash, hash, algop->rawsz);\n+\tif (algop->rawsz < GIT_MAX_RAWSZ)\n+\t\tmemset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline void oidclr(struct object_id *oid,\n+\t\t\t  const struct git_hash_algo *algop)\n+{\n+\tmemset(oid->hash, 0, GIT_MAX_RAWSZ);\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+static inline struct object_id *oiddup(const struct object_id *src)\n+{\n+\tstruct object_id *dst = xmalloc(sizeof(struct object_id));\n+\toidcpy(dst, src);\n+\treturn dst;\n+}\n+\n+static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)\n+{\n+\toid->algo = hash_algo_by_ptr(algop);\n+}\n+\n+/*\n+ * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code\n+ * for use in hash tables. Cryptographic hashes are supposed to have\n+ * uniform distribution, so in contrast to `memhash()`, this just copies\n+ * the first `sizeof(int)` bytes without shuffling any bits. Note that\n+ * the results will be different on big-endian and little-endian\n+ * platforms, so they should not be stored or transferred over the net.\n+ */\n+static inline unsigned int oidhash(const struct object_id *oid)\n+{\n+\t/*\n+\t * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on\n+\t * platforms that don't support unaligned reads.\n+\t */\n+\tunsigned int hash;\n+\tmemcpy(&hash, oid->hash, sizeof(hash));\n+\treturn hash;\n+}\n+\n+static inline int is_null_oid(const struct object_id *oid)\n+{\n+\tstatic const unsigned char null_hash[GIT_MAX_RAWSZ];\n+\treturn !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);\n+}\n+\n+const char *empty_tree_oid_hex(const struct git_hash_algo *algop);\n+\n+static inline int is_empty_blob_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_blob);\n+}\n+\n+static inline int is_empty_tree_oid(const struct object_id *oid,\n+\t\t\t\t    const struct git_hash_algo *algop)\n+{\n+\treturn oideq(oid, algop->empty_tree);\n+}\n+\n #endif\ndiff --git a/hex.h b/hex.h\nindex e0b83f776f..9809667f33 100644\n--- a/hex.h\n+++ b/hex.h\n@@ -1,7 +1,7 @@\n #ifndef HEX_H\n #define HEX_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hex-ll.h\"\n \n /*\ndiff --git a/loose.h b/loose.h\nindex 2c2957072c..28512306e5 100644\n--- a/loose.h\n+++ b/loose.h\n@@ -3,6 +3,8 @@\n \n #include \"khash.h\"\n \n+struct repository;\n+\n struct loose_object_map {\n \tkh_oid_map_t *to_compat;\n \tkh_oid_map_t *to_storage;\ndiff --git a/merge-ort.h b/merge-ort.h\nindex ce56ec1a78..a994c9a5fc 100644\n--- a/merge-ort.h\n+++ b/merge-ort.h\n@@ -2,7 +2,7 @@\n #define MERGE_ORT_H\n \n #include \"merge-recursive.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct commit;\n struct tree;\ndiff --git a/object-file-convert.c b/object-file-convert.c\nindex 958f61f094..3887d6d57b 100644\n--- a/object-file-convert.c\n+++ b/object-file-convert.c\n@@ -5,7 +5,7 @@\n #include \"strbuf.h\"\n #include \"hex.h\"\n #include \"repository.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hash.h\"\n #include \"object.h\"\n #include \"loose.h\"\ndiff --git a/object.h b/object.h\nindex 73b4ec3904..9fa42d51d9 100644\n--- a/object.h\n+++ b/object.h\n@@ -1,7 +1,7 @@\n #ifndef OBJECT_H\n #define OBJECT_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct buffer_slab;\n struct repository;\ndiff --git a/oidmap.h b/oidmap.h\nindex 05c673eb7c..fad412827a 100644\n--- a/oidmap.h\n+++ b/oidmap.h\n@@ -1,7 +1,7 @@\n #ifndef OIDMAP_H\n #define OIDMAP_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n \n /*\ndiff --git a/oidtree.h b/oidtree.h\nindex 55c83513fd..77898f510a 100644\n--- a/oidtree.h\n+++ b/oidtree.h\n@@ -2,7 +2,7 @@\n #define OIDTREE_H\n \n #include \"cbtree.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"mem-pool.h\"\n \n struct oidtree {\ndiff --git a/packfile.h b/packfile.h\nindex 28c8fd3e39..eb18ec15db 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -101,6 +101,8 @@ int close_pack_fd(struct packed_git *p);\n \n uint32_t get_pack_fanout(struct packed_git *p, uint32_t value);\n \n+struct raw_object_store;\n+\n unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);\n void close_pack_windows(struct packed_git *);\n void close_pack(struct packed_git *);\ndiff --git a/protocol-caps.c b/protocol-caps.c\nindex 75f4cbb0a7..fe8d1d5c63 100644\n--- a/protocol-caps.c\n+++ b/protocol-caps.c\n@@ -3,7 +3,7 @@\n #include \"gettext.h\"\n #include \"hex.h\"\n #include \"pkt-line.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hex.h\"\n #include \"object.h\"\n #include \"object-store-ll.h\"\ndiff --git a/read-cache-ll.h b/read-cache-ll.h\nindex 09414afd04..e0e39607ef 100644\n--- a/read-cache-ll.h\n+++ b/read-cache-ll.h\n@@ -1,7 +1,7 @@\n #ifndef READ_CACHE_LL_H\n #define READ_CACHE_LL_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"statinfo.h\"\n \ndiff --git a/refs/ref-cache.h b/refs/ref-cache.h\nindex 95c76e27c8..31ebe24f6c 100644\n--- a/refs/ref-cache.h\n+++ b/refs/ref-cache.h\n@@ -1,7 +1,7 @@\n #ifndef REFS_REF_CACHE_H\n #define REFS_REF_CACHE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct ref_dir;\n struct ref_store;\ndiff --git a/reftable/dump.c b/reftable/dump.c\nindex 41abbb8ecf..dd65d9e8bb 100644\n--- a/reftable/dump.c\n+++ b/reftable/dump.c\n@@ -7,7 +7,7 @@ license that can be found in the LICENSE file or at\n */\n \n #include \"git-compat-util.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n #include \"reftable-blocksource.h\"\n #include \"reftable-error.h\"\ndiff --git a/reftable/reftable-record.h b/reftable/reftable-record.h\nindex 2a2943cd13..ff486eb1f7 100644\n--- a/reftable/reftable-record.h\n+++ b/reftable/reftable-record.h\n@@ -9,7 +9,7 @@ license that can be found in the LICENSE file or at\n #ifndef REFTABLE_RECORD_H\n #define REFTABLE_RECORD_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include <stdint.h>\n \n /*\ndiff --git a/reftable/system.h b/reftable/system.h\nindex 5d8b6dede5..d0cabd5d17 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -15,7 +15,7 @@ license that can be found in the LICENSE file or at\n #include \"lockfile.h\"\n #include \"strbuf.h\"\n #include \"tempfile.h\"\n-#include \"hash-ll.h\" /* hash ID, sizes.*/\n+#include \"hash.h\" /* hash ID, sizes.*/\n #include \"dir.h\" /* remove_dir_recursively, for tests.*/\n \n int hash_size(uint32_t id);\ndiff --git a/remote.h b/remote.h\nindex e8c6655e42..7d04e1be1b 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -1,7 +1,7 @@\n #ifndef REMOTE_H\n #define REMOTE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"hashmap.h\"\n #include \"refspec.h\"\n \ndiff --git a/reset.h b/reset.h\nindex 10708d8ddc..a28f81829d 100644\n--- a/reset.h\n+++ b/reset.h\n@@ -1,7 +1,7 @@\n #ifndef RESET_H\n #define RESET_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"repository.h\"\n \n #define GIT_REFLOG_ACTION_ENVIRONMENT \"GIT_REFLOG_ACTION\"\ndiff --git a/resolve-undo.h b/resolve-undo.h\nindex f3f8462751..89a3227262 100644\n--- a/resolve-undo.h\n+++ b/resolve-undo.h\n@@ -6,7 +6,7 @@ struct index_state;\n struct pathspec;\n struct string_list;\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct resolve_undo_info {\n \tunsigned int mode[3];\ndiff --git a/serve.c b/serve.c\nindex 33608ea4d5..884cd84ca8 100644\n--- a/serve.c\n+++ b/serve.c\n@@ -3,7 +3,7 @@\n #include \"git-compat-util.h\"\n #include \"repository.h\"\n #include \"config.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"pkt-line.h\"\n #include \"version.h\"\n #include \"ls-refs.h\"\ndiff --git a/split-index.h b/split-index.h\nindex 15a29cd08c..1a153f47ba 100644\n--- a/split-index.h\n+++ b/split-index.h\n@@ -1,7 +1,7 @@\n #ifndef SPLIT_INDEX_H\n #define SPLIT_INDEX_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct index_state;\n struct strbuf;\ndiff --git a/t/helper/test-hash-speed.c b/t/helper/test-hash-speed.c\nindex b235da594f..7de822af51 100644\n--- a/t/helper/test-hash-speed.c\n+++ b/t/helper/test-hash-speed.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n #define NUM_SECONDS 3\n \ndiff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c\nindex dcb7f6c003..e60d000c03 100644\n--- a/t/helper/test-sha1.c\n+++ b/t/helper/test-sha1.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int cmd__sha1(int ac, const char **av)\n {\ndiff --git a/t/helper/test-sha256.c b/t/helper/test-sha256.c\nindex 08cf149001..2fb20438f3 100644\n--- a/t/helper/test-sha256.c\n+++ b/t/helper/test-sha256.c\n@@ -1,5 +1,5 @@\n #include \"test-tool.h\"\n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n int cmd__sha256(int ac, const char **av)\n {\ndiff --git a/t/unit-tests/lib-oid.h b/t/unit-tests/lib-oid.h\nindex bfde639190..8d2acca768 100644\n--- a/t/unit-tests/lib-oid.h\n+++ b/t/unit-tests/lib-oid.h\n@@ -1,7 +1,7 @@\n #ifndef LIB_OID_H\n #define LIB_OID_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n /*\n  * Convert arbitrary hex string to object_id.\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 46107772d1..9252481df3 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -8,6 +8,7 @@\n #include \"tree.h\"\n #include \"tree-walk.h\"\n #include \"environment.h\"\n+#include \"repository.h\"\n \n /*\n  * Some mode bits are also used internally for computations.\ndiff --git a/tree-walk.h b/tree-walk.h\nindex 0b1067fbc5..aaea689f9a 100644\n--- a/tree-walk.h\n+++ b/tree-walk.h\n@@ -1,7 +1,7 @@\n #ifndef TREE_WALK_H\n #define TREE_WALK_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n \n struct index_state;\n struct repository;\ndiff --git a/xdiff-interface.h b/xdiff-interface.h\nindex 38537169b7..1ed430b622 100644\n--- a/xdiff-interface.h\n+++ b/xdiff-interface.h\n@@ -1,7 +1,7 @@\n #ifndef XDIFF_INTERFACE_H\n #define XDIFF_INTERFACE_H\n \n-#include \"hash-ll.h\"\n+#include \"hash.h\"\n #include \"xdiff/xdiff.h\"\n \n /*\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497143","messageId":"30babd8a678ff0aed5a671afbaa7c1ddc062a650.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 12/20] http-fetch: don't crash when parsing packfile without a repo","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:37Z","receivedAt":"2024-06-14T06:50:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The git-http-fetch(1) command accepts a `--packfile=` option, which\nallows the user to specify that it shall fetch a specific packfile,\nonly. The parameter here is the hash of the packfile, which is specific\nto the object hash used by the repository. This requirement is implicit\nthough via our use of `parse_oid_hex()`, which internally uses\n`the_repository`.\n\nThe git-http-fetch(1) command allows for there to be no repository\nthough, which only exists such that we can show usage via the \"-h\"\noption. In that case though, starting with c8aed5e8da (repository: stop\nsetting SHA1 as the default object hash, 2024-05-07), `the_repository`\ndoes not have its object hash initialized anymore and thus we would\ncrash when trying to parse the object ID outside of a repository.\n\nFix this issue by dying immediately when we see a \"--packfile=\"\nparameter when outside a Git repository. This is not a functional\nregression as we would die later on with the same error anyway.\n\nAdd a test to detect the segfault. We use the \"nongit\" function to do\nso, which we need to allow-list in `test_must_fail ()`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n http-fetch.c               | 8 +++++++-\n t/t5550-http-fetch-dumb.sh | 6 ++++++\n t/test-lib-functions.sh    | 5 +++++\n 3 files changed, 18 insertions(+), 1 deletion(-)\n\ndiff --git a/http-fetch.c b/http-fetch.c\nindex bec94988bb..d460bb1837 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"git-compat-util.h\"\n #include \"config.h\"\n #include \"gettext.h\"\n@@ -127,8 +129,12 @@ int cmd_main(int argc, const char **argv)\n \t\t} else if (skip_prefix(argv[arg], \"--packfile=\", &p)) {\n \t\t\tconst char *end;\n \n+\t\t\tif (nongit)\n+\t\t\t\tdie(_(\"not a git repository\"));\n+\n \t\t\tpackfile = 1;\n-\t\t\tif (parse_oid_hex(p, &packfile_hash, &end) || *end)\n+\t\t\tif (parse_oid_hex_algop(p, &packfile_hash, &end,\n+\t\t\t\t\t\tthe_repository->hash_algo) || *end)\n \t\t\t\tdie(_(\"argument to --packfile must be a valid hash (got '%s')\"), p);\n \t\t} else if (skip_prefix(argv[arg], \"--index-pack-arg=\", &p)) {\n \t\t\tstrvec_push(&index_pack_args, p);\ndiff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh\nindex 5f16cbc58d..ea8e48f627 100755\n--- a/t/t5550-http-fetch-dumb.sh\n+++ b/t/t5550-http-fetch-dumb.sh\n@@ -25,6 +25,12 @@ test_expect_success 'setup repository' '\n \tgit commit -m two\n '\n \n+test_expect_success 'packfile without repository does not crash' '\n+\techo \"fatal: not a git repository\" >expect &&\n+\ttest_must_fail nongit git http-fetch --packfile=abc 2>err &&\n+\ttest_cmp expect err\n+'\n+\n setup_post_update_server_info_hook () {\n \ttest_hook --setup -C \"$1\" post-update <<-\\EOF &&\n \texec git update-server-info\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nindex 862d80c974..34bc7d7da4 100644\n--- a/t/test-lib-functions.sh\n+++ b/t/test-lib-functions.sh\n@@ -1096,6 +1096,11 @@ test_must_fail_acceptable () {\n \t\tdone\n \tfi\n \n+\tif test \"$1\" = \"nongit\"\n+\tthen\n+\t\tshift\n+\tfi\n+\n \tcase \"$1\" in\n \tgit|__git*|scalar|test-tool|test_terminal)\n \t\treturn 0\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497144","messageId":"fa41a85c7e13870439e2bc913343400e8254bda8.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 13/20] oidset: pass hash algorithm when parsing file","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:42Z","receivedAt":"2024-06-14T06:50:46Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `oidset_parse_file_carefully()` function implicitly depends on\n`the_repository` when parsing object IDs. Fix this by having callers\npass in the hash algorithm to use.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n builtin/blame.c | 1 +\n fsck.c          | 3 ++-\n oidset.c        | 8 +++++---\n oidset.h        | 4 +++-\n 4 files changed, 11 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex de89fff3f8..18f1a3cea0 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -852,6 +852,7 @@ static void build_ignorelist(struct blame_scoreboard *sb,\n \t\t\toidset_clear(&sb->ignore_list);\n \t\telse\n \t\t\toidset_parse_file_carefully(&sb->ignore_list, i->string,\n+\t\t\t\t\t\t    the_repository->hash_algo,\n \t\t\t\t\t\t    peel_to_commit_oid, sb);\n \t}\n \tfor_each_string_list_item(i, ignore_rev_list) {\ndiff --git a/fsck.c b/fsck.c\nindex 432996cbb6..304f4a17ec 100644\n--- a/fsck.c\n+++ b/fsck.c\n@@ -205,7 +205,8 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values)\n \t\tif (!strcmp(buf, \"skiplist\")) {\n \t\t\tif (equal == len)\n \t\t\t\tdie(\"skiplist requires a path\");\n-\t\t\toidset_parse_file(&options->skiplist, buf + equal + 1);\n+\t\t\toidset_parse_file(&options->skiplist, buf + equal + 1,\n+\t\t\t\t\t  the_repository->hash_algo);\n \t\t\tbuf += len + 1;\n \t\t\tcontinue;\n \t\t}\ndiff --git a/oidset.c b/oidset.c\nindex 91d1385910..8d36aef8dc 100644\n--- a/oidset.c\n+++ b/oidset.c\n@@ -48,12 +48,14 @@ void oidset_clear(struct oidset *set)\n \toidset_init(set, 0);\n }\n \n-void oidset_parse_file(struct oidset *set, const char *path)\n+void oidset_parse_file(struct oidset *set, const char *path,\n+\t\t       const struct git_hash_algo *algop)\n {\n-\toidset_parse_file_carefully(set, path, NULL, NULL);\n+\toidset_parse_file_carefully(set, path, algop, NULL, NULL);\n }\n \n void oidset_parse_file_carefully(struct oidset *set, const char *path,\n+\t\t\t\t const struct git_hash_algo *algop,\n \t\t\t\t oidset_parse_tweak_fn fn, void *cbdata)\n {\n \tFILE *fp;\n@@ -79,7 +81,7 @@ void oidset_parse_file_carefully(struct oidset *set, const char *path,\n \t\tif (!sb.len)\n \t\t\tcontinue;\n \n-\t\tif (parse_oid_hex(sb.buf, &oid, &p) || *p != '\\0')\n+\t\tif (parse_oid_hex_algop(sb.buf, &oid, &p, algop) || *p != '\\0')\n \t\t\tdie(\"invalid object name: %s\", sb.buf);\n \t\tif (fn && fn(&oid, cbdata))\n \t\t\tcontinue;\ndiff --git a/oidset.h b/oidset.h\nindex 262f4256d6..0106b6f278 100644\n--- a/oidset.h\n+++ b/oidset.h\n@@ -80,7 +80,8 @@ void oidset_clear(struct oidset *set);\n  * are allowed.  Leading whitespace and empty or white-space only lines are\n  * ignored.\n  */\n-void oidset_parse_file(struct oidset *set, const char *path);\n+void oidset_parse_file(struct oidset *set, const char *path,\n+\t\t       const struct git_hash_algo *algop);\n \n /*\n  * Similar to the above, but with a callback which can (1) return non-zero to\n@@ -89,6 +90,7 @@ void oidset_parse_file(struct oidset *set, const char *path);\n  */\n typedef int (*oidset_parse_tweak_fn)(struct object_id *, void *);\n void oidset_parse_file_carefully(struct oidset *set, const char *path,\n+\t\t\t\t const struct git_hash_algo *algop,\n \t\t\t\t oidset_parse_tweak_fn fn, void *cbdata);\n \n struct oidset_iter {\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497145","messageId":"0b42208e2f675d6f7f24b842f42b16bf38e1138e.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 14/20] protocol-caps: use hash algorithm from passed-in repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:47Z","receivedAt":"2024-06-14T06:50:51Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In `send_info()`, we pass in a repository but then use `get_oid_hex()`\nto parse passed-in object IDs, which implicitly uses `the_repository`.\nFix this by using the hash algorithm from the passed-in repository\ninstead.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n protocol-caps.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/protocol-caps.c b/protocol-caps.c\nindex fe8d1d5c63..855f279c2f 100644\n--- a/protocol-caps.c\n+++ b/protocol-caps.c\n@@ -7,6 +7,7 @@\n #include \"hex.h\"\n #include \"object.h\"\n #include \"object-store-ll.h\"\n+#include \"repository.h\"\n #include \"string-list.h\"\n #include \"strbuf.h\"\n \n@@ -52,7 +53,7 @@ static void send_info(struct repository *r, struct packet_writer *writer,\n \t\tstruct object_id oid;\n \t\tunsigned long object_size;\n \n-\t\tif (get_oid_hex(oid_str, &oid) < 0) {\n+\t\tif (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {\n \t\t\tpacket_writer_error(\n \t\t\t\twriter,\n \t\t\t\t\"object-info: protocol error, expected to get oid, not '%s'\",\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497146","messageId":"e1f4bffea1fde0f34d800d40508a246c5462e41e.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 15/20] replace-object: use hash algorithm from passed-in repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:51Z","receivedAt":"2024-06-14T06:50:56Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In `register_replace_ref()`, we pass in a repository but then use\n`get_oid_hex()` to parse passed-in object IDs, which implicitly uses\n`the_repository`. Fix this by using the hash algorithm from the\npassed-in repository instead.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n replace-object.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/replace-object.c b/replace-object.c\nindex 73f5acbcd9..59252d565e 100644\n--- a/replace-object.c\n+++ b/replace-object.c\n@@ -20,7 +20,7 @@ static int register_replace_ref(const char *refname,\n \tconst char *hash = slash ? slash + 1 : refname;\n \tstruct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));\n \n-\tif (get_oid_hex(hash, &repl_obj->original.oid)) {\n+\tif (get_oid_hex_algop(hash, &repl_obj->original.oid, r->hash_algo)) {\n \t\tfree(repl_obj);\n \t\twarning(_(\"bad replace ref name: %s\"), refname);\n \t\treturn 0;\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497147","messageId":"5b8f981ea276f1f9d1f01c21bb1c8d02fa12e397.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 16/20] compat/fsmonitor: fix socket path in networked SHA256 repos","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:50:56Z","receivedAt":"2024-06-14T06:51:00Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The IPC socket used by the fsmonitor on Darwin is usually contained in\nthe Git repository itself. When the repository is hosted on a networked\nfilesystem though, we instead create the socket path in the user's home\ndirectory or the socket directory. In that case, we derive the path by\nhashing the repository path.\n\nBut while we always use SHA1 to hash the repository path, we then end up\nusing `hash_to_hex()` to append the computed hash to the socket path.\nThis is wrong because `hash_to_hex()` uses the hash algorithm configured\nin `the_repository`, which may not be SHA1. The consequence is that we\nmay append uninitialized bytes to the path when operating in a SHA256\nrepository.\n\nFix this bug by using `hash_to_hex_algop()` with SHA1.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n compat/fsmonitor/fsm-ipc-darwin.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/compat/fsmonitor/fsm-ipc-darwin.c b/compat/fsmonitor/fsm-ipc-darwin.c\nindex 6f3a95410c..52f4f29720 100644\n--- a/compat/fsmonitor/fsm-ipc-darwin.c\n+++ b/compat/fsmonitor/fsm-ipc-darwin.c\n@@ -17,7 +17,7 @@ const char *fsmonitor_ipc__get_path(struct repository *r)\n \tgit_SHA_CTX sha1ctx;\n \tchar *sock_dir = NULL;\n \tstruct strbuf ipc_file = STRBUF_INIT;\n-\tunsigned char hash[GIT_MAX_RAWSZ];\n+\tunsigned char hash[GIT_SHA1_RAWSZ];\n \n \tif (!r)\n \t\tBUG(\"No repository passed into fsmonitor_ipc__get_path\");\n@@ -41,9 +41,10 @@ const char *fsmonitor_ipc__get_path(struct repository *r)\n \t/* Create the socket file in either socketDir or $HOME */\n \tif (sock_dir && *sock_dir) {\n \t\tstrbuf_addf(&ipc_file, \"%s/.git-fsmonitor-%s\",\n-\t\t\t\t\tsock_dir, hash_to_hex(hash));\n+\t\t\t    sock_dir, hash_to_hex_algop(hash, &hash_algos[GIT_HASH_SHA1]));\n \t} else {\n-\t\tstrbuf_addf(&ipc_file, \"~/.git-fsmonitor-%s\", hash_to_hex(hash));\n+\t\tstrbuf_addf(&ipc_file, \"~/.git-fsmonitor-%s\",\n+\t\t\t    hash_to_hex_algop(hash, &hash_algos[GIT_HASH_SHA1]));\n \t}\n \tfree(sock_dir);\n \n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497148","messageId":"ad83b17ad0d01beec98ee76bf36857d416ea6e21.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 17/20] t/helper: use correct object hash in partial-clone helper","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:51:00Z","receivedAt":"2024-06-14T06:51:05Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The `object_info()` function of the partial-clone helper is responsible\nfor checking the object ID of a repository other than `the_repository`.\nWe use `parse_oid_hex()` in this function though, which means that we\nstill depend on `the_repository->hash_algo`.\n\nFix this by using the object hash of the function-local repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-partial-clone.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c\nindex 910a128614..0ead529167 100644\n--- a/t/helper/test-partial-clone.c\n+++ b/t/helper/test-partial-clone.c\n@@ -21,7 +21,7 @@ static void object_info(const char *gitdir, const char *oid_hex)\n \n \tif (repo_init(&r, gitdir, NULL))\n \t\tdie(\"could not init repo\");\n-\tif (parse_oid_hex(oid_hex, &oid, &p))\n+\tif (parse_oid_hex_algop(oid_hex, &oid, &p, r.hash_algo))\n \t\tdie(\"could not parse oid\");\n \tif (oid_object_info_extended(&r, &oid, &oi, 0))\n \t\tdie(\"could not obtain object info\");\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497149","messageId":"a488363bcb22dd1be4e1d8f89de8acc4a95e2f6c.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 18/20] t/helper: fix segfault in \"oid-array\" command without repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:51:05Z","receivedAt":"2024-06-14T06:51:09Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"oid-array\" test helper can supposedly work without a Git\nrepository, but will in fact crash because `the_repository->hash_algo`\nis not initialized. This is because `oid_pos()`, which is used by\n`oid_array_lookup()`, depends on `the_hash_algo->rawsz`.\n\nIdeally, we'd adapt `oid_pos()` to not depend on `the_hash_algo`\nanymore. That is a bigger untertaking though, so instead we fall back to\nSHA1 when there is no repository.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-oid-array.c |  4 ++++\n t/t0064-oid-array.sh      | 18 ++++++++++++++++++\n 2 files changed, 22 insertions(+)\n\ndiff --git a/t/helper/test-oid-array.c b/t/helper/test-oid-array.c\nindex aafe398ef0..076b849cbf 100644\n--- a/t/helper/test-oid-array.c\n+++ b/t/helper/test-oid-array.c\n@@ -1,3 +1,5 @@\n+#define USE_THE_REPOSITORY_VARIABLE\n+\n #include \"test-tool.h\"\n #include \"hex.h\"\n #include \"oid-array.h\"\n@@ -17,6 +19,8 @@ int cmd__oid_array(int argc UNUSED, const char **argv UNUSED)\n \tint nongit_ok;\n \n \tsetup_git_directory_gently(&nongit_ok);\n+\tif (nongit_ok)\n+\t\trepo_set_hash_algo(the_repository, GIT_HASH_SHA1);\n \n \twhile (strbuf_getline(&line, stdin) != EOF) {\n \t\tconst char *arg;\ndiff --git a/t/t0064-oid-array.sh b/t/t0064-oid-array.sh\nindex 88c89e8f48..de74b692d0 100755\n--- a/t/t0064-oid-array.sh\n+++ b/t/t0064-oid-array.sh\n@@ -15,6 +15,24 @@ echoid () {\n \tdone\n }\n \n+test_expect_success 'without repository' '\n+\tcat >expect <<-EOF &&\n+\t4444444444444444444444444444444444444444\n+\t5555555555555555555555555555555555555555\n+\t8888888888888888888888888888888888888888\n+\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n+\tEOF\n+\tcat >input <<-EOF &&\n+\tappend 4444444444444444444444444444444444444444\n+\tappend 5555555555555555555555555555555555555555\n+\tappend 8888888888888888888888888888888888888888\n+\tappend aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n+\tfor_each_unique\n+\tEOF\n+\tnongit test-tool oid-array <input >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'ordered enumeration' '\n \techoid \"\" 44 55 88 aa >expect &&\n \t{\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497150","messageId":"5de7a01af54267fa65e6b3269abe80b1c5301919.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 19/20] t/helper: remove dependency on `the_repository` in \"proc-receive\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:51:10Z","receivedAt":"2024-06-14T06:51:15Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The \"proc-receive\" test helper implicitly relies on `the_repository` via\n`parse_oid_hex()`. This isn't necessary though, and in fact the whole\ncommand does not depend on `the_repository` at all.\n\nStop setting up `the_repository` and use `parse_oid_hex_any()` to parse\nobject IDs.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/helper/test-proc-receive.c | 9 +++------\n 1 file changed, 3 insertions(+), 6 deletions(-)\n\ndiff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c\nindex f30022d222..29361c7aab 100644\n--- a/t/helper/test-proc-receive.c\n+++ b/t/helper/test-proc-receive.c\n@@ -3,8 +3,8 @@\n #include \"hex.h\"\n #include \"parse-options.h\"\n #include \"pkt-line.h\"\n-#include \"setup.h\"\n #include \"sigchain.h\"\n+#include \"string-list.h\"\n \n static const char *proc_receive_usage[] = {\n \t\"test-tool proc-receive [<options>]\",\n@@ -92,9 +92,9 @@ static void proc_receive_read_commands(struct packet_reader *reader,\n \t\tif (die_read_commands)\n \t\t\tdie(\"die with the --die-read-commands option\");\n \n-\t\tif (parse_oid_hex(reader->line, &old_oid, &p) ||\n+\t\tif (parse_oid_hex_any(reader->line, &old_oid, &p) == GIT_HASH_UNKNOWN ||\n \t\t    *p++ != ' ' ||\n-\t\t    parse_oid_hex(p, &new_oid, &p) ||\n+\t\t    parse_oid_hex_any(p, &new_oid, &p) == GIT_HASH_UNKNOWN ||\n \t\t    *p++ != ' ')\n \t\t\tdie(\"protocol error: expected 'old new ref', got '%s'\",\n \t\t\t    reader->line);\n@@ -128,7 +128,6 @@ static void proc_receive_read_push_options(struct packet_reader *reader,\n \n int cmd__proc_receive(int argc, const char **argv)\n {\n-\tint nongit_ok = 0;\n \tstruct packet_reader reader;\n \tstruct command *commands = NULL;\n \tstruct string_list push_options = STRING_LIST_INIT_DUP;\n@@ -154,8 +153,6 @@ int cmd__proc_receive(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n-\tsetup_git_directory_gently(&nongit_ok);\n-\n \targc = parse_options(argc, argv, \"test-tools\", options, proc_receive_usage, 0);\n \tif (argc > 0)\n \t\tusage_msg_opt(\"Too many arguments.\", proc_receive_usage, options);\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497151","messageId":"436ffc05701845e1e3bb19ea46d017d5b9b4114f.1718347699.git.ps@pks.im","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"[PATCH v3 20/20] hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE`","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-14T06:51:14Z","receivedAt":"2024-06-14T06:51:19Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Guard declarations of functions that implicitly use `the_repository`\nwith `USE_THE_REPOSITORY_VARIABLE` such that callers don't accidentally\nrely on that global variable.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n hex.h | 26 ++++++++++++++++----------\n 1 file changed, 16 insertions(+), 10 deletions(-)\n\ndiff --git a/hex.h b/hex.h\nindex 9809667f33..e9ccb54065 100644\n--- a/hex.h\n+++ b/hex.h\n@@ -13,10 +13,6 @@\n  * input, so it is safe to pass this function an arbitrary\n  * null-terminated string.\n  */\n-int get_hash_hex(const char *hex, unsigned char *hash);\n-int get_oid_hex(const char *hex, struct object_id *oid);\n-\n-/* Like get_oid_hex, but for an arbitrary hash algorithm. */\n int get_oid_hex_algop(const char *hex, struct object_id *oid, const struct git_hash_algo *algop);\n \n /*\n@@ -35,7 +31,6 @@ int get_oid_hex_algop(const char *hex, struct object_id *oid, const struct git_h\n char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash, const struct git_hash_algo *);\n char *oid_to_hex_r(char *out, const struct object_id *oid);\n char *hash_to_hex_algop(const unsigned char *hash, const struct git_hash_algo *);\t/* static buffer result! */\n-char *hash_to_hex(const unsigned char *hash);\t\t\t\t\t\t/* same static buffer */\n char *oid_to_hex(const struct object_id *oid);\t\t\t\t\t\t/* same static buffer */\n \n /*\n@@ -45,13 +40,9 @@ char *oid_to_hex(const struct object_id *oid);\t\t\t\t\t\t/* same static buffer */\n  * other invalid character.  end is only updated on success; otherwise, it is\n  * unmodified.\n  */\n-int parse_oid_hex(const char *hex, struct object_id *oid, const char **end);\n-\n-/* Like parse_oid_hex, but for an arbitrary hash algorithm. */\n int parse_oid_hex_algop(const char *hex, struct object_id *oid, const char **end,\n \t\t\tconst struct git_hash_algo *algo);\n \n-\n /*\n  * These functions work like get_oid_hex and parse_oid_hex, but they will parse\n  * a hex value for any algorithm. The algorithm is detected based on the length\n@@ -61,4 +52,19 @@ int parse_oid_hex_algop(const char *hex, struct object_id *oid, const char **end\n int get_oid_hex_any(const char *hex, struct object_id *oid);\n int parse_oid_hex_any(const char *hex, struct object_id *oid, const char **end);\n \n-#endif\n+#ifdef USE_THE_REPOSITORY_VARIABLE\n+\n+/* Like get_oid_hex_algop, but for `the_hash_algo`. */\n+int get_hash_hex(const char *hex, unsigned char *hash);\n+int get_oid_hex(const char *hex, struct object_id *oid);\n+\n+/* Like parse_oid_hex_algop, but uses `the_hash_algo`. */\n+int parse_oid_hex(const char *hex, struct object_id *oid, const char **end);\n+\n+/*\n+ * Same as `hash_to_hex_algop()`, but uses `the_hash_algo`.\n+ */\n+char *hash_to_hex(const unsigned char *hash);\n+\n+#endif /* USE_THE_REPOSITORY_VARIABLE */\n+#endif /* HEX_H */\n-- \n2.45.2.457.g8d94cfb545.dirty\n\n"},{"id":"497176","messageId":"xmqq5xubikp5.fsf@gitster.g","threadId":"61621","inReplyTo":"ZmvVBwLEb0qofY2m@tanuki","subject":"Re: [PATCH v2 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-14T15:54:30Z","receivedAt":"2024-06-14T15:54:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n>> > But that does beg the question - why is repository.c not\n>> > defining the USE_THE_REPOSITORY_VARIABLE?\n>> \n>> I think the goal of the series is to eventually get to the point\n>> where nobody uses the_repository variable.  If repository.c, which\n>> consists of a set of service routines that work on a repository\n>> instance, defined it, showing willingness to implicitly rely on\n>> the_repository through things like get_oid_hex() (which would rely\n>> on the_repository->hash_algo), that would go the opposite direction,\n>> so everything, other than the definition of the_repository variable\n>> itself that allows other files that still do rely implicitly on the\n>> variable to link with it, in repository.c would actively want to\n>> refuse to use services only available to those who define USE_THE_*\n>> macro.\n>\n> Exactly, that's why it doesn't declare `USE_THE_REPOSITORY_VARIABLE`.\n> The macro doesn't only guard use of `the_repository`, but does also\n> guards other functions that implicitly relies on it, and we do not want\n> to use these in \"repository.c\". So even though the added `extern`\n> declaration is somewhat ugly, I think it is preferable over defining the\n> macro.\n\nSlightly off-topic, but in retrospect, the approach of marking \"this\nfile is done\" taken by the very initial version of the \"no more\nimplicit access to the_index\" series may have been easier to grok\neasier to grok for reviewers casually looking at it from the\nsideline, than marking \"this file still needs work\".  When we\ngradually deprecated the convenience API that implicitly access\nthe_index instance, we marked with NO_THE_INDEX_COMPATIBILITY_MACROS\nthe files that no longer require it (in other words, we are done\nwith the file wrt the transition).  We later flipped the polarity\nand gave USE_THE_INDEX_COMPATIBILITY_MACROS to those that are not\nmarked with NO_THE_INDEX_COMPATIBILITY_MACROS as we progressed and\nthe source files that still used the convenience API has become\nminorities.\n\nAnyway, I think now people understood what this series aims to\nachieve and how it does so, hopefully.\n\nThanks.\n\n"},{"id":"497238","messageId":"CAOLa=ZS491t7n_b6kNoOg=9ALSe9PWO79DxNnfxa4RFgGtdYAw@mail.gmail.com","threadId":"61621","inReplyTo":"91eb94bc0b91c8d1bda7f8fd776d94113acf8cd3.1718347699.git.ps@pks.im","subject":"Re: [PATCH v3 05/20] hash: convert `oidcmp()` and `oideq()` to compare whole hash","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-06-17T09:18:16Z","receivedAt":"2024-06-17T09:18:18Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> With the preceding commit, the hash array of object IDs is now fully\n> zero-padded even when the hash algorithm's output is smaller than the\n> array length. With that, we can now adapt both `oidcmp()` and `oideq()`\n> to unconditionally memcmp(3P) the whole array instead of depending on\n> the hash size.\n>\n> While it may feel inefficient to compare unused bytes for e.g. SHA-1, in\n> practice the compiler should now be able to produce code that is better\n> optimized both because we have no branch anymore, but also because the\n> size to compare is now known at compile time. Goldbolt spits out the\n> following assembly on an x86_64 platform with GCC 14.1 for the old and\n> new implementations of `oidcmp()`:\n>\n>     oidcmp_old:\n>             movsx   rax, DWORD PTR [rdi+32]\n>             test    eax, eax\n>             jne     .L2\n>             mov     rax, QWORD PTR the_repository[rip]\n>             cmp     QWORD PTR [rax+16], 32\n>             je      .L6\n>     .L4:\n>             mov     edx, 20\n>             jmp     memcmp\n>     .L2:\n>             lea     rdx, [rax+rax*2]\n>             lea     rax, [rax+rdx*4]\n>             lea     rax, hash_algos[0+rax*8]\n>             cmp     QWORD PTR [rax+16], 32\n>             jne     .L4\n>     .L6:\n>             mov     edx, 32\n>             jmp     memcmp\n>\n>     oidcmp_new:\n>             mov     edx, 32\n>             jmp     memcmp\n>\n> The new implementation gets ridi of all the branches and effectively\n\ns/ridi/rid\n\n> only ends setting up `edx` for `memcmp()` and then calling it.\n>\n> And for `oideq()`:\n>\n>     oideq_old:\n>             movsx   rcx, DWORD PTR [rdi+32]\n>             mov     rax, rdi\n>             mov     rdx, rsi\n>             test    ecx, ecx\n>             jne     .L2\n>             mov     rcx, QWORD PTR the_repository[rip]\n>             cmp     QWORD PTR [rcx+16], 32\n>             mov     rcx, QWORD PTR [rax]\n>             je      .L12\n>     .L4:\n>             mov     rsi, QWORD PTR [rax+8]\n>             xor     rcx, QWORD PTR [rdx]\n>             xor     rsi, QWORD PTR [rdx+8]\n>             or      rcx, rsi\n>             je      .L13\n>     .L8:\n>             mov     eax, 1\n>             test    eax, eax\n>             sete    al\n>             movzx   eax, al\n>             ret\n>     .L2:\n>             lea     rsi, [rcx+rcx*2]\n>             lea     rcx, [rcx+rsi*4]\n>             lea     rcx, hash_algos[0+rcx*8]\n>             cmp     QWORD PTR [rcx+16], 32\n>             mov     rcx, QWORD PTR [rax]\n>             jne     .L4\n>     .L12:\n>             mov     rsi, QWORD PTR [rax+8]\n>             xor     rcx, QWORD PTR [rdx]\n>             xor     rsi, QWORD PTR [rdx+8]\n>             or      rcx, rsi\n>             jne     .L8\n>             mov     rcx, QWORD PTR [rax+16]\n>             mov     rax, QWORD PTR [rax+24]\n>             xor     rcx, QWORD PTR [rdx+16]\n>             xor     rax, QWORD PTR [rdx+24]\n>             or      rcx, rax\n>             jne     .L8\n>             xor     eax, eax\n>     .L14:\n>             test    eax, eax\n>             sete    al\n>             movzx   eax, al\n>             ret\n>     .L13:\n>             mov     edi, DWORD PTR [rdx+16]\n>             cmp     DWORD PTR [rax+16], edi\n>             jne     .L8\n>             xor     eax, eax\n>             jmp     .L14\n>\n>     oideq_new:\n>             mov     rax, QWORD PTR [rdi]\n>             mov     rdx, QWORD PTR [rdi+8]\n>             xor     rax, QWORD PTR [rsi]\n>             xor     rdx, QWORD PTR [rsi+8]\n>             or      rax, rdx\n>             je      .L5\n>     .L2:\n>             mov     eax, 1\n>             xor     eax, 1\n>             ret\n>     .L5:\n>             mov     rax, QWORD PTR [rdi+16]\n>             mov     rdx, QWORD PTR [rdi+24]\n>             xor     rax, QWORD PTR [rsi+16]\n>             xor     rdx, QWORD PTR [rsi+24]\n>             or      rax, rdx\n>             jne     .L2\n>             xor     eax, eax\n>             xor     eax, 1\n>             ret\n>\n> Interestingly, the compiler decides to split the comparisons into two so\n> that it first compares the lower half of the object ID for equality and\n> then the upper half. If the first check shows a difference, then we\n> wouldn't even end up comparing the second half.\n>\n> In both cases, the new generated code is significantly shorter and has\n> way less branches. While I didn't benchmark the change, I'd be surprised\n> if the new code was slower.\n>\n\nThis was nice to read, thanks for adding the ASM here.\n\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  hash-ll.h | 10 ++++++++++\n>  hash.h    | 20 --------------------\n>  2 files changed, 10 insertions(+), 20 deletions(-)\n>\n> diff --git a/hash-ll.h b/hash-ll.h\n> index b72f84f4ae..b04fe12aef 100644\n> --- a/hash-ll.h\n> +++ b/hash-ll.h\n> @@ -278,6 +278,16 @@ static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algo\n>  \tmemset(hash, 0, algop->rawsz);\n>  }\n>\n> +static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n> +{\n> +\treturn memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n> +}\n> +\n> +static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n> +{\n> +\treturn !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);\n> +}\n> +\n>  static inline void oidcpy(struct object_id *dst, const struct object_id *src)\n>  {\n>  \tmemcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);\n> diff --git a/hash.h b/hash.h\n> index e43e3d8b5a..ddc2e5ca47 100644\n> --- a/hash.h\n> +++ b/hash.h\n> @@ -6,26 +6,6 @@\n>\n>  #define the_hash_algo the_repository->hash_algo\n>\n> -static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)\n> -{\n> -\tconst struct git_hash_algo *algop;\n> -\tif (!oid1->algo)\n> -\t\talgop = the_hash_algo;\n> -\telse\n> -\t\talgop = &hash_algos[oid1->algo];\n> -\treturn hashcmp(oid1->hash, oid2->hash, algop);\n> -}\n> -\n> -static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)\n> -{\n> -\tconst struct git_hash_algo *algop;\n> -\tif (!oid1->algo)\n> -\t\talgop = the_hash_algo;\n> -\telse\n> -\t\talgop = &hash_algos[oid1->algo];\n> -\treturn hasheq(oid1->hash, oid2->hash, algop);\n> -}\n> -\n>  static inline int is_null_oid(const struct object_id *oid)\n>  {\n>  \treturn oideq(oid, null_oid());\n> --\n> 2.45.2.457.g8d94cfb545.dirty\n"},{"id":"497239","messageId":"CAOLa=ZTq+sQAtSiQm9xmdLyn=T=u8Ck0oXEBFLnJvH+54O+AHA@mail.gmail.com","threadId":"61621","inReplyTo":"7e023a335f500658b09a0037aee48eff06c668f8.1718347699.git.ps@pks.im","subject":"Re: [PATCH v3 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-06-17T09:30:31Z","receivedAt":"2024-06-17T09:30:33Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Use of the `the_repository` variable is deprecated nowadays, and we\n> slowly but steadily convert the codebase to not use it anymore. Instead,\n> callers should be passing down the repository to work on via parameters.\n>\n> It is hard though to prove that a given code unit does not use this\n> variable anymore. The most trivial case, merely demonstrating that there\n> is no direct use of `the_repository`, is already a bit of a pain during\n> code reviews as the reviewer needs to manually verify claims made by the\n> patch author. The bigger problem though is that we have many interfaces\n> that implicitly rely on `the_repository`.\n>\n> Introduce a new `USE_THE_REPOSITORY_VARIABLE` macro that allows code\n> units to opt into usage of `the_repository`. The intent of this macro is\n> to demonstrate that a certain code unit does not use this variable\n> anymore, and to keep it from new dependencies on it in future changes,\n> be it explicit or implicit\n>\n> For now, the macro only guards `the_repository` itself as well as\n> `the_hash_algo`. There are many more known interfaces where we have an\n> implicit dependency on `the_repository`, but those are not guarded at\n> the current point in time. Over time though, we should start to add\n> guards as required (or even better, just remove them).\n>\n> Define the macro as required in our code units. As expected, most of our\n> code still relies on the global variable. Nearly all of our builtins\n> rely on the variable as there is no way yet to pass `the_repository` to\n> their entry point. For now, declare the macro in \"biultin.h\" to keep the\n\ns/biultin.h/builtin.h\n\n[snip]\n\n> diff --git a/hash.h b/hash.h\n> index 39a0164be3..cb85d26a2f 100644\n> --- a/hash.h\n> +++ b/hash.h\n> @@ -4,6 +4,8 @@\n>  #include \"hash-ll.h\"\n>  #include \"repository.h\"\n>\n> -#define the_hash_algo the_repository->hash_algo\n> +#ifdef USE_THE_REPOSITORY_VARIABLE\n> +# define the_hash_algo the_repository->hash_algo\n\ns/# define/#define/\n"},{"id":"497267","messageId":"ZnEYNzLue3OIK-Ul@framework","threadId":"61621","inReplyTo":"CAOLa=ZTq+sQAtSiQm9xmdLyn=T=u8Ck0oXEBFLnJvH+54O+AHA@mail.gmail.com","subject":"Re: [PATCH v3 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-06-18T05:16:39Z","receivedAt":"2024-06-18T05:16:47Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Jun 17, 2024 at 05:30:31AM -0400, Karthik Nayak wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> > diff --git a/hash.h b/hash.h\n> > index 39a0164be3..cb85d26a2f 100644\n> > --- a/hash.h\n> > +++ b/hash.h\n> > @@ -4,6 +4,8 @@\n> >  #include \"hash-ll.h\"\n> >  #include \"repository.h\"\n> >\n> > -#define the_hash_algo the_repository->hash_algo\n> > +#ifdef USE_THE_REPOSITORY_VARIABLE\n> > +# define the_hash_algo the_repository->hash_algo\n> \n> s/# define/#define/\n\nThis is in fact intentional. We aren't strictly following this in our\ncodebase, but when nesting preprocessor macros into ifdefs then we often\nindent the inner macros with spaces.\n\nPatrick\n"},{"id":"497282","messageId":"CAOLa=ZRA6QDojbvP6btOGX5q1Pa0DivBZA_J1gojF1gJu9aENw@mail.gmail.com","threadId":"61621","inReplyTo":"ZnEYNzLue3OIK-Ul@framework","subject":"Re: [PATCH v3 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-06-18T09:25:33Z","receivedAt":"2024-06-18T09:25:35Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> On Mon, Jun 17, 2024 at 05:30:31AM -0400, Karthik Nayak wrote:\n>> Patrick Steinhardt <ps@pks.im> writes:\n>> > diff --git a/hash.h b/hash.h\n>> > index 39a0164be3..cb85d26a2f 100644\n>> > --- a/hash.h\n>> > +++ b/hash.h\n>> > @@ -4,6 +4,8 @@\n>> >  #include \"hash-ll.h\"\n>> >  #include \"repository.h\"\n>> >\n>> > -#define the_hash_algo the_repository->hash_algo\n>> > +#ifdef USE_THE_REPOSITORY_VARIABLE\n>> > +# define the_hash_algo the_repository->hash_algo\n>>\n>> s/# define/#define/\n>\n> This is in fact intentional. We aren't strictly following this in our\n> codebase, but when nesting preprocessor macros into ifdefs then we often\n> indent the inner macros with spaces.\n>\n> Patrick\n\nThat's something I didn't know. Thanks.\n"},{"id":"497283","messageId":"b2a783cc-ad34-4647-a388-33f75b3122bd@gmail.com","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"Re: [PATCH v3 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-06-18T09:56:44Z","receivedAt":"2024-06-18T09:56:46Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Patrick\n\nOn 14/06/2024 07:49, Patrick Steinhardt wrote:\n> Changes compared to v2:\n> \n>    - Note in a commit message that we aim to have a faithful conversion\n>      when introducing a `struct git_hash_algo` parameter to functions. So\n>      even in case the calling context has a `struct git_hash_algo`\n>      available via a local repository, we still use `the_repository` such\n>      that there cannot be a change in behaviour here. Fixing those sites\n>      will be left for a future patch series such that we can avoid any\n>      kind of regressions caused by this comparatively large refactoring.\n>      I also adapted some conversions to fully follow through with this\n>      intent.\n\nThanks for clarifying that in the commit message of Patch 2.\n\nBest Wishes\n\nPhillip\n\n"},{"id":"497292","messageId":"xmqqwmmm1bw6.fsf@gitster.g","threadId":"61621","inReplyTo":"CAOLa=ZRA6QDojbvP6btOGX5q1Pa0DivBZA_J1gojF1gJu9aENw@mail.gmail.com","subject":"Re: [PATCH v3 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-18T15:58:01Z","receivedAt":"2024-06-18T15:58:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Karthik Nayak <karthik.188@gmail.com> writes:\n\n>>> s/# define/#define/\n>>\n>> This is in fact intentional. We aren't strictly following this in our\n>> codebase, but when nesting preprocessor macros into ifdefs then we often\n>> indent the inner macros with spaces.\n>>\n>> Patrick\n>\n> That's something I didn't know. Thanks.\n\nUnlike borrowed sources in compat/, in our codebase, such\nindentation is minority.  IOW \"often indent\" -> \"sometimes indent\".\n\nA quick look at an early part of git-compat-util.h would show that\neven within a single file we are not consistent at all.\n\n#if __STDC_VERSION__ - 0 < 199901L\n#error \"Required C99 support is in a test phase.  Please see git-compat-util.h for more details.\"\n#endif\n\n#ifdef USE_MSVC_CRTDBG\n#include <stdlib.h>\n#include <crtdbg.h>\n#endif\n\n#define _FILE_OFFSET_BITS 64\n\n#if defined(__GNUC__) && defined(__GNUC_MINOR__)\n# define GIT_GNUC_PREREQ(maj, min) \\\n\t((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))\n#else\n #define GIT_GNUC_PREREQ(maj, min) 0\n#endif\n\n#ifndef FLEX_ARRAY\n#if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580)\n#elif defined(__GNUC__)\n# if (__GNUC__ >= 3)\n#  define FLEX_ARRAY /* empty */\n# else\n#  define FLEX_ARRAY 0 /* older GNU extension */\n# endif\n#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n# define FLEX_ARRAY /* empty */\n#endif\n...\n\n\nWe may want to eventually fix this, but we need to decide what the\ndesirable layout is.  I am not sure if the indented version is\neasier to read and maintain, but one thing that is sure is that a\nmixed mess is harder than either.  In the above excerpt, you cannot\ntell if I quoted everything related to FLEX_ARRAY (in other words,\nif \"#ifndef FLEX_ARRAY\" is already closed in the excerpt) without\ncarefully looking.\n\n"},{"id":"497293","messageId":"xmqqjzim197j.fsf@gitster.g","threadId":"61621","inReplyTo":"xmqqwmmm1bw6.fsf@gitster.g","subject":"Re: [PATCH v3 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-18T16:56:00Z","receivedAt":"2024-06-18T16:56:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> We may want to eventually fix this, but we need to decide what the\n> desirable layout is.  I am not sure if the indented version is\n> easier to read and maintain, but one thing that is sure is that a\n> mixed mess is harder than either.  In the above excerpt, you cannot\n> tell if I quoted everything related to FLEX_ARRAY (in other words,\n> if \"#ifndef FLEX_ARRAY\" is already closed in the excerpt) without\n> carefully looking.\n\nHere is how a patch to reindent (which is full of patch noise and\nnot enough value by itself) looks like.\n\n\n\n----- >8 ---------- >8 ---------- >8 ---------- >8 -----\nSubject: [PATCH] git-compat-util.h: reindent CPP directives\n\nKarthik noticed that Patrick used a not-so-consistently-used\nconvention to indent the CPP directives inside #if/#else/#endif by\none extra space, which may look like a typo to an eye unfamiliar\nwith the convention.  Unlike compat/ with borrowed sources, we do\nnot use the convention very much, and even when it is used, we are\nvery inconsistent.\n\nTaking git-compat-util.h as an example, here is how a \"normalized\"\nversion of that file would look like.  It makes it immediately\nobvious that an unindented CPP directive (like #define and #include)\nis in effect for any and all architectures, so there might be a\nreadability value in such a change, even though the one-time patch\nnoise is a bit annoying.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\nuse strict;\nuse warnings;\n\nmy $level = 0;\n\nmy %levelchange = (\n\tif => [0, 1],\n\tifdef => [0, 1],\n\tifndef => [0, 1],\n\telse => [-1, 0],\n\telif => [-1, 0],\n\tendif => [-1, -1],\n);\n\nmy $file_name = undef;\n\nwhile (<>) {\n\tif (!defined $file_name || $ARGV ne $file_name) {\n\t\t$. = 0;\n\t\t$file_name = $ARGV;\n\t\t# Special case for the header files\n\t\tif ($file_name =~ /\\.h$/) {\n\t\t\t# cause early part of a header file\n\t\t\t# #ifndef FILENAME_H\n\t\t\t# #define FILENAME_H\n\t\t\t# and the corresponding #endif at the end\n\t\t\t# not to be indented.\n\t\t\t$level = -1;\n\t\t} else {\n\t\t\t$level = 0;\n\t\t}\n\t}\n\n\t# Not a CPP directive? copy it out.\n\tif (!/^\\s*#\\s*(\\S+)(.*)/) {\n\t\tprint;\n\t\tnext;\n\t}\n\n\t#\n\tmy ($what, $rest) = ($1, $2);\n\tmy $thislevel = $level;\n\n\tif (exists $levelchange{$what}) {\n\t\t$thislevel = $level + $levelchange{$what}[0];\n\t\t$level = $level + $levelchange{$what}[1];\n\t}\n\n\tif ($thislevel < 0) {\n\t\t$thislevel = 0;\n\t}\n\tprint \"#\", \" \" x $thislevel, \"$what$rest\\n\";\n}\n---\n git-compat-util.h | 528 +++++++++++++++++++++++-----------------------\n 1 file changed, 264 insertions(+), 264 deletions(-)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex ca7678a379..dd9edb30e1 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -11,7 +11,7 @@\n  * directive, but please report the details of your system to\n  * git@vger.kernel.org.\n  */\n-#error \"Required C99 support is in a test phase.  Please see git-compat-util.h for more details.\"\n+# error \"Required C99 support is in a test phase.  Please see git-compat-util.h for more details.\"\n #endif\n \n #ifdef USE_MSVC_CRTDBG\n@@ -19,8 +19,8 @@\n  * For these to work they must appear very early in each\n  * file -- before most of the standard header files.\n  */\n-#include <stdlib.h>\n-#include <crtdbg.h>\n+# include <stdlib.h>\n+# include <crtdbg.h>\n #endif\n \n struct strbuf;\n@@ -41,7 +41,7 @@ struct strbuf;\n # define GIT_GNUC_PREREQ(maj, min) \\\n \t((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))\n #else\n- #define GIT_GNUC_PREREQ(maj, min) 0\n+# define GIT_GNUC_PREREQ(maj, min) 0\n #endif\n \n \n@@ -57,23 +57,23 @@ struct strbuf;\n  * here, we can fall back to use the \"safer but a bit wasteful\" one\n  * later.\n  */\n-#if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580)\n-#elif defined(__GNUC__)\n-# if (__GNUC__ >= 3)\n+# if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580)\n+# elif defined(__GNUC__)\n+#  if (__GNUC__ >= 3)\n+#   define FLEX_ARRAY /* empty */\n+#  else\n+#   define FLEX_ARRAY 0 /* older GNU extension */\n+#  endif\n+# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n #  define FLEX_ARRAY /* empty */\n-# else\n-#  define FLEX_ARRAY 0 /* older GNU extension */\n # endif\n-#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n-# define FLEX_ARRAY /* empty */\n-#endif\n \n /*\n  * Otherwise, default to safer but a bit wasteful traditional style\n  */\n-#ifndef FLEX_ARRAY\n-# define FLEX_ARRAY 1\n-#endif\n+# ifndef FLEX_ARRAY\n+#  define FLEX_ARRAY 1\n+# endif\n #endif\n \n \n@@ -153,9 +153,9 @@ struct strbuf;\n      (a) > maximum_unsigned_value_of_type(a) >> (shift))\n \n #ifdef __GNUC__\n-#define TYPEOF(x) (__typeof__(x))\n+# define TYPEOF(x) (__typeof__(x))\n #else\n-#define TYPEOF(x)\n+# define TYPEOF(x)\n #endif\n \n #define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (bitsizeof(x) - (bits))))\n@@ -167,7 +167,7 @@ struct strbuf;\n #define decimal_length(x)\t((int)(sizeof(x) * 2.56 + 0.5) + 1)\n \n #ifdef __MINGW64__\n-#define _POSIX_C_SOURCE 1\n+# define _POSIX_C_SOURCE 1\n #elif defined(__sun__)\n  /*\n   * On Solaris, when _XOPEN_EXTENDED is set, its header file\n@@ -177,16 +177,16 @@ struct strbuf;\n   * non XPG6 programs must be compiled with a pre-c99 compiler.\n   */\n # if __STDC_VERSION__ - 0 >= 199901L\n-# define _XOPEN_SOURCE 600\n+#  define _XOPEN_SOURCE 600\n # else\n-# define _XOPEN_SOURCE 500\n+#  define _XOPEN_SOURCE 500\n # endif\n #elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && \\\n       !defined(_M_UNIX) && !defined(__sgi) && !defined(__DragonFly__) && \\\n       !defined(__TANDEM) && !defined(__QNX__) && !defined(__MirBSD__) && \\\n       !defined(__CYGWIN__)\n-#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */\n-#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */\n+# define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */\n+# define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */\n #endif\n #define _ALL_SOURCE 1\n #define _GNU_SOURCE 1\n@@ -196,38 +196,38 @@ struct strbuf;\n #define _SGI_SOURCE 1\n \n #if GIT_GNUC_PREREQ(4, 5)\n-#define UNUSED __attribute__((unused)) \\\n+# define UNUSED __attribute__((unused)) \\\n \t__attribute__((deprecated (\"parameter declared as UNUSED\")))\n #elif defined(__GNUC__)\n-#define UNUSED __attribute__((unused)) \\\n+# define UNUSED __attribute__((unused)) \\\n \t__attribute__((deprecated))\n #else\n-#define UNUSED\n+# define UNUSED\n #endif\n \n #if defined(WIN32) && !defined(__CYGWIN__) /* Both MinGW and MSVC */\n # if !defined(_WIN32_WINNT)\n #  define _WIN32_WINNT 0x0600\n # endif\n-#define WIN32_LEAN_AND_MEAN  /* stops windows.h including winsock.h */\n-#include <winsock2.h>\n-#ifndef NO_UNIX_SOCKETS\n-#include <afunix.h>\n-#endif\n-#include <windows.h>\n-#define GIT_WINDOWS_NATIVE\n+# define WIN32_LEAN_AND_MEAN  /* stops windows.h including winsock.h */\n+# include <winsock2.h>\n+# ifndef NO_UNIX_SOCKETS\n+#  include <afunix.h>\n+# endif\n+# include <windows.h>\n+# define GIT_WINDOWS_NATIVE\n #endif\n \n #if defined(NO_UNIX_SOCKETS) || !defined(GIT_WINDOWS_NATIVE)\n static inline int _have_unix_sockets(void)\n {\n-#if defined(NO_UNIX_SOCKETS)\n+# if defined(NO_UNIX_SOCKETS)\n \treturn 0;\n-#else\n+# else\n \treturn 1;\n-#endif\n+# endif\n }\n-#define have_unix_sockets _have_unix_sockets\n+# define have_unix_sockets _have_unix_sockets\n #endif\n \n #include <unistd.h>\n@@ -240,13 +240,13 @@ static inline int _have_unix_sockets(void)\n #include <stdbool.h>\n #include <string.h>\n #ifdef HAVE_STRINGS_H\n-#include <strings.h> /* for strcasecmp() */\n+# include <strings.h> /* for strcasecmp() */\n #endif\n #include <errno.h>\n #include <limits.h>\n #include <locale.h>\n #ifdef NEEDS_SYS_PARAM_H\n-#include <sys/param.h>\n+# include <sys/param.h>\n #endif\n #include <sys/types.h>\n #include <dirent.h>\n@@ -258,15 +258,15 @@ static inline int _have_unix_sockets(void)\n #include <utime.h>\n #include <syslog.h>\n #if !defined(NO_POLL_H)\n-#include <poll.h>\n+# include <poll.h>\n #elif !defined(NO_SYS_POLL_H)\n-#include <sys/poll.h>\n+# include <sys/poll.h>\n #else\n /* Pull the compat stuff */\n-#include <poll.h>\n+# include <poll.h>\n #endif\n #ifdef HAVE_BSD_SYSCTL\n-#include <sys/sysctl.h>\n+# include <sys/sysctl.h>\n #endif\n \n /* Used by compat/win32/path-utils.h, and more */\n@@ -276,44 +276,44 @@ static inline int is_xplatform_dir_sep(int c)\n }\n \n #if defined(__CYGWIN__)\n-#include \"compat/win32/path-utils.h\"\n+# include \"compat/win32/path-utils.h\"\n #endif\n #if defined(__MINGW32__)\n /* pull in Windows compatibility stuff */\n-#include \"compat/win32/path-utils.h\"\n-#include \"compat/mingw.h\"\n+# include \"compat/win32/path-utils.h\"\n+# include \"compat/mingw.h\"\n #elif defined(_MSC_VER)\n-#include \"compat/win32/path-utils.h\"\n-#include \"compat/msvc.h\"\n-#else\n-#include <sys/utsname.h>\n-#include <sys/wait.h>\n-#include <sys/resource.h>\n-#include <sys/socket.h>\n-#include <sys/ioctl.h>\n-#include <sys/statvfs.h>\n-#include <termios.h>\n-#ifndef NO_SYS_SELECT_H\n-#include <sys/select.h>\n-#endif\n-#include <netinet/in.h>\n-#include <netinet/tcp.h>\n-#include <arpa/inet.h>\n-#include <netdb.h>\n-#include <pwd.h>\n-#include <sys/un.h>\n-#ifndef NO_INTTYPES_H\n-#include <inttypes.h>\n+# include \"compat/win32/path-utils.h\"\n+# include \"compat/msvc.h\"\n #else\n-#include <stdint.h>\n-#endif\n-#ifdef HAVE_ARC4RANDOM_LIBBSD\n-#include <bsd/stdlib.h>\n-#endif\n-#ifdef HAVE_GETRANDOM\n-#include <sys/random.h>\n-#endif\n-#ifdef NO_INTPTR_T\n+# include <sys/utsname.h>\n+# include <sys/wait.h>\n+# include <sys/resource.h>\n+# include <sys/socket.h>\n+# include <sys/ioctl.h>\n+# include <sys/statvfs.h>\n+# include <termios.h>\n+# ifndef NO_SYS_SELECT_H\n+#  include <sys/select.h>\n+# endif\n+# include <netinet/in.h>\n+# include <netinet/tcp.h>\n+# include <arpa/inet.h>\n+# include <netdb.h>\n+# include <pwd.h>\n+# include <sys/un.h>\n+# ifndef NO_INTTYPES_H\n+#  include <inttypes.h>\n+# else\n+#  include <stdint.h>\n+# endif\n+# ifdef HAVE_ARC4RANDOM_LIBBSD\n+#  include <bsd/stdlib.h>\n+# endif\n+# ifdef HAVE_GETRANDOM\n+#  include <sys/random.h>\n+# endif\n+# ifdef NO_INTPTR_T\n /*\n  * On I16LP32, ILP32 and LP64 \"long\" is the safe bet, however\n  * on LLP86, IL33LLP64 and P64 it needs to be \"long long\",\n@@ -323,15 +323,15 @@ static inline int is_xplatform_dir_sep(int c)\n  */\n typedef long intptr_t;\n typedef unsigned long uintptr_t;\n-#endif\n-#undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */\n-#include <grp.h>\n-#define _ALL_SOURCE 1\n+# endif\n+# undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */\n+# include <grp.h>\n+# define _ALL_SOURCE 1\n #endif\n \n /* used on Mac OS X */\n #ifdef PRECOMPOSE_UNICODE\n-#include \"compat/precompose_utf8.h\"\n+# include \"compat/precompose_utf8.h\"\n #else\n static inline const char *precompose_argv_prefix(int argc UNUSED,\n \t\t\t\t\t\t const char **argv UNUSED,\n@@ -344,16 +344,16 @@ static inline const char *precompose_string_if_needed(const char *in)\n \treturn in;\n }\n \n-#define probe_utf8_pathname_composition()\n+# define probe_utf8_pathname_composition()\n #endif\n \n #ifdef MKDIR_WO_TRAILING_SLASH\n-#define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))\n+# define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))\n int compat_mkdir_wo_trailing_slash(const char*, mode_t);\n #endif\n \n #ifdef time\n-#undef time\n+# undef time\n #endif\n static inline time_t git_time(time_t *tloc)\n {\n@@ -384,34 +384,34 @@ static inline int git_setitimer(int which UNUSED,\n \t\t\t\tstruct itimerval *newvalue UNUSED) {\n \treturn 0; /* pretend success */\n }\n-#undef setitimer\n-#define setitimer(which,value,ovalue) git_setitimer(which,value,ovalue)\n+# undef setitimer\n+# define setitimer(which,value,ovalue) git_setitimer(which,value,ovalue)\n #endif\n \n #ifndef NO_LIBGEN_H\n-#include <libgen.h>\n+# include <libgen.h>\n #else\n-#define basename gitbasename\n+# define basename gitbasename\n char *gitbasename(char *);\n-#define dirname gitdirname\n+# define dirname gitdirname\n char *gitdirname(char *);\n #endif\n \n #ifndef NO_ICONV\n-#include <iconv.h>\n+# include <iconv.h>\n #endif\n \n #ifndef NO_OPENSSL\n-#ifdef __APPLE__\n-#undef __AVAILABILITY_MACROS_USES_AVAILABILITY\n-#define __AVAILABILITY_MACROS_USES_AVAILABILITY 0\n-#include <AvailabilityMacros.h>\n-#undef DEPRECATED_ATTRIBUTE\n-#define DEPRECATED_ATTRIBUTE\n-#undef __AVAILABILITY_MACROS_USES_AVAILABILITY\n-#endif\n-#include <openssl/ssl.h>\n-#include <openssl/err.h>\n+# ifdef __APPLE__\n+#  undef __AVAILABILITY_MACROS_USES_AVAILABILITY\n+#  define __AVAILABILITY_MACROS_USES_AVAILABILITY 0\n+#  include <AvailabilityMacros.h>\n+#  undef DEPRECATED_ATTRIBUTE\n+#  define DEPRECATED_ATTRIBUTE\n+#  undef __AVAILABILITY_MACROS_USES_AVAILABILITY\n+# endif\n+# include <openssl/ssl.h>\n+# include <openssl/err.h>\n #endif\n \n #ifdef HAVE_SYSINFO\n@@ -422,22 +422,22 @@ char *gitdirname(char *);\n  * not on some systems (e.g. z/OS).\n  */\n #ifndef NI_MAXHOST\n-#define NI_MAXHOST 1025\n+# define NI_MAXHOST 1025\n #endif\n \n #ifndef NI_MAXSERV\n-#define NI_MAXSERV 32\n+# define NI_MAXSERV 32\n #endif\n \n /* On most systems <limits.h> would have given us this, but\n  * not on some systems (e.g. GNU/Hurd).\n  */\n #ifndef PATH_MAX\n-#define PATH_MAX 4096\n+# define PATH_MAX 4096\n #endif\n \n #ifndef NAME_MAX\n-#define NAME_MAX 255\n+# define NAME_MAX 255\n #endif\n \n typedef uintmax_t timestamp_t;\n@@ -447,14 +447,14 @@ typedef uintmax_t timestamp_t;\n #define TIME_MIN 0\n \n #ifndef PATH_SEP\n-#define PATH_SEP ':'\n+# define PATH_SEP ':'\n #endif\n \n #ifdef HAVE_PATHS_H\n-#include <paths.h>\n+# include <paths.h>\n #endif\n #ifndef _PATH_DEFPATH\n-#define _PATH_DEFPATH \"/usr/local/bin:/usr/bin:/bin\"\n+# define _PATH_DEFPATH \"/usr/local/bin:/usr/bin:/bin\"\n #endif\n \n #ifndef platform_core_config\n@@ -466,12 +466,12 @@ static inline int noop_core_config(const char *var UNUSED,\n {\n \treturn 0;\n }\n-#define platform_core_config noop_core_config\n+# define platform_core_config noop_core_config\n #endif\n \n int lstat_cache_aware_rmdir(const char *path);\n #if !defined(__MINGW32__) && !defined(_MSC_VER)\n-#define rmdir lstat_cache_aware_rmdir\n+# define rmdir lstat_cache_aware_rmdir\n #endif\n \n #ifndef has_dos_drive_prefix\n@@ -479,7 +479,7 @@ static inline int git_has_dos_drive_prefix(const char *path UNUSED)\n {\n \treturn 0;\n }\n-#define has_dos_drive_prefix git_has_dos_drive_prefix\n+# define has_dos_drive_prefix git_has_dos_drive_prefix\n #endif\n \n #ifndef skip_dos_drive_prefix\n@@ -487,7 +487,7 @@ static inline int git_skip_dos_drive_prefix(char **path UNUSED)\n {\n \treturn 0;\n }\n-#define skip_dos_drive_prefix git_skip_dos_drive_prefix\n+# define skip_dos_drive_prefix git_skip_dos_drive_prefix\n #endif\n \n static inline int git_is_dir_sep(int c)\n@@ -495,7 +495,7 @@ static inline int git_is_dir_sep(int c)\n \treturn c == '/';\n }\n #ifndef is_dir_sep\n-#define is_dir_sep git_is_dir_sep\n+# define is_dir_sep git_is_dir_sep\n #endif\n \n #ifndef offset_1st_component\n@@ -503,20 +503,20 @@ static inline int git_offset_1st_component(const char *path)\n {\n \treturn is_dir_sep(path[0]);\n }\n-#define offset_1st_component git_offset_1st_component\n+# define offset_1st_component git_offset_1st_component\n #endif\n \n #ifndef is_valid_path\n-#define is_valid_path(path) 1\n+# define is_valid_path(path) 1\n #endif\n \n #ifndef is_path_owned_by_current_user\n \n-#ifdef __TANDEM\n-#define ROOT_UID 65535\n-#else\n-#define ROOT_UID 0\n-#endif\n+# ifdef __TANDEM\n+#  define ROOT_UID 65535\n+# else\n+#  define ROOT_UID 0\n+# endif\n \n /*\n  * Do not use this function when\n@@ -576,7 +576,7 @@ static inline int is_path_owned_by_current_uid(const char *path,\n \treturn st.st_uid == euid;\n }\n \n-#define is_path_owned_by_current_user is_path_owned_by_current_uid\n+# define is_path_owned_by_current_user is_path_owned_by_current_uid\n #endif\n \n #ifndef find_last_dir_sep\n@@ -584,7 +584,7 @@ static inline char *git_find_last_dir_sep(const char *path)\n {\n \treturn strrchr(path, '/');\n }\n-#define find_last_dir_sep git_find_last_dir_sep\n+# define find_last_dir_sep git_find_last_dir_sep\n #endif\n \n #ifndef has_dir_sep\n@@ -592,53 +592,53 @@ static inline int git_has_dir_sep(const char *path)\n {\n \treturn !!strchr(path, '/');\n }\n-#define has_dir_sep(path) git_has_dir_sep(path)\n+# define has_dir_sep(path) git_has_dir_sep(path)\n #endif\n \n #ifndef query_user_email\n-#define query_user_email() NULL\n+# define query_user_email() NULL\n #endif\n \n #ifdef __TANDEM\n-#include <floss.h(floss_execl,floss_execlp,floss_execv,floss_execvp)>\n-#include <floss.h(floss_getpwuid)>\n-#ifndef NSIG\n+# include <floss.h(floss_execl,floss_execlp,floss_execv,floss_execvp)>\n+# include <floss.h(floss_getpwuid)>\n+# ifndef NSIG\n /*\n  * NonStop NSE and NSX do not provide NSIG. SIGGUARDIAN(99) is the highest\n  * known, by detective work using kill -l as a list is all signals\n  * instead of signal.h where it should be.\n  */\n-# define NSIG 100\n-#endif\n+#  define NSIG 100\n+# endif\n #endif\n \n #if defined(__HP_cc) && (__HP_cc >= 61000)\n-#define NORETURN __attribute__((noreturn))\n-#define NORETURN_PTR\n+# define NORETURN __attribute__((noreturn))\n+# define NORETURN_PTR\n #elif defined(__GNUC__) && !defined(NO_NORETURN)\n-#define NORETURN __attribute__((__noreturn__))\n-#define NORETURN_PTR __attribute__((__noreturn__))\n+# define NORETURN __attribute__((__noreturn__))\n+# define NORETURN_PTR __attribute__((__noreturn__))\n #elif defined(_MSC_VER)\n-#define NORETURN __declspec(noreturn)\n-#define NORETURN_PTR\n+# define NORETURN __declspec(noreturn)\n+# define NORETURN_PTR\n #else\n-#define NORETURN\n-#define NORETURN_PTR\n-#ifndef __GNUC__\n-#ifndef __attribute__\n-#define __attribute__(x)\n-#endif\n-#endif\n+# define NORETURN\n+# define NORETURN_PTR\n+# ifndef __GNUC__\n+#  ifndef __attribute__\n+#   define __attribute__(x)\n+#  endif\n+# endif\n #endif\n \n /* The sentinel attribute is valid from gcc version 4.0 */\n #if defined(__GNUC__) && (__GNUC__ >= 4)\n-#define LAST_ARG_MUST_BE_NULL __attribute__((sentinel))\n+# define LAST_ARG_MUST_BE_NULL __attribute__((sentinel))\n /* warn_unused_result exists as of gcc 3.4.0, but be lazy and check 4.0 */\n-#define RESULT_MUST_BE_USED __attribute__ ((warn_unused_result))\n+# define RESULT_MUST_BE_USED __attribute__ ((warn_unused_result))\n #else\n-#define LAST_ARG_MUST_BE_NULL\n-#define RESULT_MUST_BE_USED\n+# define LAST_ARG_MUST_BE_NULL\n+# define RESULT_MUST_BE_USED\n #endif\n \n #define MAYBE_UNUSED __attribute__((__unused__))\n@@ -660,17 +660,17 @@ void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));\n void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));\n \n #ifndef NO_OPENSSL\n-#ifdef APPLE_COMMON_CRYPTO\n-#include \"compat/apple-common-crypto.h\"\n-#else\n-#include <openssl/evp.h>\n-#include <openssl/hmac.h>\n-#endif /* APPLE_COMMON_CRYPTO */\n-#include <openssl/x509v3.h>\n+# ifdef APPLE_COMMON_CRYPTO\n+#  include \"compat/apple-common-crypto.h\"\n+# else\n+#  include <openssl/evp.h>\n+#  include <openssl/hmac.h>\n+# endif /* APPLE_COMMON_CRYPTO */\n+# include <openssl/x509v3.h>\n #endif /* NO_OPENSSL */\n \n #ifdef HAVE_OPENSSL_CSPRNG\n-#include <openssl/rand.h>\n+# include <openssl/rand.h>\n #endif\n \n /*\n@@ -683,8 +683,8 @@ static inline int const_error(void)\n {\n \treturn -1;\n }\n-#define error(...) (error(__VA_ARGS__), const_error())\n-#define error_errno(...) (error_errno(__VA_ARGS__), const_error())\n+# define error(...) (error(__VA_ARGS__), const_error())\n+# define error_errno(...) (error_errno(__VA_ARGS__), const_error())\n #endif\n \n typedef void (*report_fn)(const char *, va_list params);\n@@ -782,32 +782,32 @@ static inline bool strip_suffix(const char *str, const char *suffix,\n \n #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)\n \n-#ifndef PROT_READ\n-#define PROT_READ 1\n-#define PROT_WRITE 2\n-#define MAP_PRIVATE 1\n-#endif\n+# ifndef PROT_READ\n+#  define PROT_READ 1\n+#  define PROT_WRITE 2\n+#  define MAP_PRIVATE 1\n+# endif\n \n-#define mmap git_mmap\n-#define munmap git_munmap\n+# define mmap git_mmap\n+# define munmap git_munmap\n void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);\n int git_munmap(void *start, size_t length);\n \n #else /* NO_MMAP || USE_WIN32_MMAP */\n \n-#include <sys/mman.h>\n+# include <sys/mman.h>\n \n #endif /* NO_MMAP || USE_WIN32_MMAP */\n \n #ifdef NO_MMAP\n \n /* This value must be multiple of (pagesize * 2) */\n-#define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)\n+# define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)\n \n #else /* NO_MMAP */\n \n /* This value must be multiple of (pagesize * 2) */\n-#define DEFAULT_PACKED_GIT_WINDOW_SIZE \\\n+# define DEFAULT_PACKED_GIT_WINDOW_SIZE \\\n \t(sizeof(void*) >= 8 \\\n \t\t?  1 * 1024 * 1024 * 1024 \\\n \t\t: 32 * 1024 * 1024)\n@@ -815,46 +815,46 @@ int git_munmap(void *start, size_t length);\n #endif /* NO_MMAP */\n \n #ifndef MAP_FAILED\n-#define MAP_FAILED ((void *)-1)\n+# define MAP_FAILED ((void *)-1)\n #endif\n \n #ifdef NO_ST_BLOCKS_IN_STRUCT_STAT\n-#define on_disk_bytes(st) ((st).st_size)\n+# define on_disk_bytes(st) ((st).st_size)\n #else\n-#define on_disk_bytes(st) ((st).st_blocks * 512)\n+# define on_disk_bytes(st) ((st).st_blocks * 512)\n #endif\n \n #ifdef NEEDS_MODE_TRANSLATION\n-#undef S_IFMT\n-#undef S_IFREG\n-#undef S_IFDIR\n-#undef S_IFLNK\n-#undef S_IFBLK\n-#undef S_IFCHR\n-#undef S_IFIFO\n-#undef S_IFSOCK\n-#define S_IFMT   0170000\n-#define S_IFREG  0100000\n-#define S_IFDIR  0040000\n-#define S_IFLNK  0120000\n-#define S_IFBLK  0060000\n-#define S_IFCHR  0020000\n-#define S_IFIFO  0010000\n-#define S_IFSOCK 0140000\n-#ifdef stat\n-#undef stat\n-#endif\n-#define stat(path, buf) git_stat(path, buf)\n+# undef S_IFMT\n+# undef S_IFREG\n+# undef S_IFDIR\n+# undef S_IFLNK\n+# undef S_IFBLK\n+# undef S_IFCHR\n+# undef S_IFIFO\n+# undef S_IFSOCK\n+# define S_IFMT   0170000\n+# define S_IFREG  0100000\n+# define S_IFDIR  0040000\n+# define S_IFLNK  0120000\n+# define S_IFBLK  0060000\n+# define S_IFCHR  0020000\n+# define S_IFIFO  0010000\n+# define S_IFSOCK 0140000\n+# ifdef stat\n+#  undef stat\n+# endif\n+# define stat(path, buf) git_stat(path, buf)\n int git_stat(const char *, struct stat *);\n-#ifdef fstat\n-#undef fstat\n-#endif\n-#define fstat(fd, buf) git_fstat(fd, buf)\n+# ifdef fstat\n+#  undef fstat\n+# endif\n+# define fstat(fd, buf) git_fstat(fd, buf)\n int git_fstat(int, struct stat *);\n-#ifdef lstat\n-#undef lstat\n-#endif\n-#define lstat(path, buf) git_lstat(path, buf)\n+# ifdef lstat\n+#  undef lstat\n+# endif\n+# define lstat(path, buf) git_lstat(path, buf)\n int git_lstat(const char *, struct stat *);\n #endif\n \n@@ -862,67 +862,67 @@ int git_lstat(const char *, struct stat *);\n \t((1024L * 1024L) * (size_t)(sizeof(void*) >= 8 ? (32 * 1024L * 1024L) : 256))\n \n #ifdef NO_PREAD\n-#define pread git_pread\n+# define pread git_pread\n ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);\n #endif\n \n #ifdef NO_SETENV\n-#define setenv gitsetenv\n+# define setenv gitsetenv\n int gitsetenv(const char *, const char *, int);\n #endif\n \n #ifdef NO_MKDTEMP\n-#define mkdtemp gitmkdtemp\n+# define mkdtemp gitmkdtemp\n char *gitmkdtemp(char *);\n #endif\n \n #ifdef NO_UNSETENV\n-#define unsetenv gitunsetenv\n+# define unsetenv gitunsetenv\n int gitunsetenv(const char *);\n #endif\n \n #ifdef NO_STRCASESTR\n-#define strcasestr gitstrcasestr\n+# define strcasestr gitstrcasestr\n char *gitstrcasestr(const char *haystack, const char *needle);\n #endif\n \n #ifdef NO_STRLCPY\n-#define strlcpy gitstrlcpy\n+# define strlcpy gitstrlcpy\n size_t gitstrlcpy(char *, const char *, size_t);\n #endif\n \n #ifdef NO_STRTOUMAX\n-#define strtoumax gitstrtoumax\n+# define strtoumax gitstrtoumax\n uintmax_t gitstrtoumax(const char *, char **, int);\n-#define strtoimax gitstrtoimax\n+# define strtoimax gitstrtoimax\n intmax_t gitstrtoimax(const char *, char **, int);\n #endif\n \n #ifdef NO_HSTRERROR\n-#define hstrerror githstrerror\n+# define hstrerror githstrerror\n const char *githstrerror(int herror);\n #endif\n \n #ifdef NO_MEMMEM\n-#define memmem gitmemmem\n+# define memmem gitmemmem\n void *gitmemmem(const void *haystack, size_t haystacklen,\n \t\tconst void *needle, size_t needlelen);\n #endif\n \n #ifdef OVERRIDE_STRDUP\n-#ifdef strdup\n-#undef strdup\n-#endif\n-#define strdup gitstrdup\n+# ifdef strdup\n+#  undef strdup\n+# endif\n+# define strdup gitstrdup\n char *gitstrdup(const char *s);\n #endif\n \n #ifdef NO_GETPAGESIZE\n-#define getpagesize() sysconf(_SC_PAGESIZE)\n+# define getpagesize() sysconf(_SC_PAGESIZE)\n #endif\n \n #ifndef O_CLOEXEC\n-#define O_CLOEXEC 0\n+# define O_CLOEXEC 0\n #endif\n \n #ifdef FREAD_READS_DIRECTORIES\n@@ -936,34 +936,34 @@ FILE *git_fopen(const char*, const char*);\n #endif\n \n #ifdef SNPRINTF_RETURNS_BOGUS\n-#ifdef snprintf\n-#undef snprintf\n-#endif\n-#define snprintf git_snprintf\n+# ifdef snprintf\n+#  undef snprintf\n+# endif\n+# define snprintf git_snprintf\n int git_snprintf(char *str, size_t maxsize,\n \t\t const char *format, ...);\n-#ifdef vsnprintf\n-#undef vsnprintf\n-#endif\n-#define vsnprintf git_vsnprintf\n+# ifdef vsnprintf\n+#  undef vsnprintf\n+# endif\n+# define vsnprintf git_vsnprintf\n int git_vsnprintf(char *str, size_t maxsize,\n \t\t  const char *format, va_list ap);\n #endif\n \n #ifdef OPEN_RETURNS_EINTR\n-#undef open\n-#define open git_open_with_retry\n+# undef open\n+# define open git_open_with_retry\n int git_open_with_retry(const char *path, int flag, ...);\n #endif\n \n #ifdef __GLIBC_PREREQ\n-#if __GLIBC_PREREQ(2, 1)\n-#define HAVE_STRCHRNUL\n-#endif\n+# if __GLIBC_PREREQ(2, 1)\n+#  define HAVE_STRCHRNUL\n+# endif\n #endif\n \n #ifndef HAVE_STRCHRNUL\n-#define strchrnul gitstrchrnul\n+# define strchrnul gitstrchrnul\n static inline char *gitstrchrnul(const char *s, int c)\n {\n \twhile (*s && *s != c)\n@@ -981,7 +981,7 @@ const char *inet_ntop(int af, const void *src, char *dst, size_t size);\n #endif\n \n #ifdef NO_PTHREADS\n-#define atexit git_atexit\n+# define atexit git_atexit\n int git_atexit(void (*handler)(void));\n #endif\n \n@@ -1252,7 +1252,7 @@ static inline size_t xsize_t(off_t len)\n }\n \n #ifndef HOST_NAME_MAX\n-#define HOST_NAME_MAX 256\n+# define HOST_NAME_MAX 256\n #endif\n \n #include \"sane-ctype.h\"\n@@ -1325,7 +1325,7 @@ static inline int strtol_i(char const *s, int base, int *result)\n void git_stable_qsort(void *base, size_t nmemb, size_t size,\n \t\t      int(*compar)(const void *, const void *));\n #ifdef INTERNAL_QSORT\n-#define qsort git_stable_qsort\n+# define qsort git_stable_qsort\n #endif\n \n #define QSORT(base, n, compar) sane_qsort((base), (n), sizeof(*(base)), compar)\n@@ -1342,7 +1342,7 @@ static inline void sane_qsort(void *base, size_t nmemb, size_t size,\n #ifndef HAVE_ISO_QSORT_S\n int git_qsort_s(void *base, size_t nmemb, size_t size,\n \t\tint (*compar)(const void *, const void *, void *), void *ctx);\n-#define qsort_s git_qsort_s\n+# define qsort_s git_qsort_s\n #endif\n \n #define QSORT_S(base, n, compar, ctx) do {\t\t\t\\\n@@ -1351,7 +1351,7 @@ int git_qsort_s(void *base, size_t nmemb, size_t size,\n } while (0)\n \n #ifndef REG_STARTEND\n-#error \"Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd\"\n+# error \"Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd\"\n #endif\n \n static inline int regexec_buf(const regex_t *preg, const char *buf, size_t size,\n@@ -1365,7 +1365,7 @@ static inline int regexec_buf(const regex_t *preg, const char *buf, size_t size,\n \n #ifdef USE_ENHANCED_BASIC_REGULAR_EXPRESSIONS\n int git_regcomp(regex_t *preg, const char *pattern, int cflags);\n-#define regcomp git_regcomp\n+# define regcomp git_regcomp\n #endif\n \n #ifndef DIR_HAS_BSD_GROUP_SEMANTICS\n@@ -1375,23 +1375,23 @@ int git_regcomp(regex_t *preg, const char *pattern, int cflags);\n #endif\n \n #ifdef NO_NSEC\n-#undef USE_NSEC\n-#define ST_CTIME_NSEC(st) 0\n-#define ST_MTIME_NSEC(st) 0\n+# undef USE_NSEC\n+# define ST_CTIME_NSEC(st) 0\n+# define ST_MTIME_NSEC(st) 0\n #else\n-#ifdef USE_ST_TIMESPEC\n-#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))\n-#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))\n-#else\n-#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))\n-#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))\n-#endif\n+# ifdef USE_ST_TIMESPEC\n+#  define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))\n+#  define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))\n+# else\n+#  define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))\n+#  define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))\n+# endif\n #endif\n \n #ifdef UNRELIABLE_FSTAT\n-#define fstat_is_reliable() 0\n+# define fstat_is_reliable() 0\n #else\n-#define fstat_is_reliable() 1\n+# define fstat_is_reliable() 1\n #endif\n \n #ifndef va_copy\n@@ -1400,11 +1400,11 @@ int git_regcomp(regex_t *preg, const char *pattern, int cflags);\n  * pointer into the stack frame, a simple assignment will work on\n  * many systems.  But let's try to be more portable.\n  */\n-#ifdef __va_copy\n-#define va_copy(dst, src) __va_copy(dst, src)\n-#else\n-#define va_copy(dst, src) ((dst) = (src))\n-#endif\n+# ifdef __va_copy\n+#  define va_copy(dst, src) __va_copy(dst, src)\n+# else\n+#  define va_copy(dst, src) ((dst) = (src))\n+# endif\n #endif\n \n /* usage.c: only to be used for testing BUG() implementation (see test-tool) */\n@@ -1425,11 +1425,11 @@ void bug_fl(const char *file, int line, const char *fmt, ...);\n } while (0)\n \n #ifndef FSYNC_METHOD_DEFAULT\n-#ifdef __APPLE__\n-#define FSYNC_METHOD_DEFAULT FSYNC_METHOD_WRITEOUT_ONLY\n-#else\n-#define FSYNC_METHOD_DEFAULT FSYNC_METHOD_FSYNC\n-#endif\n+# ifdef __APPLE__\n+#  define FSYNC_METHOD_DEFAULT FSYNC_METHOD_WRITEOUT_ONLY\n+# else\n+#  define FSYNC_METHOD_DEFAULT FSYNC_METHOD_FSYNC\n+# endif\n #endif\n \n #ifndef SHELL_PATH\n@@ -1445,12 +1445,12 @@ static inline void git_funlockfile(FILE *fh UNUSED)\n {\n \t; /* nothing */\n }\n-#undef flockfile\n-#undef funlockfile\n-#undef getc_unlocked\n-#define flockfile(fh) git_flockfile(fh)\n-#define funlockfile(fh) git_funlockfile(fh)\n-#define getc_unlocked(fh) getc(fh)\n+# undef flockfile\n+# undef funlockfile\n+# undef getc_unlocked\n+# define flockfile(fh) git_flockfile(fh)\n+# define funlockfile(fh) git_funlockfile(fh)\n+# define getc_unlocked(fh) getc(fh)\n #endif\n \n #ifdef FILENO_IS_A_MACRO\n@@ -1465,7 +1465,7 @@ int git_fileno(FILE *stream);\n int git_access(const char *path, int mode);\n # ifndef COMPAT_CODE_ACCESS\n #  ifdef access\n-#  undef access\n+#   undef access\n #  endif\n #  define access(path, mode) git_access(path, mode)\n # endif\n@@ -1510,9 +1510,9 @@ int common_exit(const char *file, int line, int code);\n  */\n #ifdef SUPPRESS_ANNOTATED_LEAKS\n void unleak_memory(const void *ptr, size_t len);\n-#define UNLEAK(var) unleak_memory(&(var), sizeof(var))\n+# define UNLEAK(var) unleak_memory(&(var), sizeof(var))\n #else\n-#define UNLEAK(var) do {} while (0)\n+# define UNLEAK(var) do {} while (0)\n #endif\n \n #define z_const\n@@ -1565,9 +1565,9 @@ static inline void *container_of_or_null_offset(void *ptr, size_t offset)\n  * everywhere.\n  */\n #if defined(__GNUC__) /* clang sets this, too */\n-#define OFFSETOF_VAR(ptr, member) offsetof(__typeof__(*ptr), member)\n+# define OFFSETOF_VAR(ptr, member) offsetof(__typeof__(*ptr), member)\n #else /* !__GNUC__ */\n-#define OFFSETOF_VAR(ptr, member) \\\n+# define OFFSETOF_VAR(ptr, member) \\\n \t((uintptr_t)&(ptr)->member - (uintptr_t)(ptr))\n #endif /* !__GNUC__ */\n \n-- \n2.45.2-709-g1ffe7c8bd7\n\n"},{"id":"497300","messageId":"CAOLa=ZT2iTRve+LbPDYMrZim4_tiL7rCofetThBhzH_2ae-u_g@mail.gmail.com","threadId":"61621","inReplyTo":"xmqqwmmm1bw6.fsf@gitster.g","subject":"Re: [PATCH v3 09/20] global: introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-06-18T20:20:32Z","receivedAt":"2024-06-18T20:20:34Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Karthik Nayak <karthik.188@gmail.com> writes:\n>\n>>>> s/# define/#define/\n>>>\n>>> This is in fact intentional. We aren't strictly following this in our\n>>> codebase, but when nesting preprocessor macros into ifdefs then we often\n>>> indent the inner macros with spaces.\n>>>\n>>> Patrick\n>>\n>> That's something I didn't know. Thanks.\n>\n> Unlike borrowed sources in compat/, in our codebase, such\n> indentation is minority.  IOW \"often indent\" -> \"sometimes indent\".\n>\n> A quick look at an early part of git-compat-util.h would show that\n> even within a single file we are not consistent at all.\n>\n> #if __STDC_VERSION__ - 0 < 199901L\n> #error \"Required C99 support is in a test phase.  Please see git-compat-util.h for more details.\"\n> #endif\n>\n> #ifdef USE_MSVC_CRTDBG\n> #include <stdlib.h>\n> #include <crtdbg.h>\n> #endif\n>\n> #define _FILE_OFFSET_BITS 64\n>\n> #if defined(__GNUC__) && defined(__GNUC_MINOR__)\n> # define GIT_GNUC_PREREQ(maj, min) \\\n> \t((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))\n> #else\n>  #define GIT_GNUC_PREREQ(maj, min) 0\n> #endif\n>\n> #ifndef FLEX_ARRAY\n> #if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580)\n> #elif defined(__GNUC__)\n> # if (__GNUC__ >= 3)\n> #  define FLEX_ARRAY /* empty */\n> # else\n> #  define FLEX_ARRAY 0 /* older GNU extension */\n> # endif\n> #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n> # define FLEX_ARRAY /* empty */\n> #endif\n> ...\n>\n>\n> We may want to eventually fix this, but we need to decide what the\n> desirable layout is.  I am not sure if the indented version is\n> easier to read and maintain, but one thing that is sure is that a\n> mixed mess is harder than either.  In the above excerpt, you cannot\n> tell if I quoted everything related to FLEX_ARRAY (in other words,\n> if \"#ifndef FLEX_ARRAY\" is already closed in the excerpt) without\n> carefully looking.\n\nPerhaps putting the options next to each other is good way to think of\nabout the _desired layout_.\n\n#ifndef FLEX_ARRAY\n#if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580)\n#elif defined(__GNUC__)\n# if (__GNUC__ >= 3)\n#  define FLEX_ARRAY /* empty */\n# else\n#  define FLEX_ARRAY 0 /* older GNU extension */\n# endif\n#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n# define FLEX_ARRAY /* empty */\n#endif\n\n#ifndef FLEX_ARRAY\n#if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580)\n#elif defined(__GNUC__)\n  #if (__GNUC__ >= 3)\n    #define FLEX_ARRAY /* empty */\n  #else\n    #define FLEX_ARRAY 0 /* older GNU extension */\n  #endif\n#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n  #define FLEX_ARRAY /* empty */\n#endif\n\nSomehow I feel the latter makes it a bit easier to grasp blocks, but\noverall I think its more important that we pick one and perhaps add it\nto 'Documentation/CodingGuidelines'.\n\nAlso, I did look at your response patch, but will leave it for someone\nwith perl experience to review.\n"},{"id":"497301","messageId":"CAOLa=ZSVJsPvQOnC7byRdpo7eJZRFOiSq=Rzio8QRvW_A3StOg@mail.gmail.com","threadId":"61621","inReplyTo":"cover.1718347699.git.ps@pks.im","subject":"Re: [PATCH v3 00/20] Introduce `USE_THE_REPOSITORY_VARIABLE` macro","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-06-18T20:22:40Z","receivedAt":"2024-06-18T20:22:41Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Hi,\n>\n> this is the third version of my patch series that introduces the\n> `USE_THE_REPOSITORY_VARIABLE` macro. When unset, this will cause us to\n> hide `the_repository`, `the_hash_algo` and several other functions that\n> implicitly rely on those global variables from our headers. This is a\n> first step towards fully getting rid of this global state in favor of\n> passing it down explicitly via function parameters.\n>\n> Changes compared to v2:\n>\n>   - Note in a commit message that we aim to have a faithful conversion\n>     when introducing a `struct git_hash_algo` parameter to functions. So\n>     even in case the calling context has a `struct git_hash_algo`\n>     available via a local repository, we still use `the_repository` such\n>     that there cannot be a change in behaviour here. Fixing those sites\n>     will be left for a future patch series such that we can avoid any\n>     kind of regressions caused by this comparatively large refactoring.\n>     I also adapted some conversions to fully follow through with this\n>     intent.\n>\n>   - Fix an issue with sparse by adding another `extern` declaration of\n>     `the_repository` to \"repository.c\".\n>\n> Thanks!\n>\n\nI forgot to reply here earlier.\n\nI went through the patches and only found 2 small typos, overall this\nwas an elaborate set of patches. I don't expect a reroll for that\nhowever. Thanks!\n"}]}