summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/sys/diff.h63
-rw-r--r--src/diff_print.c28
-rw-r--r--tests/diff/diff_helpers.c29
3 files changed, 96 insertions, 24 deletions
diff --git a/include/git2/sys/diff.h b/include/git2/sys/diff.h
new file mode 100644
index 000000000..bc6cdf393
--- /dev/null
+++ b/include/git2/sys/diff.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_diff_h__
+#define INCLUDE_sys_git_diff_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/sys/diff.h
+ * @brief Low-level Git diff utilities
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Diff print callback that writes to a git_buf.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs. When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a `git_buf` buffer. You
+ * must pass a `git_buf *` value as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function. The data will be appended to the
+ * buffer (after any existing content).
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_buf(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
+ void *payload); /*< payload must be a `git_buf *` */
+
+/**
+ * Diff print callback that writes to stdio FILE handle.
+ *
+ * This function is provided not for you to call it directly, but instead
+ * so you can use it as a function pointer to the `git_diff_print` or
+ * `git_patch_print` APIs. When using those APIs, you specify a callback
+ * to actually handle the diff and/or patch data.
+ *
+ * Use this callback to easily write that data to a stdio FILE handle. You
+ * must pass a `FILE *` value (such as `stdout` or `stderr` or the return
+ * value from `fopen()`) as the payload to the `git_diff_print`
+ * and/or `git_patch_print` function. If you pass NULL, this will write
+ * data to `stdout`.
+ */
+GIT_EXTERN(int) git_diff_print_callback__to_file_handle(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
+ void *payload); /*< payload must be a `FILE *` */
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/src/diff_print.c b/src/diff_print.c
index 1a09bed54..a7f7b6fe8 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -8,6 +8,7 @@
#include "diff.h"
#include "diff_patch.h"
#include "fileops.h"
+#include "git2/sys/diff.h"
typedef struct {
git_diff *diff;
@@ -435,7 +436,7 @@ int git_patch_print(
return error;
}
-static int diff_print_to_buffer_cb(
+int git_diff_print_callback__to_buf(
const git_diff_delta *delta,
const git_diff_hunk *hunk,
const git_diff_line *line,
@@ -444,6 +445,11 @@ static int diff_print_to_buffer_cb(
git_buf *output = payload;
GIT_UNUSED(delta); GIT_UNUSED(hunk);
+ if (!output) {
+ giterr_set(GITERR_INVALID, "Buffer pointer must be provided");
+ return -1;
+ }
+
if (line->origin == GIT_DIFF_LINE_ADDITION ||
line->origin == GIT_DIFF_LINE_DELETION ||
line->origin == GIT_DIFF_LINE_CONTEXT)
@@ -452,10 +458,28 @@ static int diff_print_to_buffer_cb(
return git_buf_put(output, line->content, line->content_len);
}
+int git_diff_print_callback__to_file_handle(
+ const git_diff_delta *delta,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
+ void *payload)
+{
+ FILE *fp = payload ? payload : stdout;
+
+ GIT_UNUSED(delta); GIT_UNUSED(hunk);
+
+ if (line->origin == GIT_DIFF_LINE_CONTEXT ||
+ line->origin == GIT_DIFF_LINE_ADDITION ||
+ line->origin == GIT_DIFF_LINE_DELETION)
+ fputc(line->origin, fp);
+ fwrite(line->content, 1, line->content_len, fp);
+ return 0;
+}
+
/* print a git_patch to a git_buf */
int git_patch_to_buf(
git_buf *out,
git_patch *patch)
{
- return git_patch_print(patch, diff_print_to_buffer_cb, out);
+ return git_patch_print(patch, git_diff_print_callback__to_buf, out);
}
diff --git a/tests/diff/diff_helpers.c b/tests/diff/diff_helpers.c
index 33bb561f6..279cb20c5 100644
--- a/tests/diff/diff_helpers.c
+++ b/tests/diff/diff_helpers.c
@@ -1,5 +1,6 @@
#include "clar_libgit2.h"
#include "diff_helpers.h"
+#include "git2/sys/diff.h"
git_tree *resolve_commit_oid_to_tree(
git_repository *repo,
@@ -215,32 +216,16 @@ abort:
return GIT_EUSER;
}
-static int diff_print_cb(
- const git_diff_delta *delta,
- const git_diff_hunk *hunk,
- const git_diff_line *line,
- void *payload)
-{
- FILE *fp = payload;
-
- GIT_UNUSED(delta); GIT_UNUSED(hunk);
-
- if (line->origin == GIT_DIFF_LINE_CONTEXT ||
- line->origin == GIT_DIFF_LINE_ADDITION ||
- line->origin == GIT_DIFF_LINE_DELETION)
- fputc(line->origin, fp);
- fwrite(line->content, 1, line->content_len, fp);
- return 0;
-}
-
void diff_print(FILE *fp, git_diff *diff)
{
- cl_git_pass(git_diff_print(
- diff, GIT_DIFF_FORMAT_PATCH, diff_print_cb, fp ? fp : stderr));
+ cl_git_pass(
+ git_diff_print(diff, GIT_DIFF_FORMAT_PATCH,
+ git_diff_print_callback__to_file_handle, fp ? fp : stderr));
}
void diff_print_raw(FILE *fp, git_diff *diff)
{
- cl_git_pass(git_diff_print(
- diff, GIT_DIFF_FORMAT_RAW, diff_print_cb, fp ? fp : stderr));
+ cl_git_pass(
+ git_diff_print(diff, GIT_DIFF_FORMAT_RAW,
+ git_diff_print_callback__to_file_handle, fp ? fp : stderr));
}