Libify the index refresh logic
authorLinus Torvalds <torvalds@osdl.org>
Fri, 19 May 2006 16:56:35 +0000 (09:56 -0700)
committerJunio C Hamano <junkio@cox.net>
Fri, 19 May 2006 22:59:18 +0000 (15:59 -0700)
This cleans up and libifies the "git update-index --[really-]refresh"
functionality. This will be eventually required for eventually doing the
"commit" and "status" commands as built-ins.

It really just moves "refresh_index()" from update-index.c to
read-cache.c, but it also has to change the calling convention so that the
function uses a "unsigned int flags" argument instead of various static
flags variables for passing down the information about whether to be quiet
or not, and allow unmerged entries etc.

That actually cleans up update-index.c too, since it turns out that all
those flags were really specific to that one function of the index update,
so they shouldn't have had file-scope visibility even before.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
cache.h
read-cache.c
update-index.c

diff --git a/cache.h b/cache.h
index 4b7a4392531dd4064694cd346fef902a2b1930e9..afa8e4f0acbd36947590e428fd86ed0cd2000276 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -158,6 +158,12 @@ extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_o
 extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
 extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
 
+#define REFRESH_REALLY         0x0001  /* ignore_valid */
+#define REFRESH_UNMERGED       0x0002  /* allow unmerged */
+#define REFRESH_QUIET          0x0004  /* be quiet about it */
+#define REFRESH_IGNORE_MISSING 0x0008  /* ignore non-existent */
+extern int refresh_cache(unsigned int flags);
+
 struct cache_file {
        struct cache_file *next;
        char lockfile[PATH_MAX];
index a917ab0cfe1547d1070f2567a41295c96f97b249..b95edcc14c2ae4094372f4ec307cdcfa1b8f24fe 100644 (file)
@@ -496,6 +496,123 @@ int add_cache_entry(struct cache_entry *ce, int option)
        return 0;
 }
 
+/* Three functions to allow overloaded pointer return; see linux/err.h */
+static inline void *ERR_PTR(long error)
+{
+       return (void *) error;
+}
+
+static inline long PTR_ERR(const void *ptr)
+{
+       return (long) ptr;
+}
+
+static inline long IS_ERR(const void *ptr)
+{
+       return (unsigned long)ptr > (unsigned long)-1000L;
+}
+
+/*
+ * "refresh" does not calculate a new sha1 file or bring the
+ * cache up-to-date for mode/content changes. But what it
+ * _does_ do is to "re-match" the stat information of a file
+ * with the cache, so that you can refresh the cache for a
+ * file that hasn't been changed but where the stat entry is
+ * out of date.
+ *
+ * For example, you'd want to do this after doing a "git-read-tree",
+ * to link up the stat cache details with the proper files.
+ */
+static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
+{
+       struct stat st;
+       struct cache_entry *updated;
+       int changed, size;
+
+       if (lstat(ce->name, &st) < 0)
+               return ERR_PTR(-errno);
+
+       changed = ce_match_stat(ce, &st, really);
+       if (!changed) {
+               if (really && assume_unchanged &&
+                   !(ce->ce_flags & htons(CE_VALID)))
+                       ; /* mark this one VALID again */
+               else
+                       return NULL;
+       }
+
+       if (ce_modified(ce, &st, really))
+               return ERR_PTR(-EINVAL);
+
+       size = ce_size(ce);
+       updated = xmalloc(size);
+       memcpy(updated, ce, size);
+       fill_stat_cache_info(updated, &st);
+
+       /* In this case, if really is not set, we should leave
+        * CE_VALID bit alone.  Otherwise, paths marked with
+        * --no-assume-unchanged (i.e. things to be edited) will
+        * reacquire CE_VALID bit automatically, which is not
+        * really what we want.
+        */
+       if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
+               updated->ce_flags &= ~htons(CE_VALID);
+
+       return updated;
+}
+
+int refresh_cache(unsigned int flags)
+{
+       int i;
+       int has_errors = 0;
+       int really = (flags & REFRESH_REALLY) != 0;
+       int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
+       int quiet = (flags & REFRESH_QUIET) != 0;
+       int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
+
+       for (i = 0; i < active_nr; i++) {
+               struct cache_entry *ce, *new;
+               ce = active_cache[i];
+               if (ce_stage(ce)) {
+                       while ((i < active_nr) &&
+                              ! strcmp(active_cache[i]->name, ce->name))
+                               i++;
+                       i--;
+                       if (allow_unmerged)
+                               continue;
+                       printf("%s: needs merge\n", ce->name);
+                       has_errors = 1;
+                       continue;
+               }
+
+               new = refresh_entry(ce, really);
+               if (!new)
+                       continue;
+               if (IS_ERR(new)) {
+                       if (not_new && PTR_ERR(new) == -ENOENT)
+                               continue;
+                       if (really && PTR_ERR(new) == -EINVAL) {
+                               /* If we are doing --really-refresh that
+                                * means the index is not valid anymore.
+                                */
+                               ce->ce_flags &= ~htons(CE_VALID);
+                               active_cache_changed = 1;
+                       }
+                       if (quiet)
+                               continue;
+                       printf("%s: needs update\n", ce->name);
+                       has_errors = 1;
+                       continue;
+               }
+               active_cache_changed = 1;
+               /* You can NOT just free active_cache[i] here, since it
+                * might not be necessarily malloc()ed but can also come
+                * from mmap(). */
+               active_cache[i] = new;
+       }
+       return has_errors;
+}
+
 static int verify_hdr(struct cache_header *hdr, unsigned long size)
 {
        SHA_CTX c;
index 3d7e02db2cc37dd22952f0e86e844eac3f5c1cc4..7d6de821e23fc02b19b970df94200edd31bc864f 100644 (file)
@@ -18,9 +18,6 @@
 static int allow_add;
 static int allow_remove;
 static int allow_replace;
-static int allow_unmerged; /* --refresh needing merge is not error */
-static int not_new; /* --refresh not having working tree files is not error */
-static int quiet; /* --refresh needing update is not error */
 static int info_only;
 static int force_remove;
 static int verbose;
@@ -28,23 +25,6 @@ static int mark_valid_only = 0;
 #define MARK_VALID 1
 #define UNMARK_VALID 2
 
-
-/* Three functions to allow overloaded pointer return; see linux/err.h */
-static inline void *ERR_PTR(long error)
-{
-       return (void *) error;
-}
-
-static inline long PTR_ERR(const void *ptr)
-{
-       return (long) ptr;
-}
-
-static inline long IS_ERR(const void *ptr)
-{
-       return (unsigned long)ptr > (unsigned long)-1000L;
-}
-
 static void report(const char *fmt, ...)
 {
        va_list vp;
@@ -140,103 +120,6 @@ static int add_file_to_cache(const char *path)
        return 0;
 }
 
-/*
- * "refresh" does not calculate a new sha1 file or bring the
- * cache up-to-date for mode/content changes. But what it
- * _does_ do is to "re-match" the stat information of a file
- * with the cache, so that you can refresh the cache for a
- * file that hasn't been changed but where the stat entry is
- * out of date.
- *
- * For example, you'd want to do this after doing a "git-read-tree",
- * to link up the stat cache details with the proper files.
- */
-static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
-{
-       struct stat st;
-       struct cache_entry *updated;
-       int changed, size;
-
-       if (lstat(ce->name, &st) < 0)
-               return ERR_PTR(-errno);
-
-       changed = ce_match_stat(ce, &st, really);
-       if (!changed) {
-               if (really && assume_unchanged &&
-                   !(ce->ce_flags & htons(CE_VALID)))
-                       ; /* mark this one VALID again */
-               else
-                       return NULL;
-       }
-
-       if (ce_modified(ce, &st, really))
-               return ERR_PTR(-EINVAL);
-
-       size = ce_size(ce);
-       updated = xmalloc(size);
-       memcpy(updated, ce, size);
-       fill_stat_cache_info(updated, &st);
-
-       /* In this case, if really is not set, we should leave
-        * CE_VALID bit alone.  Otherwise, paths marked with
-        * --no-assume-unchanged (i.e. things to be edited) will
-        * reacquire CE_VALID bit automatically, which is not
-        * really what we want.
-        */
-       if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
-               updated->ce_flags &= ~htons(CE_VALID);
-
-       return updated;
-}
-
-static int refresh_cache(int really)
-{
-       int i;
-       int has_errors = 0;
-
-       for (i = 0; i < active_nr; i++) {
-               struct cache_entry *ce, *new;
-               ce = active_cache[i];
-               if (ce_stage(ce)) {
-                       while ((i < active_nr) &&
-                              ! strcmp(active_cache[i]->name, ce->name))
-                               i++;
-                       i--;
-                       if (allow_unmerged)
-                               continue;
-                       printf("%s: needs merge\n", ce->name);
-                       has_errors = 1;
-                       continue;
-               }
-
-               new = refresh_entry(ce, really);
-               if (!new)
-                       continue;
-               if (IS_ERR(new)) {
-                       if (not_new && PTR_ERR(new) == -ENOENT)
-                               continue;
-                       if (really && PTR_ERR(new) == -EINVAL) {
-                               /* If we are doing --really-refresh that
-                                * means the index is not valid anymore.
-                                */
-                               ce->ce_flags &= ~htons(CE_VALID);
-                               active_cache_changed = 1;
-                       }
-                       if (quiet)
-                               continue;
-                       printf("%s: needs update\n", ce->name);
-                       has_errors = 1;
-                       continue;
-               }
-               active_cache_changed = 1;
-               /* You can NOT just free active_cache[i] here, since it
-                * might not be necessarily malloc()ed but can also come
-                * from mmap(). */
-               active_cache[i] = new;
-       }
-       return has_errors;
-}
-
 /*
  * We fundamentally don't like some paths: we don't want
  * dot or dot-dot anywhere, and for obvious reasons don't
@@ -653,6 +536,7 @@ int main(int argc, const char **argv)
        const char *prefix = setup_git_directory();
        int prefix_length = prefix ? strlen(prefix) : 0;
        char set_executable_bit = 0;
+       unsigned int refresh_flags = 0;
 
        git_config(git_default_config);
 
@@ -673,7 +557,7 @@ int main(int argc, const char **argv)
                                continue;
                        }
                        if (!strcmp(path, "-q")) {
-                               quiet = 1;
+                               refresh_flags |= REFRESH_QUIET;
                                continue;
                        }
                        if (!strcmp(path, "--add")) {
@@ -689,15 +573,15 @@ int main(int argc, const char **argv)
                                continue;
                        }
                        if (!strcmp(path, "--unmerged")) {
-                               allow_unmerged = 1;
+                               refresh_flags |= REFRESH_UNMERGED;
                                continue;
                        }
                        if (!strcmp(path, "--refresh")) {
-                               has_errors |= refresh_cache(0);
+                               has_errors |= refresh_cache(refresh_flags);
                                continue;
                        }
                        if (!strcmp(path, "--really-refresh")) {
-                               has_errors |= refresh_cache(1);
+                               has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags);
                                continue;
                        }
                        if (!strcmp(path, "--cacheinfo")) {
@@ -770,7 +654,7 @@ int main(int argc, const char **argv)
                                goto finish;
                        }
                        if (!strcmp(path, "--ignore-missing")) {
-                               not_new = 1;
+                               refresh_flags |= REFRESH_IGNORE_MISSING;
                                continue;
                        }
                        if (!strcmp(path, "--verbose")) {