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