Commit b4a4cf24 by Russell Belfer

Add git_diff_patch_size() API

This adds a new API to get the size in bytes of the diffs in a
git_diff_patch object.
parent 1cd9dc29
...@@ -943,6 +943,24 @@ GIT_EXTERN(int) git_diff_patch_get_line_in_hunk( ...@@ -943,6 +943,24 @@ GIT_EXTERN(int) git_diff_patch_get_line_in_hunk(
size_t line_of_hunk); size_t line_of_hunk);
/** /**
* Look up size of patch diff data in bytes
*
* This returns the raw size of the patch data. This only includes the
* actual data from the lines of the diff, not the file or hunk headers.
*
* If you pass `include_context` as true (non-zero), this will be the size
* of all of the diff output; if you pass it as false (zero), this will
* only include the actual changed lines (as if `context_lines` was 0).
*
* @param patch A git_diff_patch representing changes to one file
* @param include_context Include context lines in size if non-zero
* @return The number of bytes of data
*/
GIT_EXTERN(size_t) git_diff_patch_size(
git_diff_patch *patch,
int include_context);
/**
* Serialize the patch to text via callback. * Serialize the patch to text via callback.
* *
* Returning a non-zero value from the callback will terminate the iteration * Returning a non-zero value from the callback will terminate the iteration
......
...@@ -42,7 +42,7 @@ struct git_diff_patch { ...@@ -42,7 +42,7 @@ struct git_diff_patch {
git_array_t(diff_patch_hunk) hunks; git_array_t(diff_patch_hunk) hunks;
git_array_t(diff_patch_line) lines; git_array_t(diff_patch_line) lines;
size_t oldno, newno; size_t oldno, newno;
size_t content_size; size_t content_size, context_size;
git_pool flattened; git_pool flattened;
}; };
...@@ -806,6 +806,20 @@ notfound: ...@@ -806,6 +806,20 @@ notfound:
return diff_error_outofrange(thing); return diff_error_outofrange(thing);
} }
size_t git_diff_patch_size(git_diff_patch *patch, int include_context)
{
size_t out;
assert(patch);
out = patch->content_size;
if (!include_context)
out -= patch->context_size;
return out;
}
git_diff_list *git_diff_patch__diff(git_diff_patch *patch) git_diff_list *git_diff_patch__diff(git_diff_patch *patch)
{ {
return patch->diff; return patch->diff;
...@@ -934,7 +948,11 @@ static int diff_patch_line_cb( ...@@ -934,7 +948,11 @@ static int diff_patch_line_cb(
line->len = content_len; line->len = content_len;
line->origin = line_origin; line->origin = line_origin;
patch->content_size += content_len; patch->content_size += content_len + 1; /* +1 for line_origin */
if (line_origin == GIT_DIFF_LINE_CONTEXT ||
line_origin == GIT_DIFF_LINE_CONTEXT_EOFNL)
patch->context_size += content_len + 1;
/* do some bookkeeping so we can provide old/new line numbers */ /* do some bookkeeping so we can provide old/new line numbers */
......
...@@ -128,6 +128,9 @@ void test_diff_patch__to_string(void) ...@@ -128,6 +128,9 @@ void test_diff_patch__to_string(void)
cl_assert_equal_s(expected, text); cl_assert_equal_s(expected, text);
cl_assert_equal_sz(31, git_diff_patch_size(patch, 0));
cl_assert_equal_sz(31, git_diff_patch_size(patch, 1));
git__free(text); git__free(text);
git_diff_patch_free(patch); git_diff_patch_free(patch);
git_diff_list_free(diff); git_diff_list_free(diff);
...@@ -409,6 +412,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) ...@@ -409,6 +412,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
static void check_single_patch_stats( static void check_single_patch_stats(
git_repository *repo, size_t hunks, git_repository *repo, size_t hunks,
size_t adds, size_t dels, size_t ctxt, size_t adds, size_t dels, size_t ctxt,
size_t size_with_context, size_t size_without_context,
const char *expected) const char *expected)
{ {
git_diff_list *diff; git_diff_list *diff;
...@@ -439,6 +443,13 @@ static void check_single_patch_stats( ...@@ -439,6 +443,13 @@ static void check_single_patch_stats(
git__free(text); git__free(text);
} }
if (size_with_context)
cl_assert_equal_sz(
size_with_context, git_diff_patch_size(patch, 1));
if (size_without_context)
cl_assert_equal_sz(
size_without_context, git_diff_patch_size(patch, 0));
/* walk lines in hunk with basic sanity checks */ /* walk lines in hunk with basic sanity checks */
for (; hunks > 0; --hunks) { for (; hunks > 0; --hunks) {
size_t i, max_i; size_t i, max_i;
...@@ -495,14 +506,14 @@ void test_diff_patch__line_counts_with_eofnl(void) ...@@ -495,14 +506,14 @@ void test_diff_patch__line_counts_with_eofnl(void)
git_buf_consume(&content, end); git_buf_consume(&content, end);
cl_git_rewritefile("renames/songof7cities.txt", content.ptr); cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
check_single_patch_stats(g_repo, 1, 0, 1, 3, NULL); check_single_patch_stats(g_repo, 1, 0, 1, 3, 0, 0, NULL);
/* remove trailing whitespace */ /* remove trailing whitespace */
git_buf_rtrim(&content); git_buf_rtrim(&content);
cl_git_rewritefile("renames/songof7cities.txt", content.ptr); cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
check_single_patch_stats(g_repo, 2, 1, 2, 6, NULL); check_single_patch_stats(g_repo, 2, 1, 2, 6, 0, 0, NULL);
/* add trailing whitespace */ /* add trailing whitespace */
...@@ -514,7 +525,7 @@ void test_diff_patch__line_counts_with_eofnl(void) ...@@ -514,7 +525,7 @@ void test_diff_patch__line_counts_with_eofnl(void)
cl_git_pass(git_buf_putc(&content, '\n')); cl_git_pass(git_buf_putc(&content, '\n'));
cl_git_rewritefile("renames/songof7cities.txt", content.ptr); cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
check_single_patch_stats(g_repo, 1, 1, 1, 3, NULL); check_single_patch_stats(g_repo, 1, 1, 1, 3, 0, 0, NULL);
/* no trailing whitespace as context line */ /* no trailing whitespace as context line */
...@@ -537,7 +548,7 @@ void test_diff_patch__line_counts_with_eofnl(void) ...@@ -537,7 +548,7 @@ void test_diff_patch__line_counts_with_eofnl(void)
cl_git_rewritefile("renames/songof7cities.txt", content.ptr); cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
check_single_patch_stats( check_single_patch_stats(
g_repo, 1, 1, 1, 6, g_repo, 1, 1, 1, 6, 349, 115,
/* below is pasted output of 'git diff' with fn context removed */ /* below is pasted output of 'git diff' with fn context removed */
"diff --git a/songof7cities.txt b/songof7cities.txt\n" "diff --git a/songof7cities.txt b/songof7cities.txt\n"
"index 378a7d9..3d0154e 100644\n" "index 378a7d9..3d0154e 100644\n"
......
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