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.merge; 8 9 10 private static import libgit2_d.checkout; 11 private static import libgit2_d.diff; 12 private static import libgit2_d.index; 13 private static import libgit2_d.oid; 14 private static import libgit2_d.oidarray; 15 private static import libgit2_d.types; 16 17 /** 18 * @file git2/merge.h 19 * @brief Git merge routines 20 * @defgroup git_merge Git merge routines 21 * @ingroup Git 22 * @{ 23 */ 24 extern (C): 25 nothrow @nogc: 26 public: 27 28 /** 29 * The file inputs to `git_merge_file`. Callers should populate the 30 * `git_merge_file_input` structure with descriptions of the files in 31 * each side of the conflict for use in producing the merge file. 32 */ 33 struct git_merge_file_input 34 { 35 uint version_; 36 37 /** 38 * Pointer to the contents of the file. 39 */ 40 const (char)* ptr_; 41 42 /** 43 * Size of the contents pointed to in `ptr_`. 44 */ 45 size_t size; 46 47 /** 48 * File name of the conflicted file, or `null` to not merge the path. 49 */ 50 const (char)* path; 51 52 /** 53 * File mode of the conflicted file, or `0` to not merge the mode. 54 */ 55 uint mode; 56 } 57 58 enum GIT_MERGE_FILE_INPUT_VERSION = 1; 59 60 pragma(inline, true) 61 pure nothrow @safe @nogc 62 .git_merge_file_input GIT_MERGE_FILE_INPUT_INIT() 63 64 do 65 { 66 .git_merge_file_input OUTPUT = 67 { 68 version_: .GIT_MERGE_FILE_INPUT_VERSION, 69 }; 70 71 return OUTPUT; 72 } 73 74 /** 75 * Initializes a `git_merge_file_input` with default values. Equivalent to 76 * creating an instance with GIT_MERGE_FILE_INPUT_INIT. 77 * 78 * Params: 79 * opts = the `git_merge_file_input` instance to initialize. 80 * version_ = the version of the struct; you should pass `GIT_MERGE_FILE_INPUT_VERSION` here. 81 * 82 * Returns: Zero on success; -1 on failure. 83 */ 84 //GIT_EXTERN 85 int git_merge_file_input_init(.git_merge_file_input* opts, uint version_); 86 87 /** 88 * Flags for `git_merge` options. A combination of these flags can be 89 * passed in via the `flags` value in the `git_merge_options`. 90 */ 91 enum git_merge_flag_t 92 { 93 /** 94 * Detect renames that occur between the common ancestor and the "ours" 95 * side or the common ancestor and the "theirs" side. This will enable 96 * the ability to merge between a modified and renamed file. 97 */ 98 GIT_MERGE_FIND_RENAMES = 1 << 0, 99 100 /** 101 * If a conflict occurs, exit immediately instead of attempting to 102 * continue resolving conflicts. The merge operation will fail with 103 * git_error_code.GIT_EMERGECONFLICT and no index will be returned. 104 */ 105 GIT_MERGE_FAIL_ON_CONFLICT = 1 << 1, 106 107 /** 108 * Do not write the REUC extension on the generated index 109 */ 110 GIT_MERGE_SKIP_REUC = 1 << 2, 111 112 /** 113 * If the commits being merged have multiple merge bases, do not build 114 * a recursive merge base (by merging the multiple merge bases), 115 * instead simply use the first base. This flag provides a similar 116 * merge base to `git-merge-resolve`. 117 */ 118 GIT_MERGE_NO_RECURSIVE = 1 << 3, 119 } 120 121 /** 122 * Merge file favor options for `git_merge_options` instruct the file-level 123 * merging functionality how to deal with conflicting regions of the files. 124 */ 125 enum git_merge_file_favor_t 126 { 127 /** 128 * When a region of a file is changed in both branches, a conflict 129 * will be recorded in the index so that `git_checkout` can produce 130 * a merge file with conflict markers in the working directory. 131 * This is the default. 132 */ 133 GIT_MERGE_FILE_FAVOR_NORMAL = 0, 134 135 /** 136 * When a region of a file is changed in both branches, the file 137 * created in the index will contain the "ours" side of any conflicting 138 * region. The index will not record a conflict. 139 */ 140 GIT_MERGE_FILE_FAVOR_OURS = 1, 141 142 /** 143 * When a region of a file is changed in both branches, the file 144 * created in the index will contain the "theirs" side of any conflicting 145 * region. The index will not record a conflict. 146 */ 147 GIT_MERGE_FILE_FAVOR_THEIRS = 2, 148 149 /** 150 * When a region of a file is changed in both branches, the file 151 * created in the index will contain each unique line from each side, 152 * which has the result of combining both files. The index will not 153 * record a conflict. 154 */ 155 GIT_MERGE_FILE_FAVOR_UNION = 3, 156 } 157 158 /** 159 * File merging flags 160 */ 161 enum git_merge_file_flag_t 162 { 163 /** 164 * Defaults 165 */ 166 GIT_MERGE_FILE_DEFAULT = 0, 167 168 /** 169 * Create standard conflicted merge files 170 */ 171 GIT_MERGE_FILE_STYLE_MERGE = 1 << 0, 172 173 /** 174 * Create diff3-style files 175 */ 176 GIT_MERGE_FILE_STYLE_DIFF3 = 1 << 1, 177 178 /** 179 * Condense non-alphanumeric regions for simplified diff file 180 */ 181 GIT_MERGE_FILE_SIMPLIFY_ALNUM = 1 << 2, 182 183 /** 184 * Ignore all whitespace 185 */ 186 GIT_MERGE_FILE_IGNORE_WHITESPACE = 1 << 3, 187 188 /** 189 * Ignore changes in amount of whitespace 190 */ 191 GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE = 1 << 4, 192 193 /** 194 * Ignore whitespace at end of line 195 */ 196 GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL = 1 << 5, 197 198 /** 199 * Use the "patience diff" algorithm 200 */ 201 GIT_MERGE_FILE_DIFF_PATIENCE = 1 << 6, 202 203 /** 204 * Take extra time to find minimal diff 205 */ 206 GIT_MERGE_FILE_DIFF_MINIMAL = 1 << 7, 207 } 208 209 enum GIT_MERGE_CONFLICT_MARKER_SIZE = 7; 210 211 /** 212 * Options for merging a file 213 */ 214 struct git_merge_file_options 215 { 216 uint version_; 217 218 /** 219 * Label for the ancestor file side of the conflict which will be prepended 220 * to labels in diff3-format merge files. 221 */ 222 const (char)* ancestor_label; 223 224 /** 225 * Label for our file side of the conflict which will be prepended 226 * to labels in merge files. 227 */ 228 const (char)* our_label; 229 230 /** 231 * Label for their file side of the conflict which will be prepended 232 * to labels in merge files. 233 */ 234 const (char)* their_label; 235 236 /** 237 * The file to favor in region conflicts. 238 */ 239 .git_merge_file_favor_t favor; 240 241 /** 242 * see `git_merge_file_flag_t` above 243 */ 244 uint flags; 245 246 /** 247 * The size of conflict markers (eg, "<<<<<<<"). Default is 248 * GIT_MERGE_CONFLICT_MARKER_SIZE. 249 */ 250 ushort marker_size; 251 } 252 253 enum GIT_MERGE_FILE_OPTIONS_VERSION = 1; 254 255 pragma(inline, true) 256 pure nothrow @safe @nogc 257 .git_merge_file_options GIT_MERGE_FILE_OPTIONS_INIT() 258 259 do 260 { 261 .git_merge_file_options OUTPUT = 262 { 263 version_: .GIT_MERGE_FILE_OPTIONS_VERSION, 264 }; 265 266 return OUTPUT; 267 } 268 269 /** 270 * Initialize git_merge_file_options structure 271 * 272 * Initializes a `git_merge_file_options` with default values. Equivalent to 273 * creating an instance with `GIT_MERGE_FILE_OPTIONS_INIT`. 274 * 275 * Params: 276 * opts = The `git_merge_file_options` struct to initialize. 277 * version = The struct version; pass `GIT_MERGE_FILE_OPTIONS_VERSION`. 278 * 279 * Returns: Zero on success; -1 on failure. 280 */ 281 //GIT_EXTERN 282 int git_merge_file_options_init(.git_merge_file_options* opts, uint version_); 283 284 /** 285 * Information about file-level merging 286 */ 287 struct git_merge_file_result 288 { 289 /** 290 * True if the output was automerged, false if the output contains 291 * conflict markers. 292 */ 293 uint automergeable; 294 295 /** 296 * The path that the resultant merge file should use, or null if a 297 * filename conflict would occur. 298 */ 299 const (char)* path; 300 301 /** 302 * The mode that the resultant merge file should use. 303 */ 304 uint mode; 305 306 /** 307 * The contents of the merge. 308 */ 309 const (char)* ptr_; 310 311 /** 312 * The length of the merge contents. 313 */ 314 size_t len; 315 } 316 317 /** 318 * Merging options 319 */ 320 struct git_merge_options 321 { 322 uint version_; 323 324 /** 325 * See `git_merge_flag_t` above 326 */ 327 uint flags; 328 329 /** 330 * Similarity to consider a file renamed (default 50). If 331 * `git_merge_flag_t.GIT_MERGE_FIND_RENAMES` is enabled, added files will be compared 332 * with deleted files to determine their similarity. Files that are 333 * more similar than the rename threshold (percentage-wise) will be 334 * treated as a rename. 335 */ 336 uint rename_threshold; 337 338 /** 339 * Maximum similarity sources to examine for renames (default 200). 340 * If the number of rename candidates (add / delete pairs) is greater 341 * than this value, inexact rename detection is aborted. 342 * 343 * This setting overrides the `merge.renameLimit` configuration value. 344 */ 345 uint target_limit; 346 347 /** 348 * Pluggable similarity metric; pass null to use internal metric 349 */ 350 libgit2_d.diff.git_diff_similarity_metric* metric; 351 352 /** 353 * Maximum number of times to merge common ancestors to build a 354 * virtual merge base when faced with criss-cross merges. When this 355 * limit is reached, the next ancestor will simply be used instead of 356 * attempting to merge it. The default is unlimited. 357 */ 358 uint recursion_limit; 359 360 /** 361 * Default merge driver to be used when both sides of a merge have 362 * changed. The default is the `text` driver. 363 */ 364 const (char)* default_driver; 365 366 /** 367 * Flags for handling conflicting content, to be used with the standard 368 * (`text`) merge driver. 369 */ 370 .git_merge_file_favor_t file_favor; 371 372 /** 373 * see `git_merge_file_flag_t` above 374 */ 375 uint file_flags; 376 } 377 378 enum GIT_MERGE_OPTIONS_VERSION = 1; 379 380 pragma(inline, true) 381 pure nothrow @safe @nogc 382 .git_merge_options GIT_MERGE_OPTIONS_INIT() 383 384 do 385 { 386 .git_merge_options OUTPUT = 387 { 388 version_: .GIT_MERGE_OPTIONS_VERSION, 389 flags: .git_merge_flag_t.GIT_MERGE_FIND_RENAMES, 390 }; 391 392 return OUTPUT; 393 } 394 395 /** 396 * Initialize git_merge_options structure 397 * 398 * Initializes a `git_merge_options` with default values. Equivalent to 399 * creating an instance with `GIT_MERGE_OPTIONS_INIT`. 400 * 401 * Params: 402 * opts = The `git_merge_options` struct to initialize. 403 * version = The struct version; pass `GIT_MERGE_OPTIONS_VERSION`. 404 * 405 * Returns: Zero on success; -1 on failure. 406 */ 407 //GIT_EXTERN 408 int git_merge_options_init(.git_merge_options* opts, uint version_); 409 410 /** 411 * The results of `git_merge_analysis` indicate the merge opportunities. 412 */ 413 enum git_merge_analysis_t 414 { 415 /** 416 * No merge is possible. (Unused.) 417 */ 418 GIT_MERGE_ANALYSIS_NONE = 0, 419 420 /** 421 * A "normal" merge; both HEAD and the given merge input have diverged 422 * from their common ancestor. The divergent commits must be merged. 423 */ 424 GIT_MERGE_ANALYSIS_NORMAL = 1 << 0, 425 426 /** 427 * All given merge inputs are reachable from HEAD, meaning the 428 * repository is up-to-date and no merge needs to be performed. 429 */ 430 GIT_MERGE_ANALYSIS_UP_TO_DATE = 1 << 1, 431 432 /** 433 * The given merge input is a fast-forward from HEAD and no merge 434 * needs to be performed. Instead, the client can check out the 435 * given merge input. 436 */ 437 GIT_MERGE_ANALYSIS_FASTFORWARD = 1 << 2, 438 439 /** 440 * The HEAD of the current repository is "unborn" and does not point to 441 * a valid commit. No merge can be performed, but the caller may wish 442 * to simply set HEAD to the target commit(s). 443 */ 444 GIT_MERGE_ANALYSIS_UNBORN = 1 << 3, 445 } 446 447 /** 448 * The user's stated preference for merges. 449 */ 450 enum git_merge_preference_t 451 { 452 /** 453 * No configuration was found that suggests a preferred behavior for 454 * merge. 455 */ 456 GIT_MERGE_PREFERENCE_NONE = 0, 457 458 /** 459 * There is a `merge.ff=false` configuration setting, suggesting that 460 * the user does not want to allow a fast-forward merge. 461 */ 462 GIT_MERGE_PREFERENCE_NO_FASTFORWARD = 1 << 0, 463 464 /** 465 * There is a `merge.ff=only` configuration setting, suggesting that 466 * the user only wants fast-forward merges. 467 */ 468 GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = 1 << 1, 469 } 470 471 /** 472 * Analyzes the given branch(es) and determines the opportunities for 473 * merging them into the HEAD of the repository. 474 * 475 * Params: 476 * analysis_out = analysis enumeration that the result is written into 477 * repo = the repository to merge 478 * their_heads = the heads to merge into 479 * their_heads_len = the number of heads to merge 480 * 481 * Returns: 0 on success or error code 482 */ 483 //GIT_EXTERN 484 int git_merge_analysis(.git_merge_analysis_t* analysis_out, .git_merge_preference_t* preference_out, libgit2_d.types.git_repository* repo, const (libgit2_d.types.git_annotated_commit)** their_heads, size_t their_heads_len); 485 486 /** 487 * Analyzes the given branch(es) and determines the opportunities for 488 * merging them into a reference. 489 * 490 * Params: 491 * analysis_out = analysis enumeration that the result is written into 492 * repo = the repository to merge 493 * our_ref = the reference to perform the analysis from 494 * their_heads = the heads to merge into 495 * their_heads_len = the number of heads to merge 496 * 497 * Returns: 0 on success or error code 498 */ 499 //GIT_EXTERN 500 int git_merge_analysis_for_ref(.git_merge_analysis_t* analysis_out, .git_merge_preference_t* preference_out, libgit2_d.types.git_repository* repo, libgit2_d.types.git_reference* our_ref, const (libgit2_d.types.git_annotated_commit)** their_heads, size_t their_heads_len); 501 502 /** 503 * Find a merge base between two commits 504 * 505 * Params: 506 * out_ = the OID of a merge base between 'one' and 'two' 507 * repo = the repository where the commits exist 508 * one = one of the commits 509 * two = the other commit 510 * 511 * Returns: 0 on success, git_error_code.GIT_ENOTFOUND if not found or error code 512 */ 513 //GIT_EXTERN 514 int git_merge_base(libgit2_d.oid.git_oid* out_, libgit2_d.types.git_repository* repo, const (libgit2_d.oid.git_oid)* one, const (libgit2_d.oid.git_oid)* two); 515 516 /** 517 * Find merge bases between two commits 518 * 519 * Params: 520 * out_ = array in which to store the resulting ids 521 * repo = the repository where the commits exist 522 * one = one of the commits 523 * two = the other commit 524 * 525 * Returns: 0 on success, git_error_code.GIT_ENOTFOUND if not found or error code 526 */ 527 //GIT_EXTERN 528 int git_merge_bases(libgit2_d.oidarray.git_oidarray* out_, libgit2_d.types.git_repository* repo, const (libgit2_d.oid.git_oid)* one, const (libgit2_d.oid.git_oid)* two); 529 530 /** 531 * Find a merge base given a list of commits 532 * 533 * Params: 534 * out_ = the OID of a merge base considering all the commits 535 * repo = the repository where the commits exist 536 * length = The number of commits in the provided `input_array` 537 * input_array = oids of the commits 538 * 539 * Returns: Zero on success; git_error_code.GIT_ENOTFOUND or -1 on failure. 540 */ 541 //GIT_EXTERN 542 int git_merge_base_many(libgit2_d.oid.git_oid* out_, libgit2_d.types.git_repository* repo, size_t length, const libgit2_d.oid.git_oid[] input_array); 543 544 /** 545 * Find all merge bases given a list of commits 546 * 547 * Params: 548 * out_ = array in which to store the resulting ids 549 * repo = the repository where the commits exist 550 * length = The number of commits in the provided `input_array` 551 * input_array = oids of the commits 552 * 553 * Returns: Zero on success; git_error_code.GIT_ENOTFOUND or -1 on failure. 554 */ 555 //GIT_EXTERN 556 int git_merge_bases_many(libgit2_d.oidarray.git_oidarray* out_, libgit2_d.types.git_repository* repo, size_t length, const libgit2_d.oid.git_oid[] input_array); 557 558 /** 559 * Find a merge base in preparation for an octopus merge 560 * 561 * Params: 562 * out_ = the OID of a merge base considering all the commits 563 * repo = the repository where the commits exist 564 * length = The number of commits in the provided `input_array` 565 * input_array = oids of the commits 566 * 567 * Returns: Zero on success; git_error_code.GIT_ENOTFOUND or -1 on failure. 568 */ 569 //GIT_EXTERN 570 int git_merge_base_octopus(libgit2_d.oid.git_oid* out_, libgit2_d.types.git_repository* repo, size_t length, const libgit2_d.oid.git_oid[] input_array); 571 572 /** 573 * Merge two files as they exist in the in-memory data structures, using 574 * the given common ancestor as the baseline, producing a 575 * `git_merge_file_result` that reflects the merge result. The 576 * `git_merge_file_result` must be freed with `git_merge_file_result_free`. 577 * 578 * Note that this function does not reference a repository and any 579 * configuration must be passed as `git_merge_file_options`. 580 * 581 * Params: 582 * out_ = The git_merge_file_result to be filled in 583 * ancestor = The contents of the ancestor file 584 * ours = The contents of the file in "our" side 585 * theirs = The contents of the file in "their" side 586 * opts = The merge file options or `null` for defaults 587 * 588 * Returns: 0 on success or error code 589 */ 590 //GIT_EXTERN 591 int git_merge_file(.git_merge_file_result* out_, const (.git_merge_file_input)* ancestor, const (.git_merge_file_input)* ours, const (.git_merge_file_input)* theirs, const (.git_merge_file_options)* opts); 592 593 /** 594 * Merge two files as they exist in the index, using the given common 595 * ancestor as the baseline, producing a `git_merge_file_result` that 596 * reflects the merge result. The `git_merge_file_result` must be freed with 597 * `git_merge_file_result_free`. 598 * 599 * Params: 600 * out_ = The git_merge_file_result to be filled in 601 * repo = The repository 602 * ancestor = The index entry for the ancestor file (stage level 1) 603 * ours = The index entry for our file (stage level 2) 604 * theirs = The index entry for their file (stage level 3) 605 * opts = The merge file options or null 606 * 607 * Returns: 0 on success or error code 608 */ 609 //GIT_EXTERN 610 int git_merge_file_from_index(.git_merge_file_result* out_, libgit2_d.types.git_repository* repo, const (libgit2_d.index.git_index_entry)* ancestor, const (libgit2_d.index.git_index_entry)* ours, const (libgit2_d.index.git_index_entry)* theirs, const (.git_merge_file_options)* opts); 611 612 /** 613 * Frees a `git_merge_file_result`. 614 * 615 * Params: 616 * result = The result to free or `null` 617 */ 618 //GIT_EXTERN 619 void git_merge_file_result_free(.git_merge_file_result* result); 620 621 /** 622 * Merge two trees, producing a `git_index` that reflects the result of 623 * the merge. The index may be written as-is to the working directory 624 * or checked out. If the index is to be converted to a tree, the caller 625 * should resolve any conflicts that arose as part of the merge. 626 * 627 * The returned index must be freed explicitly with `git_index_free`. 628 * 629 * Params: 630 * out_ = pointer to store the index result in 631 * repo = repository that contains the given trees 632 * ancestor_tree = the common ancestor between the trees (or null if none) 633 * our_tree = the tree that reflects the destination tree 634 * their_tree = the tree to merge in to `our_tree` 635 * opts = the merge tree options (or null for defaults) 636 * 637 * Returns: 0 on success or error code 638 */ 639 //GIT_EXTERN 640 int git_merge_trees(libgit2_d.types.git_index** out_, libgit2_d.types.git_repository* repo, const (libgit2_d.types.git_tree)* ancestor_tree, const (libgit2_d.types.git_tree)* our_tree, const (libgit2_d.types.git_tree)* their_tree, const (.git_merge_options)* opts); 641 642 /** 643 * Merge two commits, producing a `git_index` that reflects the result of 644 * the merge. The index may be written as-is to the working directory 645 * or checked out. If the index is to be converted to a tree, the caller 646 * should resolve any conflicts that arose as part of the merge. 647 * 648 * The returned index must be freed explicitly with `git_index_free`. 649 * 650 * Params: 651 * out_ = pointer to store the index result in 652 * repo = repository that contains the given trees 653 * our_commit = the commit that reflects the destination tree 654 * their_commit = the commit to merge in to `our_commit` 655 * opts = the merge tree options (or null for defaults) 656 * 657 * Returns: 0 on success or error code 658 */ 659 //GIT_EXTERN 660 int git_merge_commits(libgit2_d.types.git_index** out_, libgit2_d.types.git_repository* repo, const (libgit2_d.types.git_commit)* our_commit, const (libgit2_d.types.git_commit)* their_commit, const (.git_merge_options)* opts); 661 662 /** 663 * Merges the given commit(s) into HEAD, writing the results into the working 664 * directory. Any changes are staged for commit and any conflicts are written 665 * to the index. Callers should inspect the repository's index after this 666 * completes, resolve any conflicts and prepare a commit. 667 * 668 * For compatibility with git, the repository is put into a merging 669 * state. Once the commit is done (or if the uses wishes to abort), 670 * you should clear this state by calling 671 * `git_repository_state_cleanup()`. 672 * 673 * Params: 674 * repo = the repository to merge 675 * their_heads = the heads to merge into 676 * their_heads_len = the number of heads to merge 677 * merge_opts = merge options 678 * checkout_opts = checkout options 679 * 680 * Returns: 0 on success or error code 681 */ 682 //GIT_EXTERN 683 int git_merge(libgit2_d.types.git_repository* repo, const (libgit2_d.types.git_annotated_commit)** their_heads, size_t their_heads_len, const (.git_merge_options)* merge_opts, const (libgit2_d.checkout.git_checkout_options)* checkout_opts); 684 685 /** @} */