From 121481abf8d752ef871821d4ab9a3747595d86ae Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 10 Apr 2005 11:32:54 -0700 Subject: [PATCH] Make "update-cache" a bit friendlier to use (and harder to mis-use). It now requires the "--add" flag before you add any new files, and a "--remove" file if you want to mark files for removal. And giving it the "--refresh" flag makes it just update all the files that it already knows about. --- cache.h | 4 ++-- read-cache.c | 13 ++++++++--- read-tree.c | 2 +- update-cache.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++--- write-tree.c | 2 -- 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/cache.h b/cache.h index 497a05b8fa..1e006bfa56 100644 --- a/cache.h +++ b/cache.h @@ -75,7 +75,7 @@ unsigned int active_nr, active_alloc; extern int read_cache(void); extern int write_cache(int newfd, struct cache_entry **cache, int entries); extern int cache_name_pos(const char *name, int namelen); -extern int add_cache_entry(struct cache_entry *ce); +extern int add_cache_entry(struct cache_entry *ce, int ok_to_add); extern int remove_file_from_cache(char *path); extern int cache_match_stat(struct cache_entry *ce, struct stat *st); @@ -104,7 +104,7 @@ extern int get_sha1_hex(const char *hex, unsigned char *sha1); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ /* General helper functions */ -extern void usage(const char *err); +extern void usage(const char *err, ...); extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2); #endif /* CACHE_H */ diff --git a/read-cache.c b/read-cache.c index 91b2628e3c..ebace34d05 100644 --- a/read-cache.c +++ b/read-cache.c @@ -9,9 +9,13 @@ const char *sha1_file_directory = NULL; struct cache_entry **active_cache = NULL; unsigned int active_nr = 0, active_alloc = 0; -void usage(const char *err) +void usage(const char *err, ...) { - fprintf(stderr, "read-tree: %s\n", err); + va_list args; + + va_start(args, err); + vfprintf(stderr, err, args); + va_end(args); exit(1); } @@ -294,7 +298,7 @@ int remove_file_from_cache(char *path) return 0; } -int add_cache_entry(struct cache_entry *ce) +int add_cache_entry(struct cache_entry *ce, int ok_to_add) { int pos; @@ -306,6 +310,9 @@ int add_cache_entry(struct cache_entry *ce) return 0; } + if (!ok_to_add) + return -1; + /* Make sure the array is big enough .. */ if (active_nr == active_alloc) { active_alloc = alloc_nr(active_alloc); diff --git a/read-tree.c b/read-tree.c index 6862d10126..5784802e94 100644 --- a/read-tree.c +++ b/read-tree.c @@ -18,7 +18,7 @@ static int read_one_entry(unsigned char *sha1, const char *base, int baselen, co memcpy(ce->name, base, baselen); memcpy(ce->name + baselen, pathname, len+1); memcpy(ce->sha1, sha1, 20); - return add_cache_entry(ce); + return add_cache_entry(ce, 1); } static int read_tree(unsigned char *sha1, const char *base, int baselen) diff --git a/update-cache.c b/update-cache.c index 03b111bfc0..942e309fe6 100644 --- a/update-cache.c +++ b/update-cache.c @@ -5,6 +5,15 @@ */ #include "cache.h" +/* + * Default to not allowing changes to the list of files. The + * tool doesn't actually care, but this makes it harder to add + * files to the revision control by mistake by doing something + * like "update-cache *" and suddenly having all the object + * files be revision controlled. + */ +static int allow_add = 0, allow_remove = 0; + static int index_fd(const char *path, int namelen, struct cache_entry *ce, int fd, struct stat *st) { z_stream stream; @@ -57,8 +66,10 @@ static int add_file_to_cache(char *path) fd = open(path, O_RDONLY); if (fd < 0) { - if (errno == ENOENT) - return remove_file_from_cache(path); + if (errno == ENOENT) { + if (allow_remove) + return remove_file_from_cache(path); + } return -1; } if (fstat(fd, &st) < 0) { @@ -85,7 +96,29 @@ static int add_file_to_cache(char *path) if (index_fd(path, namelen, ce, fd, &st) < 0) return -1; - return add_cache_entry(ce); + return add_cache_entry(ce, allow_add); +} + +static void refresh_entry(struct cache_entry *ce) +{ + /* + * This is really not the right way to do it, but + * add_file_to_cache() does do the right thing. + * + * We should really just update the cache + * entry in-place, I think. With this approach we + * end up allocating a new one, searching for where + * to insert it etc etc crud. + */ + add_file_to_cache(ce->name); +} + +static void refresh_cache(void) +{ + int i; + + for (i = 0; i < active_nr; i++) + refresh_entry(active_cache[i]); } /* @@ -119,6 +152,7 @@ static int verify_path(char *path) int main(int argc, char **argv) { int i, newfd, entries; + int allow_options = 1; entries = read_cache(); if (entries < 0) { @@ -133,6 +167,26 @@ int main(int argc, char **argv) } for (i = 1 ; i < argc; i++) { char *path = argv[i]; + + if (allow_options && *path == '-') { + if (!strcmp(path, "--")) { + allow_options = 0; + continue; + } + if (!strcmp(path, "--add")) { + allow_add = 1; + continue; + } + if (!strcmp(path, "--remove")) { + allow_remove = 1; + continue; + } + if (!strcmp(path, "--refresh")) { + refresh_cache(); + continue; + } + usage("unknown option %s", path); + } if (!verify_path(path)) { fprintf(stderr, "Ignoring path %s\n", argv[i]); continue; diff --git a/write-tree.c b/write-tree.c index f6358d76f1..7eac1df8fb 100644 --- a/write-tree.c +++ b/write-tree.c @@ -63,8 +63,6 @@ static int write_tree(struct cache_entry **cachep, int maxentries, const char *b int subdir_written; subdir_written = write_tree(cachep + nr, maxentries - nr, pathname, dirname-pathname+1, subdir_sha1); - fprintf(stderr, "Wrote %d entries from subdirectory '%.*s'\n", - subdir_written, dirname-pathname, pathname); nr += subdir_written; /* Now we need to write out the directory entry into this tree.. */