1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 #ifndef INCLUDE_git_pathspec_h__
8 #define INCLUDE_git_pathspec_h__
9 
10 #include "common.h"
11 #include "types.h"
12 #include "strarray.h"
13 #include "diff.h"
14 
15 GIT_BEGIN_DECL
16 
17 /**
18  * Compiled pathspec
19  */
20 typedef struct git_pathspec git_pathspec;
21 
22 /**
23  * List of filenames matching a pathspec
24  */
25 typedef struct git_pathspec_match_list git_pathspec_match_list;
26 
27 /**
28  * Options controlling how pathspec match should be executed
29  */
30 typedef enum {
31 	GIT_PATHSPEC_DEFAULT        = 0,
32 
33 	/**
34 	 * GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
35 	 * match will use native case sensitivity of platform filesystem
36 	 */
37 	GIT_PATHSPEC_IGNORE_CASE    = (1u << 0),
38 
39 	/**
40 	 * GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
41 	 * match will use native case sensitivity of platform filesystem
42 	 */
43 	GIT_PATHSPEC_USE_CASE       = (1u << 1),
44 
45 	/**
46 	 * GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
47 	 * string comparison for matching
48 	 */
49 	GIT_PATHSPEC_NO_GLOB        = (1u << 2),
50 
51 	/**
52 	 * GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
53 	 * code GIT_ENOTFOUND if no matches are found; otherwise no matches is
54 	 * still success (return 0) but `git_pathspec_match_list_entrycount`
55 	 * will indicate 0 matches.
56 	 */
57 	GIT_PATHSPEC_NO_MATCH_ERROR = (1u << 3),
58 
59 	/**
60 	 * GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
61 	 * should track which patterns matched which files so that at the end of
62 	 * the match we can identify patterns that did not match any files.
63 	 */
64 	GIT_PATHSPEC_FIND_FAILURES  = (1u << 4),
65 
66 	/**
67 	 * GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
68 	 * does not need to keep the actual matching filenames.  Use this to
69 	 * just test if there were any matches at all or in combination with
70 	 * GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
71 	 */
72 	GIT_PATHSPEC_FAILURES_ONLY  = (1u << 5),
73 } git_pathspec_flag_t;
74 
75 /**
76  * Compile a pathspec
77  *
78  * @param out Output of the compiled pathspec
79  * @param pathspec A git_strarray of the paths to match
80  * @return 0 on success, <0 on failure
81  */
82 GIT_EXTERN(int) git_pathspec_new(
83 	git_pathspec **out, const git_strarray *pathspec);
84 
85 /**
86  * Free a pathspec
87  *
88  * @param ps The compiled pathspec
89  */
90 GIT_EXTERN(void) git_pathspec_free(git_pathspec *ps);
91 
92 /**
93  * Try to match a path against a pathspec
94  *
95  * Unlike most of the other pathspec matching functions, this will not
96  * fall back on the native case-sensitivity for your platform.  You must
97  * explicitly pass flags to control case sensitivity or else this will
98  * fall back on being case sensitive.
99  *
100  * @param ps The compiled pathspec
101  * @param flags Combination of git_pathspec_flag_t options to control match
102  * @param path The pathname to attempt to match
103  * @return 1 is path matches spec, 0 if it does not
104  */
105 GIT_EXTERN(int) git_pathspec_matches_path(
106 	const git_pathspec *ps, uint32_t flags, const char *path);
107 
108 /**
109  * Match a pathspec against the working directory of a repository.
110  *
111  * This matches the pathspec against the current files in the working
112  * directory of the repository.  It is an error to invoke this on a bare
113  * repo.  This handles git ignores (i.e. ignored files will not be
114  * considered to match the `pathspec` unless the file is tracked in the
115  * index).
116  *
117  * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
118  * contains the list of all matched filenames (unless you pass the
119  * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
120  * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
121  * flag).  You must call `git_pathspec_match_list_free()` on this object.
122  *
123  * @param out Output list of matches; pass NULL to just get return value
124  * @param repo The repository in which to match; bare repo is an error
125  * @param flags Combination of git_pathspec_flag_t options to control match
126  * @param ps Pathspec to be matched
127  * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
128  *         the GIT_PATHSPEC_NO_MATCH_ERROR flag was given
129  */
130 GIT_EXTERN(int) git_pathspec_match_workdir(
131 	git_pathspec_match_list **out,
132 	git_repository *repo,
133 	uint32_t flags,
134 	git_pathspec *ps);
135 
136 /**
137  * Match a pathspec against entries in an index.
138  *
139  * This matches the pathspec against the files in the repository index.
140  *
141  * NOTE: At the moment, the case sensitivity of this match is controlled
142  * by the current case-sensitivity of the index object itself and the
143  * USE_CASE and IGNORE_CASE flags will have no effect.  This behavior will
144  * be corrected in a future release.
145  *
146  * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
147  * contains the list of all matched filenames (unless you pass the
148  * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
149  * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
150  * flag).  You must call `git_pathspec_match_list_free()` on this object.
151  *
152  * @param out Output list of matches; pass NULL to just get return value
153  * @param index The index to match against
154  * @param flags Combination of git_pathspec_flag_t options to control match
155  * @param ps Pathspec to be matched
156  * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
157  *         the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
158  */
159 GIT_EXTERN(int) git_pathspec_match_index(
160 	git_pathspec_match_list **out,
161 	git_index *index,
162 	uint32_t flags,
163 	git_pathspec *ps);
164 
165 /**
166  * Match a pathspec against files in a tree.
167  *
168  * This matches the pathspec against the files in the given tree.
169  *
170  * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
171  * contains the list of all matched filenames (unless you pass the
172  * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
173  * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
174  * flag).  You must call `git_pathspec_match_list_free()` on this object.
175  *
176  * @param out Output list of matches; pass NULL to just get return value
177  * @param tree The root-level tree to match against
178  * @param flags Combination of git_pathspec_flag_t options to control match
179  * @param ps Pathspec to be matched
180  * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
181  *         the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
182  */
183 GIT_EXTERN(int) git_pathspec_match_tree(
184 	git_pathspec_match_list **out,
185 	git_tree *tree,
186 	uint32_t flags,
187 	git_pathspec *ps);
188 
189 /**
190  * Match a pathspec against files in a diff list.
191  *
192  * This matches the pathspec against the files in the given diff list.
193  *
194  * If `out` is not NULL, this returns a `git_patchspec_match_list`.  That
195  * contains the list of all matched filenames (unless you pass the
196  * `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
197  * pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
198  * flag).  You must call `git_pathspec_match_list_free()` on this object.
199  *
200  * @param out Output list of matches; pass NULL to just get return value
201  * @param diff A generated diff list
202  * @param flags Combination of git_pathspec_flag_t options to control match
203  * @param ps Pathspec to be matched
204  * @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
205  *         the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
206  */
207 GIT_EXTERN(int) git_pathspec_match_diff(
208 	git_pathspec_match_list **out,
209 	git_diff *diff,
210 	uint32_t flags,
211 	git_pathspec *ps);
212 
213 /**
214  * Free memory associates with a git_pathspec_match_list
215  *
216  * @param m The git_pathspec_match_list to be freed
217  */
218 GIT_EXTERN(void) git_pathspec_match_list_free(git_pathspec_match_list *m);
219 
220 /**
221  * Get the number of items in a match list.
222  *
223  * @param m The git_pathspec_match_list object
224  * @return Number of items in match list
225  */
226 GIT_EXTERN(size_t) git_pathspec_match_list_entrycount(
227 	const git_pathspec_match_list *m);
228 
229 /**
230  * Get a matching filename by position.
231  *
232  * This routine cannot be used if the match list was generated by
233  * `git_pathspec_match_diff`.  If so, it will always return NULL.
234  *
235  * @param m The git_pathspec_match_list object
236  * @param pos The index into the list
237  * @return The filename of the match
238  */
239 GIT_EXTERN(const char *) git_pathspec_match_list_entry(
240 	const git_pathspec_match_list *m, size_t pos);
241 
242 /**
243  * Get a matching diff delta by position.
244  *
245  * This routine can only be used if the match list was generated by
246  * `git_pathspec_match_diff`.  Otherwise it will always return NULL.
247  *
248  * @param m The git_pathspec_match_list object
249  * @param pos The index into the list
250  * @return The filename of the match
251  */
252 GIT_EXTERN(const git_diff_delta *) git_pathspec_match_list_diff_entry(
253 	const git_pathspec_match_list *m, size_t pos);
254 
255 /**
256  * Get the number of pathspec items that did not match.
257  *
258  * This will be zero unless you passed GIT_PATHSPEC_FIND_FAILURES when
259  * generating the git_pathspec_match_list.
260  *
261  * @param m The git_pathspec_match_list object
262  * @return Number of items in original pathspec that had no matches
263  */
264 GIT_EXTERN(size_t) git_pathspec_match_list_failed_entrycount(
265 	const git_pathspec_match_list *m);
266 
267 /**
268  * Get an original pathspec string that had no matches.
269  *
270  * This will be return NULL for positions out of range.
271  *
272  * @param m The git_pathspec_match_list object
273  * @param pos The index into the failed items
274  * @return The pathspec pattern that didn't match anything
275  */
276 GIT_EXTERN(const char *) git_pathspec_match_list_failed_entry(
277 	const git_pathspec_match_list *m, size_t pos);
278 
279 GIT_END_DECL
280 #endif
281