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