static const char *tag_killed = "";
static const char *tag_modified = "";
-
-/*
- * Match a pathspec against a filename. The first "skiplen" characters
- * are the common prefix
- */
-int pathspec_match(const char **spec, char *ps_matched,
- const char *filename, int skiplen)
-{
- const char *m;
-
- while ((m = *spec++) != NULL) {
- int matchlen = strlen(m + skiplen);
-
- if (!matchlen)
- goto matched;
- if (!strncmp(m + skiplen, filename + skiplen, matchlen)) {
- if (m[skiplen + matchlen - 1] == '/')
- goto matched;
- switch (filename[skiplen + matchlen]) {
- case '/': case '\0':
- goto matched;
- }
- }
- if (!fnmatch(m + skiplen, filename + skiplen, 0))
- goto matched;
- if (ps_matched)
- ps_matched++;
- continue;
- matched:
- if (ps_matched)
- *ps_matched = 1;
- return 1;
- }
- return 0;
-}
-
static void show_dir_entry(const char *tag, struct dir_entry *ent)
{
int len = prefix_len;
if (len >= ent->len)
die("git ls-files: internal error - directory entry not superset of prefix");
- if (pathspec && !pathspec_match(pathspec, ps_matched, ent->name, len))
+ if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched))
return;
fputs(tag, stdout);
if (len >= ce_namelen(ce))
die("git ls-files: internal error - cache entry not superset of prefix");
- if (pathspec && !pathspec_match(pathspec, ps_matched, ce->name, len))
+ if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched))
return;
if (tag && *tag && show_valid_bit &&
return max ? xmemdupz(prev, max) : NULL;
}
+static void strip_trailing_slash_from_submodules(void)
+{
+ const char **p;
+
+ for (p = pathspec; *p != NULL; p++) {
+ int len = strlen(*p), pos;
+
+ if (len < 1 || (*p)[len - 1] != '/')
+ continue;
+ pos = cache_name_pos(*p, len - 1);
+ if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode))
+ *p = xstrndup(*p, len - 1);
+ }
+}
+
/*
* Read the tree specified with --with-tree option
* (typically, HEAD) into stage #1 and then
pathspec = get_pathspec(prefix, argv + i);
+ /* be nice with submodule patsh ending in a slash */
+ read_cache();
+ if (pathspec)
+ strip_trailing_slash_from_submodules();
+
/* Verify that the pathspec matches the prefix */
if (pathspec)
prefix = verify_pathspec(prefix);
show_killed | show_modified))
show_cached = 1;
- read_cache();
if (prefix)
prune_cache(prefix);
if (with_tree) {