summaryrefslogtreecommitdiff
path: root/include/git2
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-09-10 16:33:32 -0700
committerRussell Belfer <rb@github.com>2013-09-17 09:31:44 -0700
commit2a7d224f99a053d93079644947d04e7cc085930f (patch)
tree5a9082e68e98cd85e0bde8d8e399d386158ad390 /include/git2
parent974774c7b00c08585b05ff87174872be005a1f29 (diff)
downloadlibgit2-2a7d224f99a053d93079644947d04e7cc085930f.tar.gz
Extend public filter api with filter lists
This moves the git_filter_list into the public API so that users can create, apply, and dispose of filter lists. This allows more granular application of filters to user data outside of libgit2 internals. This also converts all the internal usage of filters to the public APIs along with a few small tweaks to make it easier to use the public git_buffer stuff alongside the internal git_buf.
Diffstat (limited to 'include/git2')
-rw-r--r--include/git2/buffer.h27
-rw-r--r--include/git2/filter.h94
-rw-r--r--include/git2/sys/filter.h20
3 files changed, 119 insertions, 22 deletions
diff --git a/include/git2/buffer.h b/include/git2/buffer.h
index 454a1faa5..cb80e48f7 100644
--- a/include/git2/buffer.h
+++ b/include/git2/buffer.h
@@ -21,17 +21,17 @@ GIT_BEGIN_DECL
/**
* A data buffer for exporting data from libgit2
*
- * There are a number of places where libgit2 wants to return an allocated
- * data buffer to the caller and have the caller take ownership of that
- * allocated memory. This can be awkward if the caller does not have easy
- * access to the same allocation functions that libgit2 is using. In those
- * cases, libgit2 will instead fill in a `git_buffer` and the caller can
- * use `git_buffer_free()` to release it when they are done.
+ * Sometimes libgit2 wants to return an allocated data buffer to the
+ * caller and have the caller take responsibility for freeing that memory.
+ * This can be awkward if the caller does not have easy access to the same
+ * allocation functions that libgit2 is using. In those cases, libgit2
+ * will instead fill in a `git_buffer` and the caller can use
+ * `git_buffer_free()` to release it when they are done.
*
* * `ptr` refers to the start of the allocated memory.
* * `size` contains the size of the data in `ptr` that is actually used.
- * * `available` refers to the known total amount of allocated memory in
- * cases where it is larger than the `size` actually in use.
+ * * `available` refers to the known total amount of allocated memory. It
+ * may be larger than the `size` actually in use.
*
* In a few cases, for uniformity and simplicity, an API may populate a
* `git_buffer` with data that should *not* be freed (i.e. the lifetime of
@@ -79,6 +79,17 @@ GIT_EXTERN(void) git_buffer_free(git_buffer *buffer);
*/
GIT_EXTERN(int) git_buffer_resize(git_buffer *buffer, size_t want_size);
+/**
+ * Set buffer to a copy of some raw data.
+ *
+ * @param buffer The buffer to set
+ * @param data The data to copy into the buffer
+ * @param datalen The length of the data to copy into the buffer
+ * @return 0 on success, negative error code on allocation failure
+ */
+GIT_EXTERN(int) git_buffer_copy(
+ git_buffer *buffer, const void *data, size_t datalen);
+
GIT_END_DECL
/** @} */
diff --git a/include/git2/filter.h b/include/git2/filter.h
index 478f3a6ad..cb23ae4f4 100644
--- a/include/git2/filter.h
+++ b/include/git2/filter.h
@@ -29,10 +29,10 @@ GIT_BEGIN_DECL
* change is being applied.
*/
typedef enum {
- GIT_FILTER_SMUDGE = 0,
- GIT_FILTER_TO_WORKTREE = GIT_FILTER_SMUDGE,
- GIT_FILTER_CLEAN = 1,
- GIT_FILTER_TO_ODB = GIT_FILTER_CLEAN,
+ GIT_FILTER_TO_WORKTREE = 0,
+ GIT_FILTER_SMUDGE = GIT_FILTER_TO_WORKTREE,
+ GIT_FILTER_TO_ODB = 1,
+ GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB,
} git_filter_mode_t;
/**
@@ -50,10 +50,28 @@ typedef enum {
*/
typedef struct git_filter git_filter;
+/**
+ * List of filters to be applied
+ *
+ * This represents a list of filters to be applied to a file / blob. You
+ * can build the list with one call, apply it with another, and dispose it
+ * with a third. In typical usage, there are not many occasions where a
+ * git_filter_list is needed directly since the library will generally
+ * handle conversions for you, but it can be convenient to be able to
+ * build and apply the list sometimes.
+ */
+typedef struct git_filter_list git_filter_list;
+
+/**
+ * Look up a filter by name
+ */
GIT_EXTERN(git_filter *) git_filter_lookup(const char *name);
#define GIT_FILTER_CRLF "crlf"
+/**
+ * Apply a single filter to a buffer of data
+ */
GIT_EXTERN(int) git_filter_apply_to_buffer(
git_buffer *out,
git_filter *filter,
@@ -61,6 +79,74 @@ GIT_EXTERN(int) git_filter_apply_to_buffer(
const char *as_path,
git_filter_mode_t mode);
+/**
+ * Load the filter list for a given path.
+ *
+ * This will return 0 (success) but set the output git_filter_list to NULL
+ * if no filters are requested for the given file.
+ *
+ * @param filters Output newly created git_filter_list (or NULL)
+ * @param repo Repository object that contains `path`
+ * @param path Relative path of the file to be filtered
+ * @param mode Filtering direction (WT->ODB or ODB->WT)
+ * @return 0 on success (which could still return NULL if no filters are
+ * needed for the requested file), <0 on error
+ */
+GIT_EXTERN(int) git_filter_list_load(
+ git_filter_list **filters,
+ git_repository *repo,
+ const char *path,
+ git_filter_mode_t mode);
+
+/**
+ * Apply filter list to a data buffer.
+ *
+ * See `git2/buffer.h` for background on `git_buffer` objects.
+ *
+ * If the `in` buffer refers to data managed by libgit2
+ * (i.e. `in->available` is not zero), then it will be overwritten when
+ * applying the filters. If not, then it will be left untouched.
+ *
+ * If there are no filters to apply (or `filters` is NULL), then the `out`
+ * buffer will reference the `in` buffer data (with `available` set to
+ * zero) instead of allocating data. This keeps allocations to a minimum,
+ * but it means you have to be careful about freeing the `in` data.
+ *
+ * @param out Buffer to store the result of the filtering
+ * @param filters A loaded git_filter_list (or NULL)
+ * @param in Buffer containing the data to filter
+ * @return 0 on success, an error code otherwise
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_data(
+ git_buffer *out,
+ git_filter_list *filters,
+ git_buffer *in);
+
+/**
+ * Apply filter list to the contents of a file on disk
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_file(
+ git_buffer *out,
+ git_filter_list *filters,
+ git_repository *repo,
+ const char *path);
+
+/**
+ * Apply filter list to the contents of a blob
+ */
+GIT_EXTERN(int) git_filter_list_apply_to_blob(
+ git_buffer *out,
+ git_filter_list *filters,
+ git_blob *blob);
+
+/**
+ * Free a git_filter_list
+ *
+ * @param filters A git_filter_list created by `git_filter_list_load`
+ */
+GIT_EXTERN(void) git_filter_list_free(git_filter_list *filters);
+
+
GIT_END_DECL
/** @} */
diff --git a/include/git2/sys/filter.h b/include/git2/sys/filter.h
index b0a753019..ca1fbfcce 100644
--- a/include/git2/sys/filter.h
+++ b/include/git2/sys/filter.h
@@ -46,6 +46,11 @@ GIT_EXTERN(uint16_t) git_filter_source_filemode(const git_filter_source *src);
*/
GIT_EXTERN(const git_oid *) git_filter_source_id(const git_filter_source *src);
+/**
+ * Get the git_filter_mode_t to be applied
+ */
+GIT_EXTERN(git_filter_mode_t) git_filter_source_mode(const git_filter_source *src);
+
/*
* struct git_filter
*
@@ -73,7 +78,6 @@ typedef void (*git_filter_shutdown_fn)(git_filter *self);
typedef int (*git_filter_check_fn)(
git_filter *self,
void **payload, /* points to NULL ptr on entry, may be set */
- git_filter_mode_t mode,
const git_filter_source *src,
const char **attr_values);
@@ -83,7 +87,6 @@ typedef int (*git_filter_check_fn)(
typedef int (*git_filter_apply_fn)(
git_filter *self,
void **payload, /* may be read and/or set */
- git_filter_mode_t mode,
git_buffer *to,
const git_buffer *from,
const git_filter_source *src);
@@ -105,14 +108,11 @@ typedef void (*git_filter_cleanup_fn)(
*
* `version` should be set to GIT_FILTER_VERSION
*
- * `attributes` is a list of attributes to check on a file to see if the
- * filter applies. The format is a whitespace-delimited list of names
- * (like "eol crlf text"). Each name may have an optional value that will
- * be tested even without a `check` callback. If the value does not
- * match, the filter will be skipped. The values are specified as in a
- * .gitattributes file (e.g. "myattr=foobar" or "myattr" or "-myattr").
- * If a check function is supplied, then the values of the attributes will
- * be passed to that function.
+ * `attributes` is a whitespace-separated list of attribute names to check
+ * for this filter (e.g. "eol crlf text"). If the attribute name is bare,
+ * it will be simply loaded and passed to the `check` callback. If it has
+ * a value (i.e. "name=value"), the attribute must match that value for
+ * the filter to be applied.
*
* `initialize` is an optional callback invoked before a filter is first
* used. It will be called once at most.