Skip to content

Commit c8a1f6f

Browse files
committed
pathspec.h: move pathspec_needs_expanded_index() from reset.c to here
pathspec_needs_expanded_index() is reusable when we need to verify if the index needs to be expanded when the command is utilizing a pathspec rather than a literal path. Move it for reusability. Signed-off-by: Shaoxuan Yuan <[email protected]>
1 parent cba7676 commit c8a1f6f

File tree

3 files changed

+87
-83
lines changed

3 files changed

+87
-83
lines changed

builtin/reset.c

Lines changed: 1 addition & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -174,88 +174,6 @@ static void update_index_from_diff(struct diff_queue_struct *q,
174174
}
175175
}
176176

177-
static int pathspec_needs_expanded_index(const struct pathspec *pathspec)
178-
{
179-
unsigned int i, pos;
180-
int res = 0;
181-
char *skip_worktree_seen = NULL;
182-
183-
/*
184-
* When using a magic pathspec, assume for the sake of simplicity that
185-
* the index needs to be expanded to match all matchable files.
186-
*/
187-
if (pathspec->magic)
188-
return 1;
189-
190-
for (i = 0; i < pathspec->nr; i++) {
191-
struct pathspec_item item = pathspec->items[i];
192-
193-
/*
194-
* If the pathspec item has a wildcard, the index should be expanded
195-
* if the pathspec has the possibility of matching a subset of entries inside
196-
* of a sparse directory (but not the entire directory).
197-
*
198-
* If the pathspec item is a literal path, the index only needs to be expanded
199-
* if a) the pathspec isn't in the sparse checkout cone (to make sure we don't
200-
* expand for in-cone files) and b) it doesn't match any sparse directories
201-
* (since we can reset whole sparse directories without expanding them).
202-
*/
203-
if (item.nowildcard_len < item.len) {
204-
/*
205-
* Special case: if the pattern is a path inside the cone
206-
* followed by only wildcards, the pattern cannot match
207-
* partial sparse directories, so we know we don't need to
208-
* expand the index.
209-
*
210-
* Examples:
211-
* - in-cone/foo***: doesn't need expanded index
212-
* - not-in-cone/bar*: may need expanded index
213-
* - **.c: may need expanded index
214-
*/
215-
if (strspn(item.original + item.nowildcard_len, "*") == item.len - item.nowildcard_len &&
216-
path_in_cone_mode_sparse_checkout(item.original, &the_index))
217-
continue;
218-
219-
for (pos = 0; pos < active_nr; pos++) {
220-
struct cache_entry *ce = active_cache[pos];
221-
222-
if (!S_ISSPARSEDIR(ce->ce_mode))
223-
continue;
224-
225-
/*
226-
* If the pre-wildcard length is longer than the sparse
227-
* directory name and the sparse directory is the first
228-
* component of the pathspec, need to expand the index.
229-
*/
230-
if (item.nowildcard_len > ce_namelen(ce) &&
231-
!strncmp(item.original, ce->name, ce_namelen(ce))) {
232-
res = 1;
233-
break;
234-
}
235-
236-
/*
237-
* If the pre-wildcard length is shorter than the sparse
238-
* directory and the pathspec does not match the whole
239-
* directory, need to expand the index.
240-
*/
241-
if (!strncmp(item.original, ce->name, item.nowildcard_len) &&
242-
wildmatch(item.original, ce->name, 0)) {
243-
res = 1;
244-
break;
245-
}
246-
}
247-
} else if (!path_in_cone_mode_sparse_checkout(item.original, &the_index) &&
248-
!matches_skip_worktree(pathspec, i, &skip_worktree_seen))
249-
res = 1;
250-
251-
if (res > 0)
252-
break;
253-
}
254-
255-
free(skip_worktree_seen);
256-
return res;
257-
}
258-
259177
static int read_from_tree(const struct pathspec *pathspec,
260178
struct object_id *tree_oid,
261179
int intent_to_add)
@@ -273,7 +191,7 @@ static int read_from_tree(const struct pathspec *pathspec,
273191
opt.change = diff_change;
274192
opt.add_remove = diff_addremove;
275193

276-
if (pathspec->nr && the_index.sparse_index && pathspec_needs_expanded_index(pathspec))
194+
if (pathspec->nr && the_index.sparse_index && pathspec_needs_expanded_index(&the_index, pathspec))
277195
ensure_full_index(&the_index);
278196

279197
if (do_diff_cache(tree_oid, &opt))

pathspec.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,3 +759,86 @@ int match_pathspec_attrs(struct index_state *istate,
759759

760760
return 1;
761761
}
762+
763+
int pathspec_needs_expanded_index(struct index_state *istate,
764+
const struct pathspec *pathspec)
765+
{
766+
unsigned int i, pos;
767+
int res = 0;
768+
char *skip_worktree_seen = NULL;
769+
770+
/*
771+
* When using a magic pathspec, assume for the sake of simplicity that
772+
* the index needs to be expanded to match all matchable files.
773+
*/
774+
if (pathspec->magic)
775+
return 1;
776+
777+
for (i = 0; i < pathspec->nr; i++) {
778+
struct pathspec_item item = pathspec->items[i];
779+
780+
/*
781+
* If the pathspec item has a wildcard, the index should be expanded
782+
* if the pathspec has the possibility of matching a subset of entries inside
783+
* of a sparse directory (but not the entire directory).
784+
*
785+
* If the pathspec item is a literal path, the index only needs to be expanded
786+
* if a) the pathspec isn't in the sparse checkout cone (to make sure we don't
787+
* expand for in-cone files) and b) it doesn't match any sparse directories
788+
* (since we can reset whole sparse directories without expanding them).
789+
*/
790+
if (item.nowildcard_len < item.len) {
791+
/*
792+
* Special case: if the pattern is a path inside the cone
793+
* followed by only wildcards, the pattern cannot match
794+
* partial sparse directories, so we know we don't need to
795+
* expand the index.
796+
*
797+
* Examples:
798+
* - in-cone/foo***: doesn't need expanded index
799+
* - not-in-cone/bar*: may need expanded index
800+
* - **.c: may need expanded index
801+
*/
802+
if (strspn(item.original + item.nowildcard_len, "*") == item.len - item.nowildcard_len &&
803+
path_in_cone_mode_sparse_checkout(item.original, istate))
804+
continue;
805+
806+
for (pos = 0; pos < istate->cache_nr; pos++) {
807+
struct cache_entry *ce = istate->cache[pos];
808+
809+
if (!S_ISSPARSEDIR(ce->ce_mode))
810+
continue;
811+
812+
/*
813+
* If the pre-wildcard length is longer than the sparse
814+
* directory name and the sparse directory is the first
815+
* component of the pathspec, need to expand the index.
816+
*/
817+
if (item.nowildcard_len > ce_namelen(ce) &&
818+
!strncmp(item.original, ce->name, ce_namelen(ce))) {
819+
res = 1;
820+
break;
821+
}
822+
823+
/*
824+
* If the pre-wildcard length is shorter than the sparse
825+
* directory and the pathspec does not match the whole
826+
* directory, need to expand the index.
827+
*/
828+
if (!strncmp(item.original, ce->name, item.nowildcard_len) &&
829+
wildmatch(item.original, ce->name, 0)) {
830+
res = 1;
831+
break;
832+
}
833+
}
834+
} else if (!path_in_cone_mode_sparse_checkout(item.original, istate) &&
835+
!matches_skip_worktree(pathspec, i, &skip_worktree_seen))
836+
res = 1;
837+
838+
if (res > 0)
839+
break;
840+
}
841+
842+
free(skip_worktree_seen);
843+
return res;
844+
}

pathspec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,7 @@ int match_pathspec_attrs(struct index_state *istate,
171171
const char *name, int namelen,
172172
const struct pathspec_item *item);
173173

174+
int pathspec_needs_expanded_index(struct index_state *istate,
175+
const struct pathspec *pathspec);
176+
174177
#endif /* PATHSPEC_H */

0 commit comments

Comments
 (0)