summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-07-22 16:07:56 -0700
committerRussell Belfer <rb@github.com>2013-07-22 16:07:56 -0700
commitb4a4cf24a539ce07d86fed6835c98154fb40e723 (patch)
tree74e8807bc0993d480ed38278b4f41cfde83da641
parent1cd9dc29b7105cb33959d15ab670a085f5a1445b (diff)
downloadlibgit2-b4a4cf24a539ce07d86fed6835c98154fb40e723.tar.gz
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.
-rw-r--r--include/git2/diff.h18
-rw-r--r--src/diff_patch.c22
-rw-r--r--tests-clar/diff/patch.c19
3 files changed, 53 insertions, 6 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 71a8b72bf..711967501 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -943,6 +943,24 @@ GIT_EXTERN(int) git_diff_patch_get_line_in_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.
*
* Returning a non-zero value from the callback will terminate the iteration
diff --git a/src/diff_patch.c b/src/diff_patch.c
index 1b4adac03..5febc883c 100644
--- a/src/diff_patch.c
+++ b/src/diff_patch.c
@@ -42,7 +42,7 @@ struct git_diff_patch {
git_array_t(diff_patch_hunk) hunks;
git_array_t(diff_patch_line) lines;
size_t oldno, newno;
- size_t content_size;
+ size_t content_size, context_size;
git_pool flattened;
};
@@ -806,6 +806,20 @@ notfound:
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)
{
return patch->diff;
@@ -934,7 +948,11 @@ static int diff_patch_line_cb(
line->len = content_len;
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 */
diff --git a/tests-clar/diff/patch.c b/tests-clar/diff/patch.c
index 3f14a0de7..51baadf2e 100644
--- a/tests-clar/diff/patch.c
+++ b/tests-clar/diff/patch.c
@@ -128,6 +128,9 @@ void test_diff_patch__to_string(void)
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_diff_patch_free(patch);
git_diff_list_free(diff);
@@ -409,6 +412,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
static void check_single_patch_stats(
git_repository *repo, size_t hunks,
size_t adds, size_t dels, size_t ctxt,
+ size_t size_with_context, size_t size_without_context,
const char *expected)
{
git_diff_list *diff;
@@ -439,6 +443,13 @@ static void check_single_patch_stats(
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 */
for (; hunks > 0; --hunks) {
size_t i, max_i;
@@ -495,14 +506,14 @@ void test_diff_patch__line_counts_with_eofnl(void)
git_buf_consume(&content, end);
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 */
git_buf_rtrim(&content);
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 */
@@ -514,7 +525,7 @@ void test_diff_patch__line_counts_with_eofnl(void)
cl_git_pass(git_buf_putc(&content, '\n'));
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 */
@@ -537,7 +548,7 @@ void test_diff_patch__line_counts_with_eofnl(void)
cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
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 */
"diff --git a/songof7cities.txt b/songof7cities.txt\n"
"index 378a7d9..3d0154e 100644\n"