1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 #ifndef INCLUDE_git_patch_h__
8 #define INCLUDE_git_patch_h__
9 
10 #include "common.h"
11 #include "types.h"
12 #include "oid.h"
13 #include "diff.h"
14 
15 /**
16  * @file git2/patch.h
17  * @brief Patch handling routines.
18  * @ingroup Git
19  * @{
20  */
21 GIT_BEGIN_DECL
22 
23 /**
24  * The diff patch is used to store all the text diffs for a delta.
25  *
26  * You can easily loop over the content of patches and get information about
27  * them.
28  */
29 typedef struct git_patch git_patch;
30 
31 /**
32  * Get the repository associated with this patch. May be NULL.
33  *
34  * @param patch the patch
35  * @return a pointer to the repository
36  */
37 GIT_EXTERN(git_repository *) git_patch_owner(const git_patch *patch);
38 
39 /**
40  * Return a patch for an entry in the diff list.
41  *
42  * The `git_patch` is a newly created object contains the text diffs
43  * for the delta.  You have to call `git_patch_free()` when you are
44  * done with it.  You can use the patch object to loop over all the hunks
45  * and lines in the diff of the one delta.
46  *
47  * For an unchanged file or a binary file, no `git_patch` will be
48  * created, the output will be set to NULL, and the `binary` flag will be
49  * set true in the `git_diff_delta` structure.
50  *
51  * It is okay to pass NULL for either of the output parameters; if you pass
52  * NULL for the `git_patch`, then the text diff will not be calculated.
53  *
54  * @param out Output parameter for the delta patch object
55  * @param diff Diff list object
56  * @param idx Index into diff list
57  * @return 0 on success, other value < 0 on error
58  */
59 GIT_EXTERN(int) git_patch_from_diff(
60 	git_patch **out, git_diff *diff, size_t idx);
61 
62 /**
63  * Directly generate a patch from the difference between two blobs.
64  *
65  * This is just like `git_diff_blobs()` except it generates a patch object
66  * for the difference instead of directly making callbacks.  You can use the
67  * standard `git_patch` accessor functions to read the patch data, and
68  * you must call `git_patch_free()` on the patch when done.
69  *
70  * @param out The generated patch; NULL on error
71  * @param old_blob Blob for old side of diff, or NULL for empty blob
72  * @param old_as_path Treat old blob as if it had this filename; can be NULL
73  * @param new_blob Blob for new side of diff, or NULL for empty blob
74  * @param new_as_path Treat new blob as if it had this filename; can be NULL
75  * @param opts Options for diff, or NULL for default options
76  * @return 0 on success or error code < 0
77  */
78 GIT_EXTERN(int) git_patch_from_blobs(
79 	git_patch **out,
80 	const git_blob *old_blob,
81 	const char *old_as_path,
82 	const git_blob *new_blob,
83 	const char *new_as_path,
84 	const git_diff_options *opts);
85 
86 /**
87  * Directly generate a patch from the difference between a blob and a buffer.
88  *
89  * This is just like `git_diff_blob_to_buffer()` except it generates a patch
90  * object for the difference instead of directly making callbacks.  You can
91  * use the standard `git_patch` accessor functions to read the patch
92  * data, and you must call `git_patch_free()` on the patch when done.
93  *
94  * @param out The generated patch; NULL on error
95  * @param old_blob Blob for old side of diff, or NULL for empty blob
96  * @param old_as_path Treat old blob as if it had this filename; can be NULL
97  * @param buffer Raw data for new side of diff, or NULL for empty
98  * @param buffer_len Length of raw data for new side of diff
99  * @param buffer_as_path Treat buffer as if it had this filename; can be NULL
100  * @param opts Options for diff, or NULL for default options
101  * @return 0 on success or error code < 0
102  */
103 GIT_EXTERN(int) git_patch_from_blob_and_buffer(
104 	git_patch **out,
105 	const git_blob *old_blob,
106 	const char *old_as_path,
107 	const void *buffer,
108 	size_t buffer_len,
109 	const char *buffer_as_path,
110 	const git_diff_options *opts);
111 
112 /**
113  * Directly generate a patch from the difference between two buffers.
114  *
115  * This is just like `git_diff_buffers()` except it generates a patch
116  * object for the difference instead of directly making callbacks.  You can
117  * use the standard `git_patch` accessor functions to read the patch
118  * data, and you must call `git_patch_free()` on the patch when done.
119  *
120  * @param out The generated patch; NULL on error
121  * @param old_buffer Raw data for old side of diff, or NULL for empty
122  * @param old_len Length of the raw data for old side of the diff
123  * @param old_as_path Treat old buffer as if it had this filename; can be NULL
124  * @param new_buffer Raw data for new side of diff, or NULL for empty
125  * @param new_len Length of raw data for new side of diff
126  * @param new_as_path Treat buffer as if it had this filename; can be NULL
127  * @param opts Options for diff, or NULL for default options
128  * @return 0 on success or error code < 0
129  */
130 GIT_EXTERN(int) git_patch_from_buffers(
131 	git_patch **out,
132 	const void *old_buffer,
133 	size_t old_len,
134 	const char *old_as_path,
135 	const void *new_buffer,
136 	size_t new_len,
137 	const char *new_as_path,
138 	const git_diff_options *opts);
139 
140 /**
141  * Free a git_patch object.
142  */
143 GIT_EXTERN(void) git_patch_free(git_patch *patch);
144 
145 /**
146  * Get the delta associated with a patch.  This delta points to internal
147  * data and you do not have to release it when you are done with it.
148  */
149 GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(const git_patch *patch);
150 
151 /**
152  * Get the number of hunks in a patch
153  */
154 GIT_EXTERN(size_t) git_patch_num_hunks(const git_patch *patch);
155 
156 /**
157  * Get line counts of each type in a patch.
158  *
159  * This helps imitate a diff --numstat type of output.  For that purpose,
160  * you only need the `total_additions` and `total_deletions` values, but we
161  * include the `total_context` line count in case you want the total number
162  * of lines of diff output that will be generated.
163  *
164  * All outputs are optional. Pass NULL if you don't need a particular count.
165  *
166  * @param total_context Count of context lines in output, can be NULL.
167  * @param total_additions Count of addition lines in output, can be NULL.
168  * @param total_deletions Count of deletion lines in output, can be NULL.
169  * @param patch The git_patch object
170  * @return 0 on success, <0 on error
171  */
172 GIT_EXTERN(int) git_patch_line_stats(
173 	size_t *total_context,
174 	size_t *total_additions,
175 	size_t *total_deletions,
176 	const git_patch *patch);
177 
178 /**
179  * Get the information about a hunk in a patch
180  *
181  * Given a patch and a hunk index into the patch, this returns detailed
182  * information about that hunk.  Any of the output pointers can be passed
183  * as NULL if you don't care about that particular piece of information.
184  *
185  * @param out Output pointer to git_diff_hunk of hunk
186  * @param lines_in_hunk Output count of total lines in this hunk
187  * @param patch Input pointer to patch object
188  * @param hunk_idx Input index of hunk to get information about
189  * @return 0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error
190  */
191 GIT_EXTERN(int) git_patch_get_hunk(
192 	const git_diff_hunk **out,
193 	size_t *lines_in_hunk,
194 	git_patch *patch,
195 	size_t hunk_idx);
196 
197 /**
198  * Get the number of lines in a hunk.
199  *
200  * @param patch The git_patch object
201  * @param hunk_idx Index of the hunk
202  * @return Number of lines in hunk or GIT_ENOTFOUND if invalid hunk index
203  */
204 GIT_EXTERN(int) git_patch_num_lines_in_hunk(
205 	const git_patch *patch,
206 	size_t hunk_idx);
207 
208 /**
209  * Get data about a line in a hunk of a patch.
210  *
211  * Given a patch, a hunk index, and a line index in the hunk, this
212  * will return a lot of details about that line.  If you pass a hunk
213  * index larger than the number of hunks or a line index larger than
214  * the number of lines in the hunk, this will return -1.
215  *
216  * @param out The git_diff_line data for this line
217  * @param patch The patch to look in
218  * @param hunk_idx The index of the hunk
219  * @param line_of_hunk The index of the line in the hunk
220  * @return 0 on success, <0 on failure
221  */
222 GIT_EXTERN(int) git_patch_get_line_in_hunk(
223 	const git_diff_line **out,
224 	git_patch *patch,
225 	size_t hunk_idx,
226 	size_t line_of_hunk);
227 
228 /**
229  * Look up size of patch diff data in bytes
230  *
231  * This returns the raw size of the patch data.  This only includes the
232  * actual data from the lines of the diff, not the file or hunk headers.
233  *
234  * If you pass `include_context` as true (non-zero), this will be the size
235  * of all of the diff output; if you pass it as false (zero), this will
236  * only include the actual changed lines (as if `context_lines` was 0).
237  *
238  * @param patch A git_patch representing changes to one file
239  * @param include_context Include context lines in size if non-zero
240  * @param include_hunk_headers Include hunk header lines if non-zero
241  * @param include_file_headers Include file header lines if non-zero
242  * @return The number of bytes of data
243  */
244 GIT_EXTERN(size_t) git_patch_size(
245 	git_patch *patch,
246 	int include_context,
247 	int include_hunk_headers,
248 	int include_file_headers);
249 
250 /**
251  * Serialize the patch to text via callback.
252  *
253  * Returning a non-zero value from the callback will terminate the iteration
254  * and return that value to the caller.
255  *
256  * @param patch A git_patch representing changes to one file
257  * @param print_cb Callback function to output lines of the patch.  Will be
258  *                 called for file headers, hunk headers, and diff lines.
259  * @param payload Reference pointer that will be passed to your callbacks.
260  * @return 0 on success, non-zero callback return value, or error code
261  */
262 GIT_EXTERN(int) git_patch_print(
263 	git_patch *patch,
264 	git_diff_line_cb print_cb,
265 	void *payload);
266 
267 /**
268  * Get the content of a patch as a single diff text.
269  *
270  * @param out The git_buf to be filled in
271  * @param patch A git_patch representing changes to one file
272  * @return 0 on success, <0 on failure.
273  */
274 GIT_EXTERN(int) git_patch_to_buf(
275 	git_buf *out,
276 	git_patch *patch);
277 
278 GIT_END_DECL
279 
280 /**@}*/
281 
282 #endif
283