git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] read-cache: avoid sparse-index expansion for unborn HEAD

From
Elijah Newren <newren@gmail.com>
Date
Aug 7, 2026, 06:47 UTC
Message-ID
<CABPp-BGYuQA_ngR3xS-_Mndzf_ubkn7rSc25CJG=UbLCVGdnyg@mail.gmail.com>
In-Reply-To
<20260802212826.1090943-1-sahityajb@gmail.com>
On Sun, Aug 2, 2026 at 2:28 PM Sahitya Chandra <sahityajb@gmail.com> wrote:
Show 22 quoted lines
>
> repo_index_has_changes() normally checks whether the index differs from
> a tree by passing that tree to the diff machinery. When no tree is
> passed, it tries to use HEAD for that comparison.
>
> If HEAD does not resolve, as on an unborn branch, the function falls
> back to walking the index directly. With a sparse index, however, sparse
> directory entries may stand in for many paths, so the fallback first
> expands the index before reporting the changed paths.
>
> That expansion is unnecessary. An unborn HEAD is equivalent for this
> check to comparing the index against the empty tree: every index entry
> is new relative to that tree.
>
> Use the empty tree when HEAD cannot be resolved. This keeps the
> unborn-branch case on the same diff code path as the normal
> tree-comparison case, avoiding the sparse-index expansion while still
> letting callers see paths inside sparse directories.
>
> Teach test-tool read-cache to exercise repo_index_has_changes(), and
> add a t1092 check that the unborn-branch case reports paths inside a
> sparse directory without expanding the index.

This explains what, but not why. It feels like a pedagogical exercise with no actual utility. Why would someone with an unborn HEAD be using a sparse index? They have millions of files, with none of them committed, except they don't have millions of files because they only have paths under certain directories? How did they even get the relevant tree entries into the sparse index in order to have one?

Perhaps you have a great usecase and I've just missed it. Could you explain the motivation for enabling this? Or was it more a case of trying to take care of TODOs in the code?

[...]
Show 18 quoted lines
> @@ -12,6 +13,24 @@ int cmd__read_cache(int argc, const char **argv)
>         int i, cnt = 1;
>         const char *name = NULL;
>
> +       if (argc == 2 && !strcmp(argv[1], "--index-has-changes")) {
> +               struct strbuf sb = STRBUF_INIT;
> +               int ret;
> +
> +               setup_git_directory(the_repository);
> +               repo_config(the_repository, git_default_config, NULL);
> +               prepare_repo_settings(the_repository);
> +               the_repository->settings.command_requires_full_index = 0;
> +
> +               repo_read_index(the_repository);
> +               ret = repo_index_has_changes(the_repository, NULL, &sb);
> +               printf("has_changes=%d\n", ret);
> +               if (sb.len)
> +                       printf("dirty=%s\n", sb.buf);

This seems to presume a single dirty file, otherwise wouldn't the printing look pretty odd?

Previous: Sahitya ChandraNext: Sahitya Chandra
Message 3 of 6 in “read-cache: avoid sparse-index expansion for unborn HEAD”
  1. read-cache: avoid sparse-index expansion for unborn HEADSahitya Chandra, Aug 2, 2026
  2. Sahitya ChandraAug 6, 2026
  3. Elijah NewrenAug 7, 2026
  4. Sahitya ChandraAug 7, 2026
  5. Elijah NewrenAug 7, 2026
  6. Sahitya ChandraSep 11, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.