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

[PATCH 4/4] object-name: diagnose trees in index properly

From
Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>
Date
Apr 7, 2022, 16:37 UTC
Message-ID
<99c09ccc2406e4f54c620bd7fb2d1205386e23a6.1649349442.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1207.git.1649349442.gitgitgadget@gmail.com>
From: Derrick Stolee <derrickstolee@github.com>

When running 'git show :<path>' where '<path>' is a directory, then there is a subtle difference between a full checkout and a sparse checkout. The error message from diagnose_invalid_index_path() reports whether the path is on disk or not. The full checkout will have the directory on disk, but the path will not be in the index. The sparse checokut could have the directory not exist, specifically when that directory is outside of the sparse-checkout cone.

In the case of a sparse index, we have yet another state: the path can be a sparse directory in the index. In this case, the error message from diagnose_invalid_index_path() would erroneously say "path '<path>' is in the index, but not at stage 0", which is false.

Add special casing around sparse directory entries so we get to the correct error message. This requires two checks in order to get parity with the normal sparse-checkout case.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
---
 object-name.c                            |  6 ++++--
 t/t1092-sparse-checkout-compatibility.sh | 13 +++++++++++--
 2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/object-name.c b/object-name.c
index 2dc5d2549b8..4d2746574cd 100644
--- a/object-name.c
+++ b/object-name.c
@@ -1832,7 +1832,8 @@ static void diagnose_invalid_index_path(struct repository *r,
 		pos = -pos - 1;
 	if (pos < istate->cache_nr) {
 		ce = istate->cache[pos];
-		if (ce_namelen(ce) == namelen &&
+		if (!S_ISSPARSEDIR(ce->ce_mode) &&
+		    ce_namelen(ce) == namelen &&
 		    !memcmp(ce->name, filename, namelen))
 			die(_("path '%s' is in the index, but not at stage %d\n"
 			    "hint: Did you mean ':%d:%s'?"),
@@ -1848,7 +1849,8 @@ static void diagnose_invalid_index_path(struct repository *r,
 		pos = -pos - 1;
 	if (pos < istate->cache_nr) {
 		ce = istate->cache[pos];
-		if (ce_namelen(ce) == fullname.len &&
+		if (!S_ISSPARSEDIR(ce->ce_mode) &&
+		    ce_namelen(ce) == fullname.len &&
 		    !memcmp(ce->name, fullname.buf, fullname.len))
 			die(_("path '%s' is in the index, but not '%s'\n"
 			    "hint: Did you mean ':%d:%s' aka ':%d:./%s'?"),
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 9d32361110d..921cafb950a 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -1164,8 +1164,17 @@ test_expect_success 'show (cached blobs/trees)' '
 	test_must_fail git -C full-checkout show :folder1/ &&
 	test_must_fail git -C sparse-checkout show :folder1/ &&
 
-	test_must_fail git -C sparse-index show :folder1/ 2>err &&
-	grep "is in the index, but not at stage 0" err
+	test_sparse_match test_must_fail git show :folder1/ &&
+
+	# Change the sparse cone for an extra case:
+	run_on_sparse git sparse-checkout set deep/deeper1 &&
+
+	# deep/deeper2 is a sparse directory in the sparse index.
+	test_sparse_match test_must_fail git show :deep/deeper2/ &&
+
+	# deep/deeper2/deepest is not in the sparse index, but
+	# will trigger an index expansion.
+	test_sparse_match test_must_fail git show :deep/deeper2/deepest/
 '
 
 test_expect_success 'submodule handling' '
-- 
gitgitgadget
Previous: Derrick StoleeNext: Philip Oakley
Message 11 of 26 in “Sparse index integration with 'git show'”
  1. 0/4 Sparse index integration with 'git show'Derrick Stolee via GitGitGadget, Apr 7, 2022
  2. 1/4 t1092: add compatibility tests for 'git show'Derrick Stolee via GitGitGadget, Apr 7, 2022
  3. Josh SteadmonApr 14, 2022
  4. Derrick StoleeApr 18, 2022
  5. 2/4 show: integrate with the sparse indexDerrick Stolee via GitGitGadget, Apr 7, 2022
  6. Josh SteadmonApr 14, 2022
  7. Derrick StoleeApr 18, 2022
  8. 3/4 object-name: reject trees found in the indexDerrick Stolee via GitGitGadget, Apr 7, 2022
  9. Josh SteadmonApr 14, 2022
  10. Derrick StoleeApr 18, 2022
  11. 4/4 object-name: diagnose trees in index properlyDerrick Stolee via GitGitGadget, Apr 7, 2022
  12. Philip OakleyApr 7, 2022
  13. Junio C HamanoApr 12, 2022
  14. Derrick StoleeApr 12, 2022
  15. Junio C HamanoApr 12, 2022
  16. Josh SteadmonApr 14, 2022
  17. Junio C HamanoApr 14, 2022
  18. Derrick StoleeApr 18, 2022
  19. 0/5 Sparse index integration with 'git show'Derrick Stolee via GitGitGadget, Apr 26, 2022
  20. 1/5 t1092: add compatibility tests for 'git show'Derrick Stolee via GitGitGadget, Apr 26, 2022
  21. 2/5 show: integrate with the sparse indexDerrick Stolee via GitGitGadget, Apr 26, 2022
  22. 3/5 object-name: reject trees found in the indexDerrick Stolee via GitGitGadget, Apr 26, 2022
  23. 4/5 object-name: diagnose trees in index properlyDerrick Stolee via GitGitGadget, Apr 26, 2022
  24. 5/5 rev-parse: integrate with sparse indexDerrick Stolee via GitGitGadget, Apr 26, 2022
  25. Junio C HamanoApr 26, 2022
  26. Derrick StoleeApr 27, 2022

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.