Merge pull request #3277 from git-up/git_diff_index_to_index Added git_diff_index_to_index()
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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
diff --git a/include/git2/diff.h b/include/git2/diff.h
index b3ab539..0abbc7f 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -836,6 +836,25 @@ GIT_EXTERN(int) git_diff_tree_to_workdir_with_index(
const git_diff_options *opts); /**< can be NULL for defaults */
/**
+ * Create a diff with the difference between two index objects.
+ *
+ * The first index will be used for the "old_file" side of the delta and the
+ * second index will be used for the "new_file" side of the delta.
+ *
+ * @param diff Output pointer to a git_diff pointer to be allocated.
+ * @param repo The repository containing the indexes.
+ * @param old_index A git_index object to diff from.
+ * @param new_index A git_index object to diff to.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_index_to_index(
+ git_diff **diff,
+ git_repository *repo,
+ git_index *old_index,
+ git_index *new_index,
+ const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
* Merge one diff into another.
*
* This merges items from the "from" list into the "onto" list. The
diff --git a/src/diff.c b/src/diff.c
index c1adcc6..44f6278 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1421,6 +1421,31 @@ int git_diff_tree_to_workdir_with_index(
return error;
}
+int git_diff_index_to_index(
+ git_diff **diff,
+ git_repository *repo,
+ git_index *old_index,
+ git_index *new_index,
+ const git_diff_options *opts)
+{
+ int error = 0;
+
+ assert(diff && old_index && new_index);
+
+ DIFF_FROM_ITERATORS(
+ git_iterator_for_index(
+ &a, old_index, GIT_ITERATOR_DONT_IGNORE_CASE, pfx, pfx),
+ git_iterator_for_index(
+ &b, new_index, GIT_ITERATOR_DONT_IGNORE_CASE, pfx, pfx)
+ );
+
+ /* if index is in case-insensitive order, re-sort deltas to match */
+ if (!error && (old_index->ignore_case || new_index->ignore_case))
+ diff_set_ignore_case(*diff, true);
+
+ return error;
+}
+
size_t git_diff_num_deltas(const git_diff *diff)
{
assert(diff);
diff --git a/tests/diff/index.c b/tests/diff/index.c
index f702568..df45ad2 100644
--- a/tests/diff/index.c
+++ b/tests/diff/index.c
@@ -268,3 +268,35 @@ void test_diff_index__not_in_head_conflicted(void)
git_index_free(index);
git_tree_free(a);
}
+
+void test_diff_index__to_index(void)
+{
+ const char *a_commit = "26a125ee1bf"; /* the current HEAD */
+ git_tree *old_tree;
+ git_index *old_index;
+ git_index *new_index;
+ git_diff *diff;
+ diff_expects exp;
+
+ cl_git_pass(git_index_new(&old_index));
+ old_tree = resolve_commit_oid_to_tree(g_repo, a_commit);
+ cl_git_pass(git_index_read_tree(old_index, old_tree));
+
+ cl_git_pass(git_repository_index(&new_index, g_repo));
+
+ cl_git_pass(git_diff_index_to_index(&diff, g_repo, old_index, new_index, NULL));
+
+ memset(&exp, 0, sizeof(diff_expects));
+ cl_git_pass(git_diff_foreach(
+ diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
+ cl_assert_equal_i(8, exp.files);
+ cl_assert_equal_i(3, exp.file_status[GIT_DELTA_ADDED]);
+ cl_assert_equal_i(2, exp.file_status[GIT_DELTA_DELETED]);
+ cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
+ cl_assert_equal_i(0, exp.file_status[GIT_DELTA_CONFLICTED]);
+
+ git_diff_free(diff);
+ git_index_free(new_index);
+ git_index_free(old_index);
+ git_tree_free(old_tree);
+}