summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2018-07-10 16:10:03 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2018-11-05 15:53:59 +0000
commitaf33210b735b760debc03ce558ff62c3834f0a5b (patch)
tree23095c9cb3e6024f9dd6c7e939187af187940377
parent37b25ac57f78dc72e6bf4e516e24dc5010098cee (diff)
downloadlibgit2-af33210b735b760debc03ce558ff62c3834f0a5b.tar.gz
apply: introduce a delta callback
Introduce a callback to the application options that allow callers to add a per-delta callback. The callback can return an error code to stop patch application, or can return a value to skip the application of a particular delta.
-rw-r--r--include/git2/apply.h19
-rw-r--r--src/apply.c18
2 files changed, 34 insertions, 3 deletions
diff --git a/include/git2/apply.h b/include/git2/apply.h
index cdeb9ed4c..eb9cad4d1 100644
--- a/include/git2/apply.h
+++ b/include/git2/apply.h
@@ -22,6 +22,22 @@
GIT_BEGIN_DECL
/**
+ * When applying a patch, callback that will be made per delta (file).
+ *
+ * When the callback:
+ * - returns < 0, the apply process will be aborted.
+ * - returns > 0, the delta will not be applied, but the apply process
+ * continues
+ * - returns 0, the delta is applied, and the apply process continues.
+ *
+ * @param delta The delta to be applied
+ * @param payload User-specified payload
+ */
+typedef int (*git_apply_delta_cb)(
+ const git_diff_delta *delta,
+ void *payload);
+
+/**
* Apply options structure
*
* Initialize with `GIT_APPLY_OPTIONS_INIT`. Alternatively, you can
@@ -31,6 +47,9 @@ GIT_BEGIN_DECL
*/
typedef struct {
unsigned int version;
+
+ git_apply_delta_cb delta_cb;
+ void *payload;
} git_apply_options;
#define GIT_APPLY_OPTIONS_VERSION 1
diff --git a/src/apply.c b/src/apply.c
index e6c2ae15b..95342676c 100644
--- a/src/apply.c
+++ b/src/apply.c
@@ -390,7 +390,8 @@ static int apply_one(
git_index *preimage,
git_index *postimage,
git_diff *diff,
- size_t i)
+ size_t i,
+ const git_apply_options *opts)
{
git_patch *patch = NULL;
git_buf pre_contents = GIT_BUF_INIT, post_contents = GIT_BUF_INIT;
@@ -406,6 +407,17 @@ static int apply_one(
delta = git_patch_get_delta(patch);
+ if (opts->delta_cb) {
+ error = opts->delta_cb(delta, opts->payload);
+
+ if (error) {
+ if (error > 0)
+ error = 0;
+
+ goto done;
+ }
+ }
+
if (delta->status != GIT_DELTA_ADDED) {
error = git_reader_read(&pre_contents, &pre_id,
preimage_reader, delta->old_file.path);
@@ -514,7 +526,7 @@ int git_apply_to_tree(
}
for (i = 0; i < git_diff_num_deltas(diff); i++) {
- if ((error = apply_one(repo, pre_reader, NULL, postimage, diff, i)) < 0)
+ if ((error = apply_one(repo, pre_reader, NULL, postimage, diff, i, &opts)) < 0)
goto done;
}
@@ -700,7 +712,7 @@ int git_apply(
goto done;
for (i = 0; i < git_diff_num_deltas(diff); i++) {
- if ((error = apply_one(repo, pre_reader, preimage, postimage, diff, i)) < 0)
+ if ((error = apply_one(repo, pre_reader, preimage, postimage, diff, i, &opts)) < 0)
goto done;
}