@@ -3,13 +3,12 @@ use crate::blob::builtin_driver::text::utils::{
33 hunks_differ_in_diff3, take_intersecting, tokens, write_ancestor, write_conflict_marker, write_hunks,
44 zealously_contract_hunks, CollectHunks , Hunk , Side ,
55} ;
6- use crate :: blob:: builtin_driver:: text:: { ConflictStyle , Options , ResolveWith } ;
6+ use crate :: blob:: builtin_driver:: text:: { Conflict , ConflictStyle , Labels , Options } ;
77use crate :: blob:: Resolution ;
8- use bstr:: BStr ;
98
109/// Merge `current` and `other` with `ancestor` as base according to `opts`.
1110///
12- /// Use `current_label`, `other_label` and `ancestor_label ` to annotate conflict sections.
11+ /// Use `labels ` to annotate conflict sections.
1312///
1413/// `input` is for reusing memory for lists of tokens, but note that it grows indefinitely
1514/// while tokens for `current`, `ancestor` and `other` are added.
@@ -23,12 +22,14 @@ use bstr::BStr;
2322pub fn merge < ' a > (
2423 out : & mut Vec < u8 > ,
2524 input : & mut imara_diff:: intern:: InternedInput < & ' a [ u8 ] > ,
25+ Labels {
26+ ancestor : ancestor_label,
27+ current : current_label,
28+ other : other_label,
29+ } : Labels < ' _ > ,
2630 current : & ' a [ u8 ] ,
27- current_label : Option < & BStr > ,
2831 ancestor : & ' a [ u8 ] ,
29- ancestor_label : Option < & BStr > ,
3032 other : & ' a [ u8 ] ,
31- other_label : Option < & BStr > ,
3233 opts : Options ,
3334) -> Resolution {
3435 out. clear ( ) ;
@@ -77,9 +78,9 @@ pub fn merge<'a>(
7778 . expect ( "at least one entry" ) ,
7879 & mut filled_hunks,
7980 ) ;
80- match opts. on_conflict {
81- None => {
82- let ( hunks_front_and_back, num_hunks_front) = match opts . conflict_style {
81+ match opts. conflict {
82+ Conflict :: Keep { style , marker_size } => {
83+ let ( hunks_front_and_back, num_hunks_front) = match style {
8384 ConflictStyle :: Merge | ConflictStyle :: ZealousDiff3 => {
8485 zealously_contract_hunks ( & mut filled_hunks, & mut intersecting, input, & current_tokens)
8586 }
@@ -130,28 +131,22 @@ pub fn merge<'a>(
130131 )
131132 . or_else ( || detect_line_ending ( our_hunks, input, & current_tokens) )
132133 . unwrap_or ( b"\n " . into ( ) ) ;
133- match opts . conflict_style {
134+ match style {
134135 ConflictStyle :: Merge => {
135136 if contains_lines ( our_hunks) || contains_lines ( their_hunks) {
136137 resolution = Resolution :: Conflict ;
137- write_conflict_marker ( out, b'<' , current_label, opts . marker_size , nl) ;
138+ write_conflict_marker ( out, b'<' , current_label, marker_size, nl) ;
138139 write_hunks ( our_hunks, input, & current_tokens, out) ;
139- write_conflict_marker ( out, b'=' , None , opts . marker_size , nl) ;
140+ write_conflict_marker ( out, b'=' , None , marker_size, nl) ;
140141 write_hunks ( their_hunks, input, & current_tokens, out) ;
141- write_conflict_marker ( out, b'>' , other_label, opts . marker_size , nl) ;
142+ write_conflict_marker ( out, b'>' , other_label, marker_size, nl) ;
142143 }
143144 }
144145 ConflictStyle :: Diff3 | ConflictStyle :: ZealousDiff3 => {
145146 if contains_lines ( our_hunks) || contains_lines ( their_hunks) {
146- if hunks_differ_in_diff3 (
147- opts. conflict_style ,
148- our_hunks,
149- their_hunks,
150- input,
151- & current_tokens,
152- ) {
147+ if hunks_differ_in_diff3 ( style, our_hunks, their_hunks, input, & current_tokens) {
153148 resolution = Resolution :: Conflict ;
154- write_conflict_marker ( out, b'<' , current_label, opts . marker_size , nl) ;
149+ write_conflict_marker ( out, b'<' , current_label, marker_size, nl) ;
155150 write_hunks ( our_hunks, input, & current_tokens, out) ;
156151 let ancestor_hunk = Hunk {
157152 before : first_hunk. before . start ..last_hunk. before . end ,
@@ -161,11 +156,11 @@ pub fn merge<'a>(
161156 let ancestor_hunk = std:: slice:: from_ref ( & ancestor_hunk) ;
162157 let ancestor_nl =
163158 detect_line_ending_or_nl ( ancestor_hunk, input, & current_tokens) ;
164- write_conflict_marker ( out, b'|' , ancestor_label, opts . marker_size , ancestor_nl) ;
159+ write_conflict_marker ( out, b'|' , ancestor_label, marker_size, ancestor_nl) ;
165160 write_hunks ( ancestor_hunk, input, & current_tokens, out) ;
166- write_conflict_marker ( out, b'=' , None , opts . marker_size , nl) ;
161+ write_conflict_marker ( out, b'=' , None , marker_size, nl) ;
167162 write_hunks ( their_hunks, input, & current_tokens, out) ;
168- write_conflict_marker ( out, b'>' , other_label, opts . marker_size , nl) ;
163+ write_conflict_marker ( out, b'>' , other_label, marker_size, nl) ;
169164 } else {
170165 write_hunks ( our_hunks, input, & current_tokens, out) ;
171166 }
@@ -176,64 +171,60 @@ pub fn merge<'a>(
176171 write_hunks ( back_hunks, input, & current_tokens, out) ;
177172 ancestor_integrated_until = last_hunk. before . end ;
178173 }
179- Some ( resolve) => {
180- match resolve {
181- ResolveWith :: Ours | ResolveWith :: Theirs => {
182- let ( our_hunks, their_hunks) = match filled_hunks_side {
183- Side :: Current => ( & filled_hunks, & intersecting) ,
184- Side :: Other => ( & intersecting, & filled_hunks) ,
185- Side :: Ancestor => {
186- unreachable ! ( "initial hunks are never ancestors" )
187- }
188- } ;
189- let hunks_to_write = if resolve == ResolveWith :: Ours {
190- our_hunks
191- } else {
192- their_hunks
193- } ;
194- if let Some ( first_hunk) = hunks_to_write. first ( ) {
195- write_ancestor ( input, ancestor_integrated_until, first_hunk. before . start as usize , out) ;
196- }
197- write_hunks ( hunks_to_write, input, & current_tokens, out) ;
198- if let Some ( last_hunk) = hunks_to_write. last ( ) {
199- ancestor_integrated_until = last_hunk. before . end ;
200- }
174+ Conflict :: ResolveWithOurs | Conflict :: ResolveWithTheirs => {
175+ let ( our_hunks, their_hunks) = match filled_hunks_side {
176+ Side :: Current => ( & filled_hunks, & intersecting) ,
177+ Side :: Other => ( & intersecting, & filled_hunks) ,
178+ Side :: Ancestor => {
179+ unreachable ! ( "initial hunks are never ancestors" )
201180 }
202- ResolveWith :: Union => {
203- let ( hunks_front_and_back, num_hunks_front) =
204- zealously_contract_hunks ( & mut filled_hunks, & mut intersecting, input, & current_tokens) ;
181+ } ;
182+ let hunks_to_write = if opts. conflict == Conflict :: ResolveWithOurs {
183+ our_hunks
184+ } else {
185+ their_hunks
186+ } ;
187+ if let Some ( first_hunk) = hunks_to_write. first ( ) {
188+ write_ancestor ( input, ancestor_integrated_until, first_hunk. before . start as usize , out) ;
189+ }
190+ write_hunks ( hunks_to_write, input, & current_tokens, out) ;
191+ if let Some ( last_hunk) = hunks_to_write. last ( ) {
192+ ancestor_integrated_until = last_hunk. before . end ;
193+ }
194+ }
195+ Conflict :: ResolveWithUnion => {
196+ let ( hunks_front_and_back, num_hunks_front) =
197+ zealously_contract_hunks ( & mut filled_hunks, & mut intersecting, input, & current_tokens) ;
205198
206- let ( our_hunks, their_hunks) = match filled_hunks_side {
207- Side :: Current => ( & filled_hunks, & intersecting) ,
208- Side :: Other => ( & intersecting, & filled_hunks) ,
209- Side :: Ancestor => {
210- unreachable ! ( "initial hunks are never ancestors" )
211- }
212- } ;
213- let ( front_hunks, back_hunks) = hunks_front_and_back. split_at ( num_hunks_front) ;
214- let first_hunk = front_hunks
215- . first ( )
216- . or ( our_hunks. first ( ) )
217- . expect ( "at least one hunk to write" ) ;
218- write_ancestor ( input, ancestor_integrated_until, first_hunk. before . start as usize , out) ;
219- write_hunks ( front_hunks, input, & current_tokens, out) ;
220- assure_ends_with_nl ( out, detect_line_ending_or_nl ( front_hunks, input, & current_tokens) ) ;
221- write_hunks ( our_hunks, input, & current_tokens, out) ;
222- assure_ends_with_nl ( out, detect_line_ending_or_nl ( our_hunks, input, & current_tokens) ) ;
223- write_hunks ( their_hunks, input, & current_tokens, out) ;
224- if !back_hunks. is_empty ( ) {
225- assure_ends_with_nl ( out, detect_line_ending_or_nl ( their_hunks, input, & current_tokens) ) ;
226- }
227- write_hunks ( back_hunks, input, & current_tokens, out) ;
228- let last_hunk = back_hunks
229- . last ( )
230- . or ( their_hunks. last ( ) )
231- . or ( our_hunks. last ( ) )
232- . or ( front_hunks. last ( ) )
233- . expect ( "at least one hunk" ) ;
234- ancestor_integrated_until = last_hunk. before . end ;
199+ let ( our_hunks, their_hunks) = match filled_hunks_side {
200+ Side :: Current => ( & filled_hunks, & intersecting) ,
201+ Side :: Other => ( & intersecting, & filled_hunks) ,
202+ Side :: Ancestor => {
203+ unreachable ! ( "initial hunks are never ancestors" )
235204 }
236205 } ;
206+ let ( front_hunks, back_hunks) = hunks_front_and_back. split_at ( num_hunks_front) ;
207+ let first_hunk = front_hunks
208+ . first ( )
209+ . or ( our_hunks. first ( ) )
210+ . expect ( "at least one hunk to write" ) ;
211+ write_ancestor ( input, ancestor_integrated_until, first_hunk. before . start as usize , out) ;
212+ write_hunks ( front_hunks, input, & current_tokens, out) ;
213+ assure_ends_with_nl ( out, detect_line_ending_or_nl ( front_hunks, input, & current_tokens) ) ;
214+ write_hunks ( our_hunks, input, & current_tokens, out) ;
215+ assure_ends_with_nl ( out, detect_line_ending_or_nl ( our_hunks, input, & current_tokens) ) ;
216+ write_hunks ( their_hunks, input, & current_tokens, out) ;
217+ if !back_hunks. is_empty ( ) {
218+ assure_ends_with_nl ( out, detect_line_ending_or_nl ( their_hunks, input, & current_tokens) ) ;
219+ }
220+ write_hunks ( back_hunks, input, & current_tokens, out) ;
221+ let last_hunk = back_hunks
222+ . last ( )
223+ . or ( their_hunks. last ( ) )
224+ . or ( our_hunks. last ( ) )
225+ . or ( front_hunks. last ( ) )
226+ . expect ( "at least one hunk" ) ;
227+ ancestor_integrated_until = last_hunk. before . end ;
237228 }
238229 }
239230 } else {
0 commit comments