X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=builtin-add.c;h=02fe38b0c4c7c61bcc51544d1fd54c0b1641e2e8;hb=dd8239f997962d94162790039b008acb6068a242;hp=d225988e53ce8e6fab177b7679a807bb57b4d13a;hpb=0d78153952e70c21e94dc6b7eefcb2ac5337a902;p=git.git diff --git a/builtin-add.c b/builtin-add.c index d225988e..02fe38b0 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -8,86 +8,46 @@ #include "cache.h" #include "builtin.h" #include "dir.h" +#include "cache-tree.h" static const char builtin_add_usage[] = "git-add [-n] [-v] ..."; -static int common_prefix(const char **pathspec) -{ - const char *path, *slash, *next; - int prefix; - - if (!pathspec) - return 0; - - path = *pathspec; - slash = strrchr(path, '/'); - if (!slash) - return 0; - - prefix = slash - path + 1; - while ((next = *++pathspec) != NULL) { - int len = strlen(next); - if (len >= prefix && !memcmp(path, next, len)) - continue; - for (;;) { - if (!len) - return 0; - if (next[--len] != '/') - continue; - if (memcmp(path, next, len+1)) - continue; - prefix = len + 1; - break; - } - } - return prefix; -} - -static int match(const char **pathspec, const char *name, int namelen, int prefix) -{ - const char *match; - - name += prefix; - namelen -= prefix; - - while ((match = *pathspec++) != NULL) { - int matchlen; - - 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 (!fnmatch(match, name, 0)) - return 1; - } - return 0; -} - 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(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 (!match[0] || !lstat(match, &st)) + continue; + die("pathspec '%s' did not match any files", match); + } } static void fill_directory(struct dir_struct *dir, const char **pathspec) @@ -158,6 +118,7 @@ static int add_file_to_index(const char *path, int verbose) die("unable to add %s to index",path); if (verbose) printf("add '%s'\n", path); + cache_tree_invalidate_path(active_cache_tree, path); return 0; }