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