Commit 5ef43d41b036d4178c6d886c2222db9dd7f32fc1

Edward Thomson 2015-06-23T10:29:59

git_diff__merge: allow pluggable diff merges

diff --git a/src/diff.h b/src/diff.h
index 2a35fd9..39d15fa 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -123,6 +123,16 @@ extern int git_diff_find_similar__calc_similarity(
 extern int git_diff__commit(
 	git_diff **diff, git_repository *repo, const git_commit *commit, const git_diff_options *opts);
 
+/* Merge two `git_diff`s according to the callback given by `cb`. */
+
+typedef git_diff_delta *(*git_diff__merge_cb)(
+	const git_diff_delta *left,
+	const git_diff_delta *right,
+	git_pool *pool);
+
+extern int git_diff__merge(
+	git_diff *onto, const git_diff *from, git_diff__merge_cb cb);
+
 /*
  * Sometimes a git_diff_file will have a zero size; this attempts to
  * fill in the size without loading the blob if possible.  If that is
diff --git a/src/diff_tform.c b/src/diff_tform.c
index cc809c1..52a7b52 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -109,7 +109,8 @@ static git_diff_delta *diff_delta__merge_like_cgit(
 	return dup;
 }
 
-int git_diff_merge(git_diff *onto, const git_diff *from)
+int git_diff__merge_deltas(
+	git_diff *onto, const git_diff *from, git_diff__merge_cb cb)
 {
 	int error = 0;
 	git_pool onto_pool;
@@ -154,7 +155,7 @@ int git_diff_merge(git_diff *onto, const git_diff *from)
 			const git_diff_delta *left = reversed ? f : o;
 			const git_diff_delta *right = reversed ? o : f;
 
-			delta = diff_delta__merge_like_cgit(left, right, &onto_pool);
+			delta = cb(left, right, &onto_pool);
 			i++;
 			j++;
 		}
@@ -162,7 +163,7 @@ int git_diff_merge(git_diff *onto, const git_diff *from)
 		/* the ignore rules for the target may not match the source
 		 * or the result of a merged delta could be skippable...
 		 */
-		if (git_diff_delta__should_skip(&onto->opts, delta)) {
+		if (delta && git_diff_delta__should_skip(&onto->opts, delta)) {
 			git__free(delta);
 			continue;
 		}
@@ -193,6 +194,11 @@ int git_diff_merge(git_diff *onto, const git_diff *from)
 	return error;
 }
 
+int git_diff_merge(git_diff *onto, const git_diff *from)
+{
+	return git_diff__merge_deltas(onto, from, diff_delta__merge_like_cgit);
+}
+
 int git_diff_find_similar__hashsig_for_file(
 	void **out, const git_diff_file *f, const char *path, void *p)
 {