diff options
Diffstat (limited to 'dir.h')
-rw-r--r-- | dir.h | 96 |
1 files changed, 89 insertions, 7 deletions
@@ -27,7 +27,7 @@ struct exclude { int nowildcardlen; const char *base; int baselen; - int flags; + unsigned flags; /* EXC_FLAG_* */ /* * Counting starts from 1 for line numbers in ignore files, @@ -66,6 +66,7 @@ struct exclude_stack { struct exclude_stack *prev; /* the struct exclude_stack for the parent directory */ int baselen; int exclude_ix; /* index of exclude_list within EXC_DIRS exclude_list_group */ + struct untracked_cache_dir *ucd; }; struct exclude_list_group { @@ -73,6 +74,73 @@ struct exclude_list_group { struct exclude_list *el; }; +struct sha1_stat { + struct stat_data stat; + unsigned char sha1[20]; + int valid; +}; + +/* + * Untracked cache + * + * The following inputs are sufficient to determine what files in a + * directory are excluded: + * + * - The list of files and directories of the directory in question + * - The $GIT_DIR/index + * - dir_struct flags + * - The content of $GIT_DIR/info/exclude + * - The content of core.excludesfile + * - The content (or the lack) of .gitignore of all parent directories + * from $GIT_WORK_TREE + * - The check_only flag in read_directory_recursive (for + * DIR_HIDE_EMPTY_DIRECTORIES) + * + * The first input can be checked using directory mtime. In many + * filesystems, directory mtime (stat_data field) is updated when its + * files or direct subdirs are added or removed. + * + * The second one can be hooked from cache_tree_invalidate_path(). + * Whenever a file (or a submodule) is added or removed from a + * directory, we invalidate that directory. + * + * The remaining inputs are easy, their SHA-1 could be used to verify + * their contents (exclude_sha1[], info_exclude_sha1[] and + * excludes_file_sha1[]) + */ +struct untracked_cache_dir { + struct untracked_cache_dir **dirs; + char **untracked; + struct stat_data stat_data; + unsigned int untracked_alloc, dirs_nr, dirs_alloc; + unsigned int untracked_nr; + unsigned int check_only : 1; + /* all data except 'dirs' in this struct are good */ + unsigned int valid : 1; + unsigned int recurse : 1; + /* null SHA-1 means this directory does not have .gitignore */ + unsigned char exclude_sha1[20]; + char name[FLEX_ARRAY]; +}; + +struct untracked_cache { + struct sha1_stat ss_info_exclude; + struct sha1_stat ss_excludes_file; + const char *exclude_per_dir; + struct strbuf ident; + /* + * dir_struct#flags must match dir_flags or the untracked + * cache is ignored. + */ + unsigned dir_flags; + struct untracked_cache_dir *root; + /* Statistics */ + int dir_created; + int gitignore_invalidated; + int dir_invalidated; + int dir_opened; +}; + struct dir_struct { int nr, alloc; int ignored_nr, ignored_alloc; @@ -120,6 +188,12 @@ struct dir_struct { struct exclude_stack *exclude_stack; struct exclude *exclude; struct strbuf basebuf; + + /* Enable untracked file cache if set */ + struct untracked_cache *untracked; + struct sha1_stat ss_info_exclude; + struct sha1_stat ss_excludes_file; + unsigned unmanaged_exclude_files; }; /* @@ -152,10 +226,10 @@ struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, * attr.c:path_matches() */ extern int match_basename(const char *, int, - const char *, int, int, int); + const char *, int, int, unsigned); extern int match_pathname(const char *, int, const char *, int, - const char *, int, int, int); + const char *, int, int, unsigned); extern struct exclude *last_exclude_matching(struct dir_struct *dir, const char *name, int *dtype); @@ -167,7 +241,7 @@ extern struct exclude_list *add_exclude_list(struct dir_struct *dir, extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, struct exclude_list *el, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); -extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen); +extern void parse_exclude_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen); extern void add_exclude(const char *string, const char *base, int baselen, struct exclude_list *el, int srcpos); extern void clear_exclude_list(struct exclude_list *el); @@ -196,9 +270,8 @@ extern int remove_dir_recursively(struct strbuf *path, int flag); /* tries to remove the path with empty directories along it, ignores ENOENT */ extern int remove_path(const char *path); -extern int strcmp_icase(const char *a, const char *b); -extern int strncmp_icase(const char *a, const char *b, size_t count); -extern int fnmatch_icase(const char *pattern, const char *string, int flags); +extern int fspathcmp(const char *a, const char *b); +extern int fspathncmp(const char *a, const char *b, size_t count); /* * The prefix part of pattern must not contains wildcards. @@ -226,4 +299,13 @@ static inline int dir_path_match(const struct dir_entry *ent, has_trailing_dir); } +void untracked_cache_invalidate_path(struct index_state *, const char *); +void untracked_cache_remove_from_index(struct index_state *, const char *); +void untracked_cache_add_to_index(struct index_state *, const char *); + +void free_untracked_cache(struct untracked_cache *); +struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz); +void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked); +void add_untracked_cache(struct index_state *istate); +void remove_untracked_cache(struct index_state *istate); #endif |