[RFC/PATCH] update-index: Add a --refresh-only option to refresh specified files.
From: Alexandre Julliard <hidden>
Date: 2016-06-15 22:43:26
Subsystem:
the rest · Maintainer:
Linus Torvalds
This allows to quickly refresh a file that has been touched without having to stat all the files of the project. Signed-off-by: Alexandre Julliard <redacted> --- Does this look reasonable? The refresh_index_path() function is a copy/paste of refresh_index(), I'm not sure all of it is really needed, but I don't claim to understand all the subtleties of the index management... builtin-update-index.c | 17 +++++++++++++-- cache.h | 1 + read-cache.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 509369e..ac24ef3 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c@@ -22,6 +22,7 @@ static int allow_add; static int allow_remove; static int allow_replace; static int info_only; +static int refresh_only; static int force_remove; static int verbose; static int mark_valid_only;
@@ -266,8 +267,9 @@ static void chmod_path(int flip, const char *path) die("git-update-index: cannot chmod %cx '%s'", flip, path); } -static void update_one(const char *path, const char *prefix, int prefix_length) +static int update_one(const char *path, const char *prefix, int prefix_length) { + int has_errors = 0; const char *p = prefix_path(prefix, prefix_length, path); if (!verify_path(p)) { fprintf(stderr, "Ignoring path %s\n", path);
@@ -278,6 +280,10 @@ static void update_one(const char *path, const char *prefix, int prefix_length) die("Unable to mark file %s", path); goto free_return; } + if (refresh_only) { + has_errors |= refresh_index_path(&the_index, 0, path); + goto free_return; + } cache_tree_invalidate_path(active_cache_tree, path); if (force_remove) {
@@ -292,6 +298,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length) free_return: if (p < path || p > path + strlen(path)) free((char*)p); + return has_errors; } static void read_index_info(int line_termination)
@@ -620,6 +627,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags); continue; } + if (!strcmp(path, "--refresh-only")) { + refresh_only = 1; + continue; + } if (!strcmp(path, "--cacheinfo")) { unsigned char sha1[20]; unsigned int mode;
@@ -702,7 +713,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) die("unknown option %s", path); } p = prefix_path(prefix, prefix_length, path); - update_one(p, NULL, 0); + has_errors |= update_one(p, NULL, 0); if (set_executable_bit) chmod_path(set_executable_bit, p); if (p < path || p > path + strlen(path))
@@ -722,7 +733,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) else path_name = buf.buf; p = prefix_path(prefix, prefix_length, path_name); - update_one(p, NULL, 0); + has_errors |= update_one(p, NULL, 0); if (set_executable_bit) chmod_path(set_executable_bit, p); if (p < path_name || p > path_name + strlen(path_name))
diff --git a/cache.h b/cache.h
index e97af18..6982ab4 100644
--- a/cache.h
+++ b/cache.h@@ -278,6 +278,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); #define REFRESH_QUIET 0x0004 /* be quiet about it */ #define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */ extern int refresh_index(struct index_state *, unsigned int flags); +extern int refresh_index_path(struct index_state *istate, unsigned int flags, const char *path); struct lock_file { struct lock_file *next;
diff --git a/read-cache.c b/read-cache.c
index e060392..1c0bfe8 100644
--- a/read-cache.c
+++ b/read-cache.c@@ -836,6 +836,55 @@ int refresh_index(struct index_state *istate, unsigned int flags) return has_errors; } +int refresh_index_path(struct index_state *istate, unsigned int flags, const char *path) +{ + 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; + struct cache_entry *ce, *new; + int cache_errno = 0; + int i = index_name_pos(istate, path, strlen(path)); + + if (i < 0) { + printf("%s: not in index\n", path); + return 1; + } + + ce = istate->cache[i]; + if (ce_stage(ce)) { + if (allow_unmerged) + return 0; + printf("%s: needs merge\n", ce->name); + return 1; + } + + new = refresh_cache_ent(istate, ce, really, &cache_errno); + if (new == ce) + return 0; + if (!new) { + if (not_new && cache_errno == ENOENT) + return 0; + if (really && cache_errno == EINVAL) { + /* If we are doing --really-refresh that + * means the index is not valid anymore. + */ + ce->ce_flags &= ~htons(CE_VALID); + istate->cache_changed = 1; + } + if (quiet) + return 0; + printf("%s: needs update\n", ce->name); + return 1; + } + istate->cache_changed = 1; + /* You can NOT just free istate->cache[i] here, since it + * might not be necessarily malloc()ed but can also come + * from mmap(). */ + istate->cache[i] = new; + return 0; +} + struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really) { return refresh_cache_ent(&the_index, ce, really, NULL);
--
1.5.3.rc4
--
Alexandre Julliard
julliard@winehq.org