{"thread":{"id":"64947","subject":"[PATCH] xdiff-interface: stop using the_repository","startedAt":"2026-02-08T13:47:48Z","lastAt":"2026-02-15T18:42:54Z","messageCount":14,"participants":["René Scharfe","Patrick Steinhardt","Junio C Hamano","Elijah Newren"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"535476","messageId":"f58fa33d-b015-4339-819a-9d91be60cd0c@web.de","threadId":"64947","inReplyTo":null,"subject":"[PATCH] xdiff-interface: stop using the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-02-08T13:47:40Z","receivedAt":"2026-02-08T13:47:48Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Use the algorithm-agnostic is_null_oid() and push the dependency of\nread_mmblob() on the_repository->objects to its callers.  This allows it\nto be used with arbitrary object databases.\n\nSigned-off-by: René Scharfe <l.s.r@web.de>\n---\n apply.c              | 6 +++---\n builtin/checkout.c   | 6 +++---\n builtin/merge-file.c | 2 +-\n merge-ort.c          | 6 +++---\n notes-merge.c        | 6 +++---\n xdiff-interface.c    | 9 +++++----\n xdiff-interface.h    | 5 ++++-\n 7 files changed, 22 insertions(+), 18 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 3de4aa4d2e..ea90ed16be 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -3568,9 +3568,9 @@ static int three_way_merge(struct apply_state *state,\n \telse if (oideq(base, theirs) || oideq(ours, theirs))\n \t\treturn resolve_to(image, ours);\n \n-\tread_mmblob(&base_file, base);\n-\tread_mmblob(&our_file, ours);\n-\tread_mmblob(&their_file, theirs);\n+\tread_mmblob(&base_file, the_repository->objects, base);\n+\tread_mmblob(&our_file, the_repository->objects, ours);\n+\tread_mmblob(&their_file, the_repository->objects, theirs);\n \tmerge_opts.variant = state->merge_variant;\n \tstatus = ll_merge(&result, path,\n \t\t\t  &base_file, \"base\",\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 0ba4f03f2e..f7b313816e 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -294,9 +294,9 @@ static int checkout_merged(int pos, const struct checkout *state,\n \tif (is_null_oid(&threeway[1]) || is_null_oid(&threeway[2]))\n \t\treturn error(_(\"path '%s' does not have necessary versions\"), path);\n \n-\tread_mmblob(&ancestor, &threeway[0]);\n-\tread_mmblob(&ours, &threeway[1]);\n-\tread_mmblob(&theirs, &threeway[2]);\n+\tread_mmblob(&ancestor, the_repository->objects, &threeway[0]);\n+\tread_mmblob(&ours, the_repository->objects, &threeway[1]);\n+\tread_mmblob(&theirs, the_repository->objects, &threeway[2]);\n \n \trepo_config_get_bool(the_repository, \"merge.renormalize\", &renormalize);\n \tll_opts.renormalize = renormalize;\ndiff --git a/builtin/merge-file.c b/builtin/merge-file.c\nindex 46775d0c79..c5dbd028fd 100644\n--- a/builtin/merge-file.c\n+++ b/builtin/merge-file.c\n@@ -128,7 +128,7 @@ int cmd_merge_file(int argc,\n \t\t\t\tret = error(_(\"object '%s' does not exist\"),\n \t\t\t\t\t      argv[i]);\n \t\t\telse if (!oideq(&oid, the_hash_algo->empty_blob))\n-\t\t\t\tread_mmblob(mmf, &oid);\n+\t\t\t\tread_mmblob(mmf, the_repository->objects, &oid);\n \t\t\telse\n \t\t\t\tread_mmfile(mmf, \"/dev/null\");\n \t\t} else if (read_mmfile(mmf, fname)) {\ndiff --git a/merge-ort.c b/merge-ort.c\nindex e80e4f735a..a4103d56ed 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -2136,9 +2136,9 @@ static int merge_3way(struct merge_options *opt,\n \t\tname2 = mkpathdup(\"%s:%s\", opt->branch2,  pathnames[2]);\n \t}\n \n-\tread_mmblob(&orig, o);\n-\tread_mmblob(&src1, a);\n-\tread_mmblob(&src2, b);\n+\tread_mmblob(&orig, the_repository->objects, o);\n+\tread_mmblob(&src1, the_repository->objects, a);\n+\tread_mmblob(&src2, the_repository->objects, b);\n \n \tmerge_status = ll_merge(result_buf, path, &orig, base,\n \t\t\t\t&src1, name1, &src2, name2,\ndiff --git a/notes-merge.c b/notes-merge.c\nindex 586939939f..47e9d7580a 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -359,9 +359,9 @@ static int ll_merge_in_worktree(struct notes_merge_options *o,\n \tmmfile_t base, local, remote;\n \tenum ll_merge_result status;\n \n-\tread_mmblob(&base, &p->base);\n-\tread_mmblob(&local, &p->local);\n-\tread_mmblob(&remote, &p->remote);\n+\tread_mmblob(&base, the_repository->objects, &p->base);\n+\tread_mmblob(&local, the_repository->objects, &p->local);\n+\tread_mmblob(&remote, the_repository->objects, &p->remote);\n \n \tstatus = ll_merge(&result_buf, oid_to_hex(&p->obj), &base, NULL,\n \t\t\t  &local, o->local_ref, &remote, o->remote_ref,\ndiff --git a/xdiff-interface.c b/xdiff-interface.c\nindex 1a35556380..cd7493730b 100644\n--- a/xdiff-interface.c\n+++ b/xdiff-interface.c\n@@ -1,4 +1,3 @@\n-#define USE_THE_REPOSITORY_VARIABLE\n #define DISABLE_SIGN_COMPARE_WARNINGS\n \n #include \"git-compat-util.h\"\n@@ -7,6 +6,7 @@\n #include \"config.h\"\n #include \"hex.h\"\n #include \"odb.h\"\n+#include \"repository.h\"\n #include \"strbuf.h\"\n #include \"xdiff-interface.h\"\n #include \"xdiff/xtypes.h\"\n@@ -177,18 +177,19 @@ int read_mmfile(mmfile_t *ptr, const char *filename)\n \treturn 0;\n }\n \n-void read_mmblob(mmfile_t *ptr, const struct object_id *oid)\n+void read_mmblob(mmfile_t *ptr, struct object_database *odb,\n+\t\t const struct object_id *oid)\n {\n \tunsigned long size;\n \tenum object_type type;\n \n-\tif (oideq(oid, null_oid(the_hash_algo))) {\n+\tif (is_null_oid(oid)) {\n \t\tptr->ptr = xstrdup(\"\");\n \t\tptr->size = 0;\n \t\treturn;\n \t}\n \n-\tptr->ptr = odb_read_object(the_repository->objects, oid, &type, &size);\n+\tptr->ptr = odb_read_object(odb, oid, &type, &size);\n \tif (!ptr->ptr || type != OBJ_BLOB)\n \t\tdie(\"unable to read blob object %s\", oid_to_hex(oid));\n \tptr->size = size;\ndiff --git a/xdiff-interface.h b/xdiff-interface.h\nindex dfc55daddf..fbc4ceec40 100644\n--- a/xdiff-interface.h\n+++ b/xdiff-interface.h\n@@ -4,6 +4,8 @@\n #include \"hash.h\"\n #include \"xdiff/xdiff.h\"\n \n+struct object_database;\n+\n /*\n  * xdiff isn't equipped to handle content over a gigabyte;\n  * we make the cutoff 1GB - 1MB to give some breathing\n@@ -45,7 +47,8 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,\n \t\t  void *consume_callback_data,\n \t\t  xpparam_t const *xpp, xdemitconf_t const *xecfg);\n int read_mmfile(mmfile_t *ptr, const char *filename);\n-void read_mmblob(mmfile_t *ptr, const struct object_id *oid);\n+void read_mmblob(mmfile_t *ptr, struct object_database *odb,\n+\t\t const struct object_id *oid);\n int buffer_is_binary(const char *ptr, unsigned long size);\n \n void xdiff_set_find_func(xdemitconf_t *xecfg, const char *line, int cflags);\n-- \n2.52.0\n"},{"id":"535511","messageId":"aYmtab_uqMZBygAG@pks.im","threadId":"64947","inReplyTo":"f58fa33d-b015-4339-819a-9d91be60cd0c@web.de","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-09T09:48:25Z","receivedAt":"2026-02-09T09:48:36Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sun, Feb 08, 2026 at 02:47:40PM +0100, René Scharfe wrote:\n> diff --git a/xdiff-interface.c b/xdiff-interface.c\n> index 1a35556380..cd7493730b 100644\n> --- a/xdiff-interface.c\n> +++ b/xdiff-interface.c\n> @@ -7,6 +6,7 @@\n>  #include \"config.h\"\n>  #include \"hex.h\"\n>  #include \"odb.h\"\n> +#include \"repository.h\"\n>  #include \"strbuf.h\"\n>  #include \"xdiff-interface.h\"\n>  #include \"xdiff/xtypes.h\"\n\nIt's a bit surprising that we have to add this include, but I assume\nthat we use a function that's declared in this file?\n\n> @@ -177,18 +177,19 @@ int read_mmfile(mmfile_t *ptr, const char *filename)\n>  \treturn 0;\n>  }\n>  \n> -void read_mmblob(mmfile_t *ptr, const struct object_id *oid)\n> +void read_mmblob(mmfile_t *ptr, struct object_database *odb,\n> +\t\t const struct object_id *oid)\n>  {\n>  \tunsigned long size;\n>  \tenum object_type type;\n>  \n> -\tif (oideq(oid, null_oid(the_hash_algo))) {\n> +\tif (is_null_oid(oid)) {\n>  \t\tptr->ptr = xstrdup(\"\");\n>  \t\tptr->size = 0;\n>  \t\treturn;\n>  \t}\n\nArguably the commit coudl've been split up into three:\n\n  1. The change to `is_null_oid()`.\n\n  2. Adding the ODB to the parameter.\n\n  3. Removing the macro and adding the include.\n\nSo that each of those could have a bit more explanation. But I guess the\nchanges are smallish enough so that this borders on okay-ish, so I won't\ninsist on such a change.\n\nOther than that this patch looks good to me, thanks!\n\nPatrick\n"},{"id":"535517","messageId":"xmqqms1i6uc8.fsf@gitster.g","threadId":"64947","inReplyTo":"f58fa33d-b015-4339-819a-9d91be60cd0c@web.de","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-09T11:15:51Z","receivedAt":"2026-02-09T11:15:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> Use the algorithm-agnostic is_null_oid() and push the dependency of\n> read_mmblob() on the_repository->objects to its callers.  This allows it\n> to be used with arbitrary object databases.\n\n> diff --git a/xdiff-interface.c b/xdiff-interface.c\n> index 1a35556380..cd7493730b 100644\n> --- a/xdiff-interface.c\n> +++ b/xdiff-interface.c\n> ...\n> -void read_mmblob(mmfile_t *ptr, const struct object_id *oid)\n> +void read_mmblob(mmfile_t *ptr, struct object_database *odb,\n> +\t\t const struct object_id *oid)\n\nA possible alternative may be to pass \"struct repository *\" here,\nbut this passes the (current) smallest piece of data necessary to\ndrive the helper function odb_read_object(), so it would be fine.\n\n>  {\n>  \tunsigned long size;\n>  \tenum object_type type;\n>  \n> -\tif (oideq(oid, null_oid(the_hash_algo))) {\n> +\tif (is_null_oid(oid)) {\n>  \t\tptr->ptr = xstrdup(\"\");\n>  \t\tptr->size = 0;\n>  \t\treturn;\n>  \t}\n>  \n> -\tptr->ptr = odb_read_object(the_repository->objects, oid, &type, &size);\n> +\tptr->ptr = odb_read_object(odb, oid, &type, &size);\n>  \tif (!ptr->ptr || type != OBJ_BLOB)\n>  \t\tdie(\"unable to read blob object %s\", oid_to_hex(oid));\n>  \tptr->size = size;\n\n"},{"id":"535533","messageId":"ee549683-1c80-4a9b-83b4-a44fafb1a47f@web.de","threadId":"64947","inReplyTo":"aYmtab_uqMZBygAG@pks.im","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-02-09T14:14:33Z","receivedAt":"2026-02-09T14:14:43Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"On 2/9/26 10:48 AM, Patrick Steinhardt wrote:\n> On Sun, Feb 08, 2026 at 02:47:40PM +0100, René Scharfe wrote:\n>> diff --git a/xdiff-interface.c b/xdiff-interface.c\n>> index 1a35556380..cd7493730b 100644\n>> --- a/xdiff-interface.c\n>> +++ b/xdiff-interface.c\n>> @@ -7,6 +6,7 @@\n>>  #include \"config.h\"\n>>  #include \"hex.h\"\n>>  #include \"odb.h\"\n>> +#include \"repository.h\"\n>>  #include \"strbuf.h\"\n>>  #include \"xdiff-interface.h\"\n>>  #include \"xdiff/xtypes.h\"\n> \n> It's a bit surprising that we have to add this include, but I assume\n> that we use a function that's declared in this file?\n\nGood point, we don't actually need it.  It's left over from an earlier\nversion that had a struct repository pointer as new parameter. :-|\n\nRené\n\n"},{"id":"535547","messageId":"b05f81aa-6e8a-4e90-ac9e-85fb72784afb@web.de","threadId":"64947","inReplyTo":"xmqqms1i6uc8.fsf@gitster.g","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-02-09T15:21:36Z","receivedAt":"2026-02-09T15:21:38Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"On 2/9/26 12:15 PM, Junio C Hamano wrote:\n> René Scharfe <l.s.r@web.de> writes:\n> \n>> Use the algorithm-agnostic is_null_oid() and push the dependency of\n>> read_mmblob() on the_repository->objects to its callers.  This allows it\n>> to be used with arbitrary object databases.\n> \n>> diff --git a/xdiff-interface.c b/xdiff-interface.c\n>> index 1a35556380..cd7493730b 100644\n>> --- a/xdiff-interface.c\n>> +++ b/xdiff-interface.c\n>> ...\n>> -void read_mmblob(mmfile_t *ptr, const struct object_id *oid)\n>> +void read_mmblob(mmfile_t *ptr, struct object_database *odb,\n>> +\t\t const struct object_id *oid)\n> \n> A possible alternative may be to pass \"struct repository *\" here,\n> but this passes the (current) smallest piece of data necessary to\n> drive the helper function odb_read_object(), so it would be fine.\n> \n>>  {\n>>  \tunsigned long size;\n>>  \tenum object_type type;\n>>  \n>> -\tif (oideq(oid, null_oid(the_hash_algo))) {\n>> +\tif (is_null_oid(oid)) {\n>>  \t\tptr->ptr = xstrdup(\"\");\n>>  \t\tptr->size = 0;\n>>  \t\treturn;\n>>  \t}\n>>  \n>> -\tptr->ptr = odb_read_object(the_repository->objects, oid, &type, &size);\n>> +\tptr->ptr = odb_read_object(odb, oid, &type, &size);\n>>  \tif (!ptr->ptr || type != OBJ_BLOB)\n>>  \t\tdie(\"unable to read blob object %s\", oid_to_hex(oid));\n>>  \tptr->size = size;\n\nMy initial version did that.  Then I realized that read_mmblob() is just\na thin odb_read_object() wrapper that converts null_oid to\nempty_blob_oid and dies on non-blobs, though, so requiring a full repo\npointer seemed excessive.  And all callers also use other odb_*\nfunctions already.\n\nRené\n\n"},{"id":"535579","messageId":"xmqqbjhx6cb5.fsf@gitster.g","threadId":"64947","inReplyTo":"b05f81aa-6e8a-4e90-ac9e-85fb72784afb@web.de","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-09T17:45:18Z","receivedAt":"2026-02-09T17:45:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n>>> -\tptr->ptr = odb_read_object(the_repository->objects, oid, &type, &size);\n>>> +\tptr->ptr = odb_read_object(odb, oid, &type, &size);\n>>>  \tif (!ptr->ptr || type != OBJ_BLOB)\n>>>  \t\tdie(\"unable to read blob object %s\", oid_to_hex(oid));\n>>>  \tptr->size = size;\n>\n> My initial version did that.  Then I realized that read_mmblob() is just\n> a thin odb_read_object() wrapper that converts null_oid to\n> empty_blob_oid and dies on non-blobs, though, so requiring a full repo\n> pointer seemed excessive.  And all callers also use other odb_*\n> functions already.\n\nAbsolutely.  Passing the narrowest thing the callee needs is the\nright approach and that is what is done in the version posted.\n\nThanks.  I presume that a small and final reroll is expected, if\nonly to remove the now unnecessary #include, if not splitting it\ninto three parts?\n\n"},{"id":"535592","messageId":"CABPp-BFuwvqiCTCCpoyT6em9_1-qrgPWHWhrufQ3UuZ+Kfkb6A@mail.gmail.com","threadId":"64947","inReplyTo":"f58fa33d-b015-4339-819a-9d91be60cd0c@web.de","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2026-02-09T18:57:56Z","receivedAt":"2026-02-09T18:58:08Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sun, Feb 8, 2026 at 5:47 AM René Scharfe <l.s.r@web.de> wrote:\n>\n...\n> diff --git a/merge-ort.c b/merge-ort.c\n> index e80e4f735a..a4103d56ed 100644\n> --- a/merge-ort.c\n> +++ b/merge-ort.c\n> @@ -2136,9 +2136,9 @@ static int merge_3way(struct merge_options *opt,\n>                 name2 = mkpathdup(\"%s:%s\", opt->branch2,  pathnames[2]);\n>         }\n>\n> -       read_mmblob(&orig, o);\n> -       read_mmblob(&src1, a);\n> -       read_mmblob(&src2, b);\n> +       read_mmblob(&orig, the_repository->objects, o);\n> +       read_mmblob(&src1, the_repository->objects, a);\n> +       read_mmblob(&src2, the_repository->objects, b);\n>\n>         merge_status = ll_merge(result_buf, path, &orig, base,\n>                                 &src1, name1, &src2, name2,\n\nA minor point, but could we use opt->repo instead of the_repository in\nmerge-ort?\n\nI've cleaned out all the_repository references before, except one in\nprefetch_for_content_merges(), and would prefer folks not add more.\nHowever, that one in prefetch_for_content_merges() and the use of\nDEFAULT_ABBREV prevent us from removing USE_THE_REPOSITORY, so it's\nunderstandable that folks keep adding them back -- in fact, others\nhave added a few others to this file already since I cleaned them out.\nSo, if you want to go ahead with this and then I submit a later patch\nthat cleans them all up, that's fine too.\n"},{"id":"535594","messageId":"267102b2-3ec1-4508-bf90-ccc69516669c@web.de","threadId":"64947","inReplyTo":"xmqqbjhx6cb5.fsf@gitster.g","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-02-09T19:24:51Z","receivedAt":"2026-02-09T19:24:53Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"On 2/9/26 6:45 PM, Junio C Hamano wrote:\n> René Scharfe <l.s.r@web.de> writes:\n> \n>>>> -\tptr->ptr = odb_read_object(the_repository->objects, oid, &type, &size);\n>>>> +\tptr->ptr = odb_read_object(odb, oid, &type, &size);\n>>>>  \tif (!ptr->ptr || type != OBJ_BLOB)\n>>>>  \t\tdie(\"unable to read blob object %s\", oid_to_hex(oid));\n>>>>  \tptr->size = size;\n>>\n>> My initial version did that.  Then I realized that read_mmblob() is just\n>> a thin odb_read_object() wrapper that converts null_oid to\n>> empty_blob_oid and dies on non-blobs, though, so requiring a full repo\n>> pointer seemed excessive.  And all callers also use other odb_*\n>> functions already.\n> \n> Absolutely.  Passing the narrowest thing the callee needs is the\n> right approach and that is what is done in the version posted.\n> \n> Thanks.  I presume that a small and final reroll is expected, if\n> only to remove the now unnecessary #include, if not splitting it\n> into three parts?\n\nRight, and still keeping it all in one patch, now that it has become\nslightly shorter. :)\n\nRené\n\n"},{"id":"535595","messageId":"59fe4ac7-605d-4eae-b13c-46996dd8814e@web.de","threadId":"64947","inReplyTo":"f58fa33d-b015-4339-819a-9d91be60cd0c@web.de","subject":"[PATCH v2] xdiff-interface: stop using the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-02-09T19:24:52Z","receivedAt":"2026-02-09T19:24:53Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Use the algorithm-agnostic is_null_oid() and push the dependency of\nread_mmblob() on the_repository->objects to its callers.  This allows it\nto be used with arbitrary object databases.\n\nSigned-off-by: René Scharfe <l.s.r@web.de>\n---\nChange since v1: don't add unnecessary #include\n\n apply.c              | 6 +++---\n builtin/checkout.c   | 6 +++---\n builtin/merge-file.c | 2 +-\n merge-ort.c          | 6 +++---\n notes-merge.c        | 6 +++---\n xdiff-interface.c    | 8 ++++----\n xdiff-interface.h    | 5 ++++-\n 7 files changed, 21 insertions(+), 18 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 3de4aa4d2e..ea90ed16be 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -3568,9 +3568,9 @@ static int three_way_merge(struct apply_state *state,\n \telse if (oideq(base, theirs) || oideq(ours, theirs))\n \t\treturn resolve_to(image, ours);\n \n-\tread_mmblob(&base_file, base);\n-\tread_mmblob(&our_file, ours);\n-\tread_mmblob(&their_file, theirs);\n+\tread_mmblob(&base_file, the_repository->objects, base);\n+\tread_mmblob(&our_file, the_repository->objects, ours);\n+\tread_mmblob(&their_file, the_repository->objects, theirs);\n \tmerge_opts.variant = state->merge_variant;\n \tstatus = ll_merge(&result, path,\n \t\t\t  &base_file, \"base\",\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 0ba4f03f2e..f7b313816e 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -294,9 +294,9 @@ static int checkout_merged(int pos, const struct checkout *state,\n \tif (is_null_oid(&threeway[1]) || is_null_oid(&threeway[2]))\n \t\treturn error(_(\"path '%s' does not have necessary versions\"), path);\n \n-\tread_mmblob(&ancestor, &threeway[0]);\n-\tread_mmblob(&ours, &threeway[1]);\n-\tread_mmblob(&theirs, &threeway[2]);\n+\tread_mmblob(&ancestor, the_repository->objects, &threeway[0]);\n+\tread_mmblob(&ours, the_repository->objects, &threeway[1]);\n+\tread_mmblob(&theirs, the_repository->objects, &threeway[2]);\n \n \trepo_config_get_bool(the_repository, \"merge.renormalize\", &renormalize);\n \tll_opts.renormalize = renormalize;\ndiff --git a/builtin/merge-file.c b/builtin/merge-file.c\nindex 46775d0c79..c5dbd028fd 100644\n--- a/builtin/merge-file.c\n+++ b/builtin/merge-file.c\n@@ -128,7 +128,7 @@ int cmd_merge_file(int argc,\n \t\t\t\tret = error(_(\"object '%s' does not exist\"),\n \t\t\t\t\t      argv[i]);\n \t\t\telse if (!oideq(&oid, the_hash_algo->empty_blob))\n-\t\t\t\tread_mmblob(mmf, &oid);\n+\t\t\t\tread_mmblob(mmf, the_repository->objects, &oid);\n \t\t\telse\n \t\t\t\tread_mmfile(mmf, \"/dev/null\");\n \t\t} else if (read_mmfile(mmf, fname)) {\ndiff --git a/merge-ort.c b/merge-ort.c\nindex e80e4f735a..a4103d56ed 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -2136,9 +2136,9 @@ static int merge_3way(struct merge_options *opt,\n \t\tname2 = mkpathdup(\"%s:%s\", opt->branch2,  pathnames[2]);\n \t}\n \n-\tread_mmblob(&orig, o);\n-\tread_mmblob(&src1, a);\n-\tread_mmblob(&src2, b);\n+\tread_mmblob(&orig, the_repository->objects, o);\n+\tread_mmblob(&src1, the_repository->objects, a);\n+\tread_mmblob(&src2, the_repository->objects, b);\n \n \tmerge_status = ll_merge(result_buf, path, &orig, base,\n \t\t\t\t&src1, name1, &src2, name2,\ndiff --git a/notes-merge.c b/notes-merge.c\nindex 586939939f..47e9d7580a 100644\n--- a/notes-merge.c\n+++ b/notes-merge.c\n@@ -359,9 +359,9 @@ static int ll_merge_in_worktree(struct notes_merge_options *o,\n \tmmfile_t base, local, remote;\n \tenum ll_merge_result status;\n \n-\tread_mmblob(&base, &p->base);\n-\tread_mmblob(&local, &p->local);\n-\tread_mmblob(&remote, &p->remote);\n+\tread_mmblob(&base, the_repository->objects, &p->base);\n+\tread_mmblob(&local, the_repository->objects, &p->local);\n+\tread_mmblob(&remote, the_repository->objects, &p->remote);\n \n \tstatus = ll_merge(&result_buf, oid_to_hex(&p->obj), &base, NULL,\n \t\t\t  &local, o->local_ref, &remote, o->remote_ref,\ndiff --git a/xdiff-interface.c b/xdiff-interface.c\nindex 1a35556380..f043330f2a 100644\n--- a/xdiff-interface.c\n+++ b/xdiff-interface.c\n@@ -1,4 +1,3 @@\n-#define USE_THE_REPOSITORY_VARIABLE\n #define DISABLE_SIGN_COMPARE_WARNINGS\n \n #include \"git-compat-util.h\"\n@@ -177,18 +176,19 @@ int read_mmfile(mmfile_t *ptr, const char *filename)\n \treturn 0;\n }\n \n-void read_mmblob(mmfile_t *ptr, const struct object_id *oid)\n+void read_mmblob(mmfile_t *ptr, struct object_database *odb,\n+\t\t const struct object_id *oid)\n {\n \tunsigned long size;\n \tenum object_type type;\n \n-\tif (oideq(oid, null_oid(the_hash_algo))) {\n+\tif (is_null_oid(oid)) {\n \t\tptr->ptr = xstrdup(\"\");\n \t\tptr->size = 0;\n \t\treturn;\n \t}\n \n-\tptr->ptr = odb_read_object(the_repository->objects, oid, &type, &size);\n+\tptr->ptr = odb_read_object(odb, oid, &type, &size);\n \tif (!ptr->ptr || type != OBJ_BLOB)\n \t\tdie(\"unable to read blob object %s\", oid_to_hex(oid));\n \tptr->size = size;\ndiff --git a/xdiff-interface.h b/xdiff-interface.h\nindex dfc55daddf..fbc4ceec40 100644\n--- a/xdiff-interface.h\n+++ b/xdiff-interface.h\n@@ -4,6 +4,8 @@\n #include \"hash.h\"\n #include \"xdiff/xdiff.h\"\n \n+struct object_database;\n+\n /*\n  * xdiff isn't equipped to handle content over a gigabyte;\n  * we make the cutoff 1GB - 1MB to give some breathing\n@@ -45,7 +47,8 @@ int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2,\n \t\t  void *consume_callback_data,\n \t\t  xpparam_t const *xpp, xdemitconf_t const *xecfg);\n int read_mmfile(mmfile_t *ptr, const char *filename);\n-void read_mmblob(mmfile_t *ptr, const struct object_id *oid);\n+void read_mmblob(mmfile_t *ptr, struct object_database *odb,\n+\t\t const struct object_id *oid);\n int buffer_is_binary(const char *ptr, unsigned long size);\n \n void xdiff_set_find_func(xdemitconf_t *xecfg, const char *line, int cflags);\n-- \n2.52.0\n"},{"id":"535600","messageId":"xmqq8qd14rfs.fsf@gitster.g","threadId":"64947","inReplyTo":"CABPp-BFuwvqiCTCCpoyT6em9_1-qrgPWHWhrufQ3UuZ+Kfkb6A@mail.gmail.com","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-09T20:01:27Z","receivedAt":"2026-02-09T20:01:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> On Sun, Feb 8, 2026 at 5:47 AM René Scharfe <l.s.r@web.de> wrote:\n>>\n> ...\n>> diff --git a/merge-ort.c b/merge-ort.c\n>> index e80e4f735a..a4103d56ed 100644\n>> --- a/merge-ort.c\n>> +++ b/merge-ort.c\n>> @@ -2136,9 +2136,9 @@ static int merge_3way(struct merge_options *opt,\n>>                 name2 = mkpathdup(\"%s:%s\", opt->branch2,  pathnames[2]);\n>>         }\n>>\n>> -       read_mmblob(&orig, o);\n>> -       read_mmblob(&src1, a);\n>> -       read_mmblob(&src2, b);\n>> +       read_mmblob(&orig, the_repository->objects, o);\n>> +       read_mmblob(&src1, the_repository->objects, a);\n>> +       read_mmblob(&src2, the_repository->objects, b);\n>>\n>>         merge_status = ll_merge(result_buf, path, &orig, base,\n>>                                 &src1, name1, &src2, name2,\n>\n> A minor point, but could we use opt->repo instead of the_repository in\n> merge-ort?\n\nGreat.  If we have already an appropriate structure with the\nrelevant data, using it is the most welcome.\n\n> So, if you want to go ahead with this and then I submit a later patch\n> that cleans them all up, that's fine too.\n\nTrue too, but as long as it is so obvious that \"opt\" here has .repo\nmember that we can use, I do not see a reason not to.\n\nThanks.\n\n"},{"id":"535672","messageId":"aYsylzWZXkKIYzOz@pks.im","threadId":"64947","inReplyTo":"59fe4ac7-605d-4eae-b13c-46996dd8814e@web.de","subject":"Re: [PATCH v2] xdiff-interface: stop using the_repository","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-10T13:28:55Z","receivedAt":"2026-02-10T13:29:00Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Feb 09, 2026 at 08:24:52PM +0100, René Scharfe wrote:\n> Use the algorithm-agnostic is_null_oid() and push the dependency of\n> read_mmblob() on the_repository->objects to its callers.  This allows it\n> to be used with arbitrary object databases.\n> \n> Signed-off-by: René Scharfe <l.s.r@web.de>\n> ---\n> Change since v1: don't add unnecessary #include\n\nLooks good to me, thanks!\n\nPatrick\n"},{"id":"535712","messageId":"xmqqecmsxp3b.fsf@gitster.g","threadId":"64947","inReplyTo":"aYsylzWZXkKIYzOz@pks.im","subject":"Re: [PATCH v2] xdiff-interface: stop using the_repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-10T21:31:36Z","receivedAt":"2026-02-10T21:31:39Z","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> On Mon, Feb 09, 2026 at 08:24:52PM +0100, René Scharfe wrote:\n>> Use the algorithm-agnostic is_null_oid() and push the dependency of\n>> read_mmblob() on the_repository->objects to its callers.  This allows it\n>> to be used with arbitrary object databases.\n>> \n>> Signed-off-by: René Scharfe <l.s.r@web.de>\n>> ---\n>> Change since v1: don't add unnecessary #include\n>\n> Looks good to me, thanks!\n>\n> Patrick\n\nThanks.  Replaced and marked for 'next'.\n"},{"id":"536057","messageId":"97e0fa77-0946-4898-b721-5f1a5d1153bd@web.de","threadId":"64947","inReplyTo":"CABPp-BFuwvqiCTCCpoyT6em9_1-qrgPWHWhrufQ3UuZ+Kfkb6A@mail.gmail.com","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-02-15T18:42:42Z","receivedAt":"2026-02-15T18:42:50Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"On 2/9/26 7:57 PM, Elijah Newren wrote:\n> On Sun, Feb 8, 2026 at 5:47 AM René Scharfe <l.s.r@web.de> wrote:\n>>\n> ...\n>> diff --git a/merge-ort.c b/merge-ort.c\n>> index e80e4f735a..a4103d56ed 100644\n>> --- a/merge-ort.c\n>> +++ b/merge-ort.c\n>> @@ -2136,9 +2136,9 @@ static int merge_3way(struct merge_options *opt,\n>>                 name2 = mkpathdup(\"%s:%s\", opt->branch2,  pathnames[2]);\n>>         }\n>>\n>> -       read_mmblob(&orig, o);\n>> -       read_mmblob(&src1, a);\n>> -       read_mmblob(&src2, b);\n>> +       read_mmblob(&orig, the_repository->objects, o);\n>> +       read_mmblob(&src1, the_repository->objects, a);\n>> +       read_mmblob(&src2, the_repository->objects, b);\n>>\n>>         merge_status = ll_merge(result_buf, path, &orig, base,\n>>                                 &src1, name1, &src2, name2,\n> \n> A minor point, but could we use opt->repo instead of the_repository in\n> merge-ort?\n> \n> I've cleaned out all the_repository references before, except one in\n> prefetch_for_content_merges(), and would prefer folks not add more.\n\nI can imagine that this whack-a-mole game is annoying.  The patch above\nat least didn't actually add them, it just made them explicit.  Indirect\nreferences may look better on the surface, but the functions that\ncontain them still can only be used with the_repository.\n\nThe only way I can see to avoid that pain would be to convert leaf\nfunctions, only, i.e. those that reference the_repository and friends,\nbut don't call any other functions or macros that do.  This way a\ntransition to the_repository-free would be meaningful and permanent for\neach function.\n\nConverting on all levels of the call chain in parallel requires less\ncoordination and is probably more realistic in our distributed\ndevelopment model, though.\n\nDo you (anyone) know nice tools for listing the full call chain graph\nof C functions?  cscope can probably be made to do that with some\nscripting, but seems inefficient for that purpose.  Such a tool could\nbe used to check for indirect references and tell us if functions are\nsafe for use with other repositories.\n\nRené\n\n"},{"id":"536058","messageId":"ba0e8878-1f76-4491-badf-9f37364f4cec@web.de","threadId":"64947","inReplyTo":"xmqq8qd14rfs.fsf@gitster.g","subject":"Re: [PATCH] xdiff-interface: stop using the_repository","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-02-15T18:42:44Z","receivedAt":"2026-02-15T18:42:54Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"On 2/9/26 9:01 PM, Junio C Hamano wrote:\n> Elijah Newren <newren@gmail.com> writes:\n> \n>> On Sun, Feb 8, 2026 at 5:47 AM René Scharfe <l.s.r@web.de> wrote:\n>>>\n>> ...\n>>> diff --git a/merge-ort.c b/merge-ort.c\n>>> index e80e4f735a..a4103d56ed 100644\n>>> --- a/merge-ort.c\n>>> +++ b/merge-ort.c\n>>> @@ -2136,9 +2136,9 @@ static int merge_3way(struct merge_options *opt,\n>>>                 name2 = mkpathdup(\"%s:%s\", opt->branch2,  pathnames[2]);\n>>>         }\n>>>\n>>> -       read_mmblob(&orig, o);\n>>> -       read_mmblob(&src1, a);\n>>> -       read_mmblob(&src2, b);\n>>> +       read_mmblob(&orig, the_repository->objects, o);\n>>> +       read_mmblob(&src1, the_repository->objects, a);\n>>> +       read_mmblob(&src2, the_repository->objects, b);\n>>>\n>>>         merge_status = ll_merge(result_buf, path, &orig, base,\n>>>                                 &src1, name1, &src2, name2,\n>>\n>> A minor point, but could we use opt->repo instead of the_repository in\n>> merge-ort?\n> \n> Great.  If we have already an appropriate structure with the\n> relevant data, using it is the most welcome.\n> \n>> So, if you want to go ahead with this and then I submit a later patch\n>> that cleans them all up, that's fine too.\n> \n> True too, but as long as it is so obvious that \"opt\" here has .repo\n> member that we can use, I do not see a reason not to.\nThanks for solving that issue!  I would have sent a separate patch if\nI had been quicker, because using opt->repo would not have been\nobvious to me.\n\nRené\n\n"}]}