summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/diff_file.c14
-rw-r--r--src/diff_file.h12
-rw-r--r--src/diff_patch.c133
-rw-r--r--src/diff_patch.h49
-rw-r--r--src/diff_print.c22
-rw-r--r--src/diff_xdiff.c19
6 files changed, 154 insertions, 95 deletions
diff --git a/src/diff_file.c b/src/diff_file.c
index 5bdb9e4bf..4fd1177ae 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -85,7 +85,7 @@ static int diff_file_content_init_common(
return 0;
}
-int diff_file_content_init_from_diff(
+int git_diff_file_content__init_from_diff(
git_diff_file_content *fc,
git_diff_list *diff,
size_t delta_index,
@@ -127,7 +127,7 @@ int diff_file_content_init_from_diff(
return diff_file_content_init_common(fc, &diff->opts);
}
-int diff_file_content_init_from_blob(
+int git_diff_file_content__init_from_blob(
git_diff_file_content *fc,
git_repository *repo,
const git_diff_options *opts,
@@ -152,7 +152,7 @@ int diff_file_content_init_from_blob(
return diff_file_content_init_common(fc, opts);
}
-int diff_file_content_init_from_raw(
+int git_diff_file_content__init_from_raw(
git_diff_file_content *fc,
git_repository *repo,
const git_diff_options *opts,
@@ -385,7 +385,7 @@ static int diff_file_content_load_workdir(git_diff_file_content *fc)
return error;
}
-int diff_file_content_load(git_diff_file_content *fc)
+int git_diff_file_content__load(git_diff_file_content *fc)
{
int error = 0;
@@ -409,7 +409,7 @@ int diff_file_content_load(git_diff_file_content *fc)
return 0;
}
-void diff_file_content_unload(git_diff_file_content *fc)
+void git_diff_file_content__unload(git_diff_file_content *fc)
{
if (fc->file.flags & GIT_DIFF_FLAG__FREE_DATA) {
git__free(fc->map.data);
@@ -433,9 +433,9 @@ void diff_file_content_unload(git_diff_file_content *fc)
fc->file.flags &= ~GIT_DIFF_FLAG__LOADED;
}
-void diff_file_content_clear(git_diff_file_content *fc)
+void git_diff_file_content__clear(git_diff_file_content *fc)
{
- diff_file_content_unload(fc);
+ git_diff_file_content__unload(fc);
/* for now, nothing else to do */
}
diff --git a/src/diff_file.h b/src/diff_file.h
index ab7b1dc1f..afad8510b 100644
--- a/src/diff_file.h
+++ b/src/diff_file.h
@@ -24,19 +24,19 @@ typedef struct {
git_map map;
} git_diff_file_content;
-extern int diff_file_content_init_from_diff(
+extern int git_diff_file_content__init_from_diff(
git_diff_file_content *fc,
git_diff_list *diff,
size_t delta_index,
bool use_old);
-extern int diff_file_content_init_from_blob(
+extern int git_diff_file_content__init_from_blob(
git_diff_file_content *fc,
git_repository *repo,
const git_diff_options *opts,
const git_blob *blob);
-extern int diff_file_content_init_from_raw(
+extern int git_diff_file_content__init_from_raw(
git_diff_file_content *fc,
git_repository *repo,
const git_diff_options *opts,
@@ -44,12 +44,12 @@ extern int diff_file_content_init_from_raw(
size_t buflen);
/* this loads the blob/file-on-disk as needed */
-extern int diff_file_content_load(git_diff_file_content *fc);
+extern int git_diff_file_content__load(git_diff_file_content *fc);
/* this releases the blob/file-in-memory */
-extern void diff_file_content_unload(git_diff_file_content *fc);
+extern void git_diff_file_content__unload(git_diff_file_content *fc);
/* this unloads and also releases any other resources */
-extern void diff_file_content_clear(git_diff_file_content *fc);
+extern void git_diff_file_content__clear(git_diff_file_content *fc);
#endif
diff --git a/src/diff_patch.c b/src/diff_patch.c
index 05dee5ef7..a1e1fe84c 100644
--- a/src/diff_patch.c
+++ b/src/diff_patch.c
@@ -11,6 +11,49 @@
#include "diff_patch.h"
#include "diff_xdiff.h"
+/* cached information about a single span in a diff */
+typedef struct diff_patch_line diff_patch_line;
+struct diff_patch_line {
+ const char *ptr;
+ size_t len;
+ size_t lines, oldno, newno;
+ char origin;
+};
+
+/* cached information about a hunk in a diff */
+typedef struct diff_patch_hunk diff_patch_hunk;
+struct diff_patch_hunk {
+ git_diff_range range;
+ char header[128];
+ size_t header_len;
+ size_t line_start;
+ size_t line_count;
+};
+
+struct git_diff_patch {
+ git_refcount rc;
+ git_diff_list *diff; /* for refcount purposes, maybe NULL for blob diffs */
+ git_diff_delta *delta;
+ size_t delta_index;
+ git_diff_file_content ofile;
+ git_diff_file_content nfile;
+ uint32_t flags;
+ git_array_t(diff_patch_hunk) hunks;
+ git_array_t(diff_patch_line) lines;
+ size_t oldno, newno;
+ size_t content_size;
+ git_pool flattened;
+};
+
+enum {
+ GIT_DIFF_PATCH_ALLOCATED = (1 << 0),
+ GIT_DIFF_PATCH_INITIALIZED = (1 << 1),
+ GIT_DIFF_PATCH_LOADED = (1 << 2),
+ GIT_DIFF_PATCH_DIFFABLE = (1 << 3),
+ GIT_DIFF_PATCH_DIFFED = (1 << 4),
+ GIT_DIFF_PATCH_FLATTENED = (1 << 5),
+};
+
static void diff_output_init(git_diff_output*, const git_diff_options*,
git_diff_file_cb, git_diff_hunk_cb, git_diff_data_cb, void*);
@@ -53,9 +96,9 @@ static int diff_patch_init_from_diff(
patch->delta = git_vector_get(&diff->deltas, delta_index);
patch->delta_index = delta_index;
- if ((error = diff_file_content_init_from_diff(
+ if ((error = git_diff_file_content__init_from_diff(
&patch->ofile, diff, delta_index, true)) < 0 ||
- (error = diff_file_content_init_from_diff(
+ (error = git_diff_file_content__init_from_diff(
&patch->nfile, diff, delta_index, false)) < 0)
return error;
@@ -110,24 +153,24 @@ static int diff_patch_load(git_diff_patch *patch, git_diff_output *output)
* need 2x data size and this minimizes peak memory footprint
*/
if (patch->ofile.src == GIT_ITERATOR_TYPE_WORKDIR) {
- if ((error = diff_file_content_load(&patch->ofile)) < 0 ||
+ if ((error = git_diff_file_content__load(&patch->ofile)) < 0 ||
(patch->ofile.file.flags & GIT_DIFF_FLAG_BINARY) != 0)
goto cleanup;
}
if (patch->nfile.src == GIT_ITERATOR_TYPE_WORKDIR) {
- if ((error = diff_file_content_load(&patch->nfile)) < 0 ||
+ if ((error = git_diff_file_content__load(&patch->nfile)) < 0 ||
(patch->nfile.file.flags & GIT_DIFF_FLAG_BINARY) != 0)
goto cleanup;
}
/* once workdir has been tried, load other data as needed */
if (patch->ofile.src != GIT_ITERATOR_TYPE_WORKDIR) {
- if ((error = diff_file_content_load(&patch->ofile)) < 0 ||
+ if ((error = git_diff_file_content__load(&patch->ofile)) < 0 ||
(patch->ofile.file.flags & GIT_DIFF_FLAG_BINARY) != 0)
goto cleanup;
}
if (patch->nfile.src != GIT_ITERATOR_TYPE_WORKDIR) {
- if ((error = diff_file_content_load(&patch->nfile)) < 0 ||
+ if ((error = git_diff_file_content__load(&patch->nfile)) < 0 ||
(patch->nfile.file.flags & GIT_DIFF_FLAG_BINARY) != 0)
goto cleanup;
}
@@ -198,8 +241,8 @@ static int diff_patch_generate(git_diff_patch *patch, git_diff_output *output)
static void diff_patch_free(git_diff_patch *patch)
{
- diff_file_content_clear(&patch->ofile);
- diff_file_content_clear(&patch->nfile);
+ git_diff_file_content__clear(&patch->ofile);
+ git_diff_file_content__clear(&patch->nfile);
git_array_clear(patch->lines);
git_array_clear(patch->hunks);
@@ -323,9 +366,9 @@ static int diff_patch_from_blobs(
new_blob = swap;
}
- if ((error = diff_file_content_init_from_blob(
+ if ((error = git_diff_file_content__init_from_blob(
&pd->patch.ofile, repo, opts, old_blob)) < 0 ||
- (error = diff_file_content_init_from_blob(
+ (error = git_diff_file_content__init_from_blob(
&pd->patch.nfile, repo, opts, new_blob)) < 0)
return error;
@@ -409,14 +452,14 @@ static int diff_patch_from_blob_and_buffer(
return 0;
if (opts && (opts->flags & GIT_DIFF_REVERSE) != 0) {
- if (!(error = diff_file_content_init_from_raw(
+ if (!(error = git_diff_file_content__init_from_raw(
&pd->patch.ofile, repo, opts, buf, buflen)))
- error = diff_file_content_init_from_blob(
+ error = git_diff_file_content__init_from_blob(
&pd->patch.nfile, repo, opts, old_blob);
} else {
- if (!(error = diff_file_content_init_from_blob(
+ if (!(error = git_diff_file_content__init_from_blob(
&pd->patch.ofile, repo, opts, old_blob)))
- error = diff_file_content_init_from_raw(
+ error = git_diff_file_content__init_from_raw(
&pd->patch.nfile, repo, opts, buf, buflen);
}
@@ -690,6 +733,68 @@ notfound:
return diff_error_outofrange(thing);
}
+git_diff_list *git_diff_patch__diff(git_diff_patch *patch)
+{
+ return patch->diff;
+}
+
+git_diff_driver *git_diff_patch__driver(git_diff_patch *patch)
+{
+ /* ofile driver is representative for whole patch */
+ return patch->ofile.driver;
+}
+
+void git_diff_patch__old_data(
+ char **ptr, size_t *len, git_diff_patch *patch)
+{
+ *ptr = patch->ofile.map.data;
+ *len = patch->ofile.map.len;
+}
+
+void git_diff_patch__new_data(
+ char **ptr, size_t *len, git_diff_patch *patch)
+{
+ *ptr = patch->nfile.map.data;
+ *len = patch->nfile.map.len;
+}
+
+int git_diff_patch__invoke_callbacks(
+ git_diff_patch *patch,
+ git_diff_file_cb file_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_data_cb line_cb,
+ void *payload)
+{
+ int error = 0;
+ uint32_t i, j;
+
+ if (file_cb)
+ error = file_cb(patch->delta, 0, payload);
+
+ if (!hunk_cb && !line_cb)
+ return error;
+
+ for (i = 0; !error && i < git_array_size(patch->hunks); ++i) {
+ diff_patch_hunk *h = git_array_get(patch->hunks, i);
+
+ error = hunk_cb(
+ patch->delta, &h->range, h->header, h->header_len, payload);
+
+ if (!line_cb)
+ continue;
+
+ for (j = 0; !error && j < h->line_count; ++j) {
+ diff_patch_line *l =
+ git_array_get(patch->lines, h->line_start + j);
+
+ error = line_cb(
+ patch->delta, &h->range, l->origin, l->ptr, l->len, payload);
+ }
+ }
+
+ return error;
+}
+
static int diff_patch_file_cb(
const git_diff_delta *delta,
diff --git a/src/diff_patch.h b/src/diff_patch.h
index 7de6e1e5b..56af14600 100644
--- a/src/diff_patch.h
+++ b/src/diff_patch.h
@@ -12,48 +12,19 @@
#include "diff_file.h"
#include "array.h"
-/* cached information about a single span in a diff */
-typedef struct diff_patch_line diff_patch_line;
-struct diff_patch_line {
- const char *ptr;
- size_t len;
- size_t lines, oldno, newno;
- char origin;
-};
+extern git_diff_list *git_diff_patch__diff(git_diff_patch *);
-/* cached information about a hunk in a diff */
-typedef struct diff_patch_hunk diff_patch_hunk;
-struct diff_patch_hunk {
- git_diff_range range;
- char header[128];
- size_t header_len;
- size_t line_start;
- size_t line_count;
-};
+extern git_diff_driver *git_diff_patch__driver(git_diff_patch *);
-struct git_diff_patch {
- git_refcount rc;
- git_diff_list *diff; /* for refcount purposes, maybe NULL for blob diffs */
- git_diff_delta *delta;
- size_t delta_index;
- git_diff_file_content ofile;
- git_diff_file_content nfile;
- uint32_t flags;
- git_array_t(diff_patch_hunk) hunks;
- git_array_t(diff_patch_line) lines;
- size_t oldno, newno;
- size_t content_size;
- git_pool flattened;
-};
+extern void git_diff_patch__old_data(char **, size_t *, git_diff_patch *);
+extern void git_diff_patch__new_data(char **, size_t *, git_diff_patch *);
-enum {
- GIT_DIFF_PATCH_ALLOCATED = (1 << 0),
- GIT_DIFF_PATCH_INITIALIZED = (1 << 1),
- GIT_DIFF_PATCH_LOADED = (1 << 2),
- GIT_DIFF_PATCH_DIFFABLE = (1 << 3),
- GIT_DIFF_PATCH_DIFFED = (1 << 4),
- GIT_DIFF_PATCH_FLATTENED = (1 << 5),
-};
+extern int git_diff_patch__invoke_callbacks(
+ git_diff_patch *patch,
+ git_diff_file_cb file_cb,
+ git_diff_hunk_cb hunk_cb,
+ git_diff_data_cb line_cb,
+ void *payload);
typedef struct git_diff_output git_diff_output;
struct git_diff_output {
diff --git a/src/diff_print.c b/src/diff_print.c
index 860876531..244aa6e1d 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -383,29 +383,13 @@ int git_diff_patch_print(
int error;
git_buf temp = GIT_BUF_INIT;
diff_print_info pi;
- size_t h, l;
assert(patch && print_cb);
if (!(error = diff_print_info_init(
- &pi, &temp, patch->diff, print_cb, payload)))
- error = print_patch_file(patch->delta, 0, &pi);
-
- for (h = 0; h < git_array_size(patch->hunks) && !error; ++h) {
- diff_patch_hunk *hunk = git_array_get(patch->hunks, h);
-
- error = print_patch_hunk(
- patch->delta, &hunk->range, hunk->header, hunk->header_len, &pi);
-
- for (l = 0; l < hunk->line_count && !error; ++l) {
- diff_patch_line *line =
- git_array_get(patch->lines, hunk->line_start + l);
-
- error = print_patch_line(
- patch->delta, &hunk->range,
- line->origin, line->ptr, line->len, &pi);
- }
- }
+ &pi, &temp, git_diff_patch__diff(patch), print_cb, payload)))
+ error = git_diff_patch__invoke_callbacks(
+ patch, print_patch_file, print_patch_hunk, print_patch_line, &pi);
git_buf_free(&temp);
diff --git a/src/diff_xdiff.c b/src/diff_xdiff.c
index 91c56f727..7694fb996 100644
--- a/src/diff_xdiff.c
+++ b/src/diff_xdiff.c
@@ -59,6 +59,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
{
git_xdiff_info *info = priv;
git_diff_patch *patch = info->patch;
+ const git_diff_delta *delta = git_diff_patch_delta(patch);
git_diff_output *output = &info->xo->output;
if (len == 1) {
@@ -67,7 +68,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
return output->error;
if (output->hunk_cb != NULL &&
- output->hunk_cb(patch->delta, &info->range,
+ output->hunk_cb(delta, &info->range,
bufs[0].ptr, bufs[0].size, output->payload))
output->error = GIT_EUSER;
}
@@ -80,7 +81,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
GIT_DIFF_LINE_CONTEXT;
if (output->data_cb != NULL &&
- output->data_cb(patch->delta, &info->range,
+ output->data_cb(delta, &info->range,
origin, bufs[1].ptr, bufs[1].size, output->payload))
output->error = GIT_EUSER;
}
@@ -97,7 +98,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
GIT_DIFF_LINE_CONTEXT_EOFNL;
if (output->data_cb != NULL &&
- output->data_cb(patch->delta, &info->range,
+ output->data_cb(delta, &info->range,
origin, bufs[2].ptr, bufs[2].size, output->payload))
output->error = GIT_EUSER;
}
@@ -110,7 +111,7 @@ static int git_xdiff(git_diff_output *output, git_diff_patch *patch)
git_xdiff_output *xo = (git_xdiff_output *)output;
git_xdiff_info info;
git_diff_find_context_payload findctxt;
- mmfile_t old_xdiff_data, new_xdiff_data;
+ mmfile_t xd_old_data, xd_new_data;
memset(&info, 0, sizeof(info));
info.patch = patch;
@@ -119,7 +120,7 @@ static int git_xdiff(git_diff_output *output, git_diff_patch *patch)
xo->callback.priv = &info;
git_diff_find_context_init(
- &xo->config.find_func, &findctxt, patch->ofile.driver);
+ &xo->config.find_func, &findctxt, git_diff_patch__driver(patch));
xo->config.find_func_priv = &findctxt;
if (xo->config.find_func != NULL)
@@ -131,12 +132,10 @@ static int git_xdiff(git_diff_output *output, git_diff_patch *patch)
* updates are needed to xo->params.flags
*/
- old_xdiff_data.ptr = patch->ofile.map.data;
- old_xdiff_data.size = patch->ofile.map.len;
- new_xdiff_data.ptr = patch->nfile.map.data;
- new_xdiff_data.size = patch->nfile.map.len;
+ git_diff_patch__old_data(&xd_old_data.ptr, &xd_old_data.size, patch);
+ git_diff_patch__new_data(&xd_new_data.ptr, &xd_new_data.size, patch);
- xdl_diff(&old_xdiff_data, &new_xdiff_data,
+ xdl_diff(&xd_old_data, &xd_new_data,
&xo->params, &xo->config, &xo->callback);
git_diff_find_context_clear(&findctxt);