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