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