mirror of
https://github.com/git/git.git
synced 2024-11-28 04:23:30 +08:00
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 <dstolee@microsoft.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
847a9e5d4f
commit
95e0321c4d
21
read-cache.c
21
read-cache.c
@ -567,6 +567,27 @@ static int index_name_stage_pos(struct index_state *istate, const char *name, in
|
||||
}
|
||||
first = next+1;
|
||||
}
|
||||
|
||||
if (istate->sparse_index &&
|
||||
first > 0) {
|
||||
/* Note: first <= istate->cache_nr */
|
||||
struct cache_entry *ce = istate->cache[first - 1];
|
||||
|
||||
/*
|
||||
* If we are in a sparse-index _and_ the entry before the
|
||||
* insertion position is a sparse-directory entry that is
|
||||
* an ancestor of 'name', then we need to expand the index
|
||||
* and search again. This will only trigger once, because
|
||||
* thereafter the index is fully expanded.
|
||||
*/
|
||||
if (S_ISSPARSEDIR(ce->ce_mode) &&
|
||||
ce_namelen(ce) < namelen &&
|
||||
!strncmp(name, ce->name, ce_namelen(ce))) {
|
||||
ensure_full_index(istate);
|
||||
return index_name_stage_pos(istate, name, namelen, stage);
|
||||
}
|
||||
}
|
||||
|
||||
return -first-1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user