summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0d78153)
raw | patch | inline | side by side (parent: 0d78153)
author | Linus Torvalds <torvalds@osdl.org> | |
Wed, 17 May 2006 20:23:19 +0000 (13:23 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Wed, 17 May 2006 22:27:18 +0000 (15:27 -0700) |
This is in the same spirit as what bba319b5 and 45e48120 tried
to do to help users. A command such as "git add Documentaiton"
with misspelled pathspecs would give a friendly reminder with
this.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
to do to help users. A command such as "git add Documentaiton"
with misspelled pathspecs would give a friendly reminder with
this.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-add.c | patch | blob | history |
diff --git a/builtin-add.c b/builtin-add.c
index d225988e53ce8e6fab177b7679a807bb57b4d13a..089c7a89b324ee3cfd64aec9fe2cfba4314d2f3b 100644 (file)
--- a/builtin-add.c
+++ b/builtin-add.c
return prefix;
}
-static int match(const char **pathspec, const char *name, int namelen, int prefix)
+static int match_one(const char *match, const char *name, int namelen)
{
+ int matchlen;
+
+ /* If the match was just the prefix, we matched */
+ matchlen = strlen(match);
+ if (!matchlen)
+ return 1;
+
+ /*
+ * If we don't match the matchstring exactly,
+ * we need to match by fnmatch
+ */
+ if (strncmp(match, name, matchlen))
+ return !fnmatch(match, name, 0);
+
+ /*
+ * If we did match the string exactly, we still
+ * need to make sure that it happened on a path
+ * component boundary (ie either the last character
+ * of the match was '/', or the next character of
+ * the name was '/' or the terminating NUL.
+ */
+ return match[matchlen-1] == '/' ||
+ name[matchlen] == '/' ||
+ !name[matchlen];
+}
+
+static int match(const char **pathspec, const char *name, int namelen, int prefix, char *seen)
+{
+ int retval;
const char *match;
name += prefix;
namelen -= prefix;
- while ((match = *pathspec++) != NULL) {
- int matchlen;
-
+ for (retval = 0; (match = *pathspec++) != NULL; seen++) {
+ if (retval & *seen)
+ continue;
match += prefix;
- matchlen = strlen(match);
- if (!matchlen)
- return 1;
- if (!strncmp(match, name, matchlen)) {
- if (match[matchlen-1] == '/')
- return 1;
- switch (name[matchlen]) {
- case '/': case '\0':
- return 1;
- }
+ if (match_one(match, name, namelen)) {
+ retval = 1;
+ *seen = 1;
}
- if (!fnmatch(match, name, 0))
- return 1;
}
- return 0;
+ return retval;
}
static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
{
- int i;
+ char *seen;
+ int i, specs;
struct dir_entry **src, **dst;
+ for (specs = 0; pathspec[specs]; specs++)
+ /* nothing */;
+ seen = xmalloc(specs);
+ memset(seen, 0, specs);
+
src = dst = dir->entries;
i = dir->nr;
while (--i >= 0) {
struct dir_entry *entry = *src++;
- if (!match(pathspec, entry->name, entry->len, prefix)) {
+ if (!match(pathspec, entry->name, entry->len, prefix, seen)) {
free(entry);
continue;
}
*dst++ = entry;
}
dir->nr = dst - dir->entries;
+
+ for (i = 0; i < specs; i++) {
+ struct stat st;
+ const char *match;
+ if (seen[i])
+ continue;
+
+ /* Existing file? We must have ignored it */
+ match = pathspec[i];
+ if (!lstat(match, &st))
+ continue;
+ die("pathspec '%s' did not match any files", match);
+ }
}
static void fill_directory(struct dir_struct *dir, const char **pathspec)