]> git.proxmox.com Git - libgit2.git/blob - include/git2/sys/filter.h
Merge branch 'portable-zu'
[libgit2.git] / include / git2 / sys / filter.h
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_sys_git_filter_h__
8 #define INCLUDE_sys_git_filter_h__
9
10 #include "git2/filter.h"
11
12 /**
13 * @file git2/sys/filter.h
14 * @brief Git filter backend and plugin routines
15 * @defgroup git_backend Git custom backend APIs
16 * @ingroup Git
17 * @{
18 */
19 GIT_BEGIN_DECL
20
21 /**
22 * Look up a filter by name
23 *
24 * @param name The name of the filter
25 * @return Pointer to the filter object or NULL if not found
26 */
27 GIT_EXTERN(git_filter *) git_filter_lookup(const char *name);
28
29 #define GIT_FILTER_CRLF "crlf"
30 #define GIT_FILTER_IDENT "ident"
31
32 /**
33 * This is priority that the internal CRLF filter will be registered with
34 */
35 #define GIT_FILTER_CRLF_PRIORITY 0
36
37 /**
38 * This is priority that the internal ident filter will be registered with
39 */
40 #define GIT_FILTER_IDENT_PRIORITY 100
41
42 /**
43 * This is priority to use with a custom filter to imitate a core Git
44 * filter driver, so that it will be run last on checkout and first on
45 * checkin. You do not have to use this, but it helps compatibility.
46 */
47 #define GIT_FILTER_DRIVER_PRIORITY 200
48
49 /**
50 * Create a new empty filter list
51 *
52 * Normally you won't use this because `git_filter_list_load` will create
53 * the filter list for you, but you can use this in combination with the
54 * `git_filter_lookup` and `git_filter_list_push` functions to assemble
55 * your own chains of filters.
56 */
57 GIT_EXTERN(int) git_filter_list_new(
58 git_filter_list **out,
59 git_repository *repo,
60 git_filter_mode_t mode,
61 uint32_t options);
62
63 /**
64 * Add a filter to a filter list with the given payload.
65 *
66 * Normally you won't have to do this because the filter list is created
67 * by calling the "check" function on registered filters when the filter
68 * attributes are set, but this does allow more direct manipulation of
69 * filter lists when desired.
70 *
71 * Note that normally the "check" function can set up a payload for the
72 * filter. Using this function, you can either pass in a payload if you
73 * know the expected payload format, or you can pass NULL. Some filters
74 * may fail with a NULL payload. Good luck!
75 */
76 GIT_EXTERN(int) git_filter_list_push(
77 git_filter_list *fl, git_filter *filter, void *payload);
78
79 /**
80 * Look up how many filters are in the list
81 *
82 * We will attempt to apply all of these filters to any data passed in,
83 * but note that the filter apply action still has the option of skipping
84 * data that is passed in (for example, the CRLF filter will skip data
85 * that appears to be binary).
86 *
87 * @param fl A filter list
88 * @return The number of filters in the list
89 */
90 GIT_EXTERN(size_t) git_filter_list_length(const git_filter_list *fl);
91
92 /**
93 * A filter source represents a file/blob to be processed
94 */
95 typedef struct git_filter_source git_filter_source;
96
97 /**
98 * Get the repository that the source data is coming from.
99 */
100 GIT_EXTERN(git_repository *) git_filter_source_repo(const git_filter_source *src);
101
102 /**
103 * Get the path that the source data is coming from.
104 */
105 GIT_EXTERN(const char *) git_filter_source_path(const git_filter_source *src);
106
107 /**
108 * Get the file mode of the source file
109 * If the mode is unknown, this will return 0
110 */
111 GIT_EXTERN(uint16_t) git_filter_source_filemode(const git_filter_source *src);
112
113 /**
114 * Get the OID of the source
115 * If the OID is unknown (often the case with GIT_FILTER_CLEAN) then
116 * this will return NULL.
117 */
118 GIT_EXTERN(const git_oid *) git_filter_source_id(const git_filter_source *src);
119
120 /**
121 * Get the git_filter_mode_t to be used
122 */
123 GIT_EXTERN(git_filter_mode_t) git_filter_source_mode(const git_filter_source *src);
124
125 /**
126 * Get the combination git_filter_flag_t options to be applied
127 */
128 GIT_EXTERN(uint32_t) git_filter_source_flags(const git_filter_source *src);
129
130 /*
131 * struct git_filter
132 *
133 * The filter lifecycle:
134 * - initialize - first use of filter
135 * - shutdown - filter removed/unregistered from system
136 * - check - considering filter for file
137 * - apply - apply filter to file contents
138 * - cleanup - done with file
139 */
140
141 /**
142 * Initialize callback on filter
143 *
144 * Specified as `filter.initialize`, this is an optional callback invoked
145 * before a filter is first used. It will be called once at most.
146 *
147 * If non-NULL, the filter's `initialize` callback will be invoked right
148 * before the first use of the filter, so you can defer expensive
149 * initialization operations (in case libgit2 is being used in a way that
150 * doesn't need the filter).
151 */
152 typedef int (*git_filter_init_fn)(git_filter *self);
153
154 /**
155 * Shutdown callback on filter
156 *
157 * Specified as `filter.shutdown`, this is an optional callback invoked
158 * when the filter is unregistered or when libgit2 is shutting down. It
159 * will be called once at most and should release resources as needed.
160 * This may be called even if the `initialize` callback was not made.
161 *
162 * Typically this function will free the `git_filter` object itself.
163 */
164 typedef void (*git_filter_shutdown_fn)(git_filter *self);
165
166 /**
167 * Callback to decide if a given source needs this filter
168 *
169 * Specified as `filter.check`, this is an optional callback that checks
170 * if filtering is needed for a given source.
171 *
172 * It should return 0 if the filter should be applied (i.e. success),
173 * GIT_PASSTHROUGH if the filter should not be applied, or an error code
174 * to fail out of the filter processing pipeline and return to the caller.
175 *
176 * The `attr_values` will be set to the values of any attributes given in
177 * the filter definition. See `git_filter` below for more detail.
178 *
179 * The `payload` will be a pointer to a reference payload for the filter.
180 * This will start as NULL, but `check` can assign to this pointer for
181 * later use by the `apply` callback. Note that the value should be heap
182 * allocated (not stack), so that it doesn't go away before the `apply`
183 * callback can use it. If a filter allocates and assigns a value to the
184 * `payload`, it will need a `cleanup` callback to free the payload.
185 */
186 typedef int (*git_filter_check_fn)(
187 git_filter *self,
188 void **payload, /* points to NULL ptr on entry, may be set */
189 const git_filter_source *src,
190 const char **attr_values);
191
192 /**
193 * Callback to actually perform the data filtering
194 *
195 * Specified as `filter.apply`, this is the callback that actually filters
196 * data. If it successfully writes the output, it should return 0. Like
197 * `check`, it can return GIT_PASSTHROUGH to indicate that the filter
198 * doesn't want to run. Other error codes will stop filter processing and
199 * return to the caller.
200 *
201 * The `payload` value will refer to any payload that was set by the
202 * `check` callback. It may be read from or written to as needed.
203 */
204 typedef int (*git_filter_apply_fn)(
205 git_filter *self,
206 void **payload, /* may be read and/or set */
207 git_buf *to,
208 const git_buf *from,
209 const git_filter_source *src);
210
211 typedef int (*git_filter_stream_fn)(
212 git_writestream **out,
213 git_filter *self,
214 void **payload,
215 const git_filter_source *src,
216 git_writestream *next);
217
218 /**
219 * Callback to clean up after filtering has been applied
220 *
221 * Specified as `filter.cleanup`, this is an optional callback invoked
222 * after the filter has been applied. If the `check` or `apply` callbacks
223 * allocated a `payload` to keep per-source filter state, use this
224 * callback to free that payload and release resources as required.
225 */
226 typedef void (*git_filter_cleanup_fn)(
227 git_filter *self,
228 void *payload);
229
230 /**
231 * Filter structure used to register custom filters.
232 *
233 * To associate extra data with a filter, allocate extra data and put the
234 * `git_filter` struct at the start of your data buffer, then cast the
235 * `self` pointer to your larger structure when your callback is invoked.
236 *
237 * `version` should be set to GIT_FILTER_VERSION
238 *
239 * `attributes` is a whitespace-separated list of attribute names to check
240 * for this filter (e.g. "eol crlf text"). If the attribute name is bare,
241 * it will be simply loaded and passed to the `check` callback. If it has
242 * a value (i.e. "name=value"), the attribute must match that value for
243 * the filter to be applied. The value may be a wildcard (eg, "name=*"),
244 * in which case the filter will be invoked for any value for the given
245 * attribute name. See the attribute parameter of the `check` callback
246 * for the attribute value that was specified.
247 *
248 * The `initialize`, `shutdown`, `check`, `apply`, and `cleanup` callbacks
249 * are all documented above with the respective function pointer typedefs.
250 */
251 struct git_filter {
252 unsigned int version;
253
254 const char *attributes;
255
256 git_filter_init_fn initialize;
257 git_filter_shutdown_fn shutdown;
258 git_filter_check_fn check;
259 git_filter_apply_fn apply;
260 git_filter_stream_fn stream;
261 git_filter_cleanup_fn cleanup;
262 };
263
264 #define GIT_FILTER_VERSION 1
265
266 /**
267 * Register a filter under a given name with a given priority.
268 *
269 * As mentioned elsewhere, the initialize callback will not be invoked
270 * immediately. It is deferred until the filter is used in some way.
271 *
272 * A filter's attribute checks and `check` and `apply` callbacks will be
273 * issued in order of `priority` on smudge (to workdir), and in reverse
274 * order of `priority` on clean (to odb).
275 *
276 * Two filters are preregistered with libgit2:
277 * - GIT_FILTER_CRLF with priority 0
278 * - GIT_FILTER_IDENT with priority 100
279 *
280 * Currently the filter registry is not thread safe, so any registering or
281 * deregistering of filters must be done outside of any possible usage of
282 * the filters (i.e. during application setup or shutdown).
283 *
284 * @param name A name by which the filter can be referenced. Attempting
285 * to register with an in-use name will return GIT_EEXISTS.
286 * @param filter The filter definition. This pointer will be stored as is
287 * by libgit2 so it must be a durable allocation (either static
288 * or on the heap).
289 * @param priority The priority for filter application
290 * @return 0 on successful registry, error code <0 on failure
291 */
292 GIT_EXTERN(int) git_filter_register(
293 const char *name, git_filter *filter, int priority);
294
295 /**
296 * Remove the filter with the given name
297 *
298 * Attempting to remove the builtin libgit2 filters is not permitted and
299 * will return an error.
300 *
301 * Currently the filter registry is not thread safe, so any registering or
302 * deregistering of filters must be done outside of any possible usage of
303 * the filters (i.e. during application setup or shutdown).
304 *
305 * @param name The name under which the filter was registered
306 * @return 0 on success, error code <0 on failure
307 */
308 GIT_EXTERN(int) git_filter_unregister(const char *name);
309
310 /** @} */
311 GIT_END_DECL
312 #endif