summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: caa6b78)
raw | patch | inline | side by side (parent: caa6b78)
author | Linus Torvalds <torvalds@linux-foundation.org> | |
Thu, 9 Jul 2009 20:14:28 +0000 (13:14 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Fri, 10 Jul 2009 03:05:19 +0000 (20:05 -0700) |
If we have an up-to-date index entry for a file in that directory, we
can know that the directories leading up to that file must be
directories. No need to do an lstat() on the directory.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
can know that the directories leading up to that file must be
directories. No need to do an lstat() on the directory.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
dir.c | patch | blob | history |
index 8a9e7d8131f995a83324d4be64b554e66e578d72..e05b850acf69867f2b931e7ca2f7430a9e7fc22d 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -566,18 +566,55 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
return 0;
}
+static int get_index_dtype(const char *path, int len)
+{
+ int pos;
+ struct cache_entry *ce;
+
+ ce = cache_name_exists(path, len, 0);
+ if (ce) {
+ if (!ce_uptodate(ce))
+ return DT_UNKNOWN;
+ if (S_ISGITLINK(ce->ce_mode))
+ return DT_DIR;
+ /*
+ * Nobody actually cares about the
+ * difference between DT_LNK and DT_REG
+ */
+ return DT_REG;
+ }
+
+ /* Try to look it up as a directory */
+ pos = cache_name_pos(path, len);
+ if (pos >= 0)
+ return DT_UNKNOWN;
+ pos = -pos-1;
+ while (pos < active_nr) {
+ ce = active_cache[pos++];
+ if (strncmp(ce->name, path, len))
+ break;
+ if (ce->name[len] > '/')
+ break;
+ if (ce->name[len] < '/')
+ continue;
+ if (!ce_uptodate(ce))
+ break; /* continue? */
+ return DT_DIR;
+ }
+ return DT_UNKNOWN;
+}
+
static int get_dtype(struct dirent *de, const char *path, int len)
{
int dtype = de ? DTYPE(de) : DT_UNKNOWN;
- struct cache_entry *ce;
struct stat st;
if (dtype != DT_UNKNOWN)
return dtype;
- ce = cache_name_exists(path, len, 0);
- if (ce && ce_uptodate(ce))
- st.st_mode = ce->ce_mode;
- else if (lstat(path, &st))
+ dtype = get_index_dtype(path, len);
+ if (dtype != DT_UNKNOWN)
+ return dtype;
+ if (lstat(path, &st))
return dtype;
if (S_ISREG(st.st_mode))
return DT_REG;