From: Derrick Stolee <dstolee@xxxxxxxxxxxxx> Before we check if a specific file or directory exists in the index, it would be good to see if a leading directory is a sparse-directory. If so, we will want to expand the index _just enough_ to be sure that the paths we are interested in are in the index. The actually-interesting implementation will follow in a later change. For now, simply call ensure_full_index() to expand every directory simultaneously. Calls like index_dir_exists(), adjust_dirname_case(), and index_file_exists() in name-hash.c can trust the name hash if the index was properly expanded for the requested names. These methods can transition from ensure_full_index() to expand_to_path(). Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> --- name-hash.c | 10 ++++------ sparse-index.c | 7 +++++++ sparse-index.h | 12 ++++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/name-hash.c b/name-hash.c index 0f6d4fcca5a..641f6900a7c 100644 --- a/name-hash.c +++ b/name-hash.c @@ -8,6 +8,7 @@ #include "cache.h" #include "thread-utils.h" #include "trace2.h" +#include "sparse-index.h" struct dir_entry { struct hashmap_entry ent; @@ -679,9 +680,8 @@ int index_dir_exists(struct index_state *istate, const char *name, int namelen) { struct dir_entry *dir; - ensure_full_index(istate); - lazy_init_name_hash(istate); + expand_to_path(istate, name, namelen, 0); dir = find_dir_entry(istate, name, namelen); return dir && dir->nr; } @@ -691,9 +691,8 @@ void adjust_dirname_case(struct index_state *istate, char *name) const char *startPtr = name; const char *ptr = startPtr; - ensure_full_index( istate); - lazy_init_name_hash(istate); + expand_to_path(istate, name, strlen(name), 0); while (*ptr) { while (*ptr && *ptr != '/') ptr++; @@ -716,9 +715,8 @@ struct cache_entry *index_file_exists(struct index_state *istate, const char *na struct cache_entry *ce; unsigned int hash = memihash(name, namelen); - ensure_full_index(istate); - lazy_init_name_hash(istate); + expand_to_path(istate, name, namelen, icase); ce = hashmap_get_entry_from_hash(&istate->name_hash, hash, NULL, struct cache_entry, ent); diff --git a/sparse-index.c b/sparse-index.c index 3552f88fb03..dd1a06dfdd3 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -280,3 +280,10 @@ void ensure_full_index(struct index_state *istate) trace2_region_leave("index", "ensure_full_index", istate->repo); } + +void expand_to_path(struct index_state *istate, + const char *path, size_t pathlen, int icase) +{ + /* for now, do the obviously-correct, slow thing */ + ensure_full_index(istate); +} diff --git a/sparse-index.h b/sparse-index.h index ca936e95d11..549e4171f1a 100644 --- a/sparse-index.h +++ b/sparse-index.h @@ -4,6 +4,18 @@ struct index_state; void ensure_full_index(struct index_state *istate); int convert_to_sparse(struct index_state *istate); +/* + * Some places in the codebase expect to search for a specific path. + * This path might be outside of the sparse-checkout definition, in + * which case a sparse-index may not contain a path for that index. + * + * Given an index and a path, check to see if a leading directory for + * 'path' exists in the index as a sparse directory. In that case, + * expand that sparse directory to a full range of cache entries and + * populate the index accordingly. + */ +void expand_to_path(struct index_state *istate, + const char *path, size_t pathlen, int icase); struct repository; int set_sparse_index_config(struct repository *repo, int enable); -- gitgitgadget