]>
Commit | Line | Data |
---|---|---|
632d8b23 | 1 | /* |
359fc2d2 | 2 | * Copyright (C) the libgit2 contributors. All rights reserved. |
632d8b23 ET |
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 | #ifndef INCLUDE_merge_h__ | |
8 | #define INCLUDE_merge_h__ | |
9 | ||
eae0bfdc PP |
10 | #include "common.h" |
11 | ||
42e50b5e | 12 | #include "vector.h" |
bec65a5e ET |
13 | #include "commit_list.h" |
14 | #include "pool.h" | |
9ebb5a3f | 15 | #include "iterator.h" |
bec65a5e | 16 | |
bec65a5e | 17 | #include "git2/types.h" |
3f04219f ET |
18 | #include "git2/merge.h" |
19 | #include "git2/sys/merge.h" | |
632d8b23 ET |
20 | |
21 | #define GIT_MERGE_MSG_FILE "MERGE_MSG" | |
22 | #define GIT_MERGE_MODE_FILE "MERGE_MODE" | |
1d3a8aeb | 23 | #define GIT_MERGE_FILE_MODE 0666 |
632d8b23 | 24 | |
fa78782f ET |
25 | #define GIT_MERGE_DEFAULT_RENAME_THRESHOLD 50 |
26 | #define GIT_MERGE_DEFAULT_TARGET_LIMIT 1000 | |
bec65a5e ET |
27 | |
28 | /** Types of changes when files are merged from branch to branch. */ | |
29 | typedef enum { | |
30 | /* No conflict - a change only occurs in one branch. */ | |
31 | GIT_MERGE_DIFF_NONE = 0, | |
1fed6b07 | 32 | |
bec65a5e ET |
33 | /* Occurs when a file is modified in both branches. */ |
34 | GIT_MERGE_DIFF_BOTH_MODIFIED = (1 << 0), | |
1fed6b07 | 35 | |
bec65a5e ET |
36 | /* Occurs when a file is added in both branches. */ |
37 | GIT_MERGE_DIFF_BOTH_ADDED = (1 << 1), | |
1fed6b07 | 38 | |
bec65a5e ET |
39 | /* Occurs when a file is deleted in both branches. */ |
40 | GIT_MERGE_DIFF_BOTH_DELETED = (1 << 2), | |
1fed6b07 | 41 | |
bec65a5e ET |
42 | /* Occurs when a file is modified in one branch and deleted in the other. */ |
43 | GIT_MERGE_DIFF_MODIFIED_DELETED = (1 << 3), | |
1fed6b07 | 44 | |
bec65a5e ET |
45 | /* Occurs when a file is renamed in one branch and modified in the other. */ |
46 | GIT_MERGE_DIFF_RENAMED_MODIFIED = (1 << 4), | |
1fed6b07 | 47 | |
bec65a5e ET |
48 | /* Occurs when a file is renamed in one branch and deleted in the other. */ |
49 | GIT_MERGE_DIFF_RENAMED_DELETED = (1 << 5), | |
1fed6b07 | 50 | |
bec65a5e ET |
51 | /* Occurs when a file is renamed in one branch and a file with the same |
52 | * name is added in the other. Eg, A->B and new file B. Core git calls | |
53 | * this a "rename/delete". */ | |
54 | GIT_MERGE_DIFF_RENAMED_ADDED = (1 << 6), | |
1fed6b07 | 55 | |
bec65a5e ET |
56 | /* Occurs when both a file is renamed to the same name in the ours and |
57 | * theirs branches. Eg, A->B and A->B in both. Automergeable. */ | |
58 | GIT_MERGE_DIFF_BOTH_RENAMED = (1 << 7), | |
1fed6b07 | 59 | |
bec65a5e ET |
60 | /* Occurs when a file is renamed to different names in the ours and theirs |
61 | * branches. Eg, A->B and A->C. */ | |
62 | GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2 = (1 << 8), | |
1fed6b07 | 63 | |
bec65a5e ET |
64 | /* Occurs when two files are renamed to the same name in the ours and |
65 | * theirs branches. Eg, A->C and B->C. */ | |
66 | GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 = (1 << 9), | |
1fed6b07 | 67 | |
bec65a5e ET |
68 | /* Occurs when an item at a path in one branch is a directory, and an |
69 | * item at the same path in a different branch is a file. */ | |
70 | GIT_MERGE_DIFF_DIRECTORY_FILE = (1 << 10), | |
1fed6b07 | 71 | |
bec65a5e | 72 | /* The child of a folder that is in a directory/file conflict. */ |
e579e0f7 | 73 | GIT_MERGE_DIFF_DF_CHILD = (1 << 11) |
22a2d3d5 | 74 | } git_merge_diff_t; |
bec65a5e | 75 | |
bec65a5e | 76 | typedef struct { |
0cb16fe9 L |
77 | git_repository *repo; |
78 | git_pool pool; | |
1fed6b07 | 79 | |
0cb16fe9 | 80 | /* Vector of git_index_entry that represent the merged items that |
bec65a5e ET |
81 | * have been staged, either because only one side changed, or because |
82 | * the two changes were non-conflicting and mergeable. These items | |
83 | * will be written as staged entries in the main index. | |
84 | */ | |
0cb16fe9 | 85 | git_vector staged; |
1fed6b07 | 86 | |
0cb16fe9 | 87 | /* Vector of git_merge_diff entries that represent the conflicts that |
bec65a5e ET |
88 | * have not been automerged. These items will be written to high-stage |
89 | * entries in the main index. | |
90 | */ | |
0cb16fe9 | 91 | git_vector conflicts; |
1fed6b07 | 92 | |
0cb16fe9 | 93 | /* Vector of git_merge_diff that have been automerged. These items |
bec65a5e ET |
94 | * will be written to the REUC when the index is produced. |
95 | */ | |
0cb16fe9 | 96 | git_vector resolved; |
bec65a5e ET |
97 | } git_merge_diff_list; |
98 | ||
99 | /** | |
100 | * Description of changes to one file across three trees. | |
101 | */ | |
102 | typedef struct { | |
22a2d3d5 | 103 | git_merge_diff_t type; |
1fed6b07 | 104 | |
0cb16fe9 | 105 | git_index_entry ancestor_entry; |
1fed6b07 | 106 | |
0cb16fe9 L |
107 | git_index_entry our_entry; |
108 | git_delta_t our_status; | |
1fed6b07 | 109 | |
0cb16fe9 L |
110 | git_index_entry their_entry; |
111 | git_delta_t their_status; | |
6b92c99b | 112 | |
bec65a5e ET |
113 | } git_merge_diff; |
114 | ||
115 | int git_merge__bases_many( | |
116 | git_commit_list **out, | |
117 | git_revwalk *walk, | |
118 | git_commit_list_node *one, | |
c25aa7cd PP |
119 | git_vector *twos, |
120 | uint32_t minimum_generation); | |
bec65a5e | 121 | |
9c06b250 ET |
122 | /* |
123 | * Three-way tree differencing | |
124 | */ | |
125 | ||
bec65a5e ET |
126 | git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo); |
127 | ||
9ebb5a3f ET |
128 | int git_merge_diff_list__find_differences( |
129 | git_merge_diff_list *merge_diff_list, | |
130 | git_iterator *ancestor_iterator, | |
131 | git_iterator *ours_iter, | |
132 | git_iterator *theirs_iter); | |
bec65a5e | 133 | |
5aa2ac6d | 134 | int git_merge_diff_list__find_renames(git_repository *repo, git_merge_diff_list *merge_diff_list, const git_merge_options *opts); |
632d8b23 | 135 | |
bec65a5e | 136 | void git_merge_diff_list__free(git_merge_diff_list *diff_list); |
632d8b23 | 137 | |
9c06b250 ET |
138 | /* Merge metadata setup */ |
139 | ||
140 | int git_merge__setup( | |
141 | git_repository *repo, | |
18b00406 ET |
142 | const git_annotated_commit *our_head, |
143 | const git_annotated_commit *heads[], | |
1c0b6a38 | 144 | size_t heads_len); |
9c06b250 | 145 | |
9ebb5a3f ET |
146 | int git_merge__iterators( |
147 | git_index **out, | |
148 | git_repository *repo, | |
149 | git_iterator *ancestor_iter, | |
150 | git_iterator *our_iter, | |
151 | git_iterator *their_iter, | |
152 | const git_merge_options *given_opts); | |
153 | ||
967f5a76 | 154 | int git_merge__check_result(git_repository *repo, git_index *index_new); |
300d192f | 155 | |
399f2b62 JG |
156 | int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index); |
157 | ||
3f04219f ET |
158 | /* Merge files */ |
159 | ||
160 | GIT_INLINE(const char *) git_merge_file__best_path( | |
161 | const char *ancestor, | |
162 | const char *ours, | |
163 | const char *theirs) | |
164 | { | |
165 | if (!ancestor) { | |
166 | if (ours && theirs && strcmp(ours, theirs) == 0) | |
167 | return ours; | |
168 | ||
169 | return NULL; | |
170 | } | |
171 | ||
172 | if (ours && strcmp(ancestor, ours) == 0) | |
173 | return theirs; | |
174 | else if(theirs && strcmp(ancestor, theirs) == 0) | |
175 | return ours; | |
176 | ||
177 | return NULL; | |
178 | } | |
179 | ||
180 | GIT_INLINE(uint32_t) git_merge_file__best_mode( | |
181 | uint32_t ancestor, uint32_t ours, uint32_t theirs) | |
182 | { | |
183 | /* | |
184 | * If ancestor didn't exist and either ours or theirs is executable, | |
185 | * assume executable. Otherwise, if any mode changed from the ancestor, | |
186 | * use that one. | |
187 | */ | |
188 | if (!ancestor) { | |
189 | if (ours == GIT_FILEMODE_BLOB_EXECUTABLE || | |
190 | theirs == GIT_FILEMODE_BLOB_EXECUTABLE) | |
191 | return GIT_FILEMODE_BLOB_EXECUTABLE; | |
192 | ||
193 | return GIT_FILEMODE_BLOB; | |
194 | } else if (ours && theirs) { | |
195 | if (ancestor == ours) | |
196 | return theirs; | |
197 | ||
198 | return ours; | |
199 | } | |
200 | ||
201 | return 0; | |
202 | } | |
203 | ||
632d8b23 | 204 | #endif |