@@ -160,13 +160,15 @@ pub mod tree {
160160 pub struct Options {
161161 inner : gix_merge:: tree:: Options ,
162162 file_favor : Option < FileFavor > ,
163+ tree_favor : Option < TreeFavor > ,
163164 }
164165
165166 impl From < gix_merge:: tree:: Options > for Options {
166167 fn from ( opts : gix_merge:: tree:: Options ) -> Self {
167168 Options {
168169 inner : opts,
169170 file_favor : None ,
171+ tree_favor : None ,
170172 }
171173 }
172174 }
@@ -190,6 +192,7 @@ pub mod tree {
190192 opts. blob_merge . resolve_binary_with = Some ( resolve_binary) ;
191193 opts. blob_merge . text . conflict = resolve_text;
192194 }
195+ opts. tree_conflicts = value. tree_favor . map ( Into :: into) ;
193196 opts
194197 }
195198 }
@@ -202,7 +205,7 @@ pub mod tree {
202205 /// * binary files
203206 /// * symlinks (a form of file after all)
204207 ///
205- /// Note that that union merges aren't available as they aren't available for binaries or symlinks.
208+ /// Note that * union* merges aren't available as they aren't available for binaries or symlinks.
206209 #[ derive( Debug , Copy , Clone ) ]
207210 pub enum FileFavor {
208211 /// Choose *our* side in case of a conflict.
@@ -215,6 +218,35 @@ pub mod tree {
215218 Theirs ,
216219 }
217220
221+ /// Control how irreconcilable changes to trees should be resolved.
222+ ///
223+ /// Examples for such issues are:
224+ ///
225+ /// * *we*: delete, *they*: modify
226+ /// * *we*: rename, *they*: rename to something else
227+ /// * *we*: delete, *they*: rename
228+ ///
229+ /// Use this to control which entries are visible to in the resulting tree.
230+ /// Also note that this does not apply to the many tree-related changes are reconcilable.
231+ #[ derive( Debug , Copy , Clone ) ]
232+ pub enum TreeFavor {
233+ /// Choose *our* side in case of a conflict.
234+ /// Note that content-merges are *still* performed according to the [FileFavor].
235+ Ours ,
236+ /// Choose the state of the shared common ancestor, dropping both *ours* and *their* changes.
237+ /// Content merges are not performed here.
238+ Ancestor ,
239+ }
240+
241+ impl From < TreeFavor > for gix_merge:: tree:: ResolveWith {
242+ fn from ( value : TreeFavor ) -> Self {
243+ match value {
244+ TreeFavor :: Ours => gix_merge:: tree:: ResolveWith :: Ours ,
245+ TreeFavor :: Ancestor => gix_merge:: tree:: ResolveWith :: Ancestor ,
246+ }
247+ }
248+ }
249+
218250 /// Builder
219251 impl Options {
220252 /// If *not* `None`, rename tracking will be performed when determining the changes of each side of the merge.
@@ -233,10 +265,22 @@ pub mod tree {
233265
234266 /// When `None`, the default, both sides will be treated equally, and in case of conflict an unbiased representation
235267 /// is chosen both for content and for trees, causing a conflict.
236- /// When `Some(favor)` one can choose a side to prefer in order to automatically resolve a conflict meaningfully.
268+ ///
269+ /// With `Some(favor)` one can choose a side to prefer in order to forcefully resolve an otherwise irreconcilable conflict,
270+ /// loosing information in the process.
237271 pub fn with_file_favor ( mut self , file_favor : Option < FileFavor > ) -> Self {
238272 self . file_favor = file_favor;
239273 self
240274 }
275+
276+ /// When `None`, the default, both sides will be treated equally, trying to keep both conflicting changes in the tree, possibly
277+ /// by renaming one side to move it out of the way.
278+ ///
279+ /// With `Some(favor)` one can choose a side to prefer in order to forcefully resolve an otherwise irreconcilable conflict,
280+ /// loosing information in the process.
281+ pub fn with_tree_favor ( mut self , tree_favor : Option < TreeFavor > ) -> Self {
282+ self . tree_favor = tree_favor;
283+ self
284+ }
241285 }
242286}
0 commit comments