diff: make git_diff_from_buffer diffs show binary data when printed.

This change sets the `GIT_DIFF_SHOW_BINARY` flag on all `git_diff`
structs created using `git_diff_from_buffer`. This ensures that when the
diff is printed (e.g. with `git_diff_print` or `git_diff_to_buf`) all
binary data patches in the diff are actually printed out.

Before this change printing a diff created from a patch file using
`git_diff_from_buffer` would result in binary data patches not being
included in the output. Instead, a "Binary files A and B differ" message
would be included in the printed patch, even if the original patch did
include a "GIT binary patch". This meant that you couldn't actually
round-trip such diffs, going from patch file to `git_diff` to patch
file.

Note that this change is consistent with how that same flag is already
set on all `git_patch` structs created using `git_patch_parse` (which
`git_diff_from_buffer` calls to populate the `git_diff`, and which
`git_patch_from_buffer` also calls).
This commit is contained in:
Timon Van Overveldt
2025-03-16 15:34:16 -07:00
parent 21a351b0ed
commit 0b9216802e
3 changed files with 32 additions and 0 deletions

View File

@@ -96,6 +96,8 @@ int git_diff_from_buffer_ext(
diff = diff_parsed_alloc(oid_type);
GIT_ERROR_CHECK_ALLOC(diff);
diff->base.opts.flags |= GIT_DIFF_SHOW_BINARY;
ctx = git_patch_parse_ctx_init(content, content_len, &patch_opts);
GIT_ERROR_CHECK_ALLOC(ctx);

View File

@@ -5,6 +5,7 @@
#include "delta.h"
#include "filebuf.h"
#include "repository.h"
#include "../patch/patch_common.h"
static git_repository *repo;
@@ -407,6 +408,21 @@ void test_diff_binary__print_patch_from_diff(void)
git_index_free(index);
}
void test_diff_binary__print_patch_from_diff_from_buffer(void)
{
git_diff *diff;
git_str actual = GIT_STR_INIT;
cl_git_pass(git_diff_from_buffer(&diff, PATCH_BINARY_LITERAL, strlen(PATCH_BINARY_LITERAL)));
cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, print_cb, &actual));
cl_assert_equal_s(PATCH_BINARY_LITERAL, actual.ptr);
git_str_dispose(&actual);
git_diff_free(diff);
}
struct diff_data {
char *old_path;
git_oid old_id;

View File

@@ -366,6 +366,20 @@ void test_diff_parse__patch_roundtrip_succeeds(void)
git_buf_dispose(&diffbuf);
}
void test_diff_parse__binary_patch_roundtrip_succeeds(void)
{
git_buf diffbuf = GIT_BUF_INIT;
git_diff *diff;
cl_git_pass(git_diff_from_buffer(&diff, PATCH_BINARY_LITERAL, strlen(PATCH_BINARY_LITERAL)));
cl_git_pass(git_diff_to_buf(&diffbuf, diff, GIT_DIFF_FORMAT_PATCH));
cl_assert_equal_s(PATCH_BINARY_LITERAL, diffbuf.ptr);
git_diff_free(diff);
git_buf_dispose(&diffbuf);
}
#define cl_assert_equal_i_src(i1,i2,file,func,line) clar__assert_equal(file,func,line,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
static void cl_git_assert_lineinfo_(int old_lineno, int new_lineno, int num_lines, git_patch *patch, size_t hunk_idx, size_t line_idx, const char *file, const char *func, int lineno)