[RFC/PATCH] update-index: Add a --refresh-only option to refresh specified files.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <julliard@xxxxxxxxxx>
---

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@xxxxxxxxxx
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux