mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-05 22:36:08 +00:00
Merge pull request #1246 from arrbee/fix-force-text-for-diff-blobs
Add FORCE_TEXT check into git_diff_blobs code path
This commit is contained in:
commit
fbe67de997
@ -89,13 +89,14 @@ static void update_delta_is_binary(git_diff_delta *delta)
|
|||||||
/* otherwise leave delta->binary value untouched */
|
/* otherwise leave delta->binary value untouched */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diff_delta_is_binary_by_attr(
|
/* returns if we forced binary setting (and no further checks needed) */
|
||||||
diff_context *ctxt, git_diff_patch *patch)
|
static bool diff_delta_is_binary_forced(
|
||||||
|
diff_context *ctxt,
|
||||||
|
git_diff_delta *delta)
|
||||||
{
|
{
|
||||||
int error = 0, mirror_new;
|
/* return true if binary-ness has already been settled */
|
||||||
git_diff_delta *delta = patch->delta;
|
if (delta->binary != -1)
|
||||||
|
return true;
|
||||||
delta->binary = -1;
|
|
||||||
|
|
||||||
/* make sure files are conceivably mmap-able */
|
/* make sure files are conceivably mmap-able */
|
||||||
if ((git_off_t)((size_t)delta->old_file.size) != delta->old_file.size ||
|
if ((git_off_t)((size_t)delta->old_file.size) != delta->old_file.size ||
|
||||||
@ -104,7 +105,7 @@ static int diff_delta_is_binary_by_attr(
|
|||||||
delta->old_file.flags |= GIT_DIFF_FILE_BINARY;
|
delta->old_file.flags |= GIT_DIFF_FILE_BINARY;
|
||||||
delta->new_file.flags |= GIT_DIFF_FILE_BINARY;
|
delta->new_file.flags |= GIT_DIFF_FILE_BINARY;
|
||||||
delta->binary = 1;
|
delta->binary = 1;
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if user is forcing us to text diff these files */
|
/* check if user is forcing us to text diff these files */
|
||||||
@ -112,9 +113,23 @@ static int diff_delta_is_binary_by_attr(
|
|||||||
delta->old_file.flags |= GIT_DIFF_FILE_NOT_BINARY;
|
delta->old_file.flags |= GIT_DIFF_FILE_NOT_BINARY;
|
||||||
delta->new_file.flags |= GIT_DIFF_FILE_NOT_BINARY;
|
delta->new_file.flags |= GIT_DIFF_FILE_NOT_BINARY;
|
||||||
delta->binary = 0;
|
delta->binary = 0;
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int diff_delta_is_binary_by_attr(
|
||||||
|
diff_context *ctxt, git_diff_patch *patch)
|
||||||
|
{
|
||||||
|
int error = 0, mirror_new;
|
||||||
|
git_diff_delta *delta = patch->delta;
|
||||||
|
|
||||||
|
delta->binary = -1;
|
||||||
|
|
||||||
|
if (diff_delta_is_binary_forced(ctxt, delta))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* check diff attribute +, -, or 0 */
|
/* check diff attribute +, -, or 0 */
|
||||||
if (update_file_is_binary_by_attr(ctxt->repo, &delta->old_file) < 0)
|
if (update_file_is_binary_by_attr(ctxt->repo, &delta->old_file) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -137,15 +152,17 @@ static int diff_delta_is_binary_by_content(
|
|||||||
git_diff_file *file,
|
git_diff_file *file,
|
||||||
const git_map *map)
|
const git_map *map)
|
||||||
{
|
{
|
||||||
const git_buf search = { map->data, 0, min(map->len, 4000) };
|
if (diff_delta_is_binary_forced(ctxt, delta))
|
||||||
|
return 0;
|
||||||
GIT_UNUSED(ctxt);
|
|
||||||
|
|
||||||
if ((file->flags & KNOWN_BINARY_FLAGS) == 0) {
|
if ((file->flags & KNOWN_BINARY_FLAGS) == 0) {
|
||||||
|
const git_buf search = { map->data, 0, min(map->len, 4000) };
|
||||||
|
|
||||||
/* TODO: provide encoding / binary detection callbacks that can
|
/* TODO: provide encoding / binary detection callbacks that can
|
||||||
* be UTF-8 aware, etc. For now, instead of trying to be smart,
|
* be UTF-8 aware, etc. For now, instead of trying to be smart,
|
||||||
* let's just use the simple NUL-byte detection that core git uses.
|
* let's just use the simple NUL-byte detection that core git uses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* previously was: if (git_buf_text_is_binary(&search)) */
|
/* previously was: if (git_buf_text_is_binary(&search)) */
|
||||||
if (git_buf_text_contains_nul(&search))
|
if (git_buf_text_contains_nul(&search))
|
||||||
file->flags |= GIT_DIFF_FILE_BINARY;
|
file->flags |= GIT_DIFF_FILE_BINARY;
|
||||||
|
@ -352,6 +352,20 @@ void test_diff_blob__can_correctly_detect_a_textual_blob_as_non_binary(void)
|
|||||||
* git_diff_blob_to_buffer tests
|
* git_diff_blob_to_buffer tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void assert_changed_single_one_line_file(
|
||||||
|
diff_expects *expected, git_delta_t mod)
|
||||||
|
{
|
||||||
|
cl_assert_equal_i(1, expected->files);
|
||||||
|
cl_assert_equal_i(1, expected->file_status[mod]);
|
||||||
|
cl_assert_equal_i(1, expected->hunks);
|
||||||
|
cl_assert_equal_i(1, expected->lines);
|
||||||
|
|
||||||
|
if (mod == GIT_DELTA_ADDED)
|
||||||
|
cl_assert_equal_i(1, expected->line_adds);
|
||||||
|
else if (mod == GIT_DELTA_DELETED)
|
||||||
|
cl_assert_equal_i(1, expected->line_dels);
|
||||||
|
}
|
||||||
|
|
||||||
void test_diff_blob__can_compare_blob_to_buffer(void)
|
void test_diff_blob__can_compare_blob_to_buffer(void)
|
||||||
{
|
{
|
||||||
git_blob *a;
|
git_blob *a;
|
||||||
@ -391,11 +405,7 @@ void test_diff_blob__can_compare_blob_to_buffer(void)
|
|||||||
NULL, a_content, strlen(a_content),
|
NULL, a_content, strlen(a_content),
|
||||||
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
|
||||||
cl_assert_equal_i(1, expected.files);
|
assert_changed_single_one_line_file(&expected, GIT_DELTA_ADDED);
|
||||||
cl_assert_equal_i(1, expected.file_status[GIT_DELTA_ADDED]);
|
|
||||||
cl_assert_equal_i(1, expected.hunks);
|
|
||||||
cl_assert_equal_i(1, expected.lines);
|
|
||||||
cl_assert_equal_i(1, expected.line_adds);
|
|
||||||
|
|
||||||
/* diff from blob a to NULL buffer */
|
/* diff from blob a to NULL buffer */
|
||||||
memset(&expected, 0, sizeof(expected));
|
memset(&expected, 0, sizeof(expected));
|
||||||
@ -403,11 +413,7 @@ void test_diff_blob__can_compare_blob_to_buffer(void)
|
|||||||
a, NULL, 0,
|
a, NULL, 0,
|
||||||
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
|
||||||
cl_assert_equal_i(1, expected.files);
|
assert_changed_single_one_line_file(&expected, GIT_DELTA_DELETED);
|
||||||
cl_assert_equal_i(1, expected.file_status[GIT_DELTA_DELETED]);
|
|
||||||
cl_assert_equal_i(1, expected.hunks);
|
|
||||||
cl_assert_equal_i(1, expected.lines);
|
|
||||||
cl_assert_equal_i(1, expected.line_dels);
|
|
||||||
|
|
||||||
/* diff with reverse */
|
/* diff with reverse */
|
||||||
opts.flags ^= GIT_DIFF_REVERSE;
|
opts.flags ^= GIT_DIFF_REVERSE;
|
||||||
@ -417,11 +423,109 @@ void test_diff_blob__can_compare_blob_to_buffer(void)
|
|||||||
a, NULL, 0,
|
a, NULL, 0,
|
||||||
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
|
||||||
cl_assert_equal_i(1, expected.files);
|
assert_changed_single_one_line_file(&expected, GIT_DELTA_ADDED);
|
||||||
cl_assert_equal_i(1, expected.file_status[GIT_DELTA_ADDED]);
|
|
||||||
cl_assert_equal_i(1, expected.hunks);
|
|
||||||
cl_assert_equal_i(1, expected.lines);
|
|
||||||
cl_assert_equal_i(1, expected.line_adds);
|
|
||||||
|
|
||||||
git_blob_free(a);
|
git_blob_free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void assert_one_modified_with_lines(diff_expects *expected, int lines)
|
||||||
|
{
|
||||||
|
cl_assert_equal_i(1, expected->files);
|
||||||
|
cl_assert_equal_i(1, expected->file_status[GIT_DELTA_MODIFIED]);
|
||||||
|
cl_assert_equal_i(0, expected->files_binary);
|
||||||
|
cl_assert_equal_i(lines, expected->lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_diff_blob__binary_data_comparisons(void)
|
||||||
|
{
|
||||||
|
git_blob *bin, *nonbin;
|
||||||
|
git_oid oid;
|
||||||
|
const char *nonbin_content = "Hello from the root\n";
|
||||||
|
size_t nonbin_len = 20;
|
||||||
|
const char *bin_content = "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n";
|
||||||
|
size_t bin_len = 33;
|
||||||
|
|
||||||
|
cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8));
|
||||||
|
cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 4));
|
||||||
|
|
||||||
|
cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8));
|
||||||
|
cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 4));
|
||||||
|
|
||||||
|
/* non-binary to reference content */
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blob_to_buffer(
|
||||||
|
nonbin, nonbin_content, nonbin_len,
|
||||||
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_identical_blobs_comparison(&expected);
|
||||||
|
cl_assert_equal_i(0, expected.files_binary);
|
||||||
|
|
||||||
|
/* binary to reference content */
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blob_to_buffer(
|
||||||
|
bin, bin_content, bin_len,
|
||||||
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_identical_blobs_comparison(&expected);
|
||||||
|
|
||||||
|
cl_assert_equal_i(1, expected.files_binary);
|
||||||
|
|
||||||
|
/* non-binary to binary content */
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blob_to_buffer(
|
||||||
|
nonbin, bin_content, bin_len,
|
||||||
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_binary_blobs_comparison(&expected);
|
||||||
|
|
||||||
|
/* binary to non-binary content */
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blob_to_buffer(
|
||||||
|
bin, nonbin_content, nonbin_len,
|
||||||
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_binary_blobs_comparison(&expected);
|
||||||
|
|
||||||
|
/* non-binary to binary blob */
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blobs(
|
||||||
|
bin, nonbin, &opts,
|
||||||
|
diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_binary_blobs_comparison(&expected);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* repeat with FORCE_TEXT
|
||||||
|
*/
|
||||||
|
|
||||||
|
opts.flags |= GIT_DIFF_FORCE_TEXT;
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blob_to_buffer(
|
||||||
|
bin, bin_content, bin_len,
|
||||||
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_identical_blobs_comparison(&expected);
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blob_to_buffer(
|
||||||
|
nonbin, bin_content, bin_len,
|
||||||
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_one_modified_with_lines(&expected, 4);
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blob_to_buffer(
|
||||||
|
bin, nonbin_content, nonbin_len,
|
||||||
|
&opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_one_modified_with_lines(&expected, 4);
|
||||||
|
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
cl_git_pass(git_diff_blobs(
|
||||||
|
bin, nonbin, &opts,
|
||||||
|
diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
|
||||||
|
assert_one_modified_with_lines(&expected, 4);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
git_blob_free(bin);
|
||||||
|
git_blob_free(nonbin);
|
||||||
|
}
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user