1 #include "git2/patch.h"
6 int git_patch__invoke_callbacks(
8 git_diff_file_cb file_cb
,
9 git_diff_binary_cb binary_cb
,
10 git_diff_hunk_cb hunk_cb
,
11 git_diff_line_cb line_cb
,
18 error
= file_cb(patch
->delta
, 0, payload
);
20 if ((patch
->delta
->flags
& GIT_DIFF_FLAG_BINARY
) != 0) {
22 error
= binary_cb(patch
->delta
, &patch
->binary
, payload
);
27 if (!hunk_cb
&& !line_cb
)
30 for (i
= 0; !error
&& i
< git_array_size(patch
->hunks
); ++i
) {
31 git_patch_hunk
*h
= git_array_get(patch
->hunks
, i
);
34 error
= hunk_cb(patch
->delta
, &h
->hunk
, payload
);
39 for (j
= 0; !error
&& j
< h
->line_count
; ++j
) {
41 git_array_get(patch
->lines
, h
->line_start
+ j
);
43 error
= line_cb(patch
->delta
, &h
->hunk
, l
, payload
);
50 size_t git_patch_size(
53 int include_hunk_headers
,
54 int include_file_headers
)
60 out
= patch
->content_size
;
63 out
-= patch
->context_size
;
65 if (include_hunk_headers
)
66 out
+= patch
->header_size
;
68 if (include_file_headers
) {
69 git_buf file_header
= GIT_BUF_INIT
;
71 if (git_diff_delta__format_file_header(
72 &file_header
, patch
->delta
, NULL
, NULL
, 0) < 0)
75 out
+= git_buf_len(&file_header
);
77 git_buf_free(&file_header
);
83 int git_patch_line_stats(
87 const git_patch
*patch
)
89 size_t totals
[3], idx
;
91 memset(totals
, 0, sizeof(totals
));
93 for (idx
= 0; idx
< git_array_size(patch
->lines
); ++idx
) {
94 git_diff_line
*line
= git_array_get(patch
->lines
, idx
);
98 switch (line
->origin
) {
99 case GIT_DIFF_LINE_CONTEXT
: totals
[0]++; break;
100 case GIT_DIFF_LINE_ADDITION
: totals
[1]++; break;
101 case GIT_DIFF_LINE_DELETION
: totals
[2]++; break;
103 /* diff --stat and --numstat don't count EOFNL marks because
104 * they will always be paired with a ADDITION or DELETION line.
111 *total_ctxt
= totals
[0];
113 *total_adds
= totals
[1];
115 *total_dels
= totals
[2];
120 const git_diff_delta
*git_patch_get_delta(const git_patch
*patch
)
126 size_t git_patch_num_hunks(const git_patch
*patch
)
129 return git_array_size(patch
->hunks
);
132 static int patch_error_outofrange(const char *thing
)
134 giterr_set(GITERR_INVALID
, "patch %s index out of range", thing
);
135 return GIT_ENOTFOUND
;
138 int git_patch_get_hunk(
139 const git_diff_hunk
**out
,
140 size_t *lines_in_hunk
,
144 git_patch_hunk
*hunk
;
147 hunk
= git_array_get(patch
->hunks
, hunk_idx
);
150 if (out
) *out
= NULL
;
151 if (lines_in_hunk
) *lines_in_hunk
= 0;
152 return patch_error_outofrange("hunk");
155 if (out
) *out
= &hunk
->hunk
;
156 if (lines_in_hunk
) *lines_in_hunk
= hunk
->line_count
;
160 int git_patch_num_lines_in_hunk(const git_patch
*patch
, size_t hunk_idx
)
162 git_patch_hunk
*hunk
;
165 if (!(hunk
= git_array_get(patch
->hunks
, hunk_idx
)))
166 return patch_error_outofrange("hunk");
167 return (int)hunk
->line_count
;
170 int git_patch_get_line_in_hunk(
171 const git_diff_line
**out
,
176 git_patch_hunk
*hunk
;
181 if (!(hunk
= git_array_get(patch
->hunks
, hunk_idx
))) {
182 if (out
) *out
= NULL
;
183 return patch_error_outofrange("hunk");
186 if (line_of_hunk
>= hunk
->line_count
||
187 !(line
= git_array_get(
188 patch
->lines
, hunk
->line_start
+ line_of_hunk
))) {
189 if (out
) *out
= NULL
;
190 return patch_error_outofrange("line");
193 if (out
) *out
= line
;
197 static void git_patch__free(git_patch
*patch
)
200 patch
->free_fn(patch
);
203 void git_patch_free(git_patch
*patch
)
206 GIT_REFCOUNT_DEC(patch
, git_patch__free
);