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

[PATCH 4/6] read-cache: look for shared index files next to the index, too

From
SZEDER Gábor <szeder.dev@gmail.com>
Date
Aug 17, 2021, 17:49 UTC
Message-ID
<20210817174938.3009923-5-szeder.dev@gmail.com>
In-Reply-To
<20210817174938.3009923-1-szeder.dev@gmail.com>

When reading a split index git always looks for its referenced shared base index in the gitdir of the current repository, even when reading an alternate index specified via GIT_INDEX_FILE, and even when that alternate index file is the "main" '.git/index' file of an other repository. However, if that split index and its referenced shared index files were written by a git command running entirely in that other repository, then, naturally, the shared index file is written to that other repository's gitdir. Consequently, a git command attempting to read that shared index file while running in a different repository won't be able find it and will error out.

I'm not sure in what use case it is necessary to read the index of one repository by a git command running in a different repository, but it is certainly possible to do so, and in fact the test 'bare repository: check that --cached honors index' in 't0003-attributes.sh' does exactly that. If GIT_TEST_SPLIT_INDEX=1 were to split the index in just the right moment [1], then this test would indeed fail, because the referenced shared index file could not be found.

Let's look for the referenced shared index file not only in the gitdir of the current directory, but, if the shared index is not there, right next to the split index as well.

[1] We haven't seen this issue trigger a failure in t0003 yet,
    because:
      - While GIT_TEST_SPLIT_INDEX=1 is supposed to trigger index
        splitting randomly, the first index write has always been
        deterministic and it has never split the index.
      - That alternate index file in the other repository is written
        only once in the entire test script, so it's never split.
    However, the next patch will fix GIT_TEST_SPLIT_INDEX, and while
    doing so it will slightly change its behavior to always split the
    index already on the first index write, and t0003 would always
    fail without this patch.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 read-cache.c           | 14 +++++++++++++-
 t/t1700-split-index.sh | 23 +++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/read-cache.c b/read-cache.c
index 9048ef9e90..fbd59886a3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2391,9 +2391,21 @@ int read_index_from(struct index_state *istate, const char *path,
 	base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex);
 	trace2_region_enter_printf("index", "shared/do_read_index",
 				   the_repository, "%s", base_path);
-	ret = do_read_index(split_index->base, base_path, 1);
+	ret = do_read_index(split_index->base, base_path, 0);
 	trace2_region_leave_printf("index", "shared/do_read_index",
 				   the_repository, "%s", base_path);
+	if (!ret) {
+		char *path_copy = xstrdup(path);
+		const char *base_path2 = xstrfmt("%s/sharedindex.%s",
+						 dirname(path_copy),
+						 base_oid_hex);
+		free(path_copy);
+		trace2_region_enter_printf("index", "shared/do_read_index",
+					   the_repository, "%s", base_path2);
+		ret = do_read_index(split_index->base, base_path2, 1);
+		trace2_region_leave_printf("index", "shared/do_read_index",
+					   the_repository, "%s", base_path2);
+	}
 	if (!oideq(&split_index->base_oid, &split_index->base->oid))
 		die(_("broken index, expect %s in %s, got %s"),
 		    base_oid_hex, base_path,
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index 986baa612e..e2aa0bd949 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -510,4 +510,27 @@ test_expect_success 'do not refresh null base index' '
 	)
 '
 
+test_expect_success 'reading split index at alternate location' '
+	git init reading-alternate-location &&
+	(
+		cd reading-alternate-location &&
+		>file-in-alternate &&
+		git update-index --split-index --add file-in-alternate
+	) &&
+	echo file-in-alternate >expect &&
+
+	# Should be able to find the shared index both right next to
+	# the specified split index file ...
+	GIT_INDEX_FILE=./reading-alternate-location/.git/index \
+	git ls-files --cached >actual &&
+	test_cmp expect actual &&
+
+	# ... and, for backwards compatibility, in the current GIT_DIR
+	# as well.
+	mv -v ./reading-alternate-location/.git/sharedindex.* .git &&
+	GIT_INDEX_FILE=./reading-alternate-location/.git/index \
+	git ls-files --cached >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
2.33.0.453.gc5e41af357
Previous: SZEDER GáborNext: SZEDER Gábor
Message 8 of 23 in “Fix GIT_TEST_SPLIT_INDEX”
  1. 0/6 Fix GIT_TEST_SPLIT_INDEXSZEDER Gábor, Aug 17, 2021
  2. 1/6 t1600-index: remove unnecessary redirectionSZEDER Gábor, Aug 17, 2021
  3. Derrick StoleeAug 17, 2021
  4. SZEDER GáborAug 17, 2021
  5. Derrick StoleeAug 17, 2021
  6. 2/6 t1600-index: don't run git commands upstream of a pipeSZEDER Gábor, Aug 17, 2021
  7. 3/6 t1600-index: disable GIT_TEST_SPLIT_INDEXSZEDER Gábor, Aug 17, 2021
  8. 4/6 read-cache: look for shared index files next to the index, tooSZEDER Gábor, Aug 17, 2021
  9. 5/6 tests: disable GIT_TEST_SPLIT_INDEX for sparse index testsSZEDER Gábor, Aug 17, 2021
  10. Derrick StoleeAug 17, 2021
  11. SZEDER GáborAug 17, 2021
  12. Derrick StoleeAug 18, 2021
  13. 6/6 read-cache: fix GIT_TEST_SPLIT_INDEXSZEDER Gábor, Aug 17, 2021
  14. Derrick StoleeAug 17, 2021
  15. 0/6 Fix GIT_TEST_SPLIT_INDEXSZEDER Gábor, Aug 26, 2021
  16. 1/6 t1600-index: remove unnecessary redirectionSZEDER Gábor, Aug 26, 2021
  17. 2/6 t1600-index: don't run git commands upstream of a pipeSZEDER Gábor, Aug 26, 2021
  18. 3/6 t1600-index: disable GIT_TEST_SPLIT_INDEXSZEDER Gábor, Aug 26, 2021
  19. 4/6 read-cache: look for shared index files next to the index, tooSZEDER Gábor, Aug 26, 2021
  20. 6/6 read-cache: fix GIT_TEST_SPLIT_INDEXSZEDER Gábor, Aug 26, 2021
  21. 5/6 tests: disable GIT_TEST_SPLIT_INDEX for sparse index testsSZEDER Gábor, Aug 26, 2021
  22. Derrick StoleeAug 31, 2021
  23. Junio C HamanoAug 31, 2021

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.