Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rm/sparse-index-integration #6

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 1 addition & 83 deletions builtin/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,88 +174,6 @@ static void update_index_from_diff(struct diff_queue_struct *q,
}
}

static int pathspec_needs_expanded_index(const struct pathspec *pathspec)
ffyuanda marked this conversation as resolved.
Show resolved Hide resolved
{
unsigned int i, pos;
int res = 0;
char *skip_worktree_seen = NULL;

/*
* When using a magic pathspec, assume for the sake of simplicity that
* the index needs to be expanded to match all matchable files.
*/
if (pathspec->magic)
return 1;

for (i = 0; i < pathspec->nr; i++) {
struct pathspec_item item = pathspec->items[i];

/*
* If the pathspec item has a wildcard, the index should be expanded
* if the pathspec has the possibility of matching a subset of entries inside
* of a sparse directory (but not the entire directory).
*
* If the pathspec item is a literal path, the index only needs to be expanded
* if a) the pathspec isn't in the sparse checkout cone (to make sure we don't
* expand for in-cone files) and b) it doesn't match any sparse directories
* (since we can reset whole sparse directories without expanding them).
*/
if (item.nowildcard_len < item.len) {
/*
* Special case: if the pattern is a path inside the cone
* followed by only wildcards, the pattern cannot match
* partial sparse directories, so we know we don't need to
* expand the index.
*
* Examples:
* - in-cone/foo***: doesn't need expanded index
* - not-in-cone/bar*: may need expanded index
* - **.c: may need expanded index
*/
if (strspn(item.original + item.nowildcard_len, "*") == item.len - item.nowildcard_len &&
path_in_cone_mode_sparse_checkout(item.original, &the_index))
continue;

for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];

if (!S_ISSPARSEDIR(ce->ce_mode))
continue;

/*
* If the pre-wildcard length is longer than the sparse
* directory name and the sparse directory is the first
* component of the pathspec, need to expand the index.
*/
if (item.nowildcard_len > ce_namelen(ce) &&
!strncmp(item.original, ce->name, ce_namelen(ce))) {
res = 1;
break;
}

/*
* If the pre-wildcard length is shorter than the sparse
* directory and the pathspec does not match the whole
* directory, need to expand the index.
*/
if (!strncmp(item.original, ce->name, item.nowildcard_len) &&
wildmatch(item.original, ce->name, 0)) {
res = 1;
break;
}
}
} else if (!path_in_cone_mode_sparse_checkout(item.original, &the_index) &&
!matches_skip_worktree(pathspec, i, &skip_worktree_seen))
res = 1;

if (res > 0)
break;
}

free(skip_worktree_seen);
return res;
}

static int read_from_tree(const struct pathspec *pathspec,
struct object_id *tree_oid,
int intent_to_add)
Expand All @@ -273,7 +191,7 @@ static int read_from_tree(const struct pathspec *pathspec,
opt.change = diff_change;
opt.add_remove = diff_addremove;

if (pathspec->nr && the_index.sparse_index && pathspec_needs_expanded_index(pathspec))
if (pathspec->nr && the_index.sparse_index && pathspec_needs_expanded_index(&the_index, pathspec))
ensure_full_index(&the_index);

if (do_diff_cache(tree_oid, &opt))
Expand Down
83 changes: 83 additions & 0 deletions pathspec.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,3 +759,86 @@ int match_pathspec_attrs(struct index_state *istate,

return 1;
}

int pathspec_needs_expanded_index(struct index_state *istate,
const struct pathspec *pathspec)
ffyuanda marked this conversation as resolved.
Show resolved Hide resolved
{
unsigned int i, pos;
int res = 0;
char *skip_worktree_seen = NULL;

/*
* When using a magic pathspec, assume for the sake of simplicity that
* the index needs to be expanded to match all matchable files.
*/
if (pathspec->magic)
return 1;

for (i = 0; i < pathspec->nr; i++) {
struct pathspec_item item = pathspec->items[i];

/*
* If the pathspec item has a wildcard, the index should be expanded
* if the pathspec has the possibility of matching a subset of entries inside
* of a sparse directory (but not the entire directory).
*
* If the pathspec item is a literal path, the index only needs to be expanded
* if a) the pathspec isn't in the sparse checkout cone (to make sure we don't
* expand for in-cone files) and b) it doesn't match any sparse directories
* (since we can reset whole sparse directories without expanding them).
*/
if (item.nowildcard_len < item.len) {
/*
* Special case: if the pattern is a path inside the cone
* followed by only wildcards, the pattern cannot match
* partial sparse directories, so we know we don't need to
* expand the index.
*
* Examples:
* - in-cone/foo***: doesn't need expanded index
* - not-in-cone/bar*: may need expanded index
* - **.c: may need expanded index
*/
if (strspn(item.original + item.nowildcard_len, "*") == item.len - item.nowildcard_len &&
path_in_cone_mode_sparse_checkout(item.original, istate))
continue;

for (pos = 0; pos < istate->cache_nr; pos++) {
struct cache_entry *ce = istate->cache[pos];

if (!S_ISSPARSEDIR(ce->ce_mode))
continue;

/*
* If the pre-wildcard length is longer than the sparse
* directory name and the sparse directory is the first
* component of the pathspec, need to expand the index.
*/
if (item.nowildcard_len > ce_namelen(ce) &&
!strncmp(item.original, ce->name, ce_namelen(ce))) {
res = 1;
break;
}

/*
* If the pre-wildcard length is shorter than the sparse
* directory and the pathspec does not match the whole
* directory, need to expand the index.
*/
if (!strncmp(item.original, ce->name, item.nowildcard_len) &&
wildmatch(item.original, ce->name, 0)) {
res = 1;
break;
}
}
} else if (!path_in_cone_mode_sparse_checkout(item.original, istate) &&
!matches_skip_worktree(pathspec, i, &skip_worktree_seen))
res = 1;

if (res > 0)
break;
}

free(skip_worktree_seen);
return res;
}
3 changes: 3 additions & 0 deletions pathspec.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,7 @@ int match_pathspec_attrs(struct index_state *istate,
const char *name, int namelen,
const struct pathspec_item *item);

int pathspec_needs_expanded_index(struct index_state *istate,
ffyuanda marked this conversation as resolved.
Show resolved Hide resolved
const struct pathspec *pathspec);

#endif /* PATHSPEC_H */