tree-walk.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #ifndef TREE_WALK_H
  2. #define TREE_WALK_H
  3. #include "cache.h"
  4. #define MAX_TRAVERSE_TREES 8
  5. /**
  6. * The tree walking API is used to traverse and inspect trees.
  7. */
  8. /**
  9. * An entry in a tree. Each entry has a sha1 identifier, pathname, and mode.
  10. */
  11. struct name_entry {
  12. struct object_id oid;
  13. const char *path;
  14. int pathlen;
  15. unsigned int mode;
  16. };
  17. /**
  18. * A semi-opaque data structure used to maintain the current state of the walk.
  19. */
  20. struct tree_desc {
  21. /*
  22. * pointer into the memory representation of the tree. It always
  23. * points at the current entry being visited.
  24. */
  25. const void *buffer;
  26. /* points to the current entry being visited. */
  27. struct name_entry entry;
  28. /* counts the number of bytes left in the `buffer`. */
  29. unsigned int size;
  30. };
  31. /**
  32. * Decode the entry currently being visited (the one pointed to by
  33. * `tree_desc's` `entry` member) and return the sha1 of the entry. The
  34. * `pathp` and `modep` arguments are set to the entry's pathname and mode
  35. * respectively.
  36. */
  37. static inline const struct object_id *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned short *modep)
  38. {
  39. *pathp = desc->entry.path;
  40. *modep = desc->entry.mode;
  41. return &desc->entry.oid;
  42. }
  43. /**
  44. * Calculate the length of a tree entry's pathname. This utilizes the
  45. * memory structure of a tree entry to avoid the overhead of using a
  46. * generic strlen().
  47. */
  48. static inline int tree_entry_len(const struct name_entry *ne)
  49. {
  50. return ne->pathlen;
  51. }
  52. /*
  53. * The _gently versions of these functions warn and return false on a
  54. * corrupt tree entry rather than dying,
  55. */
  56. /**
  57. * Walk to the next entry in a tree. This is commonly used in conjunction
  58. * with `tree_entry_extract` to inspect the current entry.
  59. */
  60. void update_tree_entry(struct tree_desc *);
  61. int update_tree_entry_gently(struct tree_desc *);
  62. /**
  63. * Initialize a `tree_desc` and decode its first entry. The buffer and
  64. * size parameters are assumed to be the same as the buffer and size
  65. * members of `struct tree`.
  66. */
  67. void init_tree_desc(struct tree_desc *desc, const void *buf, unsigned long size);
  68. int init_tree_desc_gently(struct tree_desc *desc, const void *buf, unsigned long size);
  69. /*
  70. * Visit the next entry in a tree. Returns 1 when there are more entries
  71. * left to visit and 0 when all entries have been visited. This is
  72. * commonly used in the test of a while loop.
  73. */
  74. int tree_entry(struct tree_desc *, struct name_entry *);
  75. int tree_entry_gently(struct tree_desc *, struct name_entry *);
  76. /**
  77. * Initialize a `tree_desc` and decode its first entry given the
  78. * object ID of a tree. Returns the `buffer` member if the latter
  79. * is a valid tree identifier and NULL otherwise.
  80. */
  81. void *fill_tree_descriptor(struct repository *r,
  82. struct tree_desc *desc,
  83. const struct object_id *oid);
  84. struct traverse_info;
  85. typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *);
  86. /**
  87. * Traverse `n` number of trees in parallel. The `fn` callback member of
  88. * `traverse_info` is called once for each tree entry.
  89. */
  90. int traverse_trees(struct index_state *istate, int n, struct tree_desc *t, struct traverse_info *info);
  91. enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r, struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned short *mode);
  92. /**
  93. * A structure used to maintain the state of a traversal.
  94. */
  95. struct traverse_info {
  96. const char *traverse_path;
  97. /*
  98. * points to the traverse_info which was used to descend into the
  99. * current tree. If this is the top-level tree `prev` will point to
  100. * a dummy traverse_info.
  101. */
  102. struct traverse_info *prev;
  103. /* is the entry for the current tree (if the tree is a subtree). */
  104. const char *name;
  105. size_t namelen;
  106. unsigned mode;
  107. /* is the length of the full path for the current tree. */
  108. size_t pathlen;
  109. struct pathspec *pathspec;
  110. /* can be used by callbacks to maintain directory-file conflicts. */
  111. unsigned long df_conflicts;
  112. /* a callback called for each entry in the tree.
  113. *
  114. * The arguments passed to the traverse callback are as follows:
  115. *
  116. * - `n` counts the number of trees being traversed.
  117. *
  118. * - `mask` has its nth bit set if something exists in the nth entry.
  119. *
  120. * - `dirmask` has its nth bit set if the nth tree's entry is a directory.
  121. *
  122. * - `entry` is an array of size `n` where the nth entry is from the nth tree.
  123. *
  124. * - `info` maintains the state of the traversal.
  125. *
  126. * Returning a negative value will terminate the traversal. Otherwise the
  127. * return value is treated as an update mask. If the nth bit is set the nth tree
  128. * will be updated and if the bit is not set the nth tree entry will be the
  129. * same in the next callback invocation.
  130. */
  131. traverse_callback_t fn;
  132. /* can be anything the `fn` callback would want to use. */
  133. void *data;
  134. /* tells whether to stop at the first error or not. */
  135. int show_all_errors;
  136. };
  137. /**
  138. * Find an entry in a tree given a pathname and the sha1 of a tree to
  139. * search. Returns 0 if the entry is found and -1 otherwise. The third
  140. * and fourth parameters are set to the entry's sha1 and mode respectively.
  141. */
  142. int get_tree_entry(struct repository *, const struct object_id *, const char *, struct object_id *, unsigned short *);
  143. /**
  144. * Generate the full pathname of a tree entry based from the root of the
  145. * traversal. For example, if the traversal has recursed into another
  146. * tree named "bar" the pathname of an entry "baz" in the "bar"
  147. * tree would be "bar/baz".
  148. */
  149. char *make_traverse_path(char *path, size_t pathlen, const struct traverse_info *info,
  150. const char *name, size_t namelen);
  151. /**
  152. * Convenience wrapper to `make_traverse_path` into a strbuf.
  153. */
  154. void strbuf_make_traverse_path(struct strbuf *out,
  155. const struct traverse_info *info,
  156. const char *name, size_t namelen);
  157. /**
  158. * Initialize a `traverse_info` given the pathname of the tree to start
  159. * traversing from.
  160. */
  161. void setup_traverse_info(struct traverse_info *info, const char *base);
  162. /**
  163. * Calculate the length of a pathname returned by `make_traverse_path`.
  164. * This utilizes the memory structure of a tree entry to avoid the
  165. * overhead of using a generic strlen().
  166. */
  167. static inline size_t traverse_path_len(const struct traverse_info *info,
  168. size_t namelen)
  169. {
  170. return st_add(info->pathlen, namelen);
  171. }
  172. /* in general, positive means "kind of interesting" */
  173. enum interesting {
  174. all_entries_not_interesting = -1, /* no, and no subsequent entries will be either */
  175. entry_not_interesting = 0,
  176. entry_interesting = 1,
  177. all_entries_interesting = 2 /* yes, and all subsequent entries will be */
  178. };
  179. enum interesting tree_entry_interesting(struct index_state *istate,
  180. const struct name_entry *,
  181. struct strbuf *, int,
  182. const struct pathspec *ps);
  183. #endif