Merge branch 'bw/ls-files-recurse-submodules'

"git ls-files" learned "--recurse-submodules" option that can be
used to get a listing of tracked files across submodules (i.e. this
only works with "--cached" option, not for listing untracked or
ignored files).  This would be a useful tool to sit on the upstream
side of a pipe that is read with xargs to work on all working tree
files from the top-level superproject.

* bw/ls-files-recurse-submodules:
  ls-files: add pathspec matching for submodules
  ls-files: pass through safe options for --recurse-submodules
  ls-files: optionally recurse into submodules
  git: make super-prefix option
This commit is contained in:
Junio C Hamano
2016-10-26 13:14:44 -07:00
9 changed files with 453 additions and 45 deletions

46
dir.c
View File

@ -207,8 +207,9 @@ int within_depth(const char *name, int namelen,
return 1;
}
#define DO_MATCH_EXCLUDE 1
#define DO_MATCH_DIRECTORY 2
#define DO_MATCH_EXCLUDE (1<<0)
#define DO_MATCH_DIRECTORY (1<<1)
#define DO_MATCH_SUBMODULE (1<<2)
/*
* Does 'match' match the given name?
@ -283,6 +284,32 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
item->nowildcard_len - prefix))
return MATCHED_FNMATCH;
/* Perform checks to see if "name" is a super set of the pathspec */
if (flags & DO_MATCH_SUBMODULE) {
/* name is a literal prefix of the pathspec */
if ((namelen < matchlen) &&
(match[namelen] == '/') &&
!ps_strncmp(item, match, name, namelen))
return MATCHED_RECURSIVELY;
/* name" doesn't match up to the first wild character */
if (item->nowildcard_len < item->len &&
ps_strncmp(item, match, name,
item->nowildcard_len - prefix))
return 0;
/*
* Here is where we would perform a wildmatch to check if
* "name" can be matched as a directory (or a prefix) against
* the pathspec. Since wildmatch doesn't have this capability
* at the present we have to punt and say that it is a match,
* potentially returning a false positive
* The submodules themselves will be able to perform more
* accurate matching to determine if the pathspec matches.
*/
return MATCHED_RECURSIVELY;
}
return 0;
}
@ -386,6 +413,21 @@ int match_pathspec(const struct pathspec *ps,
return negative ? 0 : positive;
}
/**
* Check if a submodule is a superset of the pathspec
*/
int submodule_path_match(const struct pathspec *ps,
const char *submodule_name,
char *seen)
{
int matched = do_match_pathspec(ps, submodule_name,
strlen(submodule_name),
0, seen,
DO_MATCH_DIRECTORY |
DO_MATCH_SUBMODULE);
return matched;
}
int report_path_error(const char *ps_matched,
const struct pathspec *pathspec,
const char *prefix)