Skip to content

Commit 95e0321

Browse files
derrickstoleegitster
authored andcommitted
read-cache: expand on query into sparse-directory entry
Callers to index_name_pos() or index_name_stage_pos() have a specific path in mind. If that happens to be a path with an ancestor being a sparse-directory entry, it can lead to unexpected results. In the case that we did not find the requested path, check to see if the position _before_ the inserted position is a sparse directory entry that matches the initial segment of the input path (including the directory separator at the end of the directory name). If so, then expand the index to be a full index and search again. This expansion will only happen once per index read. Future enhancements could be more careful to expand only the necessary sparse directory entry, but then we would have a special "not fully sparse, but also not fully expanded" mode that could affect writing the index to file. Since this only occurs if a specific file is requested outside of the sparse checkout definition, this is unlikely to be a common situation. Signed-off-by: Derrick Stolee <[email protected]> Reviewed-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 847a9e5 commit 95e0321

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

read-cache.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,27 @@ static int index_name_stage_pos(struct index_state *istate, const char *name, in
567567
}
568568
first = next+1;
569569
}
570+
571+
if (istate->sparse_index &&
572+
first > 0) {
573+
/* Note: first <= istate->cache_nr */
574+
struct cache_entry *ce = istate->cache[first - 1];
575+
576+
/*
577+
* If we are in a sparse-index _and_ the entry before the
578+
* insertion position is a sparse-directory entry that is
579+
* an ancestor of 'name', then we need to expand the index
580+
* and search again. This will only trigger once, because
581+
* thereafter the index is fully expanded.
582+
*/
583+
if (S_ISSPARSEDIR(ce->ce_mode) &&
584+
ce_namelen(ce) < namelen &&
585+
!strncmp(name, ce->name, ce_namelen(ce))) {
586+
ensure_full_index(istate);
587+
return index_name_stage_pos(istate, name, namelen, stage);
588+
}
589+
}
590+
570591
return -first-1;
571592
}
572593

0 commit comments

Comments
 (0)