Commit 27e54bcf by Russell Belfer

Add public diff print helpers

The usefulness of these helpers came up for me while debugging
some of the iterator changes that I was making, so since they
have also been requested (albeit indirectly) I thought I'd include
them.
parent 3dbee456
/*
* 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
......@@ -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);
}
#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));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment