diff options
author | Ben Straub <bs@github.com> | 2013-08-08 19:54:38 +0400 |
---|---|---|
committer | Ben Straub <bs@github.com> | 2013-08-08 19:54:38 +0400 |
commit | 5e96f31638fe71a0c76805b1352f437881791d98 (patch) | |
tree | 45c14d45f24bedd86b494ca76f1e4a26909de8cd /src/diff_patch.c | |
parent | bf145a6a2f08add441f55387e5ae7daef58187ae (diff) | |
parent | eb1c1707ab6a399734d9083152c05516af052412 (diff) |
Merge pull request #1738 from libgit2/diff-patch-content-size
Add API for getting at git_diff_patch->content_size
Diffstat (limited to 'src/diff_patch.c')
-rw-r--r-- | src/diff_patch.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/src/diff_patch.c b/src/diff_patch.c index 69bb08198..cc45b6ddb 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, header_size; git_pool flattened; }; @@ -810,6 +810,39 @@ notfound: return diff_error_outofrange(thing); } +size_t git_diff_patch_size( + git_diff_patch *patch, + int include_context, + int include_hunk_headers, + int include_file_headers) +{ + size_t out; + + assert(patch); + + out = patch->content_size; + + if (!include_context) + out -= patch->context_size; + + if (include_hunk_headers) + out += patch->header_size; + + if (include_file_headers) { + git_buf file_header = GIT_BUF_INIT; + + if (git_diff_delta__format_file_header( + &file_header, patch->delta, NULL, NULL, 0) < 0) + giterr_clear(); + else + out += git_buf_len(&file_header); + + git_buf_free(&file_header); + } + + return out; +} + git_diff_list *git_diff_patch__diff(git_diff_patch *patch) { return patch->diff; @@ -904,6 +937,8 @@ static int diff_patch_hunk_cb( hunk->header[header_len] = '\0'; hunk->header_len = header_len; + patch->header_size += header_len; + hunk->line_start = git_array_size(patch->lines); hunk->line_count = 0; @@ -924,6 +959,7 @@ static int diff_patch_line_cb( git_diff_patch *patch = payload; diff_patch_hunk *hunk; diff_patch_line *line; + const char *content_end = content + content_len; GIT_UNUSED(delta); GIT_UNUSED(range); @@ -938,34 +974,43 @@ static int diff_patch_line_cb( line->len = content_len; line->origin = line_origin; - patch->content_size += content_len; - /* do some bookkeeping so we can provide old/new line numbers */ - for (line->lines = 0; content_len > 0; --content_len) { + line->lines = 0; + while (content < content_end) if (*content++ == '\n') ++line->lines; - } + + patch->content_size += content_len; switch (line_origin) { case GIT_DIFF_LINE_ADDITION: + patch->content_size += 1; case GIT_DIFF_LINE_DEL_EOFNL: line->oldno = -1; line->newno = patch->newno; patch->newno += line->lines; break; case GIT_DIFF_LINE_DELETION: + patch->content_size += 1; case GIT_DIFF_LINE_ADD_EOFNL: line->oldno = patch->oldno; line->newno = -1; patch->oldno += line->lines; break; - default: + case GIT_DIFF_LINE_CONTEXT: + patch->content_size += 1; + patch->context_size += 1; + case GIT_DIFF_LINE_CONTEXT_EOFNL: + patch->context_size += content_len; line->oldno = patch->oldno; line->newno = patch->newno; patch->oldno += line->lines; patch->newno += line->lines; break; + default: + assert(false); + break; } hunk->line_count++; |