]>
Commit | Line | Data |
---|---|---|
cd33323b RB |
1 | /* |
2 | * Copyright (C) 2009-2012 the libgit2 contributors | |
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_diff_h__ | |
8 | #define INCLUDE_git_diff_h__ | |
9 | ||
10 | #include "common.h" | |
11 | #include "types.h" | |
12 | #include "oid.h" | |
13 | #include "tree.h" | |
14 | #include "refs.h" | |
15 | ||
16 | /** | |
17 | * @file git2/diff.h | |
18 | * @brief Git tree and file differencing routines. | |
3a437590 RB |
19 | * |
20 | * Calculating diffs is generally done in two phases: building a diff list | |
21 | * then traversing the diff list. This makes is easier to share logic | |
22 | * across the various types of diffs (tree vs tree, workdir vs index, etc.), | |
23 | * and also allows you to insert optional diff list post-processing phases, | |
24 | * such as rename detected, in between the steps. When you are done with a | |
25 | * diff list object, it must be freed. | |
26 | * | |
cd33323b RB |
27 | * @ingroup Git |
28 | * @{ | |
29 | */ | |
30 | GIT_BEGIN_DECL | |
31 | ||
145e696b RB |
32 | /** |
33 | * Flags for diff options. A combination of these flags can be passed | |
34 | * in via the `flags` value in the `git_diff_options`. | |
35 | */ | |
a2e895be RB |
36 | enum { |
37 | GIT_DIFF_NORMAL = 0, | |
38 | GIT_DIFF_REVERSE = (1 << 0), | |
39 | GIT_DIFF_FORCE_TEXT = (1 << 1), | |
40 | GIT_DIFF_IGNORE_WHITESPACE = (1 << 2), | |
41 | GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3), | |
42 | GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4), | |
43 | GIT_DIFF_IGNORE_SUBMODULES = (1 << 5), | |
74fa4bfa RB |
44 | GIT_DIFF_PATIENCE = (1 << 6), |
45 | GIT_DIFF_INCLUDE_IGNORED = (1 << 7), | |
66142ae0 | 46 | GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), |
4b136a94 RB |
47 | GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), |
48 | GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), | |
a1773f9d | 49 | GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11), |
a2e895be RB |
50 | }; |
51 | ||
3a437590 RB |
52 | /** |
53 | * Structure describing options about how the diff should be executed. | |
54 | * | |
a2e895be RB |
55 | * Setting all values of the structure to zero will yield the default |
56 | * values. Similarly, passing NULL for the options structure will | |
57 | * give the defaults. The default values are marked below. | |
58 | * | |
e597b189 RB |
59 | * - flags: a combination of the GIT_DIFF_... values above |
60 | * - context_lines: number of lines of context to show around diffs | |
61 | * - interhunk_lines: min lines between diff hunks to merge them | |
62 | * - old_prefix: "directory" to prefix to old file names (default "a") | |
63 | * - new_prefix: "directory" to prefix to new file names (default "b") | |
64 | * - pathspec: array of paths / patterns to constrain diff | |
65 | * - max_size: maximum blob size to diff, above this treated as binary | |
3a437590 | 66 | */ |
65b09b1d | 67 | typedef struct { |
a2e895be RB |
68 | uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */ |
69 | uint16_t context_lines; /**< defaults to 3 */ | |
29f9186d | 70 | uint16_t interhunk_lines; /**< defaults to 0 */ |
2de60205 RB |
71 | char *old_prefix; /**< defaults to "a" */ |
72 | char *new_prefix; /**< defaults to "b" */ | |
a2e895be | 73 | git_strarray pathspec; /**< defaults to show all paths */ |
e597b189 | 74 | git_off_t max_size; /**< defaults to 512Mb */ |
65b09b1d RB |
75 | } git_diff_options; |
76 | ||
3a437590 RB |
77 | /** |
78 | * The diff list object that contains all individual file deltas. | |
79 | */ | |
80 | typedef struct git_diff_list git_diff_list; | |
81 | ||
1f35e89d RB |
82 | /** |
83 | * Flags that can be set for the file on side of a diff. | |
84 | * | |
85 | * Most of the flags are just for internal consumption by libgit2, | |
86 | * but some of them may be interesting to external users. They are: | |
87 | * | |
88 | * - VALID_OID - the `oid` value is computed and correct | |
89 | * - FREE_PATH - the `path` string is separated allocated memory | |
90 | * - BINARY - this file should be considered binary data | |
91 | * - NOT_BINARY - this file should be considered text data | |
92 | * - FREE_DATA - the internal file data is kept in allocated memory | |
93 | * - UNMAP_DATA - the internal file data is kept in mmap'ed memory | |
94 | * - NO_DATA - this side of the diff should not be loaded | |
95 | */ | |
74fa4bfa RB |
96 | enum { |
97 | GIT_DIFF_FILE_VALID_OID = (1 << 0), | |
98 | GIT_DIFF_FILE_FREE_PATH = (1 << 1), | |
99 | GIT_DIFF_FILE_BINARY = (1 << 2), | |
100 | GIT_DIFF_FILE_NOT_BINARY = (1 << 3), | |
5f69a31f RB |
101 | GIT_DIFF_FILE_FREE_DATA = (1 << 4), |
102 | GIT_DIFF_FILE_UNMAP_DATA = (1 << 5), | |
103 | GIT_DIFF_FILE_NO_DATA = (1 << 6), | |
74fa4bfa RB |
104 | }; |
105 | ||
e1bcc191 RB |
106 | /** |
107 | * What type of change is described by a git_diff_delta? | |
108 | */ | |
109 | typedef enum { | |
110 | GIT_DELTA_UNMODIFIED = 0, | |
111 | GIT_DELTA_ADDED = 1, | |
112 | GIT_DELTA_DELETED = 2, | |
113 | GIT_DELTA_MODIFIED = 3, | |
114 | GIT_DELTA_RENAMED = 4, | |
115 | GIT_DELTA_COPIED = 5, | |
116 | GIT_DELTA_IGNORED = 6, | |
117 | GIT_DELTA_UNTRACKED = 7 | |
118 | } git_delta_t; | |
119 | ||
74fa4bfa RB |
120 | /** |
121 | * Description of one side of a diff. | |
122 | */ | |
123 | typedef struct { | |
124 | git_oid oid; | |
bae957b9 | 125 | const char *path; |
74fa4bfa RB |
126 | git_off_t size; |
127 | unsigned int flags; | |
3f035860 | 128 | uint16_t mode; |
74fa4bfa RB |
129 | } git_diff_file; |
130 | ||
3a437590 RB |
131 | /** |
132 | * Description of changes to one file. | |
133 | * | |
134 | * When iterating over a diff list object, this will generally be passed to | |
135 | * most callback functions and you can use the contents to understand | |
136 | * exactly what has changed. | |
137 | * | |
138 | * Under some circumstances, not all fields will be filled in, but the code | |
139 | * generally tries to fill in as much as possible. One example is that the | |
140 | * "binary" field will not actually look at file contents if you do not | |
141 | * pass in hunk and/or line callbacks to the diff foreach iteration function. | |
142 | * It will just use the git attributes for those files. | |
143 | */ | |
65b09b1d | 144 | typedef struct { |
2de60205 RB |
145 | git_diff_file old_file; |
146 | git_diff_file new_file; | |
e1bcc191 | 147 | git_delta_t status; |
2de60205 RB |
148 | unsigned int similarity; /**< for RENAMED and COPIED, value 0-100 */ |
149 | int binary; | |
65b09b1d RB |
150 | } git_diff_delta; |
151 | ||
3a437590 RB |
152 | /** |
153 | * When iterating over a diff, callback that will be made per file. | |
154 | */ | |
cd33323b RB |
155 | typedef int (*git_diff_file_fn)( |
156 | void *cb_data, | |
bae957b9 | 157 | const git_diff_delta *delta, |
65b09b1d RB |
158 | float progress); |
159 | ||
3a437590 RB |
160 | /** |
161 | * Structure describing a hunk of a diff. | |
162 | */ | |
65b09b1d RB |
163 | typedef struct { |
164 | int old_start; | |
165 | int old_lines; | |
166 | int new_start; | |
167 | int new_lines; | |
168 | } git_diff_range; | |
cd33323b | 169 | |
3a437590 RB |
170 | /** |
171 | * When iterating over a diff, callback that will be made per hunk. | |
172 | */ | |
cd33323b RB |
173 | typedef int (*git_diff_hunk_fn)( |
174 | void *cb_data, | |
bae957b9 RB |
175 | const git_diff_delta *delta, |
176 | const git_diff_range *range, | |
65b09b1d RB |
177 | const char *header, |
178 | size_t header_len); | |
cd33323b | 179 | |
3a437590 RB |
180 | /** |
181 | * Line origin constants. | |
182 | * | |
183 | * These values describe where a line came from and will be passed to | |
1d2dd864 | 184 | * the git_diff_data_fn when iterating over a diff. There are some |
d73c94b2 | 185 | * special origin constants at the end that are used for the text |
3a437590 RB |
186 | * output callbacks to demarcate lines that are actually part of |
187 | * the file or hunk headers. | |
188 | */ | |
189 | enum { | |
145e696b | 190 | /* These values will be sent to `git_diff_data_fn` along with the line */ |
3a437590 RB |
191 | GIT_DIFF_LINE_CONTEXT = ' ', |
192 | GIT_DIFF_LINE_ADDITION = '+', | |
193 | GIT_DIFF_LINE_DELETION = '-', | |
1f35e89d | 194 | GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< Removed line w/o LF & added one with */ |
3a437590 | 195 | GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */ |
145e696b RB |
196 | |
197 | /* The following values will only be sent to a `git_diff_data_fn` when | |
198 | * the content of a diff is being formatted (eg. through | |
199 | * git_diff_print_patch() or git_diff_print_compact(), for instance). | |
1d2dd864 | 200 | */ |
3a437590 RB |
201 | GIT_DIFF_LINE_FILE_HDR = 'F', |
202 | GIT_DIFF_LINE_HUNK_HDR = 'H', | |
203 | GIT_DIFF_LINE_BINARY = 'B' | |
204 | }; | |
cd33323b | 205 | |
3a437590 RB |
206 | /** |
207 | * When iterating over a diff, callback that will be made per text diff | |
1d2dd864 | 208 | * line. In this context, the provided range will be NULL. |
209 | * | |
3a437590 RB |
210 | * When printing a diff, callback that will be made to output each line |
211 | * of text. This uses some extra GIT_DIFF_LINE_... constants for output | |
212 | * of lines of file and hunk headers. | |
213 | */ | |
1d2dd864 | 214 | typedef int (*git_diff_data_fn)( |
3a437590 | 215 | void *cb_data, |
bae957b9 RB |
216 | const git_diff_delta *delta, |
217 | const git_diff_range *range, | |
3a437590 | 218 | char line_origin, /**< GIT_DIFF_LINE_... value from above */ |
1d2dd864 | 219 | const char *content, |
220 | size_t content_len); | |
3a437590 | 221 | |
f335ecd6 | 222 | /** |
9a12a625 RB |
223 | * The diff patch is used to store all the text diffs for a delta. |
224 | * | |
225 | * You can easily loop over the content of patches and get information about | |
226 | * them. | |
f335ecd6 | 227 | */ |
9a12a625 RB |
228 | typedef struct git_diff_patch git_diff_patch; |
229 | ||
f335ecd6 | 230 | |
3a437590 RB |
231 | /** @name Diff List Generator Functions |
232 | * | |
233 | * These are the functions you would use to create (or destroy) a | |
234 | * git_diff_list from various objects in a repository. | |
65b09b1d | 235 | */ |
3a437590 | 236 | /**@{*/ |
cd33323b | 237 | |
74fa4bfa RB |
238 | /** |
239 | * Deallocate a diff list. | |
240 | */ | |
241 | GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff); | |
242 | ||
3a437590 RB |
243 | /** |
244 | * Compute a difference between two tree objects. | |
74fa4bfa | 245 | * |
145e696b RB |
246 | * This is equivalent to `git diff <treeish> <treeish>` |
247 | * | |
74fa4bfa RB |
248 | * @param repo The repository containing the trees. |
249 | * @param opts Structure with options to influence diff or NULL for defaults. | |
2de60205 RB |
250 | * @param old_tree A git_tree object to diff from. |
251 | * @param new_tree A git_tree object to diff to. | |
74fa4bfa | 252 | * @param diff A pointer to a git_diff_list pointer that will be allocated. |
3a437590 | 253 | */ |
65b09b1d | 254 | GIT_EXTERN(int) git_diff_tree_to_tree( |
cd33323b | 255 | git_repository *repo, |
a2e895be | 256 | const git_diff_options *opts, /**< can be NULL for defaults */ |
2de60205 RB |
257 | git_tree *old_tree, |
258 | git_tree *new_tree, | |
65b09b1d | 259 | git_diff_list **diff); |
cd33323b | 260 | |
3a437590 RB |
261 | /** |
262 | * Compute a difference between a tree and the index. | |
74fa4bfa | 263 | * |
145e696b RB |
264 | * This is equivalent to `git diff --cached <treeish>` or if you pass |
265 | * the HEAD tree, then like `git diff --cached`. | |
266 | * | |
74fa4bfa RB |
267 | * @param repo The repository containing the tree and index. |
268 | * @param opts Structure with options to influence diff or NULL for defaults. | |
2de60205 | 269 | * @param old_tree A git_tree object to diff from. |
74fa4bfa | 270 | * @param diff A pointer to a git_diff_list pointer that will be allocated. |
3a437590 | 271 | */ |
65b09b1d | 272 | GIT_EXTERN(int) git_diff_index_to_tree( |
cd33323b | 273 | git_repository *repo, |
a2e895be | 274 | const git_diff_options *opts, /**< can be NULL for defaults */ |
2de60205 | 275 | git_tree *old_tree, |
65b09b1d | 276 | git_diff_list **diff); |
cd33323b | 277 | |
3a437590 | 278 | /** |
74fa4bfa RB |
279 | * Compute a difference between the working directory and the index. |
280 | * | |
145e696b RB |
281 | * This matches the `git diff` command. See the note below on |
282 | * `git_diff_workdir_to_tree` for a discussion of the difference between | |
283 | * `git diff` and `git diff HEAD` and how to emulate a `git diff <treeish>` | |
284 | * using libgit2. | |
285 | * | |
74fa4bfa RB |
286 | * @param repo The repository. |
287 | * @param opts Structure with options to influence diff or NULL for defaults. | |
288 | * @param diff A pointer to a git_diff_list pointer that will be allocated. | |
3a437590 | 289 | */ |
74fa4bfa | 290 | GIT_EXTERN(int) git_diff_workdir_to_index( |
cd33323b | 291 | git_repository *repo, |
a2e895be | 292 | const git_diff_options *opts, /**< can be NULL for defaults */ |
65b09b1d | 293 | git_diff_list **diff); |
cd33323b | 294 | |
3a437590 | 295 | /** |
74fa4bfa RB |
296 | * Compute a difference between the working directory and a tree. |
297 | * | |
145e696b RB |
298 | * This is *NOT* the same as `git diff <treeish>`. Running `git diff HEAD` |
299 | * or the like actually uses information from the index, along with the tree | |
300 | * and workdir dir info. | |
74fa4bfa | 301 | * |
145e696b RB |
302 | * This function returns strictly the differences between the tree and the |
303 | * files contained in the working directory, regardless of the state of | |
304 | * files in the index. It may come as a surprise, but there is no direct | |
305 | * equivalent in core git. | |
306 | * | |
307 | * To emulate `git diff <treeish>`, you should call both | |
308 | * `git_diff_index_to_tree` and `git_diff_workdir_to_index`, then call | |
309 | * `git_diff_merge` on the results. That will yield a `git_diff_list` that | |
310 | * matches the git output. | |
311 | * | |
312 | * If this seems confusing, take the case of a file with a staged deletion | |
313 | * where the file has then been put back into the working dir and modified. | |
314 | * The tree-to-workdir diff for that file is 'modified', but core git would | |
315 | * show status 'deleted' since there is a pending deletion in the index. | |
74fa4bfa RB |
316 | * |
317 | * @param repo The repository containing the tree. | |
318 | * @param opts Structure with options to influence diff or NULL for defaults. | |
2de60205 | 319 | * @param old_tree A git_tree object to diff from. |
74fa4bfa | 320 | * @param diff A pointer to a git_diff_list pointer that will be allocated. |
3a437590 | 321 | */ |
74fa4bfa | 322 | GIT_EXTERN(int) git_diff_workdir_to_tree( |
cd33323b | 323 | git_repository *repo, |
a2e895be | 324 | const git_diff_options *opts, /**< can be NULL for defaults */ |
2de60205 | 325 | git_tree *old_tree, |
65b09b1d | 326 | git_diff_list **diff); |
cd33323b | 327 | |
3a437590 | 328 | /** |
74fa4bfa RB |
329 | * Merge one diff list into another. |
330 | * | |
331 | * This merges items from the "from" list into the "onto" list. The | |
332 | * resulting diff list will have all items that appear in either list. | |
333 | * If an item appears in both lists, then it will be "merged" to appear | |
334 | * as if the old version was from the "onto" list and the new version | |
335 | * is from the "from" list (with the exception that if the item has a | |
336 | * pending DELETE in the middle, then it will show as deleted). | |
337 | * | |
338 | * @param onto Diff to merge into. | |
339 | * @param from Diff to merge. | |
3a437590 | 340 | */ |
74fa4bfa RB |
341 | GIT_EXTERN(int) git_diff_merge( |
342 | git_diff_list *onto, | |
343 | const git_diff_list *from); | |
65b09b1d | 344 | |
3a437590 RB |
345 | /**@}*/ |
346 | ||
347 | ||
348 | /** @name Diff List Processor Functions | |
349 | * | |
350 | * These are the functions you apply to a diff list to process it | |
351 | * or read it in some way. | |
cd33323b | 352 | */ |
3a437590 | 353 | /**@{*/ |
65b09b1d | 354 | |
510f1bac | 355 | /** |
9a12a625 | 356 | * Loop over all deltas in a diff list issuing callbacks. |
510f1bac RB |
357 | * |
358 | * This will iterate through all of the files described in a diff. You | |
359 | * should provide a file callback to learn about each file. | |
360 | * | |
361 | * The "hunk" and "line" callbacks are optional, and the text diff of the | |
362 | * files will only be calculated if they are not NULL. Of course, these | |
363 | * callbacks will not be invoked for binary files on the diff list or for | |
364 | * files whose only changed is a file mode change. | |
365 | * | |
366 | * Returning a non-zero value from any of the callbacks will terminate | |
367 | * the iteration and cause this return `GIT_EUSER`. | |
368 | * | |
369 | * @param diff A git_diff_list generated by one of the above functions. | |
370 | * @param cb_data Reference pointer that will be passed to your callbacks. | |
371 | * @param file_cb Callback function to make per file in the diff. | |
372 | * @param hunk_cb Optional callback to make per hunk of text diff. This | |
373 | * callback is called to describe a range of lines in the | |
374 | * diff. It will not be issued for binary files. | |
375 | * @param line_cb Optional callback to make per line of diff text. This | |
376 | * same callback will be made for context lines, added, and | |
377 | * removed lines, and even for a deleted trailing newline. | |
378 | * @return 0 on success, GIT_EUSER on non-zero callback, or error code | |
379 | */ | |
380 | GIT_EXTERN(int) git_diff_foreach( | |
381 | git_diff_list *diff, | |
382 | void *cb_data, | |
383 | git_diff_file_fn file_cb, | |
384 | git_diff_hunk_fn hunk_cb, | |
385 | git_diff_data_fn line_cb); | |
386 | ||
3a437590 RB |
387 | /** |
388 | * Iterate over a diff generating text output like "git diff --name-status". | |
5dca2010 RB |
389 | * |
390 | * Returning a non-zero value from the callbacks will terminate the | |
391 | * iteration and cause this return `GIT_EUSER`. | |
392 | * | |
393 | * @param diff A git_diff_list generated by one of the above functions. | |
394 | * @param cb_data Reference pointer that will be passed to your callback. | |
395 | * @param print_cb Callback to make per line of diff text. | |
396 | * @return 0 on success, GIT_EUSER on non-zero callback, or error code | |
3a437590 | 397 | */ |
65b09b1d | 398 | GIT_EXTERN(int) git_diff_print_compact( |
3a437590 RB |
399 | git_diff_list *diff, |
400 | void *cb_data, | |
1d2dd864 | 401 | git_diff_data_fn print_cb); |
65b09b1d | 402 | |
64286308 RB |
403 | /** |
404 | * Look up the single character abbreviation for a delta status code. | |
405 | * | |
406 | * When you call `git_diff_print_compact` it prints single letter codes into | |
407 | * the output such as 'A' for added, 'D' for deleted, 'M' for modified, etc. | |
408 | * It is sometimes convenient to convert a git_delta_t value into these | |
409 | * letters for your own purposes. This function does just that. By the | |
410 | * way, unmodified will return a space (i.e. ' '). | |
411 | * | |
412 | * @param delta_t The git_delta_t value to look up | |
413 | * @return The single character label for that code | |
414 | */ | |
415 | GIT_EXTERN(char) git_diff_status_char(git_delta_t status); | |
416 | ||
3a437590 RB |
417 | /** |
418 | * Iterate over a diff generating text output like "git diff". | |
419 | * | |
420 | * This is a super easy way to generate a patch from a diff. | |
145e696b | 421 | * |
5dca2010 RB |
422 | * Returning a non-zero value from the callbacks will terminate the |
423 | * iteration and cause this return `GIT_EUSER`. | |
424 | * | |
145e696b RB |
425 | * @param diff A git_diff_list generated by one of the above functions. |
426 | * @param cb_data Reference pointer that will be passed to your callbacks. | |
427 | * @param print_cb Callback function to output lines of the diff. This | |
428 | * same function will be called for file headers, hunk | |
429 | * headers, and diff lines. Fortunately, you can probably | |
430 | * use various GIT_DIFF_LINE constants to determine what | |
431 | * text you are given. | |
5dca2010 | 432 | * @return 0 on success, GIT_EUSER on non-zero callback, or error code |
3a437590 | 433 | */ |
65b09b1d | 434 | GIT_EXTERN(int) git_diff_print_patch( |
3a437590 RB |
435 | git_diff_list *diff, |
436 | void *cb_data, | |
1d2dd864 | 437 | git_diff_data_fn print_cb); |
3a437590 | 438 | |
5f4a61ae RB |
439 | /** |
440 | * Query how many diff records are there in a diff list. | |
441 | * | |
9a12a625 RB |
442 | * @param diff A git_diff_list generated by one of the above functions |
443 | * @return Count of number of deltas in the list | |
444 | */ | |
5f69a31f | 445 | GIT_EXTERN(size_t) git_diff_num_deltas(git_diff_list *diff); |
9a12a625 RB |
446 | |
447 | /** | |
448 | * Query how many diff deltas are there in a diff list filtered by type. | |
449 | * | |
450 | * This works just like `git_diff_entrycount()` with an extra parameter | |
451 | * that is a `git_delta_t` and returns just the count of how many deltas | |
452 | * match that particular type. | |
5f4a61ae RB |
453 | * |
454 | * @param diff A git_diff_list generated by one of the above functions | |
9a12a625 | 455 | * @param type A git_delta_t value to filter the count |
5f4a61ae RB |
456 | * @return Count of number of deltas matching delta_t type |
457 | */ | |
5f69a31f | 458 | GIT_EXTERN(size_t) git_diff_num_deltas_of_type( |
5f4a61ae | 459 | git_diff_list *diff, |
9a12a625 RB |
460 | git_delta_t type); |
461 | ||
462 | /** | |
463 | * Return the diff delta and patch for an entry in the diff list. | |
464 | * | |
465 | * The `git_diff_patch` is a newly created object contains the text diffs | |
466 | * for the delta. You have to call `git_diff_patch_free()` when you are | |
467 | * done with it. You can use the patch object to loop over all the hunks | |
468 | * and lines in the diff of the one delta. | |
469 | * | |
64286308 RB |
470 | * For an unchanged file or a binary file, no `git_diff_patch` will be |
471 | * created, the output will be set to NULL, and the `binary` flag will be | |
472 | * set true in the `git_diff_delta` structure. | |
9a12a625 RB |
473 | * |
474 | * The `git_diff_delta` pointer points to internal data and you do not have | |
475 | * to release it when you are done with it. It will go away when the | |
476 | * `git_diff_list` and `git_diff_patch` go away. | |
477 | * | |
478 | * It is okay to pass NULL for either of the output parameters; if you pass | |
479 | * NULL for the `git_diff_patch`, then the text diff will not be calculated. | |
480 | * | |
481 | * @param patch Output parameter for the delta patch object | |
482 | * @param delta Output parameter for the delta object | |
483 | * @param diff Diff list object | |
484 | * @param idx Index into diff list | |
485 | * @return 0 on success, other value < 0 on error | |
486 | */ | |
487 | GIT_EXTERN(int) git_diff_get_patch( | |
488 | git_diff_patch **patch, | |
bae957b9 | 489 | const git_diff_delta **delta, |
9a12a625 RB |
490 | git_diff_list *diff, |
491 | size_t idx); | |
492 | ||
493 | /** | |
494 | * Free a git_diff_patch object. | |
495 | */ | |
496 | GIT_EXTERN(void) git_diff_patch_free( | |
497 | git_diff_patch *patch); | |
498 | ||
499 | /** | |
500 | * Get the delta associated with a patch | |
501 | */ | |
5f69a31f | 502 | GIT_EXTERN(const git_diff_delta *) git_diff_patch_delta( |
9a12a625 RB |
503 | git_diff_patch *patch); |
504 | ||
505 | /** | |
506 | * Get the number of hunks in a patch | |
507 | */ | |
5f69a31f | 508 | GIT_EXTERN(size_t) git_diff_patch_num_hunks( |
9a12a625 RB |
509 | git_diff_patch *patch); |
510 | ||
511 | /** | |
512 | * Get the information about a hunk in a patch | |
5f69a31f RB |
513 | * |
514 | * Given a patch and a hunk index into the patch, this returns detailed | |
515 | * information about that hunk. Any of the output pointers can be passed | |
516 | * as NULL if you don't care about that particular piece of information. | |
517 | * | |
518 | * @param range Output pointer to git_diff_range of hunk | |
519 | * @param header Output pointer to header string for hunk. Unlike the | |
520 | * content pointer for each line, this will be NUL-terminated | |
521 | * @param header_len Output value of characters in header string | |
522 | * @param lines_in_hunk Output count of total lines in this hunk | |
523 | * @param patch Input pointer to patch object | |
524 | * @param hunk_idx Input index of hunk to get information about | |
525 | * @return 0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error | |
9a12a625 RB |
526 | */ |
527 | GIT_EXTERN(int) git_diff_patch_get_hunk( | |
bae957b9 | 528 | const git_diff_range **range, |
9a12a625 RB |
529 | const char **header, |
530 | size_t *header_len, | |
531 | size_t *lines_in_hunk, | |
532 | git_diff_patch *patch, | |
5f69a31f | 533 | size_t hunk_idx); |
9a12a625 RB |
534 | |
535 | /** | |
5f69a31f RB |
536 | * Get the number of lines in a hunk. |
537 | * | |
538 | * @param patch The git_diff_patch object | |
539 | * @param hunk_idx Index of the hunk | |
540 | * @return Number of lines in hunk or -1 if invalid hunk index | |
9a12a625 | 541 | */ |
5f69a31f | 542 | GIT_EXTERN(int) git_diff_patch_num_lines_in_hunk( |
9a12a625 | 543 | git_diff_patch *patch, |
5f69a31f | 544 | size_t hunk_idx); |
9a12a625 RB |
545 | |
546 | /** | |
5f69a31f RB |
547 | * Get data about a line in a hunk of a patch. |
548 | * | |
549 | * Given a patch, a hunk index, and a line index in the hunk, this | |
550 | * will return a lot of details about that line. If you pass a hunk | |
551 | * index larger than the number of hunks or a line index larger than | |
552 | * the number of lines in the hunk, this will return -1. | |
553 | * | |
554 | * @param line_origin A GIT_DIFF_LINE constant from above | |
555 | * @param content Pointer to content of diff line, not NUL-terminated | |
556 | * @param content_len Number of characters in content | |
557 | * @param old_lineno Line number in old file or -1 if line is added | |
558 | * @param new_lineno Line number in new file or -1 if line is deleted | |
559 | * @param patch The patch to look in | |
560 | * @param hunk_idx The index of the hunk | |
561 | * @param line_of_index The index of the line in the hunk | |
562 | * @return 0 on success, <0 on failure | |
9a12a625 RB |
563 | */ |
564 | GIT_EXTERN(int) git_diff_patch_get_line_in_hunk( | |
565 | char *line_origin, | |
566 | const char **content, | |
567 | size_t *content_len, | |
5f69a31f RB |
568 | int *old_lineno, |
569 | int *new_lineno, | |
9a12a625 | 570 | git_diff_patch *patch, |
5f69a31f | 571 | size_t hunk_idx, |
9a12a625 | 572 | size_t line_of_hunk); |
5f4a61ae | 573 | |
3a437590 RB |
574 | /**@}*/ |
575 | ||
65b09b1d RB |
576 | |
577 | /* | |
578 | * Misc | |
cd33323b RB |
579 | */ |
580 | ||
3a437590 RB |
581 | /** |
582 | * Directly run a text diff on two blobs. | |
d1c4312a | 583 | * |
145e696b RB |
584 | * Compared to a file, a blob lacks some contextual information. As such, |
585 | * the `git_diff_file` parameters of the callbacks will be filled | |
586 | * accordingly to the following: `mode` will be set to 0, `path` will be set | |
587 | * to NULL. When dealing with a NULL blob, `oid` will be set to 0. | |
d1c4312a | 588 | * |
145e696b RB |
589 | * When at least one of the blobs being dealt with is binary, the |
590 | * `git_diff_delta` binary attribute will be set to 1 and no call to the | |
591 | * hunk_cb nor line_cb will be made. | |
5dca2010 RB |
592 | * |
593 | * @return 0 on success, GIT_EUSER on non-zero callback, or error code | |
3a437590 | 594 | */ |
65b09b1d | 595 | GIT_EXTERN(int) git_diff_blobs( |
2de60205 RB |
596 | git_blob *old_blob, |
597 | git_blob *new_blob, | |
bae957b9 | 598 | const git_diff_options *options, |
65b09b1d | 599 | void *cb_data, |
28ef7f9b | 600 | git_diff_file_fn file_cb, |
65b09b1d | 601 | git_diff_hunk_fn hunk_cb, |
1d2dd864 | 602 | git_diff_data_fn line_cb); |
65b09b1d | 603 | |
cd33323b RB |
604 | GIT_END_DECL |
605 | ||
606 | /** @} */ | |
607 | ||
608 | #endif |