Skip to content

Commit 26cb018

Browse files
pcloudsgitster
authored andcommitted
untracked cache: mark what dirs should be recursed/saved
If we redo this thing in a functional style, we would have one struct untracked_dir as input tree and another as output. The input is used for verification. The output is a brand new tree, reflecting current worktree. But that means recreate a lot of dir nodes even if a lot could be shared between input and output trees in good cases. So we go with the messy but efficient way, combining both input and output trees into one. We need a way to know which node in this combined tree belongs to the output. This is the purpose of this "recurse" flag. "valid" bit can't be used for this because it's about data of the node except the subdirs. When we invalidate a directory, we want to keep cached data of the subdirs intact even though we don't really know what subdir still exists (yet). Then we check worktree to see what actual subdir remains on disk. Those will have 'recurse' bit set again. If cached data for those are still valid, we may be able to avoid computing exclude files for them. Those subdirs that are deleted will have 'recurse' remained clear and their 'valid' bits do not matter. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 91a2288 commit 26cb018

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

dir.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,9 +615,12 @@ static void invalidate_gitignore(struct untracked_cache *uc,
615615
static void invalidate_directory(struct untracked_cache *uc,
616616
struct untracked_cache_dir *dir)
617617
{
618+
int i;
618619
uc->dir_invalidated++;
619620
dir->valid = 0;
620621
dir->untracked_nr = 0;
622+
for (i = 0; i < dir->dirs_nr; i++)
623+
dir->dirs[i]->recurse = 0;
621624
}
622625

623626
/*
@@ -1578,6 +1581,10 @@ static int read_cached_dir(struct cached_dir *cdir)
15781581
}
15791582
while (cdir->nr_dirs < cdir->untracked->dirs_nr) {
15801583
struct untracked_cache_dir *d = cdir->untracked->dirs[cdir->nr_dirs];
1584+
if (!d->recurse) {
1585+
cdir->nr_dirs++;
1586+
continue;
1587+
}
15811588
cdir->ucd = d;
15821589
cdir->nr_dirs++;
15831590
return 0;
@@ -1599,8 +1606,10 @@ static void close_cached_dir(struct cached_dir *cdir)
15991606
* We have gone through this directory and found no untracked
16001607
* entries. Mark it valid.
16011608
*/
1602-
if (cdir->untracked)
1609+
if (cdir->untracked) {
16031610
cdir->untracked->valid = 1;
1611+
cdir->untracked->recurse = 1;
1612+
}
16041613
}
16051614

16061615
/*
@@ -1843,6 +1852,9 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
18431852
invalidate_gitignore(dir->untracked, root);
18441853
dir->untracked->ss_excludes_file = dir->ss_excludes_file;
18451854
}
1855+
1856+
/* Make sure this directory is not dropped out at saving phase */
1857+
root->recurse = 1;
18461858
return root;
18471859
}
18481860

dir.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ struct untracked_cache_dir {
115115
unsigned int untracked_alloc, dirs_nr, dirs_alloc;
116116
unsigned int untracked_nr;
117117
unsigned int check_only : 1;
118-
/* all data in this struct are good */
118+
/* all data except 'dirs' in this struct are good */
119119
unsigned int valid : 1;
120+
unsigned int recurse : 1;
120121
/* null SHA-1 means this directory does not have .gitignore */
121122
unsigned char exclude_sha1[20];
122123
char name[FLEX_ARRAY];

0 commit comments

Comments
 (0)