MCPcopy Create free account
hub / github.com/git/git / match_pathspec_item

Function match_pathspec_item

dir.c:387–492  ·  view source on GitHub ↗

* Does the given pathspec match the given name? A match is found if * * (1) the pathspec string is leading directory of 'name' ("RECURSIVELY"), or * (2) the pathspec string has a leading part matching 'name' ("LEADING"), or * (3) the pathspec string is a wildcard and matches 'name' ("WILDCARD"), or * (4) the pathspec string is exactly the same as 'name' ("EXACT"). * * Return value tells wh

Source from the content-addressed store, hash-verified

385 * [2] Only if DO_MATCH_LEADING_PATHSPEC is passed; otherwise, not a match.
386 */
387static int match_pathspec_item(struct index_state *istate,
388 const struct pathspec_item *item, int prefix,
389 const char *name, int namelen, unsigned flags)
390{
391 /* name/namelen has prefix cut off by caller */
392 const char *match = item->match + prefix;
393 int matchlen = item->len - prefix;
394
395 /*
396 * The normal call pattern is:
397 * 1. prefix = common_prefix_len(ps);
398 * 2. prune something, or fill_directory
399 * 3. match_pathspec()
400 *
401 * 'prefix' at #1 may be shorter than the command's prefix and
402 * it's ok for #2 to match extra files. Those extras will be
403 * trimmed at #3.
404 *
405 * Suppose the pathspec is 'foo' and '../bar' running from
406 * subdir 'xyz'. The common prefix at #1 will be empty, thanks
407 * to "../". We may have xyz/foo _and_ XYZ/foo after #2. The
408 * user does not want XYZ/foo, only the "foo" part should be
409 * case-insensitive. We need to filter out XYZ/foo here. In
410 * other words, we do not trust the caller on comparing the
411 * prefix part when :(icase) is involved. We do exact
412 * comparison ourselves.
413 *
414 * Normally the caller (common_prefix_len() in fact) does
415 * _exact_ matching on name[-prefix+1..-1] and we do not need
416 * to check that part. Be defensive and check it anyway, in
417 * case common_prefix_len is changed, or a new caller is
418 * introduced that does not use common_prefix_len.
419 *
420 * If the penalty turns out too high when prefix is really
421 * long, maybe change it to
422 * strncmp(match, name, item->prefix - prefix)
423 */
424 if (item->prefix && (item->magic & PATHSPEC_ICASE) &&
425 strncmp(item->match, name - prefix, item->prefix))
426 return 0;
427
428 if (item->attr_match_nr) {
429 if (!istate)
430 BUG("magic PATHSPEC_ATTR requires an index");
431 if (!match_pathspec_attrs(istate, name - prefix, namelen + prefix, item))
432 return 0;
433 }
434
435 /* If the match was just the prefix, we matched */
436 if (!*match)
437 return MATCHED_RECURSIVELY;
438
439 if (matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) {
440 if (matchlen == namelen)
441 return MATCHED_EXACTLY;
442
443 if (match[matchlen-1] == '/' || name[matchlen] == '/')
444 return MATCHED_RECURSIVELY;

Callers 1

do_match_pathspecFunction · 0.85

Calls 3

match_pathspec_attrsFunction · 0.85
ps_strncmpFunction · 0.85
git_fnmatchFunction · 0.85

Tested by

no test coverage detected