Re: Too many 'stat' calls by git-status on Windows
On Tue, 7 Jul 2009, Dmitry Potapov wrote:
Show 11 quoted lines
>
> 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?