THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
12KB

  1. #ifndef DIR_H
  2. #define DIR_H
  3. /* See Documentation/technical/api-directory-listing.txt */
  4. #include "cache.h"
  5. #include "strbuf.h"
  6. struct dir_entry {
  7. unsigned int len;
  8. char name[FLEX_ARRAY]; /* more */
  9. };
  10. #define PATTERN_FLAG_NODIR 1
  11. #define PATTERN_FLAG_ENDSWITH 4
  12. #define PATTERN_FLAG_MUSTBEDIR 8
  13. #define PATTERN_FLAG_NEGATIVE 16
  14. struct path_pattern {
  15. /*
  16. * This allows callers of last_matching_pattern() etc.
  17. * to determine the origin of the matching pattern.
  18. */
  19. struct pattern_list *pl;
  20. const char *pattern;
  21. int patternlen;
  22. int nowildcardlen;
  23. const char *base;
  24. int baselen;
  25. unsigned flags; /* PATTERN_FLAG_* */
  26. /*
  27. * Counting starts from 1 for line numbers in ignore files,
  28. * and from -1 decrementing for patterns from CLI args.
  29. */
  30. int srcpos;
  31. };
  32. /*
  33. * Each excludes file will be parsed into a fresh exclude_list which
  34. * is appended to the relevant exclude_list_group (either EXC_DIRS or
  35. * EXC_FILE). An exclude_list within the EXC_CMDL exclude_list_group
  36. * can also be used to represent the list of --exclude values passed
  37. * via CLI args.
  38. */
  39. struct pattern_list {
  40. int nr;
  41. int alloc;
  42. /* remember pointer to exclude file contents so we can free() */
  43. char *filebuf;
  44. /* origin of list, e.g. path to filename, or descriptive string */
  45. const char *src;
  46. struct path_pattern **patterns;
  47. };
  48. /*
  49. * The contents of the per-directory exclude files are lazily read on
  50. * demand and then cached in memory, one per exclude_stack struct, in
  51. * order to avoid opening and parsing each one every time that
  52. * directory is traversed.
  53. */
  54. struct exclude_stack {
  55. struct exclude_stack *prev; /* the struct exclude_stack for the parent directory */
  56. int baselen;
  57. int exclude_ix; /* index of exclude_list within EXC_DIRS exclude_list_group */
  58. struct untracked_cache_dir *ucd;
  59. };
  60. struct exclude_list_group {
  61. int nr, alloc;
  62. struct pattern_list *pl;
  63. };
  64. struct oid_stat {
  65. struct stat_data stat;
  66. struct object_id oid;
  67. int valid;
  68. };
  69. /*
  70. * Untracked cache
  71. *
  72. * The following inputs are sufficient to determine what files in a
  73. * directory are excluded:
  74. *
  75. * - The list of files and directories of the directory in question
  76. * - The $GIT_DIR/index
  77. * - dir_struct flags
  78. * - The content of $GIT_DIR/info/exclude
  79. * - The content of core.excludesfile
  80. * - The content (or the lack) of .gitignore of all parent directories
  81. * from $GIT_WORK_TREE
  82. * - The check_only flag in read_directory_recursive (for
  83. * DIR_HIDE_EMPTY_DIRECTORIES)
  84. *
  85. * The first input can be checked using directory mtime. In many
  86. * filesystems, directory mtime (stat_data field) is updated when its
  87. * files or direct subdirs are added or removed.
  88. *
  89. * The second one can be hooked from cache_tree_invalidate_path().
  90. * Whenever a file (or a submodule) is added or removed from a
  91. * directory, we invalidate that directory.
  92. *
  93. * The remaining inputs are easy, their SHA-1 could be used to verify
  94. * their contents (exclude_sha1[], info_exclude_sha1[] and
  95. * excludes_file_sha1[])
  96. */
  97. struct untracked_cache_dir {
  98. struct untracked_cache_dir **dirs;
  99. char **untracked;
  100. struct stat_data stat_data;
  101. unsigned int untracked_alloc, dirs_nr, dirs_alloc;
  102. unsigned int untracked_nr;
  103. unsigned int check_only : 1;
  104. /* all data except 'dirs' in this struct are good */
  105. unsigned int valid : 1;
  106. unsigned int recurse : 1;
  107. /* null object ID means this directory does not have .gitignore */
  108. struct object_id exclude_oid;
  109. char name[FLEX_ARRAY];
  110. };
  111. struct untracked_cache {
  112. struct oid_stat ss_info_exclude;
  113. struct oid_stat ss_excludes_file;
  114. const char *exclude_per_dir;
  115. struct strbuf ident;
  116. /*
  117. * dir_struct#flags must match dir_flags or the untracked
  118. * cache is ignored.
  119. */
  120. unsigned dir_flags;
  121. struct untracked_cache_dir *root;
  122. /* Statistics */
  123. int dir_created;
  124. int gitignore_invalidated;
  125. int dir_invalidated;
  126. int dir_opened;
  127. /* fsmonitor invalidation data */
  128. unsigned int use_fsmonitor : 1;
  129. };
  130. struct dir_struct {
  131. int nr, alloc;
  132. int ignored_nr, ignored_alloc;
  133. enum {
  134. DIR_SHOW_IGNORED = 1<<0,
  135. DIR_SHOW_OTHER_DIRECTORIES = 1<<1,
  136. DIR_HIDE_EMPTY_DIRECTORIES = 1<<2,
  137. DIR_NO_GITLINKS = 1<<3,
  138. DIR_COLLECT_IGNORED = 1<<4,
  139. DIR_SHOW_IGNORED_TOO = 1<<5,
  140. DIR_COLLECT_KILLED_ONLY = 1<<6,
  141. DIR_KEEP_UNTRACKED_CONTENTS = 1<<7,
  142. DIR_SHOW_IGNORED_TOO_MODE_MATCHING = 1<<8,
  143. DIR_SKIP_NESTED_GIT = 1<<9
  144. } flags;
  145. struct dir_entry **entries;
  146. struct dir_entry **ignored;
  147. /* Exclude info */
  148. const char *exclude_per_dir;
  149. /*
  150. * We maintain three groups of exclude pattern lists:
  151. *
  152. * EXC_CMDL lists patterns explicitly given on the command line.
  153. * EXC_DIRS lists patterns obtained from per-directory ignore files.
  154. * EXC_FILE lists patterns from fallback ignore files, e.g.
  155. * - .git/info/exclude
  156. * - core.excludesfile
  157. *
  158. * Each group contains multiple exclude lists, a single list
  159. * per source.
  160. */
  161. #define EXC_CMDL 0
  162. #define EXC_DIRS 1
  163. #define EXC_FILE 2
  164. struct exclude_list_group exclude_list_group[3];
  165. /*
  166. * Temporary variables which are used during loading of the
  167. * per-directory exclude lists.
  168. *
  169. * exclude_stack points to the top of the exclude_stack, and
  170. * basebuf contains the full path to the current
  171. * (sub)directory in the traversal. Exclude points to the
  172. * matching exclude struct if the directory is excluded.
  173. */
  174. struct exclude_stack *exclude_stack;
  175. struct path_pattern *pattern;
  176. struct strbuf basebuf;
  177. /* Enable untracked file cache if set */
  178. struct untracked_cache *untracked;
  179. struct oid_stat ss_info_exclude;
  180. struct oid_stat ss_excludes_file;
  181. unsigned unmanaged_exclude_files;
  182. };
  183. /*Count the number of slashes for string s*/
  184. int count_slashes(const char *s);
  185. /*
  186. * The ordering of these constants is significant, with
  187. * higher-numbered match types signifying "closer" (i.e. more
  188. * specific) matches which will override lower-numbered match types
  189. * when populating the seen[] array.
  190. */
  191. #define MATCHED_RECURSIVELY 1
  192. #define MATCHED_RECURSIVELY_LEADING_PATHSPEC 2
  193. #define MATCHED_FNMATCH 3
  194. #define MATCHED_EXACTLY 4
  195. int simple_length(const char *match);
  196. int no_wildcard(const char *string);
  197. char *common_prefix(const struct pathspec *pathspec);
  198. int match_pathspec(const struct index_state *istate,
  199. const struct pathspec *pathspec,
  200. const char *name, int namelen,
  201. int prefix, char *seen, int is_dir);
  202. int report_path_error(const char *ps_matched, const struct pathspec *pathspec);
  203. int within_depth(const char *name, int namelen, int depth, int max_depth);
  204. int fill_directory(struct dir_struct *dir,
  205. struct index_state *istate,
  206. const struct pathspec *pathspec);
  207. int read_directory(struct dir_struct *, struct index_state *istate,
  208. const char *path, int len,
  209. const struct pathspec *pathspec);
  210. enum pattern_match_result {
  211. UNDECIDED = -1,
  212. NOT_MATCHED = 0,
  213. MATCHED = 1,
  214. };
  215. /*
  216. * Scan the list of patterns to determine if the ordered list
  217. * of patterns matches on 'pathname'.
  218. *
  219. * Return 1 for a match, 0 for not matched and -1 for undecided.
  220. */
  221. enum pattern_match_result path_matches_pattern_list(const char *pathname,
  222. int pathlen,
  223. const char *basename, int *dtype,
  224. struct pattern_list *pl,
  225. struct index_state *istate);
  226. struct dir_entry *dir_add_ignored(struct dir_struct *dir,
  227. struct index_state *istate,
  228. const char *pathname, int len);
  229. /*
  230. * these implement the matching logic for dir.c:excluded_from_list and
  231. * attr.c:path_matches()
  232. */
  233. int match_basename(const char *, int,
  234. const char *, int, int, unsigned);
  235. int match_pathname(const char *, int,
  236. const char *, int,
  237. const char *, int, int, unsigned);
  238. struct path_pattern *last_matching_pattern(struct dir_struct *dir,
  239. struct index_state *istate,
  240. const char *name, int *dtype);
  241. int is_excluded(struct dir_struct *dir,
  242. struct index_state *istate,
  243. const char *name, int *dtype);
  244. struct pattern_list *add_pattern_list(struct dir_struct *dir,
  245. int group_type, const char *src);
  246. int add_patterns_from_file_to_list(const char *fname, const char *base, int baselen,
  247. struct pattern_list *pl, struct index_state *istate);
  248. void add_patterns_from_file(struct dir_struct *, const char *fname);
  249. int add_patterns_from_blob_to_list(struct object_id *oid,
  250. const char *base, int baselen,
  251. struct pattern_list *pl);
  252. void parse_path_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen);
  253. void add_pattern(const char *string, const char *base,
  254. int baselen, struct pattern_list *pl, int srcpos);
  255. void clear_pattern_list(struct pattern_list *pl);
  256. void clear_directory(struct dir_struct *dir);
  257. int repo_file_exists(struct repository *repo, const char *path);
  258. int file_exists(const char *);
  259. int is_inside_dir(const char *dir);
  260. int dir_inside_of(const char *subdir, const char *dir);
  261. static inline int is_dot_or_dotdot(const char *name)
  262. {
  263. return (name[0] == '.' &&
  264. (name[1] == '\0' ||
  265. (name[1] == '.' && name[2] == '\0')));
  266. }
  267. int is_empty_dir(const char *dir);
  268. void setup_standard_excludes(struct dir_struct *dir);
  269. /* Constants for remove_dir_recursively: */
  270. /*
  271. * If a non-directory is found within path, stop and return an error.
  272. * (In this case some empty directories might already have been
  273. * removed.)
  274. */
  275. #define REMOVE_DIR_EMPTY_ONLY 01
  276. /*
  277. * If any Git work trees are found within path, skip them without
  278. * considering it an error.
  279. */
  280. #define REMOVE_DIR_KEEP_NESTED_GIT 02
  281. /* Remove the contents of path, but leave path itself. */
  282. #define REMOVE_DIR_KEEP_TOPLEVEL 04
  283. /*
  284. * Remove path and its contents, recursively. flags is a combination
  285. * of the above REMOVE_DIR_* constants. Return 0 on success.
  286. *
  287. * This function uses path as temporary scratch space, but restores it
  288. * before returning.
  289. */
  290. int remove_dir_recursively(struct strbuf *path, int flag);
  291. /* tries to remove the path with empty directories along it, ignores ENOENT */
  292. int remove_path(const char *path);
  293. int fspathcmp(const char *a, const char *b);
  294. int fspathncmp(const char *a, const char *b, size_t count);
  295. /*
  296. * The prefix part of pattern must not contains wildcards.
  297. */
  298. struct pathspec_item;
  299. int git_fnmatch(const struct pathspec_item *item,
  300. const char *pattern, const char *string,
  301. int prefix);
  302. int submodule_path_match(const struct index_state *istate,
  303. const struct pathspec *ps,
  304. const char *submodule_name,
  305. char *seen);
  306. static inline int ce_path_match(const struct index_state *istate,
  307. const struct cache_entry *ce,
  308. const struct pathspec *pathspec,
  309. char *seen)
  310. {
  311. return match_pathspec(istate, pathspec, ce->name, ce_namelen(ce), 0, seen,
  312. S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode));
  313. }
  314. static inline int dir_path_match(const struct index_state *istate,
  315. const struct dir_entry *ent,
  316. const struct pathspec *pathspec,
  317. int prefix, char *seen)
  318. {
  319. int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/';
  320. int len = has_trailing_dir ? ent->len - 1 : ent->len;
  321. return match_pathspec(istate, pathspec, ent->name, len, prefix, seen,
  322. has_trailing_dir);
  323. }
  324. int cmp_dir_entry(const void *p1, const void *p2);
  325. int check_dir_entry_contains(const struct dir_entry *out, const struct dir_entry *in);
  326. void untracked_cache_invalidate_path(struct index_state *, const char *, int safe_path);
  327. void untracked_cache_remove_from_index(struct index_state *, const char *);
  328. void untracked_cache_add_to_index(struct index_state *, const char *);
  329. void free_untracked_cache(struct untracked_cache *);
  330. struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz);
  331. void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);
  332. void add_untracked_cache(struct index_state *istate);
  333. void remove_untracked_cache(struct index_state *istate);
  334. /*
  335. * Connect a worktree to a git directory by creating (or overwriting) a
  336. * '.git' file containing the location of the git directory. In the git
  337. * directory set the core.worktree setting to indicate where the worktree is.
  338. * When `recurse_into_nested` is set, recurse into any nested submodules,
  339. * connecting them as well.
  340. */
  341. void connect_work_tree_and_git_dir(const char *work_tree,
  342. const char *git_dir,
  343. int recurse_into_nested);
  344. void relocate_gitdir(const char *path,
  345. const char *old_git_dir,
  346. const char *new_git_dir);
  347. #endif