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.diff;
11 
12 
13 private static import libgit2.buffer;
14 private static import libgit2.oid;
15 private static import libgit2.strarray;
16 private static import libgit2.types;
17 private import libgit2.common: GIT_EXTERN;
18 
19 /*
20  * @file git2/diff.h
21  * @brief Git tree and file differencing routines.
22  * @ingroup Git
23  * @{
24  */
25 extern (C):
26 nothrow @nogc:
27 public:
28 
29 /**
30  * Flags for diff options.  A combination of these flags can be passed
31  * in via the `flags` value in the `git_diff_options`.
32  */
33 enum git_diff_option_t
34 {
35 	/**
36 	 * Normal diff, the default
37 	 */
38 	GIT_DIFF_NORMAL = 0,
39 
40 	/*
41 	 * Options controlling which files will be in the diff
42 	 */
43 
44 	/**
45 	 * Reverse the sides of the diff
46 	 */
47 	GIT_DIFF_REVERSE = 1u << 0,
48 
49 	/**
50 	 * Include ignored files in the diff
51 	 */
52 	GIT_DIFF_INCLUDE_IGNORED = 1u << 1,
53 
54 	/**
55 	 * Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
56 	 *  will be marked with only a single entry in the diff; this flag
57 	 *  adds all files under the directory as IGNORED entries, too.
58 	 */
59 	GIT_DIFF_RECURSE_IGNORED_DIRS = 1u << 2,
60 
61 	/**
62 	 * Include untracked files in the diff
63 	 */
64 	GIT_DIFF_INCLUDE_UNTRACKED = 1u << 3,
65 
66 	/**
67 	 * Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked
68 	 *  directory will be marked with only a single entry in the diff
69 	 *  (a la what core Git does in `git status`); this flag adds *all*
70 	 *  files under untracked directories as UNTRACKED entries, too.
71 	 */
72 	GIT_DIFF_RECURSE_UNTRACKED_DIRS = 1u << 4,
73 
74 	/**
75 	 * Include unmodified files in the diff
76 	 */
77 	GIT_DIFF_INCLUDE_UNMODIFIED = 1u << 5,
78 
79 	/**
80 	 * Normally, a type change between files will be converted into a
81 	 *  DELETED record for the old and an ADDED record for the new; this
82 	 *  options enabled the generation of TYPECHANGE delta records.
83 	 */
84 	GIT_DIFF_INCLUDE_TYPECHANGE = 1u << 6,
85 
86 	/**
87 	 * Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still
88 	 *  generally show as a DELETED blob.  This flag tries to correctly
89 	 *  label blob->tree transitions as TYPECHANGE records with new_file's
90 	 *  mode set to tree.  Note: the tree SHA will not be available.
91 	 */
92 	GIT_DIFF_INCLUDE_TYPECHANGE_TREES = 1u << 7,
93 
94 	/**
95 	 * Ignore file mode changes
96 	 */
97 	GIT_DIFF_IGNORE_FILEMODE = 1u << 8,
98 
99 	/**
100 	 * Treat all submodules as unmodified
101 	 */
102 	GIT_DIFF_IGNORE_SUBMODULES = 1u << 9,
103 
104 	/**
105 	 * Use case insensitive filename comparisons
106 	 */
107 	GIT_DIFF_IGNORE_CASE = 1u << 10,
108 
109 	/**
110 	 * May be combined with `GIT_DIFF_IGNORE_CASE` to specify that a file
111 	 *  that has changed case will be returned as an add/delete pair.
112 	 */
113 	GIT_DIFF_INCLUDE_CASECHANGE = 1u << 11,
114 
115 	/**
116 	 * If the pathspec is set in the diff options, this flags indicates
117 	 *  that the paths will be treated as literal paths instead of
118 	 *  fnmatch patterns.  Each path in the list must either be a full
119 	 *  path to a file or a directory.  (A trailing slash indicates that
120 	 *  the path will _only_ match a directory).  If a directory is
121 	 *  specified, all children will be included.
122 	 */
123 	GIT_DIFF_DISABLE_PATHSPEC_MATCH = 1u << 12,
124 
125 	/**
126 	 * Disable updating of the `binary` flag in delta records.  This is
127 	 *  useful when iterating over a diff if you don't need hunk and data
128 	 *  callbacks and want to avoid having to load file completely.
129 	 */
130 	GIT_DIFF_SKIP_BINARY_CHECK = 1u << 13,
131 
132 	/**
133 	 * When diff finds an untracked directory, to match the behavior of
134 	 *  core Git, it scans the contents for IGNORED and UNTRACKED files.
135 	 *  If *all* contents are IGNORED, then the directory is IGNORED; if
136 	 *  any contents are not IGNORED, then the directory is UNTRACKED.
137 	 *  This is extra work that may not matter in many cases.  This flag
138 	 *  turns off that scan and immediately labels an untracked directory
139 	 *  as UNTRACKED (changing the behavior to not match core Git).
140 	 */
141 	GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = 1u << 14,
142 
143 	/**
144 	 * When diff finds a file in the working directory with stat
145 	 * information different from the index, but the OID ends up being the
146 	 * same, write the correct stat information into the index.  Note:
147 	 * without this flag, diff will always leave the index untouched.
148 	 */
149 	GIT_DIFF_UPDATE_INDEX = 1u << 15,
150 
151 	/**
152 	 * Include unreadable files in the diff
153 	 */
154 	GIT_DIFF_INCLUDE_UNREADABLE = 1u << 16,
155 
156 	/**
157 	 * Include unreadable files in the diff
158 	 */
159 	GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED = 1u << 17,
160 
161 	/*
162 	 * Options controlling how output will be generated
163 	 */
164 
165 	/**
166 	 * Use a heuristic that takes indentation and whitespace into account
167 	 * which generally can produce better diffs when dealing with ambiguous
168 	 * diff hunks.
169 	 */
170 	GIT_DIFF_INDENT_HEURISTIC = 1u << 18,
171 
172 	/**
173 	 * Ignore blank lines
174 	 */
175 	GIT_DIFF_IGNORE_BLANK_LINES = 1u << 19,
176 
177 	/**
178 	 * Treat all files as text, disabling binary attributes & detection
179 	 */
180 	GIT_DIFF_FORCE_TEXT = 1u << 20,
181 
182 	/**
183 	 * Treat all files as binary, disabling text diffs
184 	 */
185 	GIT_DIFF_FORCE_BINARY = 1u << 21,
186 
187 	/**
188 	 * Ignore all whitespace
189 	 */
190 	GIT_DIFF_IGNORE_WHITESPACE = 1u << 22,
191 
192 	/**
193 	 * Ignore changes in amount of whitespace
194 	 */
195 	GIT_DIFF_IGNORE_WHITESPACE_CHANGE = 1u << 23,
196 
197 	/**
198 	 * Ignore whitespace at end of line
199 	 */
200 	GIT_DIFF_IGNORE_WHITESPACE_EOL = 1u << 24,
201 
202 	/**
203 	 * When generating patch text, include the content of untracked
204 	 *  files.  This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but
205 	 *  it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS.  Add that
206 	 *  flag if you want the content of every single UNTRACKED file.
207 	 */
208 	GIT_DIFF_SHOW_UNTRACKED_CONTENT = 1u << 25,
209 
210 	/**
211 	 * When generating output, include the names of unmodified files if
212 	 *  they are included in the git_diff.  Normally these are skipped in
213 	 *  the formats that list files (e.g. name-only, name-status, raw).
214 	 *  Even with this, these will not be included in patch format.
215 	 */
216 	GIT_DIFF_SHOW_UNMODIFIED = 1u << 26,
217 
218 	/**
219 	 * Use the "patience diff" algorithm
220 	 */
221 	GIT_DIFF_PATIENCE = 1u << 28,
222 
223 	/**
224 	 * Take extra time to find minimal diff
225 	 */
226 	GIT_DIFF_MINIMAL = 1u << 29,
227 
228 	/**
229 	 * Include the necessary deflate / delta information so that `git-apply`
230 	 *  can apply given diff information to binary files.
231 	 */
232 	GIT_DIFF_SHOW_BINARY = 1u << 30,
233 }
234 
235 //Declaration name in C language
236 enum
237 {
238 	GIT_DIFF_NORMAL = .git_diff_option_t.GIT_DIFF_NORMAL,
239 	GIT_DIFF_REVERSE = .git_diff_option_t.GIT_DIFF_REVERSE,
240 	GIT_DIFF_INCLUDE_IGNORED = .git_diff_option_t.GIT_DIFF_INCLUDE_IGNORED,
241 	GIT_DIFF_RECURSE_IGNORED_DIRS = .git_diff_option_t.GIT_DIFF_RECURSE_IGNORED_DIRS,
242 	GIT_DIFF_INCLUDE_UNTRACKED = .git_diff_option_t.GIT_DIFF_INCLUDE_UNTRACKED,
243 	GIT_DIFF_RECURSE_UNTRACKED_DIRS = .git_diff_option_t.GIT_DIFF_RECURSE_UNTRACKED_DIRS,
244 	GIT_DIFF_INCLUDE_UNMODIFIED = .git_diff_option_t.GIT_DIFF_INCLUDE_UNMODIFIED,
245 	GIT_DIFF_INCLUDE_TYPECHANGE = .git_diff_option_t.GIT_DIFF_INCLUDE_TYPECHANGE,
246 	GIT_DIFF_INCLUDE_TYPECHANGE_TREES = .git_diff_option_t.GIT_DIFF_INCLUDE_TYPECHANGE_TREES,
247 	GIT_DIFF_IGNORE_FILEMODE = .git_diff_option_t.GIT_DIFF_IGNORE_FILEMODE,
248 	GIT_DIFF_IGNORE_SUBMODULES = .git_diff_option_t.GIT_DIFF_IGNORE_SUBMODULES,
249 	GIT_DIFF_IGNORE_CASE = .git_diff_option_t.GIT_DIFF_IGNORE_CASE,
250 	GIT_DIFF_INCLUDE_CASECHANGE = .git_diff_option_t.GIT_DIFF_INCLUDE_CASECHANGE,
251 	GIT_DIFF_DISABLE_PATHSPEC_MATCH = .git_diff_option_t.GIT_DIFF_DISABLE_PATHSPEC_MATCH,
252 	GIT_DIFF_SKIP_BINARY_CHECK = .git_diff_option_t.GIT_DIFF_SKIP_BINARY_CHECK,
253 	GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = .git_diff_option_t.GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS,
254 	GIT_DIFF_UPDATE_INDEX = .git_diff_option_t.GIT_DIFF_UPDATE_INDEX,
255 	GIT_DIFF_INCLUDE_UNREADABLE = .git_diff_option_t.GIT_DIFF_INCLUDE_UNREADABLE,
256 	GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED = .git_diff_option_t.GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED,
257 	GIT_DIFF_INDENT_HEURISTIC = .git_diff_option_t.GIT_DIFF_INDENT_HEURISTIC,
258 	GIT_DIFF_IGNORE_BLANK_LINES = .git_diff_option_t.GIT_DIFF_IGNORE_BLANK_LINES,
259 	GIT_DIFF_FORCE_TEXT = .git_diff_option_t.GIT_DIFF_FORCE_TEXT,
260 	GIT_DIFF_FORCE_BINARY = .git_diff_option_t.GIT_DIFF_FORCE_BINARY,
261 	GIT_DIFF_IGNORE_WHITESPACE = .git_diff_option_t.GIT_DIFF_IGNORE_WHITESPACE,
262 	GIT_DIFF_IGNORE_WHITESPACE_CHANGE = .git_diff_option_t.GIT_DIFF_IGNORE_WHITESPACE_CHANGE,
263 	GIT_DIFF_IGNORE_WHITESPACE_EOL = .git_diff_option_t.GIT_DIFF_IGNORE_WHITESPACE_EOL,
264 	GIT_DIFF_SHOW_UNTRACKED_CONTENT = .git_diff_option_t.GIT_DIFF_SHOW_UNTRACKED_CONTENT,
265 	GIT_DIFF_SHOW_UNMODIFIED = .git_diff_option_t.GIT_DIFF_SHOW_UNMODIFIED,
266 	GIT_DIFF_PATIENCE = .git_diff_option_t.GIT_DIFF_PATIENCE,
267 	GIT_DIFF_MINIMAL = .git_diff_option_t.GIT_DIFF_MINIMAL,
268 	GIT_DIFF_SHOW_BINARY = .git_diff_option_t.GIT_DIFF_SHOW_BINARY,
269 }
270 
271 /**
272  * The diff object that contains all individual file deltas.
273  *
274  * A `diff` represents the cumulative list of differences between two
275  * snapshots of a repository (possibly filtered by a set of file name
276  * patterns).
277  *
278  * Calculating diffs is generally done in two phases: building a list of
279  * diffs then traversing it. This makes is easier to share logic across
280  * the various types of diffs (tree vs tree, workdir vs index, etc.), and
281  * also allows you to insert optional diff post-processing phases,
282  * such as rename detection, in between the steps. When you are done with
283  * a diff object, it must be freed.
284  *
285  * This is an opaque structure which will be allocated by one of the diff
286  * generator functions below (such as `git_diff_tree_to_tree`). You are
287  * responsible for releasing the object memory when done, using the
288  * `git_diff_free()` function.
289  */
290 struct git_diff;
291 
292 /**
293  * Flags for the delta object and the file objects on each side.
294  *
295  * These flags are used for both the `flags` value of the `git_diff_delta`
296  * and the flags for the `git_diff_file` objects representing the old and
297  * new sides of the delta.  Values outside of this public range should be
298  * considered reserved for internal or future use.
299  */
300 enum git_diff_flag_t
301 {
302 	/**
303 	 * file(s) treated as binary data
304 	 */
305 	GIT_DIFF_FLAG_BINARY = 1u << 0,
306 
307 	/**
308 	 * file(s) treated as text data
309 	 */
310 	GIT_DIFF_FLAG_NOT_BINARY = 1u << 1,
311 
312 	/**
313 	 * `id` value is known correct
314 	 */
315 	GIT_DIFF_FLAG_VALID_ID = 1u << 2,
316 
317 	/**
318 	 * file exists at this side of the delta
319 	 */
320 	GIT_DIFF_FLAG_EXISTS = 1u << 3,
321 
322 	/**
323 	 * file size value is known correct
324 	 */
325 	GIT_DIFF_FLAG_VALID_SIZE = 1u << 4,
326 }
327 
328 //Declaration name in C language
329 enum
330 {
331 	GIT_DIFF_FLAG_BINARY = .git_diff_flag_t.GIT_DIFF_FLAG_BINARY,
332 	GIT_DIFF_FLAG_NOT_BINARY = .git_diff_flag_t.GIT_DIFF_FLAG_NOT_BINARY,
333 	GIT_DIFF_FLAG_VALID_ID = .git_diff_flag_t.GIT_DIFF_FLAG_VALID_ID,
334 	GIT_DIFF_FLAG_EXISTS = .git_diff_flag_t.GIT_DIFF_FLAG_EXISTS,
335 	GIT_DIFF_FLAG_VALID_SIZE = .git_diff_flag_t.GIT_DIFF_FLAG_VALID_SIZE,
336 }
337 
338 /**
339  * What type of change is described by a git_diff_delta?
340  *
341  * `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run
342  * `git_diff_find_similar()` on the diff object.
343  *
344  * `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE`
345  * in the option flags (otherwise type changes will be split into ADDED /
346  * DELETED pairs).
347  */
348 enum git_delta_t
349 {
350 	/**
351 	 * no changes
352 	 */
353 	GIT_DELTA_UNMODIFIED = 0,
354 
355 	/**
356 	 * entry does not exist in old version
357 	 */
358 	GIT_DELTA_ADDED = 1,
359 
360 	/**
361 	 * entry does not exist in new version
362 	 */
363 	GIT_DELTA_DELETED = 2,
364 
365 	/**
366 	 * entry content changed between old and new
367 	 */
368 	GIT_DELTA_MODIFIED = 3,
369 
370 	/**
371 	 * entry was renamed between old and new
372 	 */
373 	GIT_DELTA_RENAMED = 4,
374 
375 	/**
376 	 * entry was copied from another old entry
377 	 */
378 	GIT_DELTA_COPIED = 5,
379 
380 	/**
381 	 * entry is ignored item in workdir
382 	 */
383 	GIT_DELTA_IGNORED = 6,
384 
385 	/**
386 	 * entry is untracked item in workdir
387 	 */
388 	GIT_DELTA_UNTRACKED = 7,
389 
390 	/**
391 	 * type of entry changed between old and new
392 	 */
393 	GIT_DELTA_TYPECHANGE = 8,
394 
395 	/**
396 	 * entry is unreadable
397 	 */
398 	GIT_DELTA_UNREADABLE = 9,
399 
400 	/**
401 	 * entry in the index is conflicted
402 	 */
403 	GIT_DELTA_CONFLICTED = 10,
404 }
405 
406 //Declaration name in C language
407 enum
408 {
409 	GIT_DELTA_UNMODIFIED = .git_delta_t.GIT_DELTA_UNMODIFIED,
410 	GIT_DELTA_ADDED = .git_delta_t.GIT_DELTA_ADDED,
411 	GIT_DELTA_DELETED = .git_delta_t.GIT_DELTA_DELETED,
412 	GIT_DELTA_MODIFIED = .git_delta_t.GIT_DELTA_MODIFIED,
413 	GIT_DELTA_RENAMED = .git_delta_t.GIT_DELTA_RENAMED,
414 	GIT_DELTA_COPIED = .git_delta_t.GIT_DELTA_COPIED,
415 	GIT_DELTA_IGNORED = .git_delta_t.GIT_DELTA_IGNORED,
416 	GIT_DELTA_UNTRACKED = .git_delta_t.GIT_DELTA_UNTRACKED,
417 	GIT_DELTA_TYPECHANGE = .git_delta_t.GIT_DELTA_TYPECHANGE,
418 	GIT_DELTA_UNREADABLE = .git_delta_t.GIT_DELTA_UNREADABLE,
419 	GIT_DELTA_CONFLICTED = .git_delta_t.GIT_DELTA_CONFLICTED,
420 }
421 
422 /**
423  * Description of one side of a delta.
424  *
425  * Although this is called a "file", it could represent a file, a symbolic
426  * link, a submodule commit id, or even a tree (although that only if you
427  * are tracking type changes or ignored/untracked directories).
428  */
429 struct git_diff_file
430 {
431 	/**
432 	 * The `git_oid` of the item.  If the entry represents an
433 	 * absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta),
434 	 * then the oid will be zeroes.
435 	 */
436 	libgit2.oid.git_oid id;
437 
438 	/**
439 	 * The null-terminated path to the entry relative to the working
440 	 * directory of the repository.
441 	 */
442 	const (char)* path;
443 
444 	/**
445 	 * The size of the entry in bytes.
446 	 */
447 	libgit2.types.git_object_size_t size;
448 
449 	/**
450 	 * A combination of the `git_diff_flag_t` types
451 	 */
452 	uint flags;
453 
454 	/**
455 	 * Roughly, the stat() `st_mode` value for the item.  This will
456 	 * be restricted to one of the `git_filemode_t` values.
457 	 */
458 	ushort mode;
459 
460 	/**
461 	 * Represents the known length of the `id` field, when
462 	 * converted to a hex string.  It is generally `GIT_OID_SHA1_HEXSIZE`, unless this
463 	 * delta was created from reading a patch file, in which case it may be
464 	 * abbreviated to something reasonable, like 7 characters.
465 	 */
466 	ushort id_abbrev;
467 }
468 
469 /**
470  * Description of changes to one entry.
471  *
472  * A `delta` is a file pair with an old and new revision.  The old version
473  * may be absent if the file was just created and the new version may be
474  * absent if the file was deleted.  A diff is mostly just a list of deltas.
475  *
476  * When iterating over a diff, this will be passed to most callbacks and
477  * you can use the contents to understand exactly what has changed.
478  *
479  * The `old_file` represents the "from" side of the diff and the `new_file`
480  * represents to "to" side of the diff.  What those means depend on the
481  * function that was used to generate the diff and will be documented below.
482  * You can also use the `git_diff_option_t.GIT_DIFF_REVERSE` flag to flip it around.
483  *
484  * Although the two sides of the delta are named "old_file" and "new_file",
485  * they actually may correspond to entries that represent a file, a symbolic
486  * link, a submodule commit id, or even a tree (if you are tracking type
487  * changes or ignored/untracked directories).
488  *
489  * Under some circumstances, in the name of efficiency, not all fields will
490  * be filled in, but we generally try to fill in as much as possible.  One
491  * example is that the "flags" field may not have either the `BINARY` or the
492  * `NOT_BINARY` flag set to avoid examining file contents if you do not pass
493  * in hunk and/or line callbacks to the diff foreach iteration function.  It
494  * will just use the git attributes for those files.
495  *
496  * The similarity score is zero unless you call `git_diff_find_similar()`
497  * which does a similarity analysis of files in the diff.  Use that
498  * function to do rename and copy detection, and to split heavily modified
499  * files in add/delete pairs.  After that call, deltas with a status of
500  * GIT_DELTA_RENAMED or GIT_DELTA_COPIED will have a similarity score
501  * between 0 and 100 indicating how similar the old and new sides are.
502  *
503  * If you ask `git_diff_find_similar` to find heavily modified files to
504  * break, but to not *actually* break the records, then GIT_DELTA_MODIFIED
505  * records may have a non-zero similarity score if the self-similarity is
506  * below the split threshold.  To display this value like core Git, invert
507  * the score (a la `printf("M%03d", 100 - delta->similarity)`).
508  */
509 struct git_diff_delta
510 {
511 	.git_delta_t status;
512 
513 	/**
514 	 * git_diff_flag_t values
515 	 */
516 	uint flags;
517 
518 	/**
519 	 * for RENAMED and COPIED, value 0-100
520 	 */
521 	ushort similarity;
522 
523 	/**
524 	 * number of files in this delta
525 	 */
526 	ushort nfiles;
527 
528 	.git_diff_file old_file;
529 	.git_diff_file new_file;
530 }
531 
532 /**
533  * Diff notification callback function.
534  *
535  * The callback will be called for each file, just before the `git_diff_delta`
536  * gets inserted into the diff.
537  *
538  * When the callback:
539  * - returns < 0, the diff process will be aborted.
540  * - returns > 0, the delta will not be inserted into the diff, but the
541  *		diff process continues.
542  * - returns 0, the delta is inserted into the diff, and the diff process
543  *		continues.
544  */
545 alias git_diff_notify_cb = int function(const (.git_diff)* diff_so_far, const (.git_diff_delta)* delta_to_add, const (char)* matched_pathspec, void* payload);
546 
547 /**
548  * Diff progress callback.
549  *
550  * Called before each file comparison.
551  *
552  * Returns: Non-zero to abort the diff.
553  */
554 /*
555  * Params:
556  *      diff_so_far = The diff being generated.
557  *      old_path = The path to the old file or null.
558  *      new_path = The path to the new file or null.
559  *      payload = ?
560  */
561 alias git_diff_progress_cb = int function(const (.git_diff)* diff_so_far, const (char)* old_path, const (char)* new_path, void* payload);
562 
563 /**
564  * Structure describing options about how the diff should be executed.
565  *
566  * Setting all values of the structure to zero will yield the default
567  * values.  Similarly, passing null for the options structure will
568  * give the defaults.  The default values are marked below.
569  */
570 struct git_diff_options
571 {
572 	/**
573 	 * version for the struct
574 	 */
575 	uint version_;
576 
577 	/**
578 	 * A combination of `git_diff_option_t` values above.
579 	 * Defaults to git_diff_option_t.GIT_DIFF_NORMAL
580 	 */
581 	uint flags;
582 
583 	/* options controlling which files are in the diff */
584 
585 	/**
586 	 * Overrides the submodule ignore setting for all submodules in the diff.
587 	 */
588 	libgit2.types.git_submodule_ignore_t ignore_submodules;
589 
590 	/**
591 	 * An array of paths / fnmatch patterns to constrain diff.
592 	 * All paths are included by default.
593 	 */
594 	libgit2.strarray.git_strarray pathspec;
595 
596 	/**
597 	 * An optional callback function, notifying the consumer of changes to
598 	 * the diff as new deltas are added.
599 	 */
600 	.git_diff_notify_cb notify_cb;
601 
602 	/**
603 	 * An optional callback function, notifying the consumer of which files
604 	 * are being examined as the diff is generated.
605 	 */
606 	.git_diff_progress_cb progress_cb;
607 
608 	/**
609 	 * The payload to pass to the callback functions.
610 	 */
611 	void* payload;
612 
613 	/* options controlling how to diff text is generated */
614 
615 	/**
616 	 * The number of unchanged lines that define the boundary of a hunk
617 	 * (and to display before and after). Defaults to 3.
618 	 */
619 	uint context_lines;
620 
621 	/**
622 	 * The maximum number of unchanged lines between hunk boundaries before
623 	 * the hunks will be merged into one. Defaults to 0.
624 	 */
625 	uint interhunk_lines;
626 
627 	/**
628 	 * The abbreviation length to use when formatting object ids.
629 	 * Defaults to the value of 'core.abbrev' from the config, or 7 if unset.
630 	 */
631 	ushort id_abbrev;
632 
633 	/**
634 	 * A size (in bytes) above which a blob will be marked as binary
635 	 * automatically; pass a negative value to disable.
636 	 * Defaults to 512MB.
637 	 */
638 	libgit2.types.git_off_t max_size;
639 
640 	/**
641 	 * The virtual "directory" prefix for old file names in hunk headers.
642 	 * Default is "a".
643 	 */
644 	const (char)* old_prefix;
645 
646 	/**
647 	 * The virtual "directory" prefix for new file names in hunk headers.
648 	 * Defaults to "b".
649 	 */
650 	const (char)* new_prefix;
651 }
652 
653 /**
654  * The current version of the diff options structure
655  */
656 enum GIT_DIFF_OPTIONS_VERSION = 1;
657 
658 /*
659  * Stack initializer for diff options.  Alternatively use
660  * `git_diff_options_init` programmatic initialization.
661  */
662 
663 pragma(inline, true)
664 pure nothrow @safe @nogc @live
665 .git_diff_options GIT_DIFF_OPTIONS_INIT()
666 
667 	do
668 	{
669 		libgit2.strarray.git_strarray PATHSPEC_OPTION =
670 		{
671 			strings: null,
672 			count: 0,
673 		};
674 
675 		.git_diff_options OUTPUT =
676 		{
677 			version_: .GIT_DIFF_OPTIONS_VERSION,
678 			flags: 0,
679 			ignore_submodules: libgit2.types.git_submodule_ignore_t.GIT_SUBMODULE_IGNORE_UNSPECIFIED,
680 			pathspec: PATHSPEC_OPTION,
681 			notify_cb: null,
682 			progress_cb: null,
683 			payload: null,
684 			context_lines: 3,
685 		};
686 
687 		return OUTPUT;
688 	}
689 
690 /**
691  * Initialize git_diff_options structure
692  *
693  * Initializes a `git_diff_options` with default values. Equivalent to creating
694  * an instance with GIT_DIFF_OPTIONS_INIT.
695  *
696  * Params:
697  *      opts = The `git_diff_options` struct to initialize.
698  *      version_ = The struct version; pass `GIT_DIFF_OPTIONS_VERSION`.
699  *
700  * Returns: Zero on success; -1 on failure.
701  */
702 @GIT_EXTERN
703 int git_diff_options_init(.git_diff_options* opts, uint version_);
704 
705 /**
706  * When iterating over a diff, callback that will be made per file.
707  */
708 /*
709  * Params:
710  *      delta = A pointer to the delta data for the file
711  *      progress = Goes from 0 to 1 over the diff
712  *      payload = User-specified pointer from foreach function
713  */
714 alias git_diff_file_cb = int function(const (.git_diff_delta)* delta, float progress, void* payload);
715 
716 enum GIT_DIFF_HUNK_HEADER_SIZE = 128;
717 
718 /**
719  * Structure describing the binary contents of a diff.
720  *
721  * A `binary` file / delta is a file (or pair) for which no text diffs
722  * should be generated. A diff can contain delta entries that are
723  * binary, but no diff content will be output for those files. There is
724  * a base heuristic for binary detection and you can further tune the
725  * behavior with git attributes or diff flags and option settings.
726  */
727 enum git_diff_binary_t
728 {
729 	/**
730 	 * Whether there is data in this binary structure or not.
731 	 *
732 	 * If this is `1`, then this was produced and included binary content.
733 	 * If this is `0` then this was generated knowing only that a binary
734 	 * file changed but without providing the data, probably from a patch
735 	 * that said `Binary files a/file.txt and b/file.txt differ`.
736 	 */
737 	GIT_DIFF_BINARY_NONE,
738 
739 	/**
740 	 * The binary data is the literal contents of the file.
741 	 */
742 	GIT_DIFF_BINARY_LITERAL,
743 
744 	/**
745 	 * The binary data is the delta from one side to the other.
746 	 */
747 	GIT_DIFF_BINARY_DELTA,
748 }
749 
750 //Declaration name in C language
751 enum
752 {
753 	GIT_DIFF_BINARY_NONE = .git_diff_binary_t.GIT_DIFF_BINARY_NONE,
754 	GIT_DIFF_BINARY_LITERAL = .git_diff_binary_t.GIT_DIFF_BINARY_LITERAL,
755 	GIT_DIFF_BINARY_DELTA = .git_diff_binary_t.GIT_DIFF_BINARY_DELTA,
756 }
757 
758 /**
759  * The contents of one of the files in a binary diff.
760  */
761 struct git_diff_binary_file
762 {
763 	/**
764 	 * The type of binary data for this file.
765 	 */
766 	.git_diff_binary_t type;
767 
768 	/**
769 	 * The binary data, deflated.
770 	 */
771 	const (char)* data;
772 
773 	/**
774 	 * The length of the binary data.
775 	 */
776 	size_t datalen;
777 
778 	/**
779 	 * The length of the binary data after inflation.
780 	 */
781 	size_t inflatedlen;
782 }
783 
784 /**
785  * Structure describing the binary contents of a diff.
786  */
787 struct git_diff_binary
788 {
789 	/**
790 	 * Whether there is data in this binary structure or not.  If this
791 	 * is `1`, then this was produced and included binary content.  If
792 	 * this is `0` then this was generated knowing only that a binary
793 	 * file changed but without providing the data, probably from a patch
794 	 * that said `Binary files a/file.txt and b/file.txt differ`.
795 	 */
796 	uint contains_data;
797 
798 	/**
799 	 * The contents of the old file.
800 	 */
801 	.git_diff_binary_file old_file;
802 
803 	/**
804 	 * The contents of the new file.
805 	 */
806 	.git_diff_binary_file new_file;
807 }
808 
809 /**
810  * When iterating over a diff, callback that will be made for
811  * binary content within the diff.
812  */
813 alias git_diff_binary_cb = int function(const (.git_diff_delta)* delta, const (.git_diff_binary)* binary, void* payload);
814 
815 /**
816  * Structure describing a hunk of a diff.
817  *
818  * A `hunk` is a span of modified lines in a delta along with some stable
819  * surrounding context. You can configure the amount of context and other
820  * properties of how hunks are generated. Each hunk also comes with a
821  * header that described where it starts and ends in both the old and new
822  * versions in the delta.
823  */
824 struct git_diff_hunk
825 {
826 	/**
827 	 * Starting line number in old_file
828 	 */
829 	int old_start;
830 
831 	/**
832 	 * Number of lines in old_file
833 	 */
834 	int old_lines;
835 
836 	/**
837 	 * Starting line number in new_file
838 	 */
839 	int new_start;
840 
841 	/**
842 	 * Number of lines in new_file
843 	 */
844 	int new_lines;
845 
846 	/**
847 	 * Number of bytes in header text
848 	 */
849 	size_t header_len;
850 
851 	/**
852 	 * Header text, null-byte terminated
853 	 */
854 	char[.GIT_DIFF_HUNK_HEADER_SIZE] header = '\0'; 
855 }
856 
857 /**
858  * When iterating over a diff, callback that will be made per hunk.
859  */
860 alias git_diff_hunk_cb = int function(const (.git_diff_delta)* delta, const (.git_diff_hunk)* hunk, void* payload);
861 
862 /**
863  * Line origin constants.
864  *
865  * These values describe where a line came from and will be passed to
866  * the git_diff_line_cb when iterating over a diff.  There are some
867  * special origin constants at the end that are used for the text
868  * output callbacks to demarcate lines that are actually part of
869  * the file or hunk headers.
870  */
871 enum git_diff_line_t
872 {
873 	/* These values will be sent to `git_diff_line_cb` along with the line */
874 	GIT_DIFF_LINE_CONTEXT = ' ',
875 	GIT_DIFF_LINE_ADDITION = '+',
876 	GIT_DIFF_LINE_DELETION = '-',
877 
878 	/**
879 	 * Both files have no LF at end
880 	 */
881 	GIT_DIFF_LINE_CONTEXT_EOFNL = '=',
882 
883 	/**
884 	 * Old has no LF at end, new does
885 	 */
886 	GIT_DIFF_LINE_ADD_EOFNL = '>',
887 
888 	/**
889 	 * Old has LF at end, new does not
890 	 */
891 	GIT_DIFF_LINE_DEL_EOFNL = '<',
892 
893 	/*
894 	 * The following values will only be sent to a `git_diff_line_cb` when
895 	 * the content of a diff is being formatted through `git_diff_print`.
896 	 */
897 	GIT_DIFF_LINE_FILE_HDR = 'F',
898 	GIT_DIFF_LINE_HUNK_HDR = 'H',
899 
900 	/**
901 	 * For "Binary files x and y differ"
902 	 */
903 	GIT_DIFF_LINE_BINARY = 'B',
904 }
905 
906 //Declaration name in C language
907 enum
908 {
909 	GIT_DIFF_LINE_CONTEXT = .git_diff_line_t.GIT_DIFF_LINE_CONTEXT,
910 	GIT_DIFF_LINE_ADDITION = .git_diff_line_t.GIT_DIFF_LINE_ADDITION,
911 	GIT_DIFF_LINE_DELETION = .git_diff_line_t.GIT_DIFF_LINE_DELETION,
912 	GIT_DIFF_LINE_CONTEXT_EOFNL = .git_diff_line_t.GIT_DIFF_LINE_CONTEXT_EOFNL,
913 	GIT_DIFF_LINE_ADD_EOFNL = .git_diff_line_t.GIT_DIFF_LINE_ADD_EOFNL,
914 	GIT_DIFF_LINE_DEL_EOFNL = .git_diff_line_t.GIT_DIFF_LINE_DEL_EOFNL,
915 	GIT_DIFF_LINE_FILE_HDR = .git_diff_line_t.GIT_DIFF_LINE_FILE_HDR,
916 	GIT_DIFF_LINE_HUNK_HDR = .git_diff_line_t.GIT_DIFF_LINE_HUNK_HDR,
917 	GIT_DIFF_LINE_BINARY = .git_diff_line_t.GIT_DIFF_LINE_BINARY,
918 }
919 
920 /**
921  * Structure describing a line (or data span) of a diff.
922  *
923  * A `line` is a range of characters inside a hunk.  It could be a context
924  * line (i.e. in both old and new versions), an added line (i.e. only in
925  * the new version), or a removed line (i.e. only in the old version).
926  * Unfortunately, we don't know anything about the encoding of data in the
927  * file being diffed, so we cannot tell you much about the line content.
928  * Line data will not be null-byte terminated, however, because it will be
929  * just a span of bytes inside the larger file.
930  */
931 struct git_diff_line
932 {
933 	/**
934 	 * A git_diff_line_t value
935 	 */
936 	char origin = '\0';
937 
938 	/**
939 	 * Line number in old file or -1 for added line
940 	 */
941 	int old_lineno;
942 
943 	/**
944 	 * Line number in new file or -1 for deleted line
945 	 */
946 	int new_lineno;
947 
948 	/**
949 	 * Number of newline characters in content
950 	 */
951 	int num_lines;
952 
953 	/**
954 	 * Number of bytes of data
955 	 */
956 	size_t content_len;
957 
958 	/**
959 	 * Offset in the original file to the content
960 	 */
961 	libgit2.types.git_off_t content_offset;
962 
963 	/**
964 	 * Pointer to diff text, not null-byte terminated
965 	 */
966 	const (char)* content;
967 }
968 
969 /**
970  * When iterating over a diff, callback that will be made per text diff
971  * line. In this context, the provided range will be null.
972  *
973  * When printing a diff, callback that will be made to output each line
974  * of text.  This uses some extra GIT_DIFF_LINE_... constants for output
975  * of lines of file and hunk headers.
976  */
977 alias git_diff_line_cb = int function(
978     const (.git_diff_delta)* delta, /*< delta that contains this data */
979     const (.git_diff_hunk)* hunk,   /*< hunk containing this data */
980     const (.git_diff_line)* line,   /*< line data */
981     void* payload);              /*< user reference data */
982 
983 /**
984  * Flags to control the behavior of diff rename/copy detection.
985  */
986 enum git_diff_find_t
987 {
988 	/**
989 	 * Obey `diff.renames`. Overridden by any other GIT_DIFF_FIND_... flag.
990 	 */
991 	GIT_DIFF_FIND_BY_CONFIG = 0,
992 
993 	/**
994 	 * Look for renames? (`--find-renames`)
995 	 */
996 	GIT_DIFF_FIND_RENAMES = 1u << 0,
997 
998 	/**
999 	 * Consider old side of MODIFIED for renames? (`--break-rewrites=N`)
1000 	 */
1001 	GIT_DIFF_FIND_RENAMES_FROM_REWRITES = 1u << 1,
1002 
1003 	/**
1004 	 * Look for copies? (a la `--find-copies`).
1005 	 */
1006 	GIT_DIFF_FIND_COPIES = 1u << 2,
1007 
1008 	/**
1009 	 * Consider UNMODIFIED as copy sources? (`--find-copies-harder`).
1010 	 *
1011 	 * For this to work correctly, use git_diff_option_t.GIT_DIFF_INCLUDE_UNMODIFIED when
1012 	 * the initial `git_diff` is being generated.
1013 	 */
1014 	GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = 1u << 3,
1015 
1016 	/**
1017 	 * Mark significant rewrites for split (`--break-rewrites=/M`)
1018 	 */
1019 	GIT_DIFF_FIND_REWRITES = 1u << 4,
1020 
1021 	/**
1022 	 * Actually split large rewrites into delete/add pairs
1023 	 */
1024 	GIT_DIFF_BREAK_REWRITES = 1u << 5,
1025 
1026 	/**
1027 	 * Mark rewrites for split and break into delete/add pairs
1028 	 */
1029 	GIT_DIFF_FIND_AND_BREAK_REWRITES = GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES,
1030 
1031 	/**
1032 	 * Find renames/copies for UNTRACKED items in working directory.
1033 	 *
1034 	 * For this to work correctly, use git_diff_option_t.GIT_DIFF_INCLUDE_UNTRACKED when the
1035 	 * initial `git_diff` is being generated (and obviously the diff must
1036 	 * be against the working directory for this to make sense).
1037 	 */
1038 	GIT_DIFF_FIND_FOR_UNTRACKED = 1u << 6,
1039 
1040 	/**
1041 	 * Turn on all finding features.
1042 	 */
1043 	GIT_DIFF_FIND_ALL = 0x00FF,
1044 
1045 	/**
1046 	 * Measure similarity ignoring leading whitespace (default)
1047 	 */
1048 	GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
1049 
1050 	/**
1051 	 * Measure similarity ignoring all whitespace
1052 	 */
1053 	GIT_DIFF_FIND_IGNORE_WHITESPACE = 1u << 12,
1054 
1055 	/**
1056 	 * Measure similarity including all data
1057 	 */
1058 	GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = 1u << 13,
1059 
1060 	/**
1061 	 * Measure similarity only by comparing SHAs (fast and cheap)
1062 	 */
1063 	GIT_DIFF_FIND_EXACT_MATCH_ONLY = 1u << 14,
1064 
1065 	/**
1066 	 * Do not break rewrites unless they contribute to a rename.
1067 	 *
1068 	 * Normally, GIT_DIFF_FIND_AND_BREAK_REWRITES will measure the self-
1069 	 * similarity of modified files and split the ones that have changed a
1070 	 * lot into a DELETE / ADD pair.  Then the sides of that pair will be
1071 	 * considered candidates for rename and copy detection.
1072 	 *
1073 	 * If you add this flag in and the split pair is *not* used for an
1074 	 * actual rename or copy, then the modified record will be restored to
1075 	 * a regular MODIFIED record instead of being split.
1076 	 */
1077 	GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = 1u << 15,
1078 
1079 	/**
1080 	 * Remove any UNMODIFIED deltas after find_similar is done.
1081 	 *
1082 	 * Using GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED to emulate the
1083 	 * --find-copies-harder behavior requires building a diff with the
1084 	 * GIT_DIFF_INCLUDE_UNMODIFIED flag.  If you do not want UNMODIFIED
1085 	 * records in the final result, pass this flag to have them removed.
1086 	 */
1087 	GIT_DIFF_FIND_REMOVE_UNMODIFIED = 1u << 16,
1088 }
1089 
1090 //Declaration name in C language
1091 enum
1092 {
1093 	GIT_DIFF_FIND_BY_CONFIG = .git_diff_find_t.GIT_DIFF_FIND_BY_CONFIG,
1094 	GIT_DIFF_FIND_RENAMES = .git_diff_find_t.GIT_DIFF_FIND_RENAMES,
1095 	GIT_DIFF_FIND_RENAMES_FROM_REWRITES = .git_diff_find_t.GIT_DIFF_FIND_RENAMES_FROM_REWRITES,
1096 	GIT_DIFF_FIND_COPIES = .git_diff_find_t.GIT_DIFF_FIND_COPIES,
1097 	GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = .git_diff_find_t.GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED,
1098 	GIT_DIFF_FIND_REWRITES = .git_diff_find_t.GIT_DIFF_FIND_REWRITES,
1099 	GIT_DIFF_BREAK_REWRITES = .git_diff_find_t.GIT_DIFF_BREAK_REWRITES,
1100 	GIT_DIFF_FIND_AND_BREAK_REWRITES = .git_diff_find_t.GIT_DIFF_FIND_AND_BREAK_REWRITES,
1101 	GIT_DIFF_FIND_FOR_UNTRACKED = .git_diff_find_t.GIT_DIFF_FIND_FOR_UNTRACKED,
1102 	GIT_DIFF_FIND_ALL = .git_diff_find_t.GIT_DIFF_FIND_ALL,
1103 	GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = .git_diff_find_t.GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE,
1104 	GIT_DIFF_FIND_IGNORE_WHITESPACE = .git_diff_find_t.GIT_DIFF_FIND_IGNORE_WHITESPACE,
1105 	GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = .git_diff_find_t.GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE,
1106 	GIT_DIFF_FIND_EXACT_MATCH_ONLY = .git_diff_find_t.GIT_DIFF_FIND_EXACT_MATCH_ONLY,
1107 	GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = .git_diff_find_t.GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY,
1108 	GIT_DIFF_FIND_REMOVE_UNMODIFIED = .git_diff_find_t.GIT_DIFF_FIND_REMOVE_UNMODIFIED,
1109 }
1110 
1111 /**
1112  * Pluggable similarity metric
1113  */
1114 struct git_diff_similarity_metric
1115 {
1116 	int function(void** out_, const (.git_diff_file)* file, const (char)* fullpath, void* payload) file_signature;
1117 	int function(void** out_, const (.git_diff_file)* file, const (char)* buf, size_t buflen, void* payload) buffer_signature;
1118 	void function(void* sig, void* payload) free_signature;
1119 	int function(int* score, void* siga, void* sigb, void* payload) similarity;
1120 	void* payload;
1121 }
1122 
1123 /**
1124  * Control behavior of rename and copy detection
1125  *
1126  * These options mostly mimic parameters that can be passed to git-diff.
1127  */
1128 struct git_diff_find_options
1129 {
1130 	uint version_;
1131 
1132 	/**
1133 	 * Combination of git_diff_find_t values (default git_diff_find_t.GIT_DIFF_FIND_BY_CONFIG).
1134 	 * NOTE: if you don't explicitly set this, `diff.renames` could be set
1135 	 * to false, resulting in `git_diff_find_similar` doing nothing.
1136 	 */
1137 	uint flags;
1138 
1139 	/**
1140 	 * Threshold above which similar files will be considered renames.
1141 	 * This is equivalent to the -M option. Defaults to 50.
1142 	 */
1143 	ushort rename_threshold;
1144 
1145 	/**
1146 	 * Threshold below which similar files will be eligible to be a rename source.
1147 	 * This is equivalent to the first part of the -B option. Defaults to 50.
1148 	 */
1149 	ushort rename_from_rewrite_threshold;
1150 
1151 	/**
1152 	 * Threshold above which similar files will be considered copies.
1153 	 * This is equivalent to the -C option. Defaults to 50.
1154 	 */
1155 	ushort copy_threshold;
1156 
1157 	/**
1158 	 * Threshold below which similar files will be split into a delete/add pair.
1159 	 * This is equivalent to the last part of the -B option. Defaults to 60.
1160 	 */
1161 	ushort break_rewrite_threshold;
1162 
1163 	/**
1164 	 * Maximum number of matches to consider for a particular file.
1165 	 *
1166 	 * This is a little different from the `-l` option from Git because we
1167 	 * will still process up to this many matches before abandoning the search.
1168 	 * Defaults to 1000.
1169 	 */
1170 	size_t rename_limit;
1171 
1172 	/**
1173 	 * The `metric` option allows you to plug in a custom similarity metric.
1174 	 *
1175 	 * Set it to null to use the default internal metric.
1176 	 *
1177 	 * The default metric is based on sampling hashes of ranges of data in
1178 	 * the file, which is a pretty good similarity approximation that should
1179 	 * work fairly well for both text and binary data while still being
1180 	 * pretty fast with a fixed memory overhead.
1181 	 */
1182 	.git_diff_similarity_metric* metric;
1183 }
1184 
1185 enum GIT_DIFF_FIND_OPTIONS_VERSION = 1;
1186 
1187 pragma(inline, true)
1188 pure nothrow @safe @nogc @live
1189 .git_diff_find_options GIT_DIFF_FIND_OPTIONS_INIT()
1190 
1191 	do
1192 	{
1193 		.git_diff_find_options OUTPUT =
1194 		{
1195 			version_: .GIT_DIFF_FIND_OPTIONS_VERSION,
1196 		};
1197 
1198 		return OUTPUT;
1199 	}
1200 
1201 /**
1202  * Initialize git_diff_find_options structure
1203  *
1204  * Initializes a `git_diff_find_options` with default values. Equivalent to creating
1205  * an instance with GIT_DIFF_FIND_OPTIONS_INIT.
1206  *
1207  * Params:
1208  *      opts = The `git_diff_find_options` struct to initialize.
1209  *      version_ = The struct version; pass `GIT_DIFF_FIND_OPTIONS_VERSION`.
1210  *
1211  * Returns: Zero on success; -1 on failure.
1212  */
1213 @GIT_EXTERN
1214 int git_diff_find_options_init(.git_diff_find_options* opts, uint version_);
1215 
1216 /*
1217  * @name Diff Generator Functions
1218  *
1219  * These are the functions you would use to create (or destroy) a
1220  * git_diff from various objects in a repository.
1221  */
1222 /*@{*/
1223 
1224 /**
1225  * Deallocate a diff.
1226  *
1227  * Params:
1228  *      diff = The previously created diff; cannot be used after free.
1229  */
1230 @GIT_EXTERN
1231 void git_diff_free(.git_diff* diff);
1232 
1233 /**
1234  * Create a diff with the difference between two tree objects.
1235  *
1236  * This is equivalent to `git diff <old-tree> <new-tree>`
1237  *
1238  * The first tree will be used for the "old_file" side of the delta and the
1239  * second tree will be used for the "new_file" side of the delta.  You can
1240  * pass null to indicate an empty tree, although it is an error to pass
1241  * null for both the `old_tree` and `new_tree`.
1242  *
1243  * Params:
1244  *      diff = Output pointer to a git_diff pointer to be allocated.
1245  *      repo = The repository containing the trees.
1246  *      old_tree = A git_tree object to diff from, or null for empty tree.
1247  *      new_tree = A git_tree object to diff to, or null for empty tree.
1248  *      opts = Structure with options to influence diff or null for defaults.
1249  *
1250  * Returns: 0 or an error code.
1251  */
1252 @GIT_EXTERN
1253 int git_diff_tree_to_tree(.git_diff** diff, libgit2.types.git_repository* repo, libgit2.types.git_tree* old_tree, libgit2.types.git_tree* new_tree, const (.git_diff_options)* opts);
1254 
1255 /**
1256  * Create a diff between a tree and repository index.
1257  *
1258  * This is equivalent to `git diff --cached <treeish>` or if you pass
1259  * the HEAD tree, then like `git diff --cached`.
1260  *
1261  * The tree you pass will be used for the "old_file" side of the delta, and
1262  * the index will be used for the "new_file" side of the delta.
1263  *
1264  * If you pass null for the index, then the existing index of the `repo`
1265  * will be used.  In this case, the index will be refreshed from disk
1266  * (if it has changed) before the diff is generated.
1267  *
1268  * Params:
1269  *      diff = Output pointer to a git_diff pointer to be allocated.
1270  *      repo = The repository containing the tree and index.
1271  *      old_tree = A git_tree object to diff from, or null for empty tree.
1272  *      index = The index to diff with; repo index used if null.
1273  *      opts = Structure with options to influence diff or null for defaults.
1274  *
1275  * Returns: 0 or an error code.
1276  */
1277 @GIT_EXTERN
1278 int git_diff_tree_to_index(.git_diff** diff, libgit2.types.git_repository* repo, libgit2.types.git_tree* old_tree, libgit2.types.git_index* index, const (.git_diff_options)* opts);
1279 
1280 /**
1281  * Create a diff between the repository index and the workdir directory.
1282  *
1283  * This matches the `git diff` command.  See the note below on
1284  * `git_diff_tree_to_workdir` for a discussion of the difference between
1285  * `git diff` and `git diff HEAD` and how to emulate a `git diff <treeish>`
1286  * using libgit2.
1287  *
1288  * The index will be used for the "old_file" side of the delta, and the
1289  * working directory will be used for the "new_file" side of the delta.
1290  *
1291  * If you pass null for the index, then the existing index of the `repo`
1292  * will be used.  In this case, the index will be refreshed from disk
1293  * (if it has changed) before the diff is generated.
1294  *
1295  * Params:
1296  *      diff = Output pointer to a git_diff pointer to be allocated.
1297  *      repo = The repository.
1298  *      index = The index to diff from; repo index used if null.
1299  *      opts = Structure with options to influence diff or null for defaults.
1300  *
1301  * Returns: 0 or an error code.
1302  */
1303 @GIT_EXTERN
1304 int git_diff_index_to_workdir(.git_diff** diff, libgit2.types.git_repository* repo, libgit2.types.git_index* index, const (.git_diff_options)* opts);
1305 
1306 /**
1307  * Create a diff between a tree and the working directory.
1308  *
1309  * The tree you provide will be used for the "old_file" side of the delta,
1310  * and the working directory will be used for the "new_file" side.
1311  *
1312  * This is not the same as `git diff <treeish>` or `git diff-index
1313  * <treeish>`.  Those commands use information from the index, whereas this
1314  * function strictly returns the differences between the tree and the files
1315  * in the working directory, regardless of the state of the index.  Use
1316  * `git_diff_tree_to_workdir_with_index` to emulate those commands.
1317  *
1318  * To see difference between this and `git_diff_tree_to_workdir_with_index`,
1319  * consider the example of a staged file deletion where the file has then
1320  * been put back into the working dir and further modified.  The
1321  * tree-to-workdir diff for that file is 'modified', but `git diff` would
1322  * show status 'deleted' since there is a staged delete.
1323  *
1324  * Params:
1325  *      diff = A pointer to a git_diff pointer that will be allocated.
1326  *      repo = The repository containing the tree.
1327  *      old_tree = A git_tree object to diff from, or null for empty tree.
1328  *      opts = Structure with options to influence diff or null for defaults.
1329  *
1330  * Returns: 0 or an error code.
1331  */
1332 @GIT_EXTERN
1333 int git_diff_tree_to_workdir(.git_diff** diff, libgit2.types.git_repository* repo, libgit2.types.git_tree* old_tree, const (.git_diff_options)* opts);
1334 
1335 /**
1336  * Create a diff between a tree and the working directory using index data
1337  * to account for staged deletes, tracked files, etc.
1338  *
1339  * This emulates `git diff <tree>` by diffing the tree to the index and
1340  * the index to the working directory and blending the results into a
1341  * single diff that includes staged deleted, etc.
1342  *
1343  * Params:
1344  *      diff = A pointer to a git_diff pointer that will be allocated.
1345  *      repo = The repository containing the tree.
1346  *      old_tree = A git_tree object to diff from, or null for empty tree.
1347  *      opts = Structure with options to influence diff or null for defaults.
1348  *
1349  * Returns: 0 or an error code.
1350  */
1351 @GIT_EXTERN
1352 int git_diff_tree_to_workdir_with_index(.git_diff** diff, libgit2.types.git_repository* repo, libgit2.types.git_tree* old_tree, const (.git_diff_options)* opts);
1353 
1354 /**
1355  * Create a diff with the difference between two index objects.
1356  *
1357  * The first index will be used for the "old_file" side of the delta and the
1358  * second index will be used for the "new_file" side of the delta.
1359  *
1360  * Params:
1361  *      diff = Output pointer to a git_diff pointer to be allocated.
1362  *      repo = The repository containing the indexes.
1363  *      old_index = A git_index object to diff from.
1364  *      new_index = A git_index object to diff to.
1365  *      opts = Structure with options to influence diff or null for defaults.
1366  *
1367  * Returns: 0 or an error code.
1368  */
1369 @GIT_EXTERN
1370 int git_diff_index_to_index(.git_diff** diff, libgit2.types.git_repository* repo, libgit2.types.git_index* old_index, libgit2.types.git_index* new_index, const (.git_diff_options)* opts);
1371 
1372 /**
1373  * Merge one diff into another.
1374  *
1375  * This merges items from the "from" list into the "onto" list.  The
1376  * resulting diff will have all items that appear in either list.
1377  * If an item appears in both lists, then it will be "merged" to appear
1378  * as if the old version was from the "onto" list and the new version
1379  * is from the "from" list (with the exception that if the item has a
1380  * pending DELETE in the middle, then it will show as deleted).
1381  *
1382  * Params:
1383  *      onto = Diff to merge into.
1384  *      from = Diff to merge.
1385  *
1386  * Returns: 0 or an error code.
1387  */
1388 @GIT_EXTERN
1389 int git_diff_merge(.git_diff* onto, const (.git_diff)* from);
1390 
1391 /**
1392  * Transform a diff marking file renames, copies, etc.
1393  *
1394  * This modifies a diff in place, replacing old entries that look
1395  * like renames or copies with new entries reflecting those changes.
1396  * This also will, if requested, break modified files into add/remove
1397  * pairs if the amount of change is above a threshold.
1398  *
1399  * Params:
1400  *      diff = diff to run detection algorithms on
1401  *      options = Control how detection should be run, null for defaults
1402  *
1403  * Returns: 0 on success, -1 on failure
1404  */
1405 @GIT_EXTERN
1406 int git_diff_find_similar(.git_diff* diff, const (.git_diff_find_options)* options);
1407 
1408 /*@}*/
1409 
1410 /*
1411  * @name Diff Processor Functions
1412  *
1413  * These are the functions you apply to a diff to process it
1414  * or read it in some way.
1415  */
1416 /*@{*/
1417 
1418 /**
1419  * Query how many diff records are there in a diff.
1420  *
1421  * Params:
1422  *      diff = A git_diff generated by one of the above functions
1423  *
1424  * Returns: Count of number of deltas in the list
1425  */
1426 @GIT_EXTERN
1427 size_t git_diff_num_deltas(const (.git_diff)* diff);
1428 
1429 /**
1430  * Query how many diff deltas are there in a diff filtered by type.
1431  *
1432  * This works just like `git_diff_num_deltas()` with an extra parameter
1433  * that is a `git_delta_t` and returns just the count of how many deltas
1434  * match that particular type.
1435  *
1436  * Params:
1437  *      diff = A git_diff generated by one of the above functions
1438  *      type = A git_delta_t value to filter the count
1439  *
1440  * Returns: Count of number of deltas matching delta_t type
1441  */
1442 @GIT_EXTERN
1443 size_t git_diff_num_deltas_of_type(const (.git_diff)* diff, .git_delta_t type);
1444 
1445 /**
1446  * Return the diff delta for an entry in the diff list.
1447  *
1448  * The `git_diff_delta` pointer points to internal data and you do not
1449  * have to release it when you are done with it.  It will go away when
1450  * the * `git_diff` (or any associated `git_patch`) goes away.
1451  *
1452  * Note that the flags on the delta related to whether it has binary
1453  * content or not may not be set if there are no attributes set for the
1454  * file and there has been no reason to load the file data at this point.
1455  * For now, if you need those flags to be up to date, your only option is
1456  * to either use `git_diff_foreach` or create a `git_patch`.
1457  *
1458  * Params:
1459  *      diff = Diff list object
1460  *      idx = Index into diff list
1461  *
1462  * Returns: Pointer to git_diff_delta (or null if `idx` out of range)
1463  */
1464 @GIT_EXTERN
1465 const (.git_diff_delta)* git_diff_get_delta(const (.git_diff)* diff, size_t idx);
1466 
1467 /**
1468  * Check if deltas are sorted case sensitively or insensitively.
1469  *
1470  * Params:
1471  *      diff = diff to check
1472  *
1473  * Returns: 0 if case sensitive, 1 if case is ignored
1474  */
1475 @GIT_EXTERN
1476 int git_diff_is_sorted_icase(const (.git_diff)* diff);
1477 
1478 /**
1479  * Loop over all deltas in a diff issuing callbacks.
1480  *
1481  * This will iterate through all of the files described in a diff.  You
1482  * should provide a file callback to learn about each file.
1483  *
1484  * The "hunk" and "line" callbacks are optional, and the text diff of the
1485  * files will only be calculated if they are not null.  Of course, these
1486  * callbacks will not be invoked for binary files on the diff or for
1487  * files whose only changed is a file mode change.
1488  *
1489  * Returning a non-zero value from any of the callbacks will terminate
1490  * the iteration and return the value to the user.
1491  *
1492  * Params:
1493  *      diff = A git_diff generated by one of the above functions.
1494  *      file_cb = Callback function to make per file in the diff.
1495  *      binary_cb = Optional callback to make for binary files.
1496  *      hunk_cb = Optional callback to make per hunk of text diff.  This callback is called to describe a range of lines in the diff.  It will not be issued for binary files.
1497  *      line_cb = Optional callback to make per line of diff text.  This same callback will be made for context lines, added, and removed lines, and even for a deleted trailing newline.
1498  *      payload = Reference pointer that will be passed to your callbacks.
1499  *
1500  * Returns: 0 on success, non-zero callback return value, or error code
1501  */
1502 @GIT_EXTERN
1503 int git_diff_foreach(.git_diff* diff, .git_diff_file_cb file_cb, .git_diff_binary_cb binary_cb, .git_diff_hunk_cb hunk_cb, .git_diff_line_cb line_cb, void* payload);
1504 
1505 /**
1506  * Look up the single character abbreviation for a delta status code.
1507  *
1508  * When you run `git diff --name-status` it uses single letter codes in
1509  * the output such as 'A' for added, 'D' for deleted, 'M' for modified,
1510  * etc.  This function converts a git_delta_t value into these letters for
1511  * your own purposes.  git_delta_t.GIT_DELTA_UNTRACKED will return a space (i.e. ' ').
1512  *
1513  * Params:
1514  *      status = The git_delta_t value to look up
1515  *
1516  * Returns: The single character label for that code
1517  */
1518 @GIT_EXTERN
1519 char git_diff_status_char(.git_delta_t status);
1520 
1521 /**
1522  * Possible output formats for diff data
1523  */
1524 enum git_diff_format_t
1525 {
1526 	/**
1527 	 * full git diff
1528 	 */
1529 	GIT_DIFF_FORMAT_PATCH = 1u,
1530 
1531 	/**
1532 	 * just the file headers of patch
1533 	 */
1534 	GIT_DIFF_FORMAT_PATCH_HEADER = 2u,
1535 
1536 	/**
1537 	 * like git diff --raw
1538 	 */
1539 	GIT_DIFF_FORMAT_RAW = 3u,
1540 
1541 	/**
1542 	 * like git diff --name-only
1543 	 */
1544 	GIT_DIFF_FORMAT_NAME_ONLY = 4u,
1545 
1546 	/**
1547 	 * like git diff --name-status
1548 	 */
1549 	GIT_DIFF_FORMAT_NAME_STATUS = 5u,
1550 
1551 	/**
1552 	 * git diff as used by git patch-id
1553 	 */
1554 	GIT_DIFF_FORMAT_PATCH_ID = 6u,
1555 }
1556 
1557 //Declaration name in C language
1558 enum
1559 {
1560 	GIT_DIFF_FORMAT_PATCH = .git_diff_format_t.GIT_DIFF_FORMAT_PATCH,
1561 	GIT_DIFF_FORMAT_PATCH_HEADER = .git_diff_format_t.GIT_DIFF_FORMAT_PATCH_HEADER,
1562 	GIT_DIFF_FORMAT_RAW = .git_diff_format_t.GIT_DIFF_FORMAT_RAW,
1563 	GIT_DIFF_FORMAT_NAME_ONLY = .git_diff_format_t.GIT_DIFF_FORMAT_NAME_ONLY,
1564 	GIT_DIFF_FORMAT_NAME_STATUS = .git_diff_format_t.GIT_DIFF_FORMAT_NAME_STATUS,
1565 	GIT_DIFF_FORMAT_PATCH_ID = .git_diff_format_t.GIT_DIFF_FORMAT_PATCH_ID,
1566 }
1567 
1568 /**
1569  * Iterate over a diff generating formatted text output.
1570  *
1571  * Returning a non-zero value from the callbacks will terminate the
1572  * iteration and return the non-zero value to the caller.
1573  *
1574  * Params:
1575  *      diff = A git_diff generated by one of the above functions.
1576  *      format = A git_diff_format_t value to pick the text format.
1577  *      print_cb = Callback to make per line of diff text.
1578  *      payload = Reference pointer that will be passed to your callback.
1579  *
1580  * Returns: 0 on success, non-zero callback return value, or error code
1581  */
1582 @GIT_EXTERN
1583 int git_diff_print(.git_diff* diff, .git_diff_format_t format, .git_diff_line_cb print_cb, void* payload);
1584 
1585 /**
1586  * Produce the complete formatted text output from a diff into a
1587  * buffer.
1588  *
1589  * Params:
1590  *      out_ = A pointer to a user-allocated git_buf that will contain the diff text
1591  *      diff = A git_diff generated by one of the above functions.
1592  *      format = A git_diff_format_t value to pick the text format.
1593  *
1594  * Returns: 0 on success or error code
1595  */
1596 @GIT_EXTERN
1597 int git_diff_to_buf(libgit2.buffer.git_buf* out_, .git_diff* diff, .git_diff_format_t format);
1598 
1599 /*@}*/
1600 
1601 /*
1602  * Misc
1603  */
1604 
1605 /**
1606  * Directly run a diff on two blobs.
1607  *
1608  * Compared to a file, a blob lacks some contextual information. As such,
1609  * the `git_diff_file` given to the callback will have some fake data; i.e.
1610  * `mode` will be 0 and `path` will be null.
1611  *
1612  * null is allowed for either `old_blob` or `new_blob` and will be treated
1613  * as an empty blob, with the `oid` set to null in the `git_diff_file` data.
1614  * Passing null for both blobs is a noop; no callbacks will be made at all.
1615  *
1616  * We do run a binary content check on the blob content and if either blob
1617  * looks like binary data, the `git_diff_delta` binary attribute will be set
1618  * to 1 and no call to the hunk_cb nor line_cb will be made (unless you pass
1619  * `git_diff_option_t.GIT_DIFF_FORCE_TEXT` of course).
1620  *
1621  * Params:
1622  *      old_blob = Blob for old side of diff, or null for empty blob
1623  *      old_as_path = Treat old blob as if it had this filename; can be null
1624  *      new_blob = Blob for new side of diff, or null for empty blob
1625  *      new_as_path = Treat new blob as if it had this filename; can be null
1626  *      options = Options for diff, or null for default options
1627  *      file_cb = Callback for "file"; made once if there is a diff; can be null
1628  *      binary_cb = Callback for binary files; can be null
1629  *      hunk_cb = Callback for each hunk in diff; can be null
1630  *      line_cb = Callback for each line in diff; can be null
1631  *      payload = Payload passed to each callback function
1632  *
1633  * Returns: 0 on success, non-zero callback return value, or error code
1634  */
1635 @GIT_EXTERN
1636 int git_diff_blobs(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 (.git_diff_options)* options, .git_diff_file_cb file_cb, .git_diff_binary_cb binary_cb, .git_diff_hunk_cb hunk_cb, .git_diff_line_cb line_cb, void* payload);
1637 
1638 /**
1639  * Directly run a diff between a blob and a buffer.
1640  *
1641  * As with `git_diff_blobs`, comparing a blob and buffer lacks some context,
1642  * so the `git_diff_file` parameters to the callbacks will be faked a la the
1643  * rules for `git_diff_blobs()`.
1644  *
1645  * Passing null for `old_blob` will be treated as an empty blob (i.e. the
1646  * `file_cb` will be invoked with git_delta_t.GIT_DELTA_ADDED and the diff will be the
1647  * entire content of the buffer added).  Passing null to the buffer will do
1648  * the reverse, with GIT_DELTA_REMOVED and blob content removed.
1649  *
1650  * Params:
1651  *      old_blob = Blob for old side of diff, or null for empty blob
1652  *      old_as_path = Treat old blob as if it had this filename; can be null
1653  *      buffer = Raw data for new side of diff, or null for empty
1654  *      buffer_len = Length of raw data for new side of diff
1655  *      buffer_as_path = Treat buffer as if it had this filename; can be null
1656  *      options = Options for diff, or null for default options
1657  *      file_cb = Callback for "file"; made once if there is a diff; can be null
1658  *      binary_cb = Callback for binary files; can be null
1659  *      hunk_cb = Callback for each hunk in diff; can be null
1660  *      line_cb = Callback for each line in diff; can be null
1661  *      payload = Payload passed to each callback function
1662  *
1663  * Returns: 0 on success, non-zero callback return value, or error code
1664  */
1665 @GIT_EXTERN
1666 int git_diff_blob_to_buffer(const (libgit2.types.git_blob)* old_blob, const (char)* old_as_path, const (char)* buffer, size_t buffer_len, const (char)* buffer_as_path, const (.git_diff_options)* options, .git_diff_file_cb file_cb, .git_diff_binary_cb binary_cb, .git_diff_hunk_cb hunk_cb, .git_diff_line_cb line_cb, void* payload);
1667 
1668 /**
1669  * Directly run a diff between two buffers.
1670  *
1671  * Even more than with `git_diff_blobs`, comparing two buffer lacks
1672  * context, so the `git_diff_file` parameters to the callbacks will be
1673  * faked a la the rules for `git_diff_blobs()`.
1674  *
1675  * Params:
1676  *      old_buffer = Raw data for old side of diff, or null for empty
1677  *      old_len = Length of the raw data for old side of the diff
1678  *      old_as_path = Treat old buffer as if it had this filename; can be null
1679  *      new_buffer = Raw data for new side of diff, or null for empty
1680  *      new_len = Length of raw data for new side of diff
1681  *      new_as_path = Treat buffer as if it had this filename; can be null
1682  *      options = Options for diff, or null for default options
1683  *      file_cb = Callback for "file"; made once if there is a diff; can be null
1684  *      binary_cb = Callback for binary files; can be null
1685  *      hunk_cb = Callback for each hunk in diff; can be null
1686  *      line_cb = Callback for each line in diff; can be null
1687  *      payload = Payload passed to each callback function
1688  *
1689  * Returns: 0 on success, non-zero callback return value, or error code
1690  */
1691 @GIT_EXTERN
1692 int git_diff_buffers(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 (.git_diff_options)* options, .git_diff_file_cb file_cb, .git_diff_binary_cb binary_cb, .git_diff_hunk_cb hunk_cb, .git_diff_line_cb line_cb, void* payload);
1693 
1694 /**
1695  * Read the contents of a git patch file into a `git_diff` object.
1696  *
1697  * The diff object produced is similar to the one that would be
1698  * produced if you actually produced it computationally by comparing
1699  * two trees, however there may be subtle differences.  For example,
1700  * a patch file likely contains abbreviated object IDs, so the
1701  * object IDs in a `git_diff_delta` produced by this function will
1702  * also be abbreviated.
1703  *
1704  * This function will only read patch files created by a git
1705  * implementation, it will not read unified diffs produced by
1706  * the `diff` program, nor any other types of patch files.
1707  *
1708  * Params:
1709  *      out_ = A pointer to a git_diff pointer that will be allocated.
1710  *      content = The contents of a patch file
1711  *      content_len = The length of the patch file contents
1712  *
1713  * Returns: 0 or an error code
1714  */
1715 @GIT_EXTERN
1716 int git_diff_from_buffer(.git_diff** out_, const (char)* content, size_t content_len);
1717 
1718 /**
1719  * This is an opaque structure which is allocated by `git_diff_get_stats`.
1720  * You are responsible for releasing the object memory when done, using the
1721  * `git_diff_stats_free()` function.
1722  */
1723 struct git_diff_stats;
1724 
1725 /**
1726  * Formatting options for diff stats
1727  */
1728 enum git_diff_stats_format_t
1729 {
1730 	/**
1731 	 * No stats
1732 	 */
1733 	GIT_DIFF_STATS_NONE = 0,
1734 
1735 	/**
1736 	 * Full statistics, equivalent of `--stat`
1737 	 */
1738 	GIT_DIFF_STATS_FULL = 1u << 0,
1739 
1740 	/**
1741 	 * Short statistics, equivalent of `--shortstat`
1742 	 */
1743 	GIT_DIFF_STATS_SHORT = 1u << 1,
1744 
1745 	/**
1746 	 * Number statistics, equivalent of `--numstat`
1747 	 */
1748 	GIT_DIFF_STATS_NUMBER = 1u << 2,
1749 
1750 	/**
1751 	 * Extended header information such as creations, renames and mode changes,
1752 	 * equivalent of `--summary`
1753 	 */
1754 	GIT_DIFF_STATS_INCLUDE_SUMMARY = 1u << 3,
1755 }
1756 
1757 //Declaration name in C language
1758 enum
1759 {
1760 	GIT_DIFF_STATS_NONE = .git_diff_stats_format_t.GIT_DIFF_STATS_NONE,
1761 	GIT_DIFF_STATS_FULL = .git_diff_stats_format_t.GIT_DIFF_STATS_FULL,
1762 	GIT_DIFF_STATS_SHORT = .git_diff_stats_format_t.GIT_DIFF_STATS_SHORT,
1763 	GIT_DIFF_STATS_NUMBER = .git_diff_stats_format_t.GIT_DIFF_STATS_NUMBER,
1764 	GIT_DIFF_STATS_INCLUDE_SUMMARY = .git_diff_stats_format_t.GIT_DIFF_STATS_INCLUDE_SUMMARY,
1765 }
1766 
1767 /**
1768  * Accumulate diff statistics for all patches.
1769  *
1770  * Params:
1771  *      out_ = Structure containing the diff statistics.
1772  *      diff = A git_diff generated by one of the above functions.
1773  *
1774  * Returns: 0 on success; non-zero on error
1775  */
1776 @GIT_EXTERN
1777 int git_diff_get_stats(.git_diff_stats** out_, .git_diff* diff);
1778 
1779 /**
1780  * Get the total number of files changed in a diff
1781  *
1782  * Params:
1783  *      stats = A `git_diff_stats` generated by one of the above functions.
1784  *
1785  * Returns: total number of files changed in the diff
1786  */
1787 @GIT_EXTERN
1788 size_t git_diff_stats_files_changed(const (.git_diff_stats)* stats);
1789 
1790 /**
1791  * Get the total number of insertions in a diff
1792  *
1793  * Params:
1794  *      stats = A `git_diff_stats` generated by one of the above functions.
1795  *
1796  * Returns: total number of insertions in the diff
1797  */
1798 @GIT_EXTERN
1799 size_t git_diff_stats_insertions(const (.git_diff_stats)* stats);
1800 
1801 /**
1802  * Get the total number of deletions in a diff
1803  *
1804  * Params:
1805  *      stats = A `git_diff_stats` generated by one of the above functions.
1806  *
1807  * Returns: total number of deletions in the diff
1808  */
1809 @GIT_EXTERN
1810 size_t git_diff_stats_deletions(const (.git_diff_stats)* stats);
1811 
1812 /**
1813  * Print diff statistics to a `git_buf`.
1814  *
1815  * Params:
1816  *      out_ = buffer to store the formatted diff statistics in.
1817  *      stats = A `git_diff_stats` generated by one of the above functions.
1818  *      format = Formatting option.
1819  *      width = Target width for output (only affects git_diff_stats_format_t.GIT_DIFF_STATS_FULL)
1820  *
1821  * Returns: 0 on success; non-zero on error
1822  */
1823 @GIT_EXTERN
1824 int git_diff_stats_to_buf(libgit2.buffer.git_buf* out_, const (.git_diff_stats)* stats, .git_diff_stats_format_t format, size_t width);
1825 
1826 /**
1827  * Deallocate a `git_diff_stats`.
1828  *
1829  * Params:
1830  *      stats = The previously created statistics object;
1831  * cannot be used after free.
1832  */
1833 @GIT_EXTERN
1834 void git_diff_stats_free(.git_diff_stats* stats);
1835 
1836 /**
1837  * Patch ID options structure
1838  *
1839  * Initialize with `GIT_PATCHID_OPTIONS_INIT`. Alternatively, you can
1840  * use `git_diff_patchid_options_init`.
1841  */
1842 struct git_diff_patchid_options
1843 {
1844 	uint version_;
1845 }
1846 
1847 enum GIT_DIFF_PATCHID_OPTIONS_VERSION = 1;
1848 
1849 pragma(inline, true)
1850 pure nothrow @safe @nogc @live
1851 .git_diff_patchid_options GIT_DIFF_PATCHID_OPTIONS_INIT()
1852 
1853 	do
1854 	{
1855 		.git_diff_patchid_options OUTPUT =
1856 		{
1857 			version_: .GIT_DIFF_PATCHID_OPTIONS_VERSION,
1858 		};
1859 
1860 		return OUTPUT;
1861 	}
1862 
1863 /**
1864  * Initialize git_diff_patchid_options structure
1865  *
1866  * Initializes a `git_diff_patchid_options` with default values. Equivalent to
1867  * creating an instance with `GIT_DIFF_PATCHID_OPTIONS_INIT`.
1868  *
1869  * Params:
1870  *      opts = The `git_diff_patchid_options` struct to initialize.
1871  *      version_ = The struct version; pass `GIT_DIFF_PATCHID_OPTIONS_VERSION`.
1872  *
1873  * Returns: Zero on success; -1 on failure.
1874  */
1875 @GIT_EXTERN
1876 int git_diff_patchid_options_init(.git_diff_patchid_options* opts, uint version_);
1877 
1878 /**
1879  * Calculate the patch ID for the given patch.
1880  *
1881  * Calculate a stable patch ID for the given patch by summing the
1882  * hash of the file diffs, ignoring whitespace and line numbers.
1883  * This can be used to derive whether two diffs are the same with
1884  * a high probability.
1885  *
1886  * Currently, this function only calculates stable patch IDs, as
1887  * defined in git-patch-id(1), and should in fact generate the
1888  * same IDs as the upstream git project does.
1889  *
1890  * Params:
1891  *      out_ = Pointer where the calculated patch ID should be stored
1892  *      diff = The diff to calculate the ID for
1893  *      opts = Options for how to calculate the patch ID. This is intended for future changes, as currently no options are available.
1894  *
1895  * Returns: 0 on success, an error code otherwise.
1896  */
1897 @GIT_EXTERN
1898 int git_diff_patchid(libgit2.oid.git_oid* out_, .git_diff* diff, .git_diff_patchid_options* opts);
1899 
1900 /* @} */