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