blob: b88000e3c25277d07d20b7ba29755b9670cd28ff [file] [log] [blame]
Daniel Barkalowe1b3a2c2008-02-07 11:40:05 -05001#ifndef MERGE_RECURSIVE_H
2#define MERGE_RECURSIVE_H
3
Elijah Newren5bf7e572019-08-17 11:41:41 -07004#include "strbuf.h"
Elijah Newrenef3ca952018-08-15 10:54:05 -07005
6struct commit;
Elijah Newren5bf7e572019-08-17 11:41:41 -07007struct commit_list;
8struct object_id;
Nguyễn Thái Ngọc Duy0d6caa22019-01-12 09:13:29 +07009struct repository;
Elijah Newren5bf7e572019-08-17 11:41:41 -070010struct tree;
Nguyễn Thái Ngọc Duy0d6caa22019-01-12 09:13:29 +070011
Elijah Newren5bf7e572019-08-17 11:41:41 -070012struct merge_options_internal;
Miklos Vajna8a2fce12008-08-25 16:25:57 +020013struct merge_options {
Elijah Newrena779fb82019-08-17 11:41:39 -070014 struct repository *repo;
15
16 /* ref names used in console messages and conflict markers */
Jonathan Nieder4c5868f2010-03-20 19:41:38 -050017 const char *ancestor;
Miklos Vajna8a2fce12008-08-25 16:25:57 +020018 const char *branch1;
19 const char *branch2;
Elijah Newrena779fb82019-08-17 11:41:39 -070020
21 /* rename related options */
22 int detect_renames;
Derrick Stolee8e012512019-08-17 11:41:25 -070023 enum {
24 MERGE_DIRECTORY_RENAMES_NONE = 0,
25 MERGE_DIRECTORY_RENAMES_CONFLICT = 1,
26 MERGE_DIRECTORY_RENAMES_TRUE = 2
27 } detect_directory_renames;
Elijah Newren8599ab42019-08-17 11:41:38 -070028 int rename_limit;
Kevin Ballard10ae7522010-09-27 16:58:25 -070029 int rename_score;
Jeff King99bfc662011-02-20 04:53:21 -050030 int show_rename_progress;
Elijah Newrena779fb82019-08-17 11:41:39 -070031
32 /* xdiff-related options (patience, ignore whitespace, ours/theirs) */
33 long xdl_opts;
34 enum {
Elijah Newrenf3081da2019-08-17 11:41:42 -070035 MERGE_VARIANT_NORMAL = 0,
36 MERGE_VARIANT_OURS,
37 MERGE_VARIANT_THEIRS
Elijah Newrena779fb82019-08-17 11:41:39 -070038 } recursive_variant;
39
40 /* console output related options */
41 int verbosity;
42 unsigned buffer_output; /* 1: output at end, 2: keep buffered */
Elijah Newrene95e4812019-08-17 11:41:40 -070043 struct strbuf obuf; /* output buffer; if buffer_output == 2, caller
44 * must handle and call strbuf_release */
Elijah Newrena779fb82019-08-17 11:41:39 -070045
46 /* miscellaneous control options */
47 const char *subtree_shift;
48 unsigned renormalize : 1;
Elijah Newren6054d1a2022-02-02 02:37:33 +000049 unsigned record_conflict_msgs_as_headers : 1;
50 const char *msg_header_prefix;
Elijah Newrena779fb82019-08-17 11:41:39 -070051
Elijah Newren5bf7e572019-08-17 11:41:41 -070052 /* internal fields used by the implementation */
53 struct merge_options_internal *priv;
Elijah Newrenea625cb2018-02-14 10:51:57 -080054};
55
Elijah Newren7c0a6c82019-08-17 11:41:37 -070056void init_merge_options(struct merge_options *opt, struct repository *repo);
57
58/* parse the option in s and update the relevant field of opt */
59int parse_merge_opt(struct merge_options *opt, const char *s);
60
Elijah Newren7fe40b82018-04-19 10:58:05 -070061/*
Elijah Newren7c0a6c82019-08-17 11:41:37 -070062 * RETURN VALUES: All the merge_* functions below return a value as follows:
63 * > 0 Merge was clean
64 * = 0 Merge had conflicts
65 * < 0 Merge hit an unexpected and unrecoverable problem (e.g. disk
66 * full) and aborted merge part-way through.
Elijah Newren7fe40b82018-04-19 10:58:05 -070067 */
Elijah Newren7fe40b82018-04-19 10:58:05 -070068
Elijah Newren7c0a6c82019-08-17 11:41:37 -070069/*
70 * rename-detecting three-way merge, no recursion.
71 *
72 * Outputs:
73 * - See RETURN VALUES above
Elijah Newren7c0a6c82019-08-17 11:41:37 -070074 * - opt->repo->index has the new index
Elijah Newren56e74342020-08-02 03:14:27 +000075 * - new index NOT written to disk
Elijah Newren7c0a6c82019-08-17 11:41:37 -070076 * - The working tree is updated with results of the merge
77 */
78int merge_trees(struct merge_options *opt,
79 struct tree *head,
80 struct tree *merge,
81 struct tree *merge_base);
Ben Peart85b46032018-05-02 16:01:14 +000082
Elijah Newrenb4db8a22019-08-17 11:41:30 -070083/*
84 * merge_recursive is like merge_trees() but with recursive ancestor
Elijah Newren56e74342020-08-02 03:14:27 +000085 * consolidation.
Elijah Newrenb4db8a22019-08-17 11:41:30 -070086 *
87 * NOTE: empirically, about a decade ago it was determined that with more
88 * than two merge bases, optimal behavior was found when the
Elijah Newrenff1bfa22019-08-17 11:41:34 -070089 * merge_bases were passed in the order of oldest commit to newest
90 * commit. Also, merge_bases will be consumed (emptied) so make a
91 * copy if you need it.
Elijah Newren7c0a6c82019-08-17 11:41:37 -070092 *
93 * Outputs:
94 * - See RETURN VALUES above
Elijah Newren56e74342020-08-02 03:14:27 +000095 * - *result is treated as scratch space for temporary recursive merges
Elijah Newren7c0a6c82019-08-17 11:41:37 -070096 * - opt->repo->index has the new index
Elijah Newren56e74342020-08-02 03:14:27 +000097 * - new index NOT written to disk
Elijah Newren7c0a6c82019-08-17 11:41:37 -070098 * - The working tree is updated with results of the merge
Elijah Newrenb4db8a22019-08-17 11:41:30 -070099 */
Elijah Newrenc749ab12019-08-17 11:41:36 -0700100int merge_recursive(struct merge_options *opt,
Miklos Vajna8a2fce12008-08-25 16:25:57 +0200101 struct commit *h1,
Daniel Barkalowe1b3a2c2008-02-07 11:40:05 -0500102 struct commit *h2,
Elijah Newrenff1bfa22019-08-17 11:41:34 -0700103 struct commit_list *merge_bases,
Daniel Barkalowe1b3a2c2008-02-07 11:40:05 -0500104 struct commit **result);
105
Elijah Newrenb4db8a22019-08-17 11:41:30 -0700106/*
Elijah Newren7c0a6c82019-08-17 11:41:37 -0700107 * merge_recursive_generic can operate on trees instead of commits, by
108 * wrapping the trees into virtual commits, and calling merge_recursive().
109 * It also writes out the in-memory index to disk if the merge is successful.
110 *
111 * Outputs:
112 * - See RETURN VALUES above
Elijah Newren56e74342020-08-02 03:14:27 +0000113 * - *result is treated as scratch space for temporary recursive merges
Elijah Newren7c0a6c82019-08-17 11:41:37 -0700114 * - opt->repo->index has the new index
Elijah Newren56e74342020-08-02 03:14:27 +0000115 * - new index also written to $GIT_INDEX_FILE on disk
Elijah Newren7c0a6c82019-08-17 11:41:37 -0700116 * - The working tree is updated with results of the merge
Miklos Vajna8a2fce12008-08-25 16:25:57 +0200117 */
Elijah Newrenc749ab12019-08-17 11:41:36 -0700118int merge_recursive_generic(struct merge_options *opt,
brian m. carlson4e8161a2016-06-24 23:09:28 +0000119 const struct object_id *head,
120 const struct object_id *merge,
Elijah Newrenff1bfa22019-08-17 11:41:34 -0700121 int num_merge_bases,
122 const struct object_id **merge_bases,
Miklos Vajna8a2fce12008-08-25 16:25:57 +0200123 struct commit **result);
124
Daniel Barkalowe1b3a2c2008-02-07 11:40:05 -0500125#endif