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 /* @} */