X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=builtin-add.c;h=bfbbb1bf52e10667f94dd574ab32fe070c98c4cb;hb=74237d6236d7e32f69469ff26df3f3bb3875f523;hp=d225988e53ce8e6fab177b7679a807bb57b4d13a;hpb=0d78153952e70c21e94dc6b7eefcb2ac5337a902;p=git.git diff --git a/builtin-add.c b/builtin-add.c index d225988e..bfbbb1bf 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,10 +118,11 @@ 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; } -static struct cache_file cache_file; +static struct lock_file lock_file; int cmd_add(int argc, const char **argv, char **envp) { @@ -173,9 +134,9 @@ int cmd_add(int argc, const char **argv, char **envp) git_config(git_default_config); - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); if (newfd < 0) - die("unable to create new cachefile"); + die("unable to create new index file"); if (read_cache() < 0) die("index file corrupt"); @@ -220,7 +181,7 @@ int cmd_add(int argc, const char **argv, char **envp) if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) + commit_lock_file(&lock_file)) die("Unable to write new index file"); }