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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
diff --git a/include/git2/apply.h b/include/git2/apply.h
index cdeb9ed..eb9cad4 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 e6c2ae1..9534267 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;
}