Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-06-10 21:10:39 +0400
committerRussell Belfer <rb@github.com>2013-06-10 21:10:39 +0400
commit114f5a6c41ea03393e00ae41126a6ddb0ef39a15 (patch)
treef579e849a72749123a54483180726396244177b2 /src/diff.c
parent7000f3fa7bad25ec07355d6afb640ea272201dff (diff)
Reorganize diff and add basic diff driver
This is a significant reorganization of the diff code to break it into a set of more clearly distinct files and to document the new organization. Hopefully this will make the diff code easier to understand and to extend. This adds a new `git_diff_driver` object that looks of diff driver information from the attributes and the config so that things like function content in diff headers can be provided. The full driver spec is not implemented in the commit - this is focused on the reorganization of the code and putting the driver hooks in place. This also removes a few #includes from src/repository.h that were overbroad, but as a result required extra #includes in a variety of places since including src/repository.h no longer results in pulling in the whole world.
Diffstat (limited to 'src/diff.c')
-rw-r--r--src/diff.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/diff.c b/src/diff.c
index 05ef4f16b..97ccb3cbd 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -11,6 +11,8 @@
#include "attr_file.h"
#include "filter.h"
#include "pathspec.h"
+#include "index.h"
+#include "odb.h"
#define DIFF_FLAG_IS_SET(DIFF,FLAG) (((DIFF)->opts.flags & (FLAG)) != 0)
#define DIFF_FLAG_ISNT_SET(DIFF,FLAG) (((DIFF)->opts.flags & (FLAG)) == 0)
@@ -1170,3 +1172,73 @@ int git_diff_tree_to_workdir(
return error;
}
+
+size_t git_diff_num_deltas(git_diff_list *diff)
+{
+ assert(diff);
+ return (size_t)diff->deltas.length;
+}
+
+size_t git_diff_num_deltas_of_type(git_diff_list *diff, git_delta_t type)
+{
+ size_t i, count = 0;
+ git_diff_delta *delta;
+
+ assert(diff);
+
+ git_vector_foreach(&diff->deltas, i, delta) {
+ count += (delta->status == type);
+ }
+
+ return count;
+}
+
+int git_diff__paired_foreach(
+ git_diff_list *idx2head,
+ git_diff_list *wd2idx,
+ int (*cb)(git_diff_delta *i2h, git_diff_delta *w2i, void *payload),
+ void *payload)
+{
+ int cmp;
+ git_diff_delta *i2h, *w2i;
+ size_t i, j, i_max, j_max;
+ int (*strcomp)(const char *, const char *);
+
+ i_max = idx2head ? idx2head->deltas.length : 0;
+ j_max = wd2idx ? wd2idx->deltas.length : 0;
+
+ /* Get appropriate strcmp function */
+ strcomp = idx2head ? idx2head->strcomp : wd2idx ? wd2idx->strcomp : NULL;
+
+ /* Assert both iterators use matching ignore-case. If this function ever
+ * supports merging diffs that are not sorted by the same function, then
+ * it will need to spool and sort on one of the results before merging
+ */
+ if (idx2head && wd2idx) {
+ assert(idx2head->strcomp == wd2idx->strcomp);
+ }
+
+ for (i = 0, j = 0; i < i_max || j < j_max; ) {
+ i2h = idx2head ? GIT_VECTOR_GET(&idx2head->deltas,i) : NULL;
+ w2i = wd2idx ? GIT_VECTOR_GET(&wd2idx->deltas,j) : NULL;
+
+ cmp = !w2i ? -1 : !i2h ? 1 :
+ strcomp(i2h->old_file.path, w2i->old_file.path);
+
+ if (cmp < 0) {
+ if (cb(i2h, NULL, payload))
+ return GIT_EUSER;
+ i++;
+ } else if (cmp > 0) {
+ if (cb(NULL, w2i, payload))
+ return GIT_EUSER;
+ j++;
+ } else {
+ if (cb(i2h, w2i, payload))
+ return GIT_EUSER;
+ i++; j++;
+ }
+ }
+
+ return 0;
+}