Commit af33210b by Edward Thomson

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.
parent 37b25ac5
...@@ -22,6 +22,22 @@ ...@@ -22,6 +22,22 @@
GIT_BEGIN_DECL 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 * Apply options structure
* *
* Initialize with `GIT_APPLY_OPTIONS_INIT`. Alternatively, you can * Initialize with `GIT_APPLY_OPTIONS_INIT`. Alternatively, you can
...@@ -31,6 +47,9 @@ GIT_BEGIN_DECL ...@@ -31,6 +47,9 @@ GIT_BEGIN_DECL
*/ */
typedef struct { typedef struct {
unsigned int version; unsigned int version;
git_apply_delta_cb delta_cb;
void *payload;
} git_apply_options; } git_apply_options;
#define GIT_APPLY_OPTIONS_VERSION 1 #define GIT_APPLY_OPTIONS_VERSION 1
......
...@@ -390,7 +390,8 @@ static int apply_one( ...@@ -390,7 +390,8 @@ static int apply_one(
git_index *preimage, git_index *preimage,
git_index *postimage, git_index *postimage,
git_diff *diff, git_diff *diff,
size_t i) size_t i,
const git_apply_options *opts)
{ {
git_patch *patch = NULL; git_patch *patch = NULL;
git_buf pre_contents = GIT_BUF_INIT, post_contents = GIT_BUF_INIT; git_buf pre_contents = GIT_BUF_INIT, post_contents = GIT_BUF_INIT;
...@@ -406,6 +407,17 @@ static int apply_one( ...@@ -406,6 +407,17 @@ static int apply_one(
delta = git_patch_get_delta(patch); 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) { if (delta->status != GIT_DELTA_ADDED) {
error = git_reader_read(&pre_contents, &pre_id, error = git_reader_read(&pre_contents, &pre_id,
preimage_reader, delta->old_file.path); preimage_reader, delta->old_file.path);
...@@ -514,7 +526,7 @@ int git_apply_to_tree( ...@@ -514,7 +526,7 @@ int git_apply_to_tree(
} }
for (i = 0; i < git_diff_num_deltas(diff); i++) { 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; goto done;
} }
...@@ -700,7 +712,7 @@ int git_apply( ...@@ -700,7 +712,7 @@ int git_apply(
goto done; goto done;
for (i = 0; i < git_diff_num_deltas(diff); i++) { 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; goto done;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment