{"thread":{"id":"64932","subject":"[PATCH 0/2] merge-ours: sparse-index integration","startedAt":"2026-02-06T02:32:06Z","lastAt":"2026-02-10T04:35:51Z","messageCount":11,"participants":["Sam Bostock via GitGitGadget","Junio C Hamano","Patrick Steinhardt","Derrick Stolee"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"535292","messageId":"pull.2189.git.git.1770345124.gitgitgadget@gmail.com","threadId":"64932","inReplyTo":null,"subject":"[PATCH 0/2] merge-ours: sparse-index integration","fromName":"Sam Bostock via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-06T02:32:02Z","receivedAt":"2026-02-06T02:32:06Z","isPatch":true,"sender":{"key":"sam.bostock@shopify.com","avatar":"https://avatars.githubusercontent.com/u/8219340?v=4"},"body":"This short series teaches merge-ours to work with a sparse index.\n\nPatch 1 is a preparatory cleanup that converts merge-ours away from\nthe_repository global, using the repo parameter instead.\n\nPatch 2 adds the actual sparse-index integration and tests. Because\nmerge-ours is invoked as a subprocess by git merge -s ours and never\npreviously read config, the sparse-checkout globals remained unset, causing\nthe index to be expanded unconditionally. A repo_config() call fixes this.\n\nDeveloped with AI assistance (Claude).\n\nSam Bostock (2):\n  merge-ours: drop USE_THE_REPOSITORY_VARIABLE\n  merge-ours: integrate with sparse-index\n\n builtin/merge-ours.c                     | 15 +++++++++------\n t/t1092-sparse-checkout-compatibility.sh | 14 ++++++++++++++\n 2 files changed, 23 insertions(+), 6 deletions(-)\n\n\nbase-commit: b2826b52eb7caff9f4ed6e85ec45e338bf02ad09\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2189%2Fsambostock%2Fsb%2Fmerge-ours-sparse-index-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2189/sambostock/sb/merge-ours-sparse-index-v1\nPull-Request: https://github.com/git/git/pull/2189\n-- \ngitgitgadget\n"},{"id":"535293","messageId":"6cb970e512c02f0db11b8aae247aaa1675b31ef0.1770345124.git.gitgitgadget@gmail.com","threadId":"64932","inReplyTo":"pull.2189.git.git.1770345124.gitgitgadget@gmail.com","subject":"[PATCH 1/2] merge-ours: drop USE_THE_REPOSITORY_VARIABLE","fromName":"Sam Bostock via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-06T02:32:03Z","receivedAt":"2026-02-06T02:32:08Z","isPatch":true,"sender":{"key":"sam.bostock@shopify.com","avatar":"https://avatars.githubusercontent.com/u/8219340?v=4"},"body":"From: Sam Bostock <sam@sambostock.ca>\n\nUse the `repo` parameter passed to cmd_merge_ours() instead of\n`the_repository`, and drop the USE_THE_REPOSITORY_VARIABLE macro that\nis no longer needed.\n\nWhile at it, remove a stray double blank line between the #include\nblock and the usage string.\n\nSigned-off-by: Sam Bostock <sam@sambostock.ca>\n---\n builtin/merge-ours.c | 9 +++------\n 1 file changed, 3 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/merge-ours.c b/builtin/merge-ours.c\nindex 97b8a792c7..2312e58ab3 100644\n--- a/builtin/merge-ours.c\n+++ b/builtin/merge-ours.c\n@@ -8,20 +8,17 @@\n  * Pretend we resolved the heads, but declare our tree trumps everybody else.\n  */\n \n-#define USE_THE_REPOSITORY_VARIABLE\n-\n #include \"git-compat-util.h\"\n #include \"builtin.h\"\n #include \"diff.h\"\n \n-\n static const char builtin_merge_ours_usage[] =\n \t\"git merge-ours <base>... -- HEAD <remote>...\";\n \n int cmd_merge_ours(int argc,\n \t\t   const char **argv,\n \t\t   const char *prefix UNUSED,\n-\t\t   struct repository *repo UNUSED)\n+\t\t   struct repository *repo)\n {\n \tshow_usage_if_asked(argc, argv, builtin_merge_ours_usage);\n \n@@ -30,9 +27,9 @@ int cmd_merge_ours(int argc,\n \t * commit.  The index must match HEAD, or this merge cannot go\n \t * through.\n \t */\n-\tif (repo_read_index(the_repository) < 0)\n+\tif (repo_read_index(repo) < 0)\n \t\tdie_errno(\"read_cache failed\");\n-\tif (index_differs_from(the_repository, \"HEAD\", NULL, 0))\n+\tif (index_differs_from(repo, \"HEAD\", NULL, 0))\n \t\treturn 2;\n \treturn 0;\n }\n-- \ngitgitgadget\n\n"},{"id":"535294","messageId":"20b9e0bf6e2b12eea1ff50b14d0d2809c601a943.1770345124.git.gitgitgadget@gmail.com","threadId":"64932","inReplyTo":"pull.2189.git.git.1770345124.gitgitgadget@gmail.com","subject":"[PATCH 2/2] merge-ours: integrate with sparse-index","fromName":"Sam Bostock via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-06T02:32:04Z","receivedAt":"2026-02-06T02:32:09Z","isPatch":true,"sender":{"key":"sam.bostock@shopify.com","avatar":"https://avatars.githubusercontent.com/u/8219340?v=4"},"body":"From: Sam Bostock <sam@sambostock.ca>\n\nThe merge-ours builtin reads the index only to compare it against HEAD\nvia index_differs_from(), whose diff machinery (run_diff_index) is\nalready sparse-aware.\n\nTeach merge-ours to opt out of requiring a full index by setting\ncommand_requires_full_index to 0. Because merge-ours is invoked as a\nsubprocess by \"git merge -s ours\" and never previously read config,\nthe global variables core_apply_sparse_checkout and\ncore_sparse_checkout_cone remained unset, causing\nis_sparse_index_allowed() to return false and the index to be expanded\nanyway. Add a repo_config() call with git_default_config to populate\nthese globals.\n\nAdd tests to t1092 verifying that \"git merge -s ours\" produces\nidentical results across full-checkout, sparse-checkout, and\nsparse-index modes, including verifying the resulting merge commit\nstructure, and that the sparse index is not expanded during the\noperation.\n\nSigned-off-by: Sam Bostock <sam@sambostock.ca>\n---\n builtin/merge-ours.c                     |  6 ++++++\n t/t1092-sparse-checkout-compatibility.sh | 14 ++++++++++++++\n 2 files changed, 20 insertions(+)\n\ndiff --git a/builtin/merge-ours.c b/builtin/merge-ours.c\nindex 2312e58ab3..405b2989f7 100644\n--- a/builtin/merge-ours.c\n+++ b/builtin/merge-ours.c\n@@ -10,6 +10,8 @@\n \n #include \"git-compat-util.h\"\n #include \"builtin.h\"\n+#include \"config.h\"\n+#include \"environment.h\"\n #include \"diff.h\"\n \n static const char builtin_merge_ours_usage[] =\n@@ -22,6 +24,10 @@ int cmd_merge_ours(int argc,\n {\n \tshow_usage_if_asked(argc, argv, builtin_merge_ours_usage);\n \n+\trepo_config(repo, git_default_config, NULL);\n+\tprepare_repo_settings(repo);\n+\trepo->settings.command_requires_full_index = 0;\n+\n \t/*\n \t * The contents of the current index becomes the tree we\n \t * commit.  The index must match HEAD, or this merge cannot go\ndiff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh\nindex b0f691c151..d98cb4ac11 100755\n--- a/t/t1092-sparse-checkout-compatibility.sh\n+++ b/t/t1092-sparse-checkout-compatibility.sh\n@@ -2559,4 +2559,18 @@ test_expect_success 'cat-file --batch' '\n \tensure_expanded cat-file --batch <in\n '\n \n+test_expect_success 'merge -s ours' '\n+\tinit_repos &&\n+\n+\ttest_all_match git rev-parse HEAD^{tree} &&\n+\ttest_all_match git merge -s ours merge-right &&\n+\ttest_all_match git rev-parse HEAD^{tree} &&\n+\ttest_all_match git rev-parse HEAD^2\n+'\n+\n+test_expect_success 'sparse-index is not expanded: merge-ours' '\n+\tinit_repos &&\n+\tensure_not_expanded merge -s ours merge-right\n+'\n+\n test_done\n-- \ngitgitgadget\n"},{"id":"535340","messageId":"xmqq343ehu4o.fsf@gitster.g","threadId":"64932","inReplyTo":"20b9e0bf6e2b12eea1ff50b14d0d2809c601a943.1770345124.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/2] merge-ours: integrate with sparse-index","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-06T13:35:51Z","receivedAt":"2026-02-06T13:35:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Sam Bostock via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Sam Bostock <sam@sambostock.ca>\n>\n> The merge-ours builtin reads the index only to compare it against HEAD\n> via index_differs_from(), whose diff machinery (run_diff_index) is\n> already sparse-aware.\n>\n> Teach merge-ours to opt out of requiring a full index by setting\n> command_requires_full_index to 0.\n\n> Because merge-ours is invoked as a\n> subprocess by \"git merge -s ours\"\n\nIt may be correct but I do not see a relevance\n\n> and never previously read config,\n> the global variables core_apply_sparse_checkout and\n> core_sparse_checkout_cone remained unset,\n\nThis may be correct, but it only becomes relevant after somebody\ndecides to do something to cause is_sparse_index_allowed() to say\nYes.\n\n> causing\n> is_sparse_index_allowed() to return false and the index to be expanded\n> anyway. Add a repo_config() call with git_default_config to populate\n> these globals.\n\nIn total, while individual sentences in the above may tell correct\nthings, the order of presentation makes it hard to understand, at\nleast to me.\n\nThe usual way to compose a log message of this project is to\n\n - Give an observation on how the current system works in the\n   present tense (so no need to say \"Currently X is Y\", or\n   \"Previously X was Y\" to describe the state before your change;\n   just \"X is Y\" is enough), and discuss what you perceive as a\n   problem in it.\n\n - Propose a solution (optional---often, problem description\n   trivially leads to an obvious solution in reader's minds).\n\n - Give commands to somebody editing the codebase to \"make it so\",\n   instead of saying \"This commit does X\".\n\nin this order.\n\nSo perhaps\n\n    The merge-ours built-in opens the index to compare it against\n    HEAD.  The machinery used to do this (i.e. run_diff_index()) is\n    capable of working with sparse index, but because of the start\n    up sequence of this command does not take necessary steps, we\n    end up first expanding the index fully before doing this\n    comparison.\n\n    In order to convince sparse-index.c:is_sparse_index_allowed() to\n    return true, we need to:\n\n    - enable the global switch \"core_apply_sparse_checkout\" via\n      the core.sparsecheckout configuration variable.  merge-ours\n      currently do not even read basic configuration, so we need to\n      make the configuration call ourselves.\n\n    - set command_requires_full_index to 0.\n\n    With that, the command can work without expanding the index\n    fully before doing its work.\n\nor something.\n\nThanks.\n\n> Add tests to t1092 verifying that \"git merge -s ours\" produces\n> identical results across full-checkout, sparse-checkout, and\n> sparse-index modes, including verifying the resulting merge commit\n> structure, and that the sparse index is not expanded during the\n> operation.\n>\n> Signed-off-by: Sam Bostock <sam@sambostock.ca>\n> ---\n>  builtin/merge-ours.c                     |  6 ++++++\n>  t/t1092-sparse-checkout-compatibility.sh | 14 ++++++++++++++\n>  2 files changed, 20 insertions(+)\n>\n> diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c\n> index 2312e58ab3..405b2989f7 100644\n> --- a/builtin/merge-ours.c\n> +++ b/builtin/merge-ours.c\n> @@ -10,6 +10,8 @@\n>  \n>  #include \"git-compat-util.h\"\n>  #include \"builtin.h\"\n> +#include \"config.h\"\n> +#include \"environment.h\"\n>  #include \"diff.h\"\n>  \n>  static const char builtin_merge_ours_usage[] =\n> @@ -22,6 +24,10 @@ int cmd_merge_ours(int argc,\n>  {\n>  \tshow_usage_if_asked(argc, argv, builtin_merge_ours_usage);\n>  \n> +\trepo_config(repo, git_default_config, NULL);\n> +\tprepare_repo_settings(repo);\n> +\trepo->settings.command_requires_full_index = 0;\n> +\n>  \t/*\n>  \t * The contents of the current index becomes the tree we\n>  \t * commit.  The index must match HEAD, or this merge cannot go\n> diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh\n> index b0f691c151..d98cb4ac11 100755\n> --- a/t/t1092-sparse-checkout-compatibility.sh\n> +++ b/t/t1092-sparse-checkout-compatibility.sh\n> @@ -2559,4 +2559,18 @@ test_expect_success 'cat-file --batch' '\n>  \tensure_expanded cat-file --batch <in\n>  '\n>  \n> +test_expect_success 'merge -s ours' '\n> +\tinit_repos &&\n> +\n> +\ttest_all_match git rev-parse HEAD^{tree} &&\n> +\ttest_all_match git merge -s ours merge-right &&\n> +\ttest_all_match git rev-parse HEAD^{tree} &&\n> +\ttest_all_match git rev-parse HEAD^2\n> +'\n> +\n> +test_expect_success 'sparse-index is not expanded: merge-ours' '\n> +\tinit_repos &&\n> +\tensure_not_expanded merge -s ours merge-right\n> +'\n> +\n>  test_done\n"},{"id":"535347","messageId":"aYYCesJsZMdHu1Ia@pks.im","threadId":"64932","inReplyTo":"6cb970e512c02f0db11b8aae247aaa1675b31ef0.1770345124.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/2] merge-ours: drop USE_THE_REPOSITORY_VARIABLE","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-06T15:02:18Z","receivedAt":"2026-02-06T15:02:24Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Feb 06, 2026 at 02:32:03AM +0000, Sam Bostock via GitGitGadget wrote:\n> From: Sam Bostock <sam@sambostock.ca>\n> \n> Use the `repo` parameter passed to cmd_merge_ours() instead of\n> `the_repository`, and drop the USE_THE_REPOSITORY_VARIABLE macro that\n> is no longer needed.\n> \n> While at it, remove a stray double blank line between the #include\n> block and the usage string.\n\nNice to see that the required changes are this small, only :)\n\n> diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c\n> index 97b8a792c7..2312e58ab3 100644\n> --- a/builtin/merge-ours.c\n> +++ b/builtin/merge-ours.c\n> @@ -8,20 +8,17 @@\n>   * Pretend we resolved the heads, but declare our tree trumps everybody else.\n>   */\n>  \n> -#define USE_THE_REPOSITORY_VARIABLE\n> -\n>  #include \"git-compat-util.h\"\n>  #include \"builtin.h\"\n>  #include \"diff.h\"\n>  \n> -\n>  static const char builtin_merge_ours_usage[] =\n>  \t\"git merge-ours <base>... -- HEAD <remote>...\";\n>  \n>  int cmd_merge_ours(int argc,\n>  \t\t   const char **argv,\n>  \t\t   const char *prefix UNUSED,\n> -\t\t   struct repository *repo UNUSED)\n> +\t\t   struct repository *repo)\n>  {\n>  \tshow_usage_if_asked(argc, argv, builtin_merge_ours_usage);\n\nOne important part of the puzzle here is that git-merge-ours(1) cannot\nrun outside of a repository, as it is tagged with `RUN_SETUP`. So as a\nconsequence, `repo` will never be `NULL`, and thus all the changes to\ns/the_repository/repo/ are safe.\n\nPatrick\n"},{"id":"535371","messageId":"xmqqy0l5g4kw.fsf@gitster.g","threadId":"64932","inReplyTo":"aYYCesJsZMdHu1Ia@pks.im","subject":"Re: [PATCH 1/2] merge-ours: drop USE_THE_REPOSITORY_VARIABLE","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-02-06T17:33:03Z","receivedAt":"2026-02-06T17:33:05Z","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>> -\t\t   struct repository *repo UNUSED)\n>> +\t\t   struct repository *repo)\n>>  {\n>>  \tshow_usage_if_asked(argc, argv, builtin_merge_ours_usage);\n>\n> One important part of the puzzle here is that git-merge-ours(1) cannot\n> run outside of a repository, as it is tagged with `RUN_SETUP`. So as a\n> consequence, `repo` will never be `NULL`, and thus all the changes to\n> s/the_repository/repo/ are safe.\n\nIndeed.  It may be worth recording that reasoning in the log\nmessage.\n"},{"id":"535381","messageId":"pull.2189.v2.git.git.1770405383.gitgitgadget@gmail.com","threadId":"64932","inReplyTo":"pull.2189.git.git.1770345124.gitgitgadget@gmail.com","subject":"[PATCH v2 0/2] merge-ours: sparse-index integration","fromName":"Sam Bostock via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-06T19:16:21Z","receivedAt":"2026-02-06T19:16:26Z","isPatch":true,"sender":{"key":"sam.bostock@shopify.com","avatar":"https://avatars.githubusercontent.com/u/8219340?v=4"},"body":"This short series teaches merge-ours to work with a sparse index as a small\nstep toward broader sparse-index support.\n\nPatch 1 is a preparatory cleanup that converts merge-ours away from\nthe_repository global, using the repo parameter instead.\n\nPatch 2 adds the actual sparse-index integration and tests.\n\nChanges since v1:\n\n * Patch 1: note in commit message that RUN_SETUP guarantees repo is never\n   NULL (Patrick, Junio)\n * Patch 2: rewrite commit message to follow the project's standard log\n   message structure (Junio)\n\nThanks Junio and Patrick for the review.\n\nDeveloped with AI assistance (Claude).\n\nSam Bostock (2):\n  merge-ours: drop USE_THE_REPOSITORY_VARIABLE\n  merge-ours: integrate with sparse-index\n\n builtin/merge-ours.c                     | 15 +++++++++------\n t/t1092-sparse-checkout-compatibility.sh | 14 ++++++++++++++\n 2 files changed, 23 insertions(+), 6 deletions(-)\n\n\nbase-commit: b2826b52eb7caff9f4ed6e85ec45e338bf02ad09\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2189%2Fsambostock%2Fsb%2Fmerge-ours-sparse-index-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2189/sambostock/sb/merge-ours-sparse-index-v2\nPull-Request: https://github.com/git/git/pull/2189\n\nRange-diff vs v1:\n\n 1:  6cb970e512 ! 1:  775d76df69 merge-ours: drop USE_THE_REPOSITORY_VARIABLE\n     @@ Metadata\n       ## Commit message ##\n          merge-ours: drop USE_THE_REPOSITORY_VARIABLE\n      \n     -    Use the `repo` parameter passed to cmd_merge_ours() instead of\n     -    `the_repository`, and drop the USE_THE_REPOSITORY_VARIABLE macro that\n     -    is no longer needed.\n     +    The merge-ours built-in uses the `the_repository` global to access\n     +    the repository. The project is moving away from this global in favor\n     +    of the `repo` parameter that is passed to each built-in command.\n     +    Since merge-ours is registered with RUN_SETUP, `repo` is guaranteed\n     +    to be non-NULL and can be used directly.\n     +\n     +    Drop the USE_THE_REPOSITORY_VARIABLE macro and use `repo` throughout.\n      \n          While at it, remove a stray double blank line between the #include\n          block and the usage string.\n 2:  20b9e0bf6e ! 2:  55d39ff778 merge-ours: integrate with sparse-index\n     @@ Metadata\n       ## Commit message ##\n          merge-ours: integrate with sparse-index\n      \n     -    The merge-ours builtin reads the index only to compare it against HEAD\n     -    via index_differs_from(), whose diff machinery (run_diff_index) is\n     -    already sparse-aware.\n     +    The merge-ours built-in opens the index to compare it against HEAD.\n     +    The machinery used to do this (i.e. run_diff_index()) is capable of\n     +    working with a sparse index, but the start-up sequence of this\n     +    command does not take the necessary steps, so we end up expanding the\n     +    index fully before doing the comparison.\n      \n     -    Teach merge-ours to opt out of requiring a full index by setting\n     -    command_requires_full_index to 0. Because merge-ours is invoked as a\n     -    subprocess by \"git merge -s ours\" and never previously read config,\n     -    the global variables core_apply_sparse_checkout and\n     -    core_sparse_checkout_cone remained unset, causing\n     -    is_sparse_index_allowed() to return false and the index to be expanded\n     -    anyway. Add a repo_config() call with git_default_config to populate\n     -    these globals.\n     +    In order to convince sparse-index.c:is_sparse_index_allowed() to\n     +    return true, we need to:\n      \n     -    Add tests to t1092 verifying that \"git merge -s ours\" produces\n     -    identical results across full-checkout, sparse-checkout, and\n     -    sparse-index modes, including verifying the resulting merge commit\n     -    structure, and that the sparse index is not expanded during the\n     -    operation.\n     +     - Read basic configuration with git_default_config so that global\n     +       variables like core_apply_sparse_checkout are populated.\n     +       merge-ours currently does not read configuration at all.\n     +\n     +     - Set command_requires_full_index to 0.\n     +\n     +    With that, the command can work without expanding the index fully\n     +    before doing its work.\n      \n          Signed-off-by: Sam Bostock <sam@sambostock.ca>\n      \n\n-- \ngitgitgadget\n"},{"id":"535382","messageId":"55d39ff778b7156d1a1abba4ccc3ea41ae680d2f.1770405383.git.gitgitgadget@gmail.com","threadId":"64932","inReplyTo":"pull.2189.v2.git.git.1770405383.gitgitgadget@gmail.com","subject":"[PATCH v2 2/2] merge-ours: integrate with sparse-index","fromName":"Sam Bostock via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-06T19:16:23Z","receivedAt":"2026-02-06T19:16:29Z","isPatch":true,"sender":{"key":"sam.bostock@shopify.com","avatar":"https://avatars.githubusercontent.com/u/8219340?v=4"},"body":"From: Sam Bostock <sam@sambostock.ca>\n\nThe merge-ours built-in opens the index to compare it against HEAD.\nThe machinery used to do this (i.e. run_diff_index()) is capable of\nworking with a sparse index, but the start-up sequence of this\ncommand does not take the necessary steps, so we end up expanding the\nindex fully before doing the comparison.\n\nIn order to convince sparse-index.c:is_sparse_index_allowed() to\nreturn true, we need to:\n\n - Read basic configuration with git_default_config so that global\n   variables like core_apply_sparse_checkout are populated.\n   merge-ours currently does not read configuration at all.\n\n - Set command_requires_full_index to 0.\n\nWith that, the command can work without expanding the index fully\nbefore doing its work.\n\nSigned-off-by: Sam Bostock <sam@sambostock.ca>\n---\n builtin/merge-ours.c                     |  6 ++++++\n t/t1092-sparse-checkout-compatibility.sh | 14 ++++++++++++++\n 2 files changed, 20 insertions(+)\n\ndiff --git a/builtin/merge-ours.c b/builtin/merge-ours.c\nindex 2312e58ab3..405b2989f7 100644\n--- a/builtin/merge-ours.c\n+++ b/builtin/merge-ours.c\n@@ -10,6 +10,8 @@\n \n #include \"git-compat-util.h\"\n #include \"builtin.h\"\n+#include \"config.h\"\n+#include \"environment.h\"\n #include \"diff.h\"\n \n static const char builtin_merge_ours_usage[] =\n@@ -22,6 +24,10 @@ int cmd_merge_ours(int argc,\n {\n \tshow_usage_if_asked(argc, argv, builtin_merge_ours_usage);\n \n+\trepo_config(repo, git_default_config, NULL);\n+\tprepare_repo_settings(repo);\n+\trepo->settings.command_requires_full_index = 0;\n+\n \t/*\n \t * The contents of the current index becomes the tree we\n \t * commit.  The index must match HEAD, or this merge cannot go\ndiff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh\nindex b0f691c151..d98cb4ac11 100755\n--- a/t/t1092-sparse-checkout-compatibility.sh\n+++ b/t/t1092-sparse-checkout-compatibility.sh\n@@ -2559,4 +2559,18 @@ test_expect_success 'cat-file --batch' '\n \tensure_expanded cat-file --batch <in\n '\n \n+test_expect_success 'merge -s ours' '\n+\tinit_repos &&\n+\n+\ttest_all_match git rev-parse HEAD^{tree} &&\n+\ttest_all_match git merge -s ours merge-right &&\n+\ttest_all_match git rev-parse HEAD^{tree} &&\n+\ttest_all_match git rev-parse HEAD^2\n+'\n+\n+test_expect_success 'sparse-index is not expanded: merge-ours' '\n+\tinit_repos &&\n+\tensure_not_expanded merge -s ours merge-right\n+'\n+\n test_done\n-- \ngitgitgadget\n"},{"id":"535383","messageId":"775d76df69c118e0dbf24522eb3e75f58d6e9240.1770405383.git.gitgitgadget@gmail.com","threadId":"64932","inReplyTo":"pull.2189.v2.git.git.1770405383.gitgitgadget@gmail.com","subject":"[PATCH v2 1/2] merge-ours: drop USE_THE_REPOSITORY_VARIABLE","fromName":"Sam Bostock via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-06T19:16:22Z","receivedAt":"2026-02-06T19:16:29Z","isPatch":true,"sender":{"key":"sam.bostock@shopify.com","avatar":"https://avatars.githubusercontent.com/u/8219340?v=4"},"body":"From: Sam Bostock <sam@sambostock.ca>\n\nThe merge-ours built-in uses the `the_repository` global to access\nthe repository. The project is moving away from this global in favor\nof the `repo` parameter that is passed to each built-in command.\nSince merge-ours is registered with RUN_SETUP, `repo` is guaranteed\nto be non-NULL and can be used directly.\n\nDrop the USE_THE_REPOSITORY_VARIABLE macro and use `repo` throughout.\n\nWhile at it, remove a stray double blank line between the #include\nblock and the usage string.\n\nSigned-off-by: Sam Bostock <sam@sambostock.ca>\n---\n builtin/merge-ours.c | 9 +++------\n 1 file changed, 3 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/merge-ours.c b/builtin/merge-ours.c\nindex 97b8a792c7..2312e58ab3 100644\n--- a/builtin/merge-ours.c\n+++ b/builtin/merge-ours.c\n@@ -8,20 +8,17 @@\n  * Pretend we resolved the heads, but declare our tree trumps everybody else.\n  */\n \n-#define USE_THE_REPOSITORY_VARIABLE\n-\n #include \"git-compat-util.h\"\n #include \"builtin.h\"\n #include \"diff.h\"\n \n-\n static const char builtin_merge_ours_usage[] =\n \t\"git merge-ours <base>... -- HEAD <remote>...\";\n \n int cmd_merge_ours(int argc,\n \t\t   const char **argv,\n \t\t   const char *prefix UNUSED,\n-\t\t   struct repository *repo UNUSED)\n+\t\t   struct repository *repo)\n {\n \tshow_usage_if_asked(argc, argv, builtin_merge_ours_usage);\n \n@@ -30,9 +27,9 @@ int cmd_merge_ours(int argc,\n \t * commit.  The index must match HEAD, or this merge cannot go\n \t * through.\n \t */\n-\tif (repo_read_index(the_repository) < 0)\n+\tif (repo_read_index(repo) < 0)\n \t\tdie_errno(\"read_cache failed\");\n-\tif (index_differs_from(the_repository, \"HEAD\", NULL, 0))\n+\tif (index_differs_from(repo, \"HEAD\", NULL, 0))\n \t\treturn 2;\n \treturn 0;\n }\n-- \ngitgitgadget\n\n"},{"id":"535544","messageId":"aYn3pnjC7WUr6jfc@pks.im","threadId":"64932","inReplyTo":"pull.2189.v2.git.git.1770405383.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/2] merge-ours: sparse-index integration","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-02-09T15:05:10Z","receivedAt":"2026-02-09T15:05:16Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Feb 06, 2026 at 07:16:21PM +0000, Sam Bostock via GitGitGadget wrote:\n> This short series teaches merge-ours to work with a sparse index as a small\n> step toward broader sparse-index support.\n> \n> Patch 1 is a preparatory cleanup that converts merge-ours away from\n> the_repository global, using the repo parameter instead.\n> \n> Patch 2 adds the actual sparse-index integration and tests.\n> \n> Changes since v1:\n> \n>  * Patch 1: note in commit message that RUN_SETUP guarantees repo is never\n>    NULL (Patrick, Junio)\n>  * Patch 2: rewrite commit message to follow the project's standard log\n>    message structure (Junio)\n\nI'm happy with this version of the patch series, thanks!\n\nPatrick\n"},{"id":"535639","messageId":"b365b5a8-b66c-40ac-bd85-a57aa9fa7d12@gmail.com","threadId":"64932","inReplyTo":"pull.2189.v2.git.git.1770405383.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/2] merge-ours: sparse-index integration","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2026-02-10T04:35:48Z","receivedAt":"2026-02-10T04:35:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/6/2026 2:16 PM, Sam Bostock via GitGitGadget wrote:\n> This short series teaches merge-ours to work with a sparse index as a small\n> step toward broader sparse-index support.\n> \n> Patch 1 is a preparatory cleanup that converts merge-ours away from\n> the_repository global, using the repo parameter instead.\n> \n> Patch 2 adds the actual sparse-index integration and tests.\n\nThanks for working in this area. We have a long tail of instances where\nthe sparse-index could be integrated at its most bare-minimum case.\n\n> Developed with AI assistance (Claude).\n\nMy experiments with such tools seem to do well when there are clear\nexamples of how to make tests and how to make appropriate fixes. The\ntests added to t1092 follow the standard model for checking that\nthe index isn't expanded. Perhaps the many cases we have for these\nintegrations could be tackled more easily with such tools. I expect\nthat they are _mostly_ boilerplate tests and minor fixes (but don't\nlook too closely at 'git mv' which doesn't have clear patterns with\nsparse-checkout even with a full index).\n\nThe one thing I didn't see that we normally see is a case where the\nsparse index _is_ expanded, but that shouldn't happen with the 'ours'\nstrategy! Excellent.\n\nThese patches LGTM.\n\nThanks,\n-Stolee\n\n"}]}