Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 1 | #ifndef DIR_H |
| 2 | #define DIR_H |
| 3 | |
Elijah Newren | b9a7ac2 | 2023-05-16 06:34:07 +0000 | [diff] [blame] | 4 | #include "hash-ll.h" |
Derrick Stolee | 96cc8ab | 2019-11-21 22:04:41 +0000 | [diff] [blame] | 5 | #include "hashmap.h" |
Elijah Newren | ac48adf | 2023-02-24 00:09:31 +0000 | [diff] [blame] | 6 | #include "pathspec.h" |
| 7 | #include "statinfo.h" |
Junio C Hamano | eb41775 | 2012-06-01 11:28:00 -0700 | [diff] [blame] | 8 | #include "strbuf.h" |
| 9 | |
Junio C Hamano | 67e7305 | 2023-07-06 11:54:46 -0700 | [diff] [blame] | 10 | struct repository; |
| 11 | |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 12 | /** |
| 13 | * The directory listing API is used to enumerate paths in the work tree, |
| 14 | * optionally taking `.git/info/exclude` and `.gitignore` files per directory |
| 15 | * into account. |
| 16 | */ |
| 17 | |
| 18 | /** |
| 19 | * Calling sequence |
| 20 | * ---------------- |
| 21 | * |
| 22 | * Note: The index may be checked for .gitignore files that are |
| 23 | * CE_SKIP_WORKTREE marked. If you want to exclude files, make sure you have |
| 24 | * loaded the index first. |
| 25 | * |
Elijah Newren | eceba53 | 2020-08-18 22:58:26 +0000 | [diff] [blame] | 26 | * - Prepare `struct dir_struct dir` using `dir_init()` function. |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 27 | * |
| 28 | * - To add single exclude pattern, call `add_pattern_list()` and then |
| 29 | * `add_pattern()`. |
| 30 | * |
| 31 | * - To add patterns from a file (e.g. `.git/info/exclude`), call |
Elijah Newren | eceba53 | 2020-08-18 22:58:26 +0000 | [diff] [blame] | 32 | * `add_patterns_from_file()` , and/or set `dir.exclude_per_dir`. |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 33 | * |
Elijah Newren | eceba53 | 2020-08-18 22:58:26 +0000 | [diff] [blame] | 34 | * - A short-hand function `setup_standard_excludes()` can be used to set |
| 35 | * up the standard set of exclude settings, instead of manually calling |
| 36 | * the add_pattern*() family of functions. |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 37 | * |
Elijah Newren | eceba53 | 2020-08-18 22:58:26 +0000 | [diff] [blame] | 38 | * - Call `fill_directory()`. |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 39 | * |
Elijah Newren | eceba53 | 2020-08-18 22:58:26 +0000 | [diff] [blame] | 40 | * - Use `dir.entries[]` and `dir.ignored[]`. |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 41 | * |
Elijah Newren | eceba53 | 2020-08-18 22:58:26 +0000 | [diff] [blame] | 42 | * - Call `dir_clear()` when the contained elements are no longer in use. |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 43 | * |
| 44 | */ |
| 45 | |
Calvin Wan | f940185 | 2023-06-06 19:48:41 +0000 | [diff] [blame] | 46 | struct repository; |
| 47 | |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 48 | struct dir_entry { |
Jeff King | e96980e | 2007-06-12 23:42:14 +0200 | [diff] [blame] | 49 | unsigned int len; |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 50 | char name[FLEX_ARRAY]; /* more */ |
| 51 | }; |
| 52 | |
Derrick Stolee | 4ff89ee | 2019-09-03 11:04:56 -0700 | [diff] [blame] | 53 | #define PATTERN_FLAG_NODIR 1 |
| 54 | #define PATTERN_FLAG_ENDSWITH 4 |
| 55 | #define PATTERN_FLAG_MUSTBEDIR 8 |
| 56 | #define PATTERN_FLAG_NEGATIVE 16 |
Lars Knoll | 68492fc | 2007-10-28 21:27:13 +0100 | [diff] [blame] | 57 | |
Derrick Stolee | ab8db61 | 2019-09-03 11:04:55 -0700 | [diff] [blame] | 58 | struct path_pattern { |
Nguyễn Thái Ngọc Duy | 709359c | 2014-07-14 11:48:03 +0200 | [diff] [blame] | 59 | /* |
Derrick Stolee | 65edd96 | 2019-09-03 11:04:57 -0700 | [diff] [blame] | 60 | * This allows callers of last_matching_pattern() etc. |
Nguyễn Thái Ngọc Duy | 709359c | 2014-07-14 11:48:03 +0200 | [diff] [blame] | 61 | * to determine the origin of the matching pattern. |
| 62 | */ |
Derrick Stolee | caa3d55 | 2019-09-03 11:04:56 -0700 | [diff] [blame] | 63 | struct pattern_list *pl; |
Nguyễn Thái Ngọc Duy | 709359c | 2014-07-14 11:48:03 +0200 | [diff] [blame] | 64 | |
| 65 | const char *pattern; |
| 66 | int patternlen; |
| 67 | int nowildcardlen; |
| 68 | const char *base; |
| 69 | int baselen; |
Derrick Stolee | 4ff89ee | 2019-09-03 11:04:56 -0700 | [diff] [blame] | 70 | unsigned flags; /* PATTERN_FLAG_* */ |
Nguyễn Thái Ngọc Duy | 709359c | 2014-07-14 11:48:03 +0200 | [diff] [blame] | 71 | |
| 72 | /* |
| 73 | * Counting starts from 1 for line numbers in ignore files, |
| 74 | * and from -1 decrementing for patterns from CLI args. |
| 75 | */ |
| 76 | int srcpos; |
| 77 | }; |
| 78 | |
Derrick Stolee | 96cc8ab | 2019-11-21 22:04:41 +0000 | [diff] [blame] | 79 | /* used for hashmaps for cone patterns */ |
| 80 | struct pattern_entry { |
| 81 | struct hashmap_entry ent; |
| 82 | char *pattern; |
| 83 | size_t patternlen; |
| 84 | }; |
| 85 | |
Adam Spiers | 95a6834 | 2012-12-27 02:32:21 +0000 | [diff] [blame] | 86 | /* |
Adam Spiers | c082df2 | 2013-01-06 16:58:03 +0000 | [diff] [blame] | 87 | * Each excludes file will be parsed into a fresh exclude_list which |
| 88 | * is appended to the relevant exclude_list_group (either EXC_DIRS or |
| 89 | * EXC_FILE). An exclude_list within the EXC_CMDL exclude_list_group |
| 90 | * can also be used to represent the list of --exclude values passed |
| 91 | * via CLI args. |
Adam Spiers | 95a6834 | 2012-12-27 02:32:21 +0000 | [diff] [blame] | 92 | */ |
Derrick Stolee | caa3d55 | 2019-09-03 11:04:56 -0700 | [diff] [blame] | 93 | struct pattern_list { |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 94 | int nr; |
| 95 | int alloc; |
Adam Spiers | c04318e | 2013-01-06 16:58:04 +0000 | [diff] [blame] | 96 | |
Adam Spiers | c082df2 | 2013-01-06 16:58:03 +0000 | [diff] [blame] | 97 | /* remember pointer to exclude file contents so we can free() */ |
| 98 | char *filebuf; |
| 99 | |
Adam Spiers | c04318e | 2013-01-06 16:58:04 +0000 | [diff] [blame] | 100 | /* origin of list, e.g. path to filename, or descriptive string */ |
| 101 | const char *src; |
| 102 | |
Derrick Stolee | ab8db61 | 2019-09-03 11:04:55 -0700 | [diff] [blame] | 103 | struct path_pattern **patterns; |
Derrick Stolee | 96cc8ab | 2019-11-21 22:04:41 +0000 | [diff] [blame] | 104 | |
| 105 | /* |
| 106 | * While scanning the excludes, we attempt to match the patterns |
| 107 | * with a more restricted set that allows us to use hashsets for |
| 108 | * matching logic, which is faster than the linear lookup in the |
| 109 | * excludes array above. If non-zero, that check succeeded. |
| 110 | */ |
| 111 | unsigned use_cone_patterns; |
| 112 | unsigned full_cone; |
| 113 | |
| 114 | /* |
| 115 | * Stores paths where everything starting with those paths |
| 116 | * is included. |
| 117 | */ |
| 118 | struct hashmap recursive_hashmap; |
| 119 | |
| 120 | /* |
| 121 | * Used to check single-level parents of blobs. |
| 122 | */ |
| 123 | struct hashmap parent_hashmap; |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 124 | }; |
| 125 | |
Adam Spiers | 95a6834 | 2012-12-27 02:32:21 +0000 | [diff] [blame] | 126 | /* |
| 127 | * The contents of the per-directory exclude files are lazily read on |
| 128 | * demand and then cached in memory, one per exclude_stack struct, in |
| 129 | * order to avoid opening and parsing each one every time that |
| 130 | * directory is traversed. |
| 131 | */ |
Junio C Hamano | 63d285c | 2007-11-29 02:17:44 -0800 | [diff] [blame] | 132 | struct exclude_stack { |
Adam Spiers | 95a6834 | 2012-12-27 02:32:21 +0000 | [diff] [blame] | 133 | struct exclude_stack *prev; /* the struct exclude_stack for the parent directory */ |
Junio C Hamano | 63d285c | 2007-11-29 02:17:44 -0800 | [diff] [blame] | 134 | int baselen; |
Adam Spiers | c082df2 | 2013-01-06 16:58:03 +0000 | [diff] [blame] | 135 | int exclude_ix; /* index of exclude_list within EXC_DIRS exclude_list_group */ |
Nguyễn Thái Ngọc Duy | 0dcb8d7 | 2015-03-08 17:12:25 +0700 | [diff] [blame] | 136 | struct untracked_cache_dir *ucd; |
Adam Spiers | c082df2 | 2013-01-06 16:58:03 +0000 | [diff] [blame] | 137 | }; |
| 138 | |
| 139 | struct exclude_list_group { |
| 140 | int nr, alloc; |
Derrick Stolee | caa3d55 | 2019-09-03 11:04:56 -0700 | [diff] [blame] | 141 | struct pattern_list *pl; |
Junio C Hamano | 63d285c | 2007-11-29 02:17:44 -0800 | [diff] [blame] | 142 | }; |
| 143 | |
Patryk Obara | 4b33e60 | 2018-01-28 01:13:12 +0100 | [diff] [blame] | 144 | struct oid_stat { |
Nguyễn Thái Ngọc Duy | 55fe6f5 | 2015-03-08 17:12:24 +0700 | [diff] [blame] | 145 | struct stat_data stat; |
Patryk Obara | 4b33e60 | 2018-01-28 01:13:12 +0100 | [diff] [blame] | 146 | struct object_id oid; |
Nguyễn Thái Ngọc Duy | 55fe6f5 | 2015-03-08 17:12:24 +0700 | [diff] [blame] | 147 | int valid; |
| 148 | }; |
| 149 | |
Nguyễn Thái Ngọc Duy | 0dcb8d7 | 2015-03-08 17:12:25 +0700 | [diff] [blame] | 150 | /* |
| 151 | * Untracked cache |
| 152 | * |
| 153 | * The following inputs are sufficient to determine what files in a |
| 154 | * directory are excluded: |
| 155 | * |
| 156 | * - The list of files and directories of the directory in question |
| 157 | * - The $GIT_DIR/index |
| 158 | * - dir_struct flags |
| 159 | * - The content of $GIT_DIR/info/exclude |
| 160 | * - The content of core.excludesfile |
| 161 | * - The content (or the lack) of .gitignore of all parent directories |
| 162 | * from $GIT_WORK_TREE |
| 163 | * - The check_only flag in read_directory_recursive (for |
| 164 | * DIR_HIDE_EMPTY_DIRECTORIES) |
| 165 | * |
| 166 | * The first input can be checked using directory mtime. In many |
| 167 | * filesystems, directory mtime (stat_data field) is updated when its |
| 168 | * files or direct subdirs are added or removed. |
| 169 | * |
| 170 | * The second one can be hooked from cache_tree_invalidate_path(). |
| 171 | * Whenever a file (or a submodule) is added or removed from a |
| 172 | * directory, we invalidate that directory. |
| 173 | * |
| 174 | * The remaining inputs are easy, their SHA-1 could be used to verify |
| 175 | * their contents (exclude_sha1[], info_exclude_sha1[] and |
| 176 | * excludes_file_sha1[]) |
| 177 | */ |
| 178 | struct untracked_cache_dir { |
| 179 | struct untracked_cache_dir **dirs; |
| 180 | char **untracked; |
| 181 | struct stat_data stat_data; |
| 182 | unsigned int untracked_alloc, dirs_nr, dirs_alloc; |
| 183 | unsigned int untracked_nr; |
| 184 | unsigned int check_only : 1; |
Nguyễn Thái Ngọc Duy | 26cb018 | 2015-03-08 17:12:30 +0700 | [diff] [blame] | 185 | /* all data except 'dirs' in this struct are good */ |
Nguyễn Thái Ngọc Duy | ccad261 | 2015-03-08 17:12:26 +0700 | [diff] [blame] | 186 | unsigned int valid : 1; |
Nguyễn Thái Ngọc Duy | 26cb018 | 2015-03-08 17:12:30 +0700 | [diff] [blame] | 187 | unsigned int recurse : 1; |
brian m. carlson | 70c369c | 2018-05-02 00:25:48 +0000 | [diff] [blame] | 188 | /* null object ID means this directory does not have .gitignore */ |
| 189 | struct object_id exclude_oid; |
Nguyễn Thái Ngọc Duy | 0dcb8d7 | 2015-03-08 17:12:25 +0700 | [diff] [blame] | 190 | char name[FLEX_ARRAY]; |
| 191 | }; |
| 192 | |
| 193 | struct untracked_cache { |
Patryk Obara | 4b33e60 | 2018-01-28 01:13:12 +0100 | [diff] [blame] | 194 | struct oid_stat ss_info_exclude; |
| 195 | struct oid_stat ss_excludes_file; |
Nguyễn Thái Ngọc Duy | 0dcb8d7 | 2015-03-08 17:12:25 +0700 | [diff] [blame] | 196 | const char *exclude_per_dir; |
Ævar Arnfjörð Bjarmason | 083fd1a | 2022-11-08 19:17:41 +0100 | [diff] [blame] | 197 | char *exclude_per_dir_to_free; |
Nguyễn Thái Ngọc Duy | 1e8fef6 | 2015-03-08 17:12:46 +0700 | [diff] [blame] | 198 | struct strbuf ident; |
Nguyễn Thái Ngọc Duy | 0dcb8d7 | 2015-03-08 17:12:25 +0700 | [diff] [blame] | 199 | /* |
| 200 | * dir_struct#flags must match dir_flags or the untracked |
| 201 | * cache is ignored. |
| 202 | */ |
| 203 | unsigned dir_flags; |
| 204 | struct untracked_cache_dir *root; |
| 205 | /* Statistics */ |
| 206 | int dir_created; |
Nguyễn Thái Ngọc Duy | ccad261 | 2015-03-08 17:12:26 +0700 | [diff] [blame] | 207 | int gitignore_invalidated; |
Nguyễn Thái Ngọc Duy | 91a2288 | 2015-03-08 17:12:29 +0700 | [diff] [blame] | 208 | int dir_invalidated; |
| 209 | int dir_opened; |
Ben Peart | 883e248 | 2017-09-22 12:35:40 -0400 | [diff] [blame] | 210 | /* fsmonitor invalidation data */ |
| 211 | unsigned int use_fsmonitor : 1; |
Nguyễn Thái Ngọc Duy | 0dcb8d7 | 2015-03-08 17:12:25 +0700 | [diff] [blame] | 212 | }; |
| 213 | |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 214 | /** |
| 215 | * structure is used to pass directory traversal options to the library and to |
| 216 | * record the paths discovered. A single `struct dir_struct` is used regardless |
| 217 | * of whether or not the traversal recursively descends into subdirectories. |
| 218 | */ |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 219 | struct dir_struct { |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 220 | |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 221 | /* bit-field of options */ |
Johannes Schindelin | 7c4c97c | 2009-02-16 13:20:25 +0100 | [diff] [blame] | 222 | enum { |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 223 | |
| 224 | /** |
| 225 | * Return just ignored files in `entries[]`, not untracked files. |
| 226 | * This flag is mutually exclusive with `DIR_SHOW_IGNORED_TOO`. |
| 227 | */ |
Johannes Schindelin | 7c4c97c | 2009-02-16 13:20:25 +0100 | [diff] [blame] | 228 | DIR_SHOW_IGNORED = 1<<0, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 229 | |
| 230 | /* Include a directory that is not tracked. */ |
Johannes Schindelin | 7c4c97c | 2009-02-16 13:20:25 +0100 | [diff] [blame] | 231 | DIR_SHOW_OTHER_DIRECTORIES = 1<<1, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 232 | |
| 233 | /* Do not include a directory that is not tracked and is empty. */ |
Johannes Schindelin | 7c4c97c | 2009-02-16 13:20:25 +0100 | [diff] [blame] | 234 | DIR_HIDE_EMPTY_DIRECTORIES = 1<<2, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 235 | |
| 236 | /** |
| 237 | * If set, recurse into a directory that looks like a Git directory. |
| 238 | * Otherwise it is shown as a directory. |
| 239 | */ |
Johannes Schindelin | 7c4c97c | 2009-02-16 13:20:25 +0100 | [diff] [blame] | 240 | DIR_NO_GITLINKS = 1<<3, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 241 | |
| 242 | /** |
| 243 | * Special mode for git-add. Return ignored files in `ignored[]` and |
| 244 | * untracked files in `entries[]`. Only returns ignored files that match |
| 245 | * pathspec exactly (no wildcards). Does not recurse into ignored |
| 246 | * directories. |
| 247 | */ |
Karsten Blees | 0aaf62b | 2013-04-15 21:15:03 +0200 | [diff] [blame] | 248 | DIR_COLLECT_IGNORED = 1<<4, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 249 | |
| 250 | /** |
| 251 | * Similar to `DIR_SHOW_IGNORED`, but return ignored files in |
| 252 | * `ignored[]` in addition to untracked files in `entries[]`. |
| 253 | * This flag is mutually exclusive with `DIR_SHOW_IGNORED`. |
| 254 | */ |
Junio C Hamano | 2eac2a4 | 2013-08-15 12:13:46 -0700 | [diff] [blame] | 255 | DIR_SHOW_IGNORED_TOO = 1<<5, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 256 | |
Samuel Lijin | fb89888 | 2017-05-18 04:21:52 -0400 | [diff] [blame] | 257 | DIR_COLLECT_KILLED_ONLY = 1<<6, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 258 | |
| 259 | /** |
| 260 | * Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is |
| 261 | * set, the untracked contents of untracked directories are also |
| 262 | * returned in `entries[]`. |
| 263 | */ |
Jameson Miller | eec0f7f | 2017-10-30 13:21:37 -0400 | [diff] [blame] | 264 | DIR_KEEP_UNTRACKED_CONTENTS = 1<<7, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 265 | |
| 266 | /** |
| 267 | * Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is |
| 268 | * set, returns ignored files and directories that match an exclude |
| 269 | * pattern. If a directory matches an exclude pattern, then the |
| 270 | * directory is returned and the contained paths are not. A directory |
| 271 | * that does not match an exclude pattern will not be returned even if |
| 272 | * all of its contents are ignored. In this case, the contents are |
| 273 | * returned as individual entries. |
| 274 | * |
| 275 | * If this is set, files and directories that explicitly match an ignore |
| 276 | * pattern are reported. Implicitly ignored directories (directories that |
| 277 | * do not match an ignore pattern, but whose contents are all ignored) |
| 278 | * are not reported, instead all of the contents are reported. |
| 279 | */ |
Elijah Newren | 09487f2 | 2019-09-17 09:35:02 -0700 | [diff] [blame] | 280 | DIR_SHOW_IGNORED_TOO_MODE_MATCHING = 1<<8, |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 281 | |
Elijah Newren | 09487f2 | 2019-09-17 09:35:02 -0700 | [diff] [blame] | 282 | DIR_SKIP_NESTED_GIT = 1<<9 |
Johannes Schindelin | 7c4c97c | 2009-02-16 13:20:25 +0100 | [diff] [blame] | 283 | } flags; |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 284 | |
Elijah Newren | d144a9d | 2023-02-27 15:28:12 +0000 | [diff] [blame] | 285 | /* The number of members in `entries[]` array. */ |
| 286 | int nr; /* output only */ |
| 287 | |
| 288 | /* The number of members in `ignored[]` array. */ |
| 289 | int ignored_nr; /* output only */ |
| 290 | |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 291 | /* An array of `struct dir_entry`, each element of which describes a path. */ |
Elijah Newren | d144a9d | 2023-02-27 15:28:12 +0000 | [diff] [blame] | 292 | struct dir_entry **entries; /* output only */ |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 293 | |
| 294 | /** |
| 295 | * used for ignored paths with the `DIR_SHOW_IGNORED_TOO` and |
| 296 | * `DIR_COLLECT_IGNORED` flags. |
| 297 | */ |
Elijah Newren | d144a9d | 2023-02-27 15:28:12 +0000 | [diff] [blame] | 298 | struct dir_entry **ignored; /* output only */ |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 299 | |
Elijah Newren | 5fdf285 | 2023-02-27 15:28:10 +0000 | [diff] [blame] | 300 | /* Enable/update untracked file cache if set */ |
| 301 | struct untracked_cache *untracked; |
| 302 | |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 303 | /** |
Elijah Newren | 59e009b | 2023-02-27 15:28:11 +0000 | [diff] [blame] | 304 | * Deprecated: ls-files is the only allowed caller; all other callers |
| 305 | * should leave this as NULL; it pre-dated the |
| 306 | * setup_standard_excludes() mechanism that replaces this. |
| 307 | * |
| 308 | * This field tracks the name of the file to be read in each directory |
| 309 | * for excluded files (typically `.gitignore`). |
Heba Waly | 266f03e | 2019-11-17 21:04:41 +0000 | [diff] [blame] | 310 | */ |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 311 | const char *exclude_per_dir; |
Adam Spiers | c082df2 | 2013-01-06 16:58:03 +0000 | [diff] [blame] | 312 | |
Elijah Newren | 5fdf285 | 2023-02-27 15:28:10 +0000 | [diff] [blame] | 313 | struct dir_struct_internal { |
| 314 | /* Keeps track of allocation of `entries[]` array.*/ |
| 315 | int alloc; |
| 316 | |
| 317 | /* Keeps track of allocation of `ignored[]` array. */ |
| 318 | int ignored_alloc; |
| 319 | |
| 320 | /* |
| 321 | * We maintain three groups of exclude pattern lists: |
| 322 | * |
| 323 | * EXC_CMDL lists patterns explicitly given on the command line. |
| 324 | * EXC_DIRS lists patterns obtained from per-directory ignore |
| 325 | * files. |
| 326 | * EXC_FILE lists patterns from fallback ignore files, e.g. |
| 327 | * - .git/info/exclude |
| 328 | * - core.excludesfile |
| 329 | * |
| 330 | * Each group contains multiple exclude lists, a single list |
| 331 | * per source. |
| 332 | */ |
Junio C Hamano | 63d285c | 2007-11-29 02:17:44 -0800 | [diff] [blame] | 333 | #define EXC_CMDL 0 |
| 334 | #define EXC_DIRS 1 |
| 335 | #define EXC_FILE 2 |
Elijah Newren | 5fdf285 | 2023-02-27 15:28:10 +0000 | [diff] [blame] | 336 | struct exclude_list_group exclude_list_group[3]; |
Junio C Hamano | 63d285c | 2007-11-29 02:17:44 -0800 | [diff] [blame] | 337 | |
Elijah Newren | 5fdf285 | 2023-02-27 15:28:10 +0000 | [diff] [blame] | 338 | /* |
| 339 | * Temporary variables which are used during loading of the |
| 340 | * per-directory exclude lists. |
| 341 | * |
| 342 | * exclude_stack points to the top of the exclude_stack, and |
| 343 | * basebuf contains the full path to the current |
| 344 | * (sub)directory in the traversal. Exclude points to the |
| 345 | * matching exclude struct if the directory is excluded. |
| 346 | */ |
| 347 | struct exclude_stack *exclude_stack; |
| 348 | struct path_pattern *pattern; |
| 349 | struct strbuf basebuf; |
Nguyễn Thái Ngọc Duy | 0dcb8d7 | 2015-03-08 17:12:25 +0700 | [diff] [blame] | 350 | |
Elijah Newren | 5fdf285 | 2023-02-27 15:28:10 +0000 | [diff] [blame] | 351 | /* Additional metadata related to 'untracked' */ |
| 352 | struct oid_stat ss_info_exclude; |
| 353 | struct oid_stat ss_excludes_file; |
| 354 | unsigned unmanaged_exclude_files; |
Elijah Newren | 7fe1ffdaf | 2021-05-12 17:28:15 +0000 | [diff] [blame] | 355 | |
Elijah Newren | 5fdf285 | 2023-02-27 15:28:10 +0000 | [diff] [blame] | 356 | /* Stats about the traversal */ |
| 357 | unsigned visited_paths; |
| 358 | unsigned visited_directories; |
| 359 | } internal; |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 360 | }; |
| 361 | |
Ævar Arnfjörð Bjarmason | ce93a4c | 2021-07-01 12:51:27 +0200 | [diff] [blame] | 362 | #define DIR_INIT { 0 } |
| 363 | |
Elijah Newren | b548f0f | 2021-05-12 17:28:22 +0000 | [diff] [blame] | 364 | struct dirent *readdir_skip_dot_and_dotdot(DIR *dirp); |
| 365 | |
Prathamesh Chavan | e0556a9 | 2017-06-08 23:38:12 +0530 | [diff] [blame] | 366 | /*Count the number of slashes for string s*/ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 367 | int count_slashes(const char *s); |
Prathamesh Chavan | e0556a9 | 2017-06-08 23:38:12 +0530 | [diff] [blame] | 368 | |
Adam Spiers | 52ed189 | 2013-01-06 16:58:06 +0000 | [diff] [blame] | 369 | /* |
| 370 | * The ordering of these constants is significant, with |
| 371 | * higher-numbered match types signifying "closer" (i.e. more |
| 372 | * specific) matches which will override lower-numbered match types |
| 373 | * when populating the seen[] array. |
| 374 | */ |
Junio C Hamano | e813d50 | 2006-12-25 03:09:52 -0800 | [diff] [blame] | 375 | #define MATCHED_RECURSIVELY 1 |
Elijah Newren | 89a1f4a | 2019-09-17 09:34:58 -0700 | [diff] [blame] | 376 | #define MATCHED_RECURSIVELY_LEADING_PATHSPEC 2 |
| 377 | #define MATCHED_FNMATCH 3 |
| 378 | #define MATCHED_EXACTLY 4 |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 379 | int simple_length(const char *match); |
| 380 | int no_wildcard(const char *string); |
| 381 | char *common_prefix(const struct pathspec *pathspec); |
Junio C Hamano | 4aeeef3 | 2019-05-13 23:50:32 +0900 | [diff] [blame] | 382 | int report_path_error(const char *ps_matched, const struct pathspec *pathspec); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 383 | int within_depth(const char *name, int namelen, int depth, int max_depth); |
Linus Torvalds | 3c6a370 | 2006-05-19 16:07:51 -0700 | [diff] [blame] | 384 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 385 | int fill_directory(struct dir_struct *dir, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 386 | struct index_state *istate, |
| 387 | const struct pathspec *pathspec); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 388 | int read_directory(struct dir_struct *, struct index_state *istate, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 389 | const char *path, int len, |
| 390 | const struct pathspec *pathspec); |
Junio C Hamano | f8a9d42 | 2006-12-04 16:00:46 -0800 | [diff] [blame] | 391 | |
Derrick Stolee | 468ce99 | 2019-09-03 11:04:58 -0700 | [diff] [blame] | 392 | enum pattern_match_result { |
| 393 | UNDECIDED = -1, |
| 394 | NOT_MATCHED = 0, |
| 395 | MATCHED = 1, |
Derrick Stolee | eb42fec | 2019-11-21 22:04:43 +0000 | [diff] [blame] | 396 | MATCHED_RECURSIVE = 2, |
Derrick Stolee | 468ce99 | 2019-09-03 11:04:58 -0700 | [diff] [blame] | 397 | }; |
| 398 | |
| 399 | /* |
| 400 | * Scan the list of patterns to determine if the ordered list |
| 401 | * of patterns matches on 'pathname'. |
| 402 | * |
| 403 | * Return 1 for a match, 0 for not matched and -1 for undecided. |
| 404 | */ |
| 405 | enum pattern_match_result path_matches_pattern_list(const char *pathname, |
| 406 | int pathlen, |
| 407 | const char *basename, int *dtype, |
| 408 | struct pattern_list *pl, |
| 409 | struct index_state *istate); |
Derrick Stolee | 02155c8 | 2021-09-08 01:42:30 +0000 | [diff] [blame] | 410 | |
| 411 | int init_sparse_checkout_patterns(struct index_state *state); |
| 412 | |
| 413 | int path_in_sparse_checkout(const char *path, |
| 414 | struct index_state *istate); |
| 415 | int path_in_cone_mode_sparse_checkout(const char *path, |
| 416 | struct index_state *istate); |
| 417 | |
Brandon Williams | 9e58bec | 2017-05-05 12:53:25 -0700 | [diff] [blame] | 418 | struct dir_entry *dir_add_ignored(struct dir_struct *dir, |
| 419 | struct index_state *istate, |
| 420 | const char *pathname, int len); |
Junio C Hamano | eb41775 | 2012-06-01 11:28:00 -0700 | [diff] [blame] | 421 | |
| 422 | /* |
Nguyễn Thái Ngọc Duy | 82dce99 | 2012-10-15 13:24:39 +0700 | [diff] [blame] | 423 | * these implement the matching logic for dir.c:excluded_from_list and |
| 424 | * attr.c:path_matches() |
| 425 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 426 | int match_basename(const char *, int, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 427 | const char *, int, int, unsigned); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 428 | int match_pathname(const char *, int, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 429 | const char *, int, |
Jeff King | 77651c0 | 2022-08-19 04:50:54 -0400 | [diff] [blame] | 430 | const char *, int, int); |
Nguyễn Thái Ngọc Duy | 82dce99 | 2012-10-15 13:24:39 +0700 | [diff] [blame] | 431 | |
Derrick Stolee | 65edd96 | 2019-09-03 11:04:57 -0700 | [diff] [blame] | 432 | struct path_pattern *last_matching_pattern(struct dir_struct *dir, |
| 433 | struct index_state *istate, |
| 434 | const char *name, int *dtype); |
Junio C Hamano | 782cd4c | 2012-06-05 21:17:52 -0700 | [diff] [blame] | 435 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 436 | int is_excluded(struct dir_struct *dir, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 437 | struct index_state *istate, |
| 438 | const char *name, int *dtype); |
Junio C Hamano | eb41775 | 2012-06-01 11:28:00 -0700 | [diff] [blame] | 439 | |
Derrick Stolee | af09ce2 | 2019-11-21 22:04:42 +0000 | [diff] [blame] | 440 | int pl_hashmap_cmp(const void *unused_cmp_data, |
| 441 | const struct hashmap_entry *a, |
| 442 | const struct hashmap_entry *b, |
| 443 | const void *key); |
Derrick Stolee | 96cc8ab | 2019-11-21 22:04:41 +0000 | [diff] [blame] | 444 | int hashmap_contains_parent(struct hashmap *map, |
| 445 | const char *path, |
| 446 | struct strbuf *buffer); |
Derrick Stolee | 65edd96 | 2019-09-03 11:04:57 -0700 | [diff] [blame] | 447 | struct pattern_list *add_pattern_list(struct dir_struct *dir, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 448 | int group_type, const char *src); |
Derrick Stolee | 65edd96 | 2019-09-03 11:04:57 -0700 | [diff] [blame] | 449 | int add_patterns_from_file_to_list(const char *fname, const char *base, int baselen, |
Jeff King | 1679d60 | 2021-02-16 09:44:28 -0500 | [diff] [blame] | 450 | struct pattern_list *pl, struct index_state *istate, |
| 451 | unsigned flags); |
Derrick Stolee | 65edd96 | 2019-09-03 11:04:57 -0700 | [diff] [blame] | 452 | void add_patterns_from_file(struct dir_struct *, const char *fname); |
| 453 | int add_patterns_from_blob_to_list(struct object_id *oid, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 454 | const char *base, int baselen, |
Derrick Stolee | caa3d55 | 2019-09-03 11:04:56 -0700 | [diff] [blame] | 455 | struct pattern_list *pl); |
Derrick Stolee | 65edd96 | 2019-09-03 11:04:57 -0700 | [diff] [blame] | 456 | void parse_path_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen); |
| 457 | void add_pattern(const char *string, const char *base, |
Derrick Stolee | caa3d55 | 2019-09-03 11:04:56 -0700 | [diff] [blame] | 458 | int baselen, struct pattern_list *pl, int srcpos); |
Derrick Stolee | 65edd96 | 2019-09-03 11:04:57 -0700 | [diff] [blame] | 459 | void clear_pattern_list(struct pattern_list *pl); |
Elijah Newren | eceba53 | 2020-08-18 22:58:26 +0000 | [diff] [blame] | 460 | void dir_clear(struct dir_struct *dir); |
Nguyễn Thái Ngọc Duy | 0488481 | 2019-04-16 16:33:34 +0700 | [diff] [blame] | 461 | |
| 462 | int repo_file_exists(struct repository *repo, const char *path); |
| 463 | int file_exists(const char *); |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 464 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 465 | int is_inside_dir(const char *dir); |
| 466 | int dir_inside_of(const char *subdir, const char *dir); |
Johannes Schindelin | e663674 | 2007-08-01 01:29:17 +0100 | [diff] [blame] | 467 | |
Alexander Potashev | 8ca12c0 | 2009-01-10 15:07:50 +0300 | [diff] [blame] | 468 | static inline int is_dot_or_dotdot(const char *name) |
| 469 | { |
| 470 | return (name[0] == '.' && |
| 471 | (name[1] == '\0' || |
| 472 | (name[1] == '.' && name[2] == '\0'))); |
| 473 | } |
| 474 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 475 | int is_empty_dir(const char *dir); |
Alexander Potashev | 55892d2 | 2009-01-11 15:19:12 +0300 | [diff] [blame] | 476 | |
Atharva Raykar | ed86301 | 2021-08-10 17:16:36 +0530 | [diff] [blame] | 477 | /* |
| 478 | * Retrieve the "humanish" basename of the given Git URL. |
| 479 | * |
| 480 | * For example: |
| 481 | * /path/to/repo.git => "repo" |
| 482 | * host.xz:foo/.git => "foo" |
| 483 | * http://example.com/user/bar.baz => "bar.baz" |
| 484 | */ |
| 485 | char *git_url_basename(const char *repo, int is_bundle, int is_bare); |
| 486 | void strip_dir_trailing_slashes(char *dir); |
| 487 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 488 | void setup_standard_excludes(struct dir_struct *dir); |
Junio C Hamano | a0f4afb | 2009-06-30 15:33:45 -0700 | [diff] [blame] | 489 | |
Derrick Stolee | dd23022 | 2021-01-23 19:58:17 +0000 | [diff] [blame] | 490 | char *get_sparse_checkout_filename(void); |
| 491 | int get_sparse_checkout_patterns(struct pattern_list *pl); |
Michael Haggerty | 728af28 | 2016-04-24 07:07:59 +0200 | [diff] [blame] | 492 | |
| 493 | /* Constants for remove_dir_recursively: */ |
| 494 | |
| 495 | /* |
| 496 | * If a non-directory is found within path, stop and return an error. |
| 497 | * (In this case some empty directories might already have been |
| 498 | * removed.) |
| 499 | */ |
Junio C Hamano | a0f4afb | 2009-06-30 15:33:45 -0700 | [diff] [blame] | 500 | #define REMOVE_DIR_EMPTY_ONLY 01 |
Michael Haggerty | 728af28 | 2016-04-24 07:07:59 +0200 | [diff] [blame] | 501 | |
| 502 | /* |
| 503 | * If any Git work trees are found within path, skip them without |
| 504 | * considering it an error. |
| 505 | */ |
Junio C Hamano | a0f4afb | 2009-06-30 15:33:45 -0700 | [diff] [blame] | 506 | #define REMOVE_DIR_KEEP_NESTED_GIT 02 |
Michael Haggerty | 728af28 | 2016-04-24 07:07:59 +0200 | [diff] [blame] | 507 | |
| 508 | /* Remove the contents of path, but leave path itself. */ |
Junio C Hamano | c844a80 | 2012-03-15 15:58:54 +0100 | [diff] [blame] | 509 | #define REMOVE_DIR_KEEP_TOPLEVEL 04 |
Michael Haggerty | 728af28 | 2016-04-24 07:07:59 +0200 | [diff] [blame] | 510 | |
Elijah Newren | 580a5d7 | 2021-12-09 05:08:34 +0000 | [diff] [blame] | 511 | /* Remove the_original_cwd too */ |
| 512 | #define REMOVE_DIR_PURGE_ORIGINAL_CWD 0x08 |
| 513 | |
Michael Haggerty | 728af28 | 2016-04-24 07:07:59 +0200 | [diff] [blame] | 514 | /* |
| 515 | * Remove path and its contents, recursively. flags is a combination |
| 516 | * of the above REMOVE_DIR_* constants. Return 0 on success. |
| 517 | * |
| 518 | * This function uses path as temporary scratch space, but restores it |
| 519 | * before returning. |
| 520 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 521 | int remove_dir_recursively(struct strbuf *path, int flag); |
Johannes Schindelin | 7155b72 | 2007-09-28 16:28:54 +0100 | [diff] [blame] | 522 | |
Elijah Newren | 63bbe8b | 2021-12-09 05:08:33 +0000 | [diff] [blame] | 523 | /* |
| 524 | * Tries to remove the path, along with leading empty directories so long as |
| 525 | * those empty directories are not startup_info->original_cwd. Ignores |
| 526 | * ENOENT. |
| 527 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 528 | int remove_path(const char *path); |
Alex Riesen | 4a92d1b | 2008-09-27 00:56:46 +0200 | [diff] [blame] | 529 | |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 530 | int fspathcmp(const char *a, const char *b); |
Eric Wong | cf2dc1c | 2021-07-07 23:10:15 +0000 | [diff] [blame] | 531 | int fspatheq(const char *a, const char *b); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 532 | int fspathncmp(const char *a, const char *b, size_t count); |
Eric Wong | cf2dc1c | 2021-07-07 23:10:15 +0000 | [diff] [blame] | 533 | unsigned int fspathhash(const char *str); |
Joshua Jensen | 8cf2a84 | 2010-10-03 09:56:41 +0000 | [diff] [blame] | 534 | |
Nguyễn Thái Ngọc Duy | 5d74762 | 2012-11-24 11:33:49 +0700 | [diff] [blame] | 535 | /* |
| 536 | * The prefix part of pattern must not contains wildcards. |
| 537 | */ |
Nguyễn Thái Ngọc Duy | bd30c2e | 2013-07-14 15:36:08 +0700 | [diff] [blame] | 538 | struct pathspec_item; |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 539 | int git_fnmatch(const struct pathspec_item *item, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 540 | const char *pattern, const char *string, |
| 541 | int prefix); |
Nguyễn Thái Ngọc Duy | 5d74762 | 2012-11-24 11:33:49 +0700 | [diff] [blame] | 542 | |
Derrick Stolee | 847a9e5 | 2021-04-01 01:49:39 +0000 | [diff] [blame] | 543 | int submodule_path_match(struct index_state *istate, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 544 | const struct pathspec *ps, |
| 545 | const char *submodule_name, |
| 546 | char *seen); |
Brandon Williams | 75a6315 | 2016-10-07 11:18:51 -0700 | [diff] [blame] | 547 | |
Derrick Stolee | 847a9e5 | 2021-04-01 01:49:39 +0000 | [diff] [blame] | 548 | static inline int dir_path_match(struct index_state *istate, |
Nguyễn Thái Ngọc Duy | 6d2df28 | 2018-08-13 18:14:22 +0200 | [diff] [blame] | 549 | const struct dir_entry *ent, |
Nguyễn Thái Ngọc Duy | ebb3289 | 2014-01-24 20:40:29 +0700 | [diff] [blame] | 550 | const struct pathspec *pathspec, |
| 551 | int prefix, char *seen) |
| 552 | { |
Nguyễn Thái Ngọc Duy | ae8d082 | 2014-01-24 20:40:33 +0700 | [diff] [blame] | 553 | int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/'; |
| 554 | int len = has_trailing_dir ? ent->len - 1 : ent->len; |
Nguyễn Thái Ngọc Duy | 6d2df28 | 2018-08-13 18:14:22 +0200 | [diff] [blame] | 555 | return match_pathspec(istate, pathspec, ent->name, len, prefix, seen, |
Nguyễn Thái Ngọc Duy | ae8d082 | 2014-01-24 20:40:33 +0700 | [diff] [blame] | 556 | has_trailing_dir); |
Nguyễn Thái Ngọc Duy | ebb3289 | 2014-01-24 20:40:29 +0700 | [diff] [blame] | 557 | } |
| 558 | |
Samuel Lijin | bbf504a | 2017-05-18 04:21:53 -0400 | [diff] [blame] | 559 | int cmp_dir_entry(const void *p1, const void *p2); |
| 560 | int check_dir_entry_contains(const struct dir_entry *out, const struct dir_entry *in); |
| 561 | |
Nguyễn Thái Ngọc Duy | 0cacebf | 2018-02-07 16:21:40 +0700 | [diff] [blame] | 562 | void untracked_cache_invalidate_path(struct index_state *, const char *, int safe_path); |
Nguyễn Thái Ngọc Duy | e931371 | 2015-03-08 17:12:35 +0700 | [diff] [blame] | 563 | void untracked_cache_remove_from_index(struct index_state *, const char *); |
| 564 | void untracked_cache_add_to_index(struct index_state *, const char *); |
| 565 | |
Nguyễn Thái Ngọc Duy | f9e6c64 | 2015-03-08 17:12:34 +0700 | [diff] [blame] | 566 | void free_untracked_cache(struct untracked_cache *); |
| 567 | struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz); |
Nguyễn Thái Ngọc Duy | 83c094a | 2015-03-08 17:12:33 +0700 | [diff] [blame] | 568 | void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked); |
Christian Couder | 4a4ca47 | 2016-01-24 16:28:19 +0100 | [diff] [blame] | 569 | void add_untracked_cache(struct index_state *istate); |
Christian Couder | 07b29bf | 2016-01-24 16:28:20 +0100 | [diff] [blame] | 570 | void remove_untracked_cache(struct index_state *istate); |
Stefan Beller | da62f78 | 2018-03-28 15:35:31 -0700 | [diff] [blame] | 571 | |
| 572 | /* |
| 573 | * Connect a worktree to a git directory by creating (or overwriting) a |
| 574 | * '.git' file containing the location of the git directory. In the git |
| 575 | * directory set the core.worktree setting to indicate where the worktree is. |
| 576 | * When `recurse_into_nested` is set, recurse into any nested submodules, |
| 577 | * connecting them as well. |
| 578 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 579 | void connect_work_tree_and_git_dir(const char *work_tree, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 580 | const char *git_dir, |
| 581 | int recurse_into_nested); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 582 | void relocate_gitdir(const char *path, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 583 | const char *old_git_dir, |
| 584 | const char *new_git_dir); |
Ævar Arnfjörð Bjarmason | 9fd512c | 2022-05-16 20:10:59 +0000 | [diff] [blame] | 585 | |
| 586 | /** |
| 587 | * The "enum path_matches_kind" determines how path_match_flags() will |
| 588 | * behave. The flags come in sets, and one (and only one) must be |
| 589 | * provided out of each "set": |
| 590 | * |
| 591 | * PATH_MATCH_NATIVE: |
| 592 | * Path separator is is_dir_sep() |
| 593 | * PATH_MATCH_XPLATFORM: |
| 594 | * Path separator is is_xplatform_dir_sep() |
| 595 | * |
| 596 | * Do we use is_dir_sep() to check for a directory separator |
| 597 | * (*_NATIVE), or do we always check for '/' or '\' (*_XPLATFORM). The |
| 598 | * "*_NATIVE" version on Windows is the same as "*_XPLATFORM", |
| 599 | * everywhere else "*_NATIVE" means "only /". |
| 600 | * |
| 601 | * PATH_MATCH_STARTS_WITH_DOT_SLASH: |
| 602 | * Match a path starting with "./" |
| 603 | * PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH: |
| 604 | * Match a path starting with "../" |
| 605 | * |
| 606 | * The "/" in the above is adjusted based on the "*_NATIVE" and |
| 607 | * "*_XPLATFORM" flags. |
| 608 | */ |
| 609 | enum path_match_flags { |
| 610 | PATH_MATCH_NATIVE = 1 << 0, |
| 611 | PATH_MATCH_XPLATFORM = 1 << 1, |
| 612 | PATH_MATCH_STARTS_WITH_DOT_SLASH = 1 << 2, |
| 613 | PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH = 1 << 3, |
| 614 | }; |
| 615 | #define PATH_MATCH_KINDS_MASK (PATH_MATCH_STARTS_WITH_DOT_SLASH | \ |
| 616 | PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH) |
| 617 | #define PATH_MATCH_PLATFORM_MASK (PATH_MATCH_NATIVE | PATH_MATCH_XPLATFORM) |
| 618 | |
| 619 | /** |
| 620 | * path_match_flags() checks if a given "path" matches a given "enum |
| 621 | * path_match_flags" criteria. |
| 622 | */ |
| 623 | int path_match_flags(const char *const path, const enum path_match_flags f); |
| 624 | |
| 625 | /** |
| 626 | * starts_with_dot_slash_native(): convenience wrapper for |
| 627 | * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_SLASH and |
| 628 | * PATH_MATCH_NATIVE. |
| 629 | */ |
| 630 | static inline int starts_with_dot_slash_native(const char *const path) |
| 631 | { |
| 632 | const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_SLASH; |
| 633 | |
| 634 | return path_match_flags(path, what | PATH_MATCH_NATIVE); |
| 635 | } |
| 636 | |
| 637 | /** |
| 638 | * starts_with_dot_slash_native(): convenience wrapper for |
| 639 | * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH and |
| 640 | * PATH_MATCH_NATIVE. |
| 641 | */ |
| 642 | static inline int starts_with_dot_dot_slash_native(const char *const path) |
| 643 | { |
| 644 | const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH; |
| 645 | |
| 646 | return path_match_flags(path, what | PATH_MATCH_NATIVE); |
| 647 | } |
Elijah Newren | 592fc5b | 2023-04-22 20:17:18 +0000 | [diff] [blame] | 648 | |
Linus Torvalds | 453ec4b | 2006-05-16 19:02:14 -0700 | [diff] [blame] | 649 | #endif |