Merge branch 'ds/status-with-sparse-index'

"git status" codepath learned to work with sparsely populated index
without hydrating it fully.

* ds/status-with-sparse-index:
  t1092: document bad sparse-checkout behavior
  fsmonitor: integrate with sparse index
  wt-status: expand added sparse directory entries
  status: use sparse-index throughout
  status: skip sparse-checkout percentage with sparse-index
  diff-lib: handle index diffs with sparse dirs
  dir.c: accept a directory as part of cone-mode patterns
  unpack-trees: unpack sparse directory entries
  unpack-trees: rename unpack_nondirectories()
  unpack-trees: compare sparse directories correctly
  unpack-trees: preserve cache_bottom
  t1092: add tests for status/add and sparse files
  t1092: expand repository data shape
  t1092: replace incorrect 'echo' with 'cat'
  sparse-index: include EXTENDED flag when expanding
  sparse-index: skip indexes with unmerged entries
This commit is contained in:
Junio C Hamano
2021-07-28 13:18:01 -07:00
10 changed files with 471 additions and 39 deletions

24
dir.c
View File

@ -1380,7 +1380,7 @@ enum pattern_match_result path_matches_pattern_list(
struct path_pattern *pattern;
struct strbuf parent_pathname = STRBUF_INIT;
int result = NOT_MATCHED;
const char *slash_pos;
size_t slash_pos;
if (!pl->use_cone_patterns) {
pattern = last_matching_pattern_from_list(pathname, pathlen, basename,
@ -1401,21 +1401,35 @@ enum pattern_match_result path_matches_pattern_list(
strbuf_addch(&parent_pathname, '/');
strbuf_add(&parent_pathname, pathname, pathlen);
/*
* Directory entries are matched if and only if a file
* contained immediately within them is matched. For the
* case of a directory entry, modify the path to create
* a fake filename within this directory, allowing us to
* use the file-base matching logic in an equivalent way.
*/
if (parent_pathname.len > 0 &&
parent_pathname.buf[parent_pathname.len - 1] == '/') {
slash_pos = parent_pathname.len - 1;
strbuf_add(&parent_pathname, "-", 1);
} else {
const char *slash_ptr = strrchr(parent_pathname.buf, '/');
slash_pos = slash_ptr ? slash_ptr - parent_pathname.buf : 0;
}
if (hashmap_contains_path(&pl->recursive_hashmap,
&parent_pathname)) {
result = MATCHED_RECURSIVE;
goto done;
}
slash_pos = strrchr(parent_pathname.buf, '/');
if (slash_pos == parent_pathname.buf) {
if (!slash_pos) {
/* include every file in root */
result = MATCHED;
goto done;
}
strbuf_setlen(&parent_pathname, slash_pos - parent_pathname.buf);
strbuf_setlen(&parent_pathname, slash_pos);
if (hashmap_contains_path(&pl->parent_hashmap, &parent_pathname)) {
result = MATCHED;