Skip to content

dir.c: regression fix for add_excludes with fscache #1407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions compat/win32/fscache.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ static struct hashmap map;
static CRITICAL_SECTION mutex;
static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);

int fscache_is_enabled(void)
{
return enabled;
}

/*
* An entry in the file system cache. Used for both entire directory listings
* and file entries.
Expand Down Expand Up @@ -257,7 +252,7 @@ static void fscache_clear(void)
/*
* Checks if the cache is enabled for the given path.
*/
static inline int fscache_enabled(const char *path)
int fscache_enabled(const char *path)

This comment was marked as off-topic.

{
return enabled > 0 && !is_absolute_path(path);
}
Expand Down
4 changes: 2 additions & 2 deletions compat/win32/fscache.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
int fscache_enable(int enable);
#define enable_fscache(x) fscache_enable(x)

int fscache_is_enabled(void);
#define is_fscache_enabled() (fscache_is_enabled())
int fscache_enabled(const char *path);
#define is_fscache_enabled(path) fscache_enabled(path)

DIR *fscache_opendir(const char *dir);
int fscache_lstat(const char *file_name, struct stat *buf);
Expand Down
27 changes: 26 additions & 1 deletion dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,13 +758,38 @@ static int add_excludes(const char *fname, const char *base, int baselen,
size_t size = 0;
char *buf, *entry;

if (is_fscache_enabled()) {
/*
* A performance optimization for status.
*
* During a status scan, git looks in each directory for a .gitignore
* file before scanning the directory. Since .gitignore files are not
* that common, we can waste a lot of time looking for files that are
* not there. Fortunately, the fscache already knows if the directory
* contains a .gitignore file, since it has already read the directory
* and it already has the stat-data.
*
* If the fscache is enabled, use the fscache-lstat() interlude to see
* if the file exists (in the fscache hash maps) before trying to open()
* it.
*
* This causes problem when the .gitignore file is a symlink, because
* we call lstat() rather than stat() on the symlnk and the resulting
* stat-data is for the symlink itself rather than the target file.
* We CANNOT use stat() here because the fscache DOES NOT install an
* interlude for stat() and mingw_stat() always calls "open-fstat-close"
* on the file and defeats the purpose of the optimization here. Since
* symlinks are even more rare than .gitignore files, we force a fstat()
* after our open() to get stat-data for the target file.
*/
if (is_fscache_enabled(fname)) {
if (lstat(fname, &st) < 0) {
fd = -1;
} else {
fd = open(fname, O_RDONLY);
if (fd < 0)
warn_on_fopen_errors(fname);
if (S_ISLNK(st.st_mode))
fstat(fd, &st);
}
} else {
fd = open(fname, O_RDONLY);
Expand Down
2 changes: 1 addition & 1 deletion git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,7 @@ static inline int is_missing_file_error(int errno_)
#endif

#ifndef is_fscache_enabled
#define is_fscache_enabled() (0)
#define is_fscache_enabled(path) (0)
#endif

extern int cmd_main(int, const char **);
Expand Down