Skip to content

Commit 4925adb

Browse files
derrickstoleegitster
authored andcommitted
object-name: diagnose trees in index properly
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 checkout 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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 561287d commit 4925adb

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

object-name.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,7 +1832,8 @@ static void diagnose_invalid_index_path(struct repository *r,
18321832
pos = -pos - 1;
18331833
if (pos < istate->cache_nr) {
18341834
ce = istate->cache[pos];
1835-
if (ce_namelen(ce) == namelen &&
1835+
if (!S_ISSPARSEDIR(ce->ce_mode) &&
1836+
ce_namelen(ce) == namelen &&
18361837
!memcmp(ce->name, filename, namelen))
18371838
die(_("path '%s' is in the index, but not at stage %d\n"
18381839
"hint: Did you mean ':%d:%s'?"),
@@ -1848,7 +1849,8 @@ static void diagnose_invalid_index_path(struct repository *r,
18481849
pos = -pos - 1;
18491850
if (pos < istate->cache_nr) {
18501851
ce = istate->cache[pos];
1851-
if (ce_namelen(ce) == fullname.len &&
1852+
if (!S_ISSPARSEDIR(ce->ce_mode) &&
1853+
ce_namelen(ce) == fullname.len &&
18521854
!memcmp(ce->name, fullname.buf, fullname.len))
18531855
die(_("path '%s' is in the index, but not '%s'\n"
18541856
"hint: Did you mean ':%d:%s' aka ':%d:./%s'?"),

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,15 +1158,21 @@ test_expect_success 'show (cached blobs/trees)' '
11581158
test_all_match git show :deep/a &&
11591159
test_sparse_match git show :folder1/a &&
11601160
1161-
# Asking "git show" for directories in the index
1162-
# had different behavior depending on the existence
1163-
# of a sparse index.
1161+
# The error message differs depending on whether
1162+
# the directory exists in the worktree.
11641163
test_all_match test_must_fail git show :deep/ &&
11651164
test_must_fail git -C full-checkout show :folder1/ &&
1166-
test_must_fail git -C sparse-checkout show :folder1/ &&
1165+
test_sparse_match test_must_fail git show :folder1/ &&
11671166
1168-
test_must_fail git -C sparse-index show :folder1/ 2>err &&
1169-
grep "is in the index, but not at stage 0" err
1167+
# Change the sparse cone for an extra case:
1168+
run_on_sparse git sparse-checkout set deep/deeper1 &&
1169+
1170+
# deep/deeper2 is a sparse directory in the sparse index.
1171+
test_sparse_match test_must_fail git show :deep/deeper2/ &&
1172+
1173+
# deep/deeper2/deepest is not in the sparse index, but
1174+
# will trigger an index expansion.
1175+
test_sparse_match test_must_fail git show :deep/deeper2/deepest/
11701176
'
11711177

11721178
test_expect_success 'submodule handling' '

0 commit comments

Comments
 (0)