Git fork
at reftables-rust 181 lines 5.6 kB view raw
1#ifndef MERGE_ORT_H 2#define MERGE_ORT_H 3 4#include "hash.h" 5#include "strbuf.h" 6 7struct commit; 8struct commit_list; 9struct tree; 10struct strmap; 11 12struct merge_result { 13 /* 14 * Whether the merge is clean; possible values: 15 * 1: clean 16 * 0: not clean (merge conflicts) 17 * <0: operation aborted prematurely. (object database 18 * unreadable, disk full, etc.) Worktree may be left in an 19 * inconsistent state if operation failed near the end. 20 */ 21 int clean; 22 23 /* 24 * Result of merge. If !clean, represents what would go in worktree 25 * (thus possibly including files containing conflict markers). 26 */ 27 struct tree *tree; 28 29 /* 30 * Special messages and conflict notices for various paths 31 * 32 * This is a map of pathnames to a string_list. It contains various 33 * warning/conflict/notice messages (possibly multiple per path) 34 * that callers may want to use. 35 */ 36 struct strmap *path_messages; 37 38 /* 39 * Additional metadata used by merge_switch_to_result() or future calls 40 * to merge_incore_*(). Includes data needed to update the index (if 41 * !clean) and to print "CONFLICT" messages. Not for external use. 42 */ 43 void *priv; 44 /* Also private */ 45 unsigned _properly_initialized; 46}; 47 48struct merge_options_internal; 49struct merge_options { 50 struct repository *repo; 51 52 /* ref names used in console messages and conflict markers */ 53 const char *ancestor; 54 const char *branch1; 55 const char *branch2; 56 57 /* rename related options */ 58 int detect_renames; 59 enum { 60 MERGE_DIRECTORY_RENAMES_NONE = 0, 61 MERGE_DIRECTORY_RENAMES_CONFLICT = 1, 62 MERGE_DIRECTORY_RENAMES_TRUE = 2 63 } detect_directory_renames; 64 int rename_limit; 65 int rename_score; 66 int show_rename_progress; 67 68 /* xdiff-related options (patience, ignore whitespace, ours/theirs) */ 69 long xdl_opts; 70 int conflict_style; 71 enum { 72 MERGE_VARIANT_NORMAL = 0, 73 MERGE_VARIANT_OURS, 74 MERGE_VARIANT_THEIRS 75 } recursive_variant; 76 77 /* console output related options */ 78 int verbosity; 79 unsigned buffer_output; /* 1: output at end, 2: keep buffered */ 80 struct strbuf obuf; /* output buffer; if buffer_output == 2, caller 81 * must handle and call strbuf_release */ 82 83 /* miscellaneous control options */ 84 const char *subtree_shift; 85 unsigned renormalize : 1; 86 unsigned mergeability_only : 1; /* exit early, write fewer objects */ 87 unsigned record_conflict_msgs_as_headers : 1; 88 const char *msg_header_prefix; 89 90 /* internal fields used by the implementation */ 91 struct merge_options_internal *priv; 92}; 93 94/* Mostly internal function also used by merge-ort-wrappers.c */ 95struct commit *make_virtual_commit(struct repository *repo, 96 struct tree *tree, 97 const char *comment); 98 99/* 100 * rename-detecting three-way merge with recursive ancestor consolidation. 101 * working tree and index are untouched. 102 * 103 * merge_bases will be consumed (emptied) so make a copy if you need it. 104 * 105 * NOTE: empirically, the recursive algorithm will perform better if you 106 * pass the merge_bases in the order of oldest commit to the 107 * newest[1][2]. 108 * 109 * [1] https://lore.kernel.org/git/nycvar.QRO.7.76.6.1907252055500.21907@tvgsbejvaqbjf.bet/ 110 * [2] commit 8918b0c9c2 ("merge-recur: try to merge older merge bases 111 * first", 2006-08-09) 112 */ 113void merge_incore_recursive(struct merge_options *opt, 114 const struct commit_list *merge_bases, 115 struct commit *side1, 116 struct commit *side2, 117 struct merge_result *result); 118 119/* 120 * rename-detecting three-way merge, no recursion. 121 * working tree and index are untouched. 122 */ 123void merge_incore_nonrecursive(struct merge_options *opt, 124 struct tree *merge_base, 125 struct tree *side1, 126 struct tree *side2, 127 struct merge_result *result); 128 129/* Update the working tree and index from head to result after incore merge */ 130void merge_switch_to_result(struct merge_options *opt, 131 struct tree *head, 132 struct merge_result *result, 133 int update_worktree_and_index, 134 int display_update_msgs); 135 136/* 137 * Display messages about conflicts and which files were 3-way merged. 138 * Automatically called by merge_switch_to_result() with stream == stdout, 139 * so only call this when bypassing merge_switch_to_result(). 140 */ 141void merge_display_update_messages(struct merge_options *opt, 142 int detailed, 143 struct merge_result *result); 144 145struct stage_info { 146 struct object_id oid; 147 int mode; 148 int stage; 149}; 150 151/* 152 * Provide a list of path -> {struct stage_info*} mappings for 153 * all conflicted files. Note that each path could appear up to three 154 * times in the list, corresponding to 3 different stage entries. In short, 155 * this basically provides the info that would be printed by `ls-files -u`. 156 * 157 * result should have been populated by a call to 158 * one of the merge_incore_[non]recursive() functions. 159 * 160 * conflicted_files should be empty before calling this function. 161 */ 162void merge_get_conflicted_files(struct merge_result *result, 163 struct string_list *conflicted_files); 164 165/* Do needed cleanup when not calling merge_switch_to_result() */ 166void merge_finalize(struct merge_options *opt, 167 struct merge_result *result); 168 169 170/* for use by porcelain commands */ 171void init_ui_merge_options(struct merge_options *opt, struct repository *repo); 172/* for use by plumbing commands */ 173void init_basic_merge_options(struct merge_options *opt, struct repository *repo); 174 175void copy_merge_options(struct merge_options *dst, struct merge_options *src); 176void clear_merge_options(struct merge_options *opt); 177 178/* parse the option in s and update the relevant field of opt */ 179int parse_merge_opt(struct merge_options *opt, const char *s); 180 181#endif