summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d6b8fc3)
raw | patch | inline | side by side (parent: d6b8fc3)
author | Junio C Hamano <gitster@pobox.com> | |
Fri, 1 Feb 2008 04:23:25 +0000 (20:23 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 5 Feb 2008 08:46:49 +0000 (00:46 -0800) |
When we process "foo/" entries in gitignore files on a system
that does not have d_type member in "struct dirent", the earlier
implementation ran lstat(2) separately when matching with
entries that came from the command line, in-tree .gitignore
files, and $GIT_DIR/info/excludes file.
This optimizes it by delaying the lstat(2) call until it becomes
absolutely necessary.
The initial idea for this change was by Jeff King, but I
optimized it further to pass pointers to around.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
that does not have d_type member in "struct dirent", the earlier
implementation ran lstat(2) separately when matching with
entries that came from the command line, in-tree .gitignore
files, and $GIT_DIR/info/excludes file.
This optimizes it by delaying the lstat(2) call until it becomes
absolutely necessary.
The initial idea for this change was by Jeff King, but I
optimized it further to pass pointers to around.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-ls-files.c | patch | blob | history | |
dir.c | patch | blob | history | |
dir.h | patch | blob | history | |
unpack-trees.c | patch | blob | history |
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index dbba371b8e37dc73e4e07f9df703698af9fa0933..54cb2518dbbfed70dcbe1b5a2112f79c78bfd6a6 100644 (file)
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
if (show_cached | show_stage) {
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
- if (excluded(dir, ce->name, ce_to_dtype(ce)) !=
- dir->show_ignored)
+ int dtype = ce_to_dtype(ce);
+ if (excluded(dir, ce->name, &dtype) != dir->show_ignored)
continue;
if (show_unmerged && !ce_stage(ce))
continue;
struct cache_entry *ce = active_cache[i];
struct stat st;
int err;
- if (excluded(dir, ce->name, ce_to_dtype(ce)) !=
- dir->show_ignored)
+ int dtype = ce_to_dtype(ce);
+ if (excluded(dir, ce->name, &dtype) != dir->show_ignored)
continue;
err = lstat(ce->name, &st);
if (show_deleted && err)
index a4f8c258cc49b558ce26cf35a065849fc73be1ff..292639b1562d8995025557341e3dc3215cef7b96 100644 (file)
--- a/dir.c
+++ b/dir.c
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);
int common_prefix(const char **pathspec)
{
* Return 1 for exclude, 0 for include and -1 for undecided.
*/
static int excluded_1(const char *pathname,
- int pathlen, const char *basename, int dtype,
+ int pathlen, const char *basename, int *dtype,
struct exclude_list *el)
{
int i;
const char *exclude = x->pattern;
int to_exclude = x->to_exclude;
- if ((x->flags & EXC_FLAG_MUSTBEDIR) &&
- (dtype != DT_DIR))
- continue;
+ if (x->flags & EXC_FLAG_MUSTBEDIR) {
+ if (*dtype == DT_UNKNOWN)
+ *dtype = get_dtype(NULL, pathname);
+ if (*dtype != DT_DIR)
+ continue;
+ }
if (x->flags & EXC_FLAG_NODIR) {
/* match basename */
return -1; /* undecided */
}
-int excluded(struct dir_struct *dir, const char *pathname, int dtype)
+int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
{
int pathlen = strlen(pathname);
int st;
prep_exclude(dir, pathname, basename-pathname);
for (st = EXC_CMDL; st <= EXC_FILE; st++) {
switch (excluded_1(pathname, pathlen, basename,
- dtype, &dir->exclude_list[st])) {
+ dtype_p, &dir->exclude_list[st])) {
case 0:
return 0;
case 1:
@@ -529,7 +533,7 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
static int get_dtype(struct dirent *de, const char *path)
{
- int dtype = DTYPE(de);
+ int dtype = de ? DTYPE(de) : DT_UNKNOWN;
struct stat st;
if (dtype != DT_UNKNOWN)
@@ -581,8 +585,8 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
if (simplify_away(fullname, baselen + len, simplify))
continue;
- dtype = get_dtype(de, fullname);
- exclude = excluded(dir, fullname, dtype);
+ dtype = DTYPE(de);
+ exclude = excluded(dir, fullname, &dtype);
if (exclude && dir->collect_ignored
&& in_pathspec(fullname, baselen + len, simplify))
dir_add_ignored(dir, fullname, baselen + len);
@@ -594,6 +598,9 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
if (exclude && !dir->show_ignored)
continue;
+ if (dtype == DT_UNKNOWN)
+ dtype = get_dtype(de, fullname);
+
/*
* Do we want to see just the ignored files?
* We still need to recurse into directories,
index 10d72b5222b20d15dfe8f0a42f9d4fdd33642924..2df15defb6720a742282f24721233c4816deceb6 100644 (file)
--- a/dir.h
+++ b/dir.h
extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen, const char **pathspec);
-extern int excluded(struct dir_struct *, const char *, int);
+extern int excluded(struct dir_struct *, const char *, int *);
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *which);
diff --git a/unpack-trees.c b/unpack-trees.c
index 11af2636c27b53d2fed14b71e16e6991892c241e..29848e926c9a17b2aaf54b924c7176346c5d3d02 100644 (file)
--- a/unpack-trees.c
+++ b/unpack-trees.c
if (!lstat(ce->name, &st)) {
int cnt;
+ int dtype = ce_to_dtype(ce);
- if (o->dir && excluded(o->dir, ce->name, ce_to_dtype(ce)))
+ if (o->dir && excluded(o->dir, ce->name, &dtype))
/*
* ce->name is explicitly excluded, so it is Ok to
* overwrite it.