Skip to content

Commit fc02dcf

Browse files
benpeartdscho
authored andcommitted
Add virtual file system settings and hook proc
On index load, clear/set the skip worktree bits based on the virtual file system data. Use virtual file system data to update skip-worktree bit in unpack-trees. Use virtual file system data to exclude files and folders not explicitly requested. Signed-off-by: Ben Peart <benpeart@microsoft.com>
1 parent 5386123 commit fc02dcf

File tree

13 files changed

+789
-9
lines changed

13 files changed

+789
-9
lines changed

Documentation/config/core.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ core.fsmonitor::
6868
avoiding unnecessary processing of files that have not changed.
6969
See the "fsmonitor-watchman" section of linkgit:githooks[5].
7070

71+
core.virtualFilesystem::
72+
If set, the value of this variable is used as a command which
73+
will identify all files and directories that are present in
74+
the working directory. Git will only track and update files
75+
listed in the virtual file system. Using the virtual file system
76+
will supersede the sparse-checkout settings which will be ignored.
77+
See the "virtual file system" section of linkgit:githooks[5].
78+
7179
core.trustctime::
7280
If false, the ctime differences between the index and the
7381
working tree are ignored; useful when the inode change time

Documentation/githooks.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,26 @@ This hook is invoked by `git-p4 submit`. It takes no parameters and nothing
492492
from standard input. Exiting with non-zero status from this script prevent
493493
`git-p4 submit` from launching. Run `git-p4 submit --help` for details.
494494

495+
virtualFilesystem
496+
~~~~~~~~~~~~~~~~~~
497+
498+
"Virtual File System" allows populating the working directory sparsely.
499+
The projection data is typically automatically generated by an external
500+
process. Git will limit what files it checks for changes as well as which
501+
directories are checked for untracked files based on the path names given.
502+
Git will also only update those files listed in the projection.
503+
504+
The hook is invoked when the configuration option core.virtualFilesystem
505+
is set. It takes one argument, a version (currently 1).
506+
507+
The hook should output to stdout the list of all files in the working
508+
directory that git should track. The paths are relative to the root
509+
of the working directory and are separated by a single NUL. Full paths
510+
('dir1/a.txt') as well as directories are supported (ie 'dir1/').
511+
512+
The exit status determines whether git will use the data from the
513+
hook. On error, git will abort the command with an error message.
514+
495515
GIT
496516
---
497517
Part of the linkgit:git[1] suite

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ LIB_OBJS += utf8.o
10371037
LIB_OBJS += varint.o
10381038
LIB_OBJS += version.o
10391039
LIB_OBJS += versioncmp.o
1040+
LIB_OBJS += virtualfilesystem.o
10401041
LIB_OBJS += walker.o
10411042
LIB_OBJS += wildmatch.o
10421043
LIB_OBJS += worktree.o

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,7 @@ extern char *git_replace_ref_base;
886886
extern int fsync_object_files;
887887
extern int core_preload_index;
888888
extern int core_apply_sparse_checkout;
889+
extern const char *core_virtualfilesystem;
889890
extern int core_gvfs;
890891
extern int precomposed_unicode;
891892
extern int protect_hfs;

config.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,11 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
13311331
}
13321332

13331333
if (!strcmp(var, "core.sparsecheckout")) {
1334-
core_apply_sparse_checkout = git_config_bool(var, value);
1334+
/* virtual file system relies on the sparse checkout logic so force it on */
1335+
if (core_virtualfilesystem)
1336+
core_apply_sparse_checkout = 1;
1337+
else
1338+
core_apply_sparse_checkout = git_config_bool(var, value);
13351339
return 0;
13361340
}
13371341

@@ -2312,6 +2316,23 @@ int git_config_get_fsmonitor(void)
23122316
return 0;
23132317
}
23142318

2319+
int git_config_get_virtualfilesystem(void)
2320+
{
2321+
if (git_config_get_pathname("core.virtualfilesystem", &core_virtualfilesystem))
2322+
core_virtualfilesystem = getenv("GIT_VIRTUALFILESYSTEM_TEST");
2323+
2324+
if (core_virtualfilesystem && !*core_virtualfilesystem)
2325+
core_virtualfilesystem = NULL;
2326+
2327+
/* virtual file system relies on the sparse checkout logic so force it on */
2328+
if (core_virtualfilesystem) {
2329+
core_apply_sparse_checkout = 1;
2330+
return 1;
2331+
}
2332+
2333+
return 0;
2334+
}
2335+
23152336
int git_config_get_index_threads(int *dest)
23162337
{
23172338
int is_bool, val;

config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ extern int git_config_get_untracked_cache(void);
251251
extern int git_config_get_split_index(void);
252252
extern int git_config_get_max_percent_split_change(void);
253253
extern int git_config_get_fsmonitor(void);
254+
extern int git_config_get_virtualfilesystem(void);
254255

255256
/* This dies if the configured or default date is in the future */
256257
extern int git_config_get_expiry(const char *key, const char **output);

dir.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "ewah/ewok.h"
2121
#include "fsmonitor.h"
2222
#include "submodule-config.h"
23+
#include "virtualfilesystem.h"
2324

2425
/*
2526
* Tells read_directory_recursive how a file or directory should be treated.
@@ -1121,6 +1122,18 @@ int is_excluded_from_list(const char *pathname,
11211122
struct exclude_list *el, struct index_state *istate)
11221123
{
11231124
struct exclude *exclude;
1125+
1126+
/*
1127+
* The virtual file system data is used to prevent git from traversing
1128+
* any part of the tree that is not in the virtual file system. Return
1129+
* 1 to exclude the entry if it is not found in the virtual file system,
1130+
* else fall through to the regular excludes logic as it may further exclude.
1131+
*/
1132+
if (*dtype == DT_UNKNOWN)
1133+
*dtype = get_dtype(NULL, istate, pathname, pathlen);
1134+
if (is_excluded_from_virtualfilesystem(pathname, pathlen, *dtype) > 0)
1135+
return 1;
1136+
11241137
exclude = last_exclude_matching_from_list(pathname, pathlen, basename,
11251138
dtype, el, istate);
11261139
if (exclude)
@@ -1336,8 +1349,20 @@ struct exclude *last_exclude_matching(struct dir_struct *dir,
13361349
int is_excluded(struct dir_struct *dir, struct index_state *istate,
13371350
const char *pathname, int *dtype_p)
13381351
{
1339-
struct exclude *exclude =
1340-
last_exclude_matching(dir, istate, pathname, dtype_p);
1352+
struct exclude *exclude;
1353+
1354+
/*
1355+
* The virtual file system data is used to prevent git from traversing
1356+
* any part of the tree that is not in the virtual file system. Return
1357+
* 1 to exclude the entry if it is not found in the virtual file system,
1358+
* else fall through to the regular excludes logic as it may further exclude.
1359+
*/
1360+
if (*dtype_p == DT_UNKNOWN)
1361+
*dtype_p = get_dtype(NULL, istate, pathname, strlen(pathname));
1362+
if (is_excluded_from_virtualfilesystem(pathname, strlen(pathname), *dtype_p) > 0)
1363+
return 1;
1364+
1365+
exclude = last_exclude_matching(dir, istate, pathname, dtype_p);
13411366
if (exclude)
13421367
return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1;
13431368
return 0;
@@ -1690,6 +1715,9 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
16901715
if (dtype != DT_DIR && has_path_in_index)
16911716
return path_none;
16921717

1718+
if (is_excluded_from_virtualfilesystem(path->buf, path->len, dtype) > 0)
1719+
return path_excluded;
1720+
16931721
/*
16941722
* When we are looking at a directory P in the working tree,
16951723
* there are three cases:
@@ -2030,6 +2058,8 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
20302058
/* add the path to the appropriate result list */
20312059
switch (state) {
20322060
case path_excluded:
2061+
if (is_excluded_from_virtualfilesystem(path.buf, path.len, DT_DIR) > 0)
2062+
break;
20332063
if (dir->flags & DIR_SHOW_IGNORED)
20342064
dir_add_name(dir, istate, path.buf, path.len);
20352065
else if ((dir->flags & DIR_SHOW_IGNORED_TOO) ||

environment.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ char *notes_ref_name;
7070
int grafts_replace_parents = 1;
7171
int core_apply_sparse_checkout;
7272
int core_gvfs;
73+
const char *core_virtualfilesystem;
7374
int merge_log_config = -1;
7475
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
7576
unsigned long pack_size_limit_cfg;

read-cache.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "fsmonitor.h"
2525
#include "thread-utils.h"
2626
#include "progress.h"
27+
#include "virtualfilesystem.h"
2728
#include "gvfs.h"
2829

2930
/* Mask for the name length in ce_flags in the on-disk index */
@@ -1886,6 +1887,7 @@ static void post_read_index_from(struct index_state *istate)
18861887
tweak_untracked_cache(istate);
18871888
tweak_split_index(istate);
18881889
tweak_fsmonitor(istate);
1890+
apply_virtualfilesystem(istate);
18891891
}
18901892

18911893
static size_t estimate_cache_size_from_compressed(unsigned int entries)

0 commit comments

Comments
 (0)