Skip to content

Commit 5e622c7

Browse files
committed
Merge branch 'dont-clean-junctions-fscache'
We already avoid traversing NTFS junction points in `git clean -dfx`. With this topic branch, we do that when the FSCache is enabled, too. Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 73626ae + 5e51490 commit 5e622c7

File tree

5 files changed

+47
-1
lines changed

5 files changed

+47
-1
lines changed

builtin/clean.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
10411041

10421042
if (repo_read_index(the_repository) < 0)
10431043
die(_("index file corrupt"));
1044+
enable_fscache(the_index.cache_nr);
10441045

10451046
pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
10461047
for (i = 0; i < exclude_list.nr; i++)
@@ -1115,6 +1116,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
11151116
}
11161117
}
11171118

1119+
disable_fscache();
11181120
strbuf_release(&abs_path);
11191121
strbuf_release(&buf);
11201122
string_list_clear(&del_list, 0);

compat/mingw.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,6 +2746,8 @@ pid_t waitpid(pid_t pid, int *status, int options)
27462746
return -1;
27472747
}
27482748

2749+
int (*win32_is_mount_point)(struct strbuf *path) = mingw_is_mount_point;
2750+
27492751
int mingw_is_mount_point(struct strbuf *path)
27502752
{
27512753
WIN32_FIND_DATAW findbuf = { 0 };

compat/mingw.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,8 @@ static inline void convert_slashes(char *path)
471471
}
472472
struct strbuf;
473473
int mingw_is_mount_point(struct strbuf *path);
474-
#define is_mount_point mingw_is_mount_point
474+
extern int (*win32_is_mount_point)(struct strbuf *path);
475+
#define is_mount_point win32_is_mount_point
475476
#define CAN_UNLINK_MOUNT_POINTS 1
476477
#define PATH_SEP ';'
477478
char *mingw_query_user_email(void);

compat/win32/fscache.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
4444
struct fsentry {
4545
struct hashmap_entry ent;
4646
mode_t st_mode;
47+
ULONG reparse_tag;
4748
/* Pointer to the directory listing, or NULL for the listing itself. */
4849
struct fsentry *list;
4950
/* Pointer to the next file entry of the list. */
@@ -195,6 +196,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
195196

196197
fse = fsentry_alloc(cache, list, buf, len);
197198

199+
fse->reparse_tag =
200+
fdata->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
201+
fdata->EaSize : 0;
202+
198203
fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes);
199204
fse->dirent.d_type = S_ISDIR(fse->st_mode) ? DT_DIR : DT_REG;
200205
fse->u.s.st_size = fdata->EndOfFile.LowPart |
@@ -462,6 +467,7 @@ int fscache_enable(size_t initial_size)
462467
/* redirect opendir and lstat to the fscache implementations */
463468
opendir = fscache_opendir;
464469
lstat = fscache_lstat;
470+
win32_is_mount_point = fscache_is_mount_point;
465471
}
466472
initialized++;
467473
LeaveCriticalSection(&fscache_cs);
@@ -522,6 +528,7 @@ void fscache_disable(void)
522528
/* reset opendir and lstat to the original implementations */
523529
opendir = dirent_opendir;
524530
lstat = mingw_lstat;
531+
win32_is_mount_point = mingw_is_mount_point;
525532
}
526533
LeaveCriticalSection(&fscache_cs);
527534

@@ -592,6 +599,39 @@ int fscache_lstat(const char *filename, struct stat *st)
592599
return 0;
593600
}
594601

602+
/*
603+
* is_mount_point() replacement, uses cache if enabled, otherwise falls
604+
* back to mingw_is_mount_point().
605+
*/
606+
int fscache_is_mount_point(struct strbuf *path)
607+
{
608+
int dirlen, base, len;
609+
struct heap_fsentry key[2];
610+
struct fsentry *fse;
611+
struct fscache *cache = fscache_getcache();
612+
613+
if (!cache || !do_fscache_enabled(cache, path->buf))
614+
return mingw_is_mount_point(path);
615+
616+
cache->lstat_requests++;
617+
/* split path into path + name */
618+
len = path->len;
619+
if (len && is_dir_sep(path->buf[len - 1]))
620+
len--;
621+
base = len;
622+
while (base && !is_dir_sep(path->buf[base - 1]))
623+
base--;
624+
dirlen = base ? base - 1 : 0;
625+
626+
/* lookup entry for path + name in cache */
627+
fsentry_init(&key[0].u.ent, NULL, path->buf, dirlen);
628+
fsentry_init(&key[1].u.ent, &key[0].u.ent, path->buf + base, len - base);
629+
fse = fscache_get(cache, &key[1].u.ent);
630+
if (!fse)
631+
return mingw_is_mount_point(path);
632+
return fse->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT;
633+
}
634+
595635
typedef struct fscache_DIR {
596636
struct DIR base_dir; /* extend base struct DIR */
597637
struct fsentry *pfsentry;

compat/win32/fscache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void fscache_flush(void);
2222

2323
DIR *fscache_opendir(const char *dir);
2424
int fscache_lstat(const char *file_name, struct stat *buf);
25+
int fscache_is_mount_point(struct strbuf *path);
2526

2627
/* opaque fscache structure */
2728
struct fscache;

0 commit comments

Comments
 (0)