Re: Too many 'stat' calls by git-status on Windows

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

 




On Tue, 7 Jul 2009, Dmitry Potapov wrote:
> 
> It appears that the second 'stat' for files on Windows caused by lack
> of d_type in dirent. When I recompiled the Linux version with
> NO_D_TYPE_IN_DIRENT = YesPlease, I got the same result for files.
> (Still I am not sure what caused those extra stat calls for
> directory, maybe, it is Cygwin specific...)
> 
> The question is whether it is possible to avoid this redundant 'stat'
> for files on system that do not have d_type in dirent or that would
> require too much modification? Is it possible to use the cache where
> d_stat is not available provided that the entry is marked as uptodate?

Hmm. Sure. Something like this?

		Linus

---
 dir.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/dir.c b/dir.c
index 74b3bbf..aaf269b 100644
--- a/dir.c
+++ b/dir.c
@@ -17,7 +17,7 @@ struct path_simplify {
 static int read_directory_recursive(struct dir_struct *dir,
 	const char *path, const char *base, int baselen,
 	int check_only, const struct path_simplify *simplify);
-static int get_dtype(struct dirent *de, const char *path);
+static int get_dtype(struct dirent *de, const char *path, int pathlen);
 
 int common_prefix(const char **pathspec)
 {
@@ -307,7 +307,7 @@ static int excluded_1(const char *pathname,
 
 			if (x->flags & EXC_FLAG_MUSTBEDIR) {
 				if (*dtype == DT_UNKNOWN)
-					*dtype = get_dtype(NULL, pathname);
+					*dtype = get_dtype(NULL, pathname, pathlen);
 				if (*dtype != DT_DIR)
 					continue;
 			}
@@ -547,14 +547,18 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
 	return 0;
 }
 
-static int get_dtype(struct dirent *de, const char *path)
+static int get_dtype(struct dirent *de, const char *path, int pathlen)
 {
 	int dtype = de ? DTYPE(de) : DT_UNKNOWN;
+	struct cache_entry *ce;
 	struct stat st;
 
 	if (dtype != DT_UNKNOWN)
 		return dtype;
-	if (lstat(path, &st))
+	ce = cache_name_exists(path, pathlen, 0);
+	if (ce && ce_uptodate(ce))
+		st.st_mode = ce->ce_mode;
+	else if (lstat(path, &st))
 		return dtype;
 	if (S_ISREG(st.st_mode))
 		return DT_REG;
@@ -613,7 +617,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
 				continue;
 
 			if (dtype == DT_UNKNOWN)
-				dtype = get_dtype(de, fullname);
+				dtype = get_dtype(de, fullname, baselen + len);
 
 			/*
 			 * Do we want to see just the ignored files?
--
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]