@@ -47,20 +47,38 @@ pub struct Outcome<'a> {
47
47
48
48
/// Determine what should be considered an unresolved conflict.
49
49
///
50
- /// Note that no matter which variant, [conflicts](Conflict) with [resolution failure](`ResolutionFailure`)
51
- /// will always be unresolved.
50
+ /// Note that no matter which variant, [conflicts](Conflict) with
51
+ /// [resolution failure](`ResolutionFailure`) will always be unresolved.
52
+ ///
53
+ /// Also, when one side was modified but the other side renamed it, this will not
54
+ /// be considered a conflict, even if a non-conflicting merge happened.
52
55
#[ derive( Debug , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
53
- pub enum UnresolvedConflict {
56
+ pub enum TreatAsUnresolved {
54
57
/// Only consider content merges with conflict markers as unresolved.
58
+ ///
59
+ /// Auto-resolved tree conflicts will *not* be considered unresolved.
55
60
ConflictMarkers ,
56
- /// Whenever there was any rename, or conflict markers, it is unresolved.
61
+ /// Consider content merges with conflict markers as unresolved, and content
62
+ /// merges where conflicts where auto-resolved in any way, like choosing
63
+ /// *ours*, *theirs* or by their *union*.
64
+ ///
65
+ /// Auto-resolved tree conflicts will *not* be considered unresolved.
66
+ ConflictMarkersAndAutoResolved ,
67
+ /// Whenever there were conflicting renames, or conflict markers, it is unresolved.
68
+ /// Note that auto-resolved content merges will *not* be considered unresolved.
69
+ ///
70
+ /// Also note that files that were changed in one and renamed in another will
71
+ /// be moved into place, which will be considered resolved.
57
72
Renames ,
73
+ /// Similar to [`Self::Renames`], but auto-resolved content-merges will
74
+ /// also be considered unresolved.
75
+ RenamesAndAutoResolvedContent ,
58
76
}
59
77
60
78
impl Outcome < ' _ > {
61
79
/// Return `true` if there is any conflict that would still need to be resolved as they would yield undesirable trees.
62
80
/// This is based on `how` to determine what should be considered unresolved.
63
- pub fn has_unresolved_conflicts ( & self , how : UnresolvedConflict ) -> bool {
81
+ pub fn has_unresolved_conflicts ( & self , how : TreatAsUnresolved ) -> bool {
64
82
self . conflicts . iter ( ) . any ( |c| c. is_unresolved ( how) )
65
83
}
66
84
}
@@ -109,20 +127,29 @@ impl ConflictMapping {
109
127
110
128
impl Conflict {
111
129
/// Return `true` if this instance is considered unresolved based on the criterion specified by `how`.
112
- pub fn is_unresolved ( & self , how : UnresolvedConflict ) -> bool {
130
+ pub fn is_unresolved ( & self , how : TreatAsUnresolved ) -> bool {
131
+ use crate :: blob;
132
+ let content_merge_matches = |info : & ContentMerge | match how {
133
+ TreatAsUnresolved :: ConflictMarkers | TreatAsUnresolved :: Renames => {
134
+ matches ! ( info. resolution, blob:: Resolution :: Conflict )
135
+ }
136
+ TreatAsUnresolved :: RenamesAndAutoResolvedContent | TreatAsUnresolved :: ConflictMarkersAndAutoResolved => {
137
+ matches ! (
138
+ info. resolution,
139
+ blob:: Resolution :: Conflict | blob:: Resolution :: CompleteWithAutoResolvedConflict
140
+ )
141
+ }
142
+ } ;
113
143
match how {
114
- UnresolvedConflict :: ConflictMarkers => {
115
- self . resolution . is_err ( )
116
- || self . content_merge ( ) . map_or ( false , |info| {
117
- matches ! ( info. resolution, crate :: blob:: Resolution :: Conflict )
118
- } )
144
+ TreatAsUnresolved :: ConflictMarkers | TreatAsUnresolved :: ConflictMarkersAndAutoResolved => {
145
+ self . resolution . is_err ( ) || self . content_merge ( ) . map_or ( false , |info| content_merge_matches ( & info) )
119
146
}
120
- UnresolvedConflict :: Renames => match & self . resolution {
147
+ TreatAsUnresolved :: Renames | TreatAsUnresolved :: RenamesAndAutoResolvedContent => match & self . resolution {
121
148
Ok ( success) => match success {
122
- Resolution :: SourceLocationAffectedByRename { .. }
123
- | Resolution :: OursModifiedTheirsRenamedAndChangedThenRename { .. } => true ,
149
+ Resolution :: SourceLocationAffectedByRename { .. } => false ,
150
+ Resolution :: OursModifiedTheirsRenamedAndChangedThenRename { .. } => true ,
124
151
Resolution :: OursModifiedTheirsModifiedThenBlobContentMerge { merged_blob } => {
125
- matches ! ( merged_blob. resolution , crate :: blob :: Resolution :: Conflict )
152
+ content_merge_matches ( merged_blob)
126
153
}
127
154
} ,
128
155
Err ( _failure) => true ,
@@ -264,7 +291,7 @@ pub struct Options {
264
291
/// If `Some(what-is-unresolved)`, the first unresolved conflict will cause the entire merge to stop.
265
292
/// This is useful to see if there is any conflict, without performing the whole operation, something
266
293
/// that can be very relevant during merges that would cause a lot of blob-diffs.
267
- pub fail_on_conflict : Option < UnresolvedConflict > ,
294
+ pub fail_on_conflict : Option < TreatAsUnresolved > ,
268
295
/// This value also affects the size of merge-conflict markers, to allow differentiating
269
296
/// merge conflicts on each level, for any value greater than 0, with values `N` causing `N*2`
270
297
/// markers to be added to the configured value.
0 commit comments