@@ -11,6 +11,7 @@ use gix_features::parallel::{in_parallel_if, Reduce};
1111use gix_filter:: pipeline:: convert:: ToGitOutcome ;
1212use gix_object:: FindExt ;
1313
14+ use crate :: index_as_worktree:: types:: ConflictIndexEntry ;
1415use crate :: {
1516 index_as_worktree:: {
1617 traits,
@@ -165,7 +166,7 @@ where
165166 return None ;
166167 }
167168 Conflict :: try_from_entry ( all_entries, state. path_backing , absolute_entry_index, entry_path)
168- . map ( |( _conflict, offset) | offset)
169+ . map ( |( _conflict, offset, _entries ) | offset)
169170 } ) ;
170171 if let Some ( entries_to_skip_as_conflict_originates_in_previous_chunk) = offset {
171172 // skip current entry as it's done, along with following conflict entries
@@ -287,10 +288,22 @@ impl<'index> State<'_, 'index> {
287288 }
288289 let status = if entry. stage_raw ( ) != 0 {
289290 Ok (
290- Conflict :: try_from_entry ( entries, self . path_backing , entry_index, path) . map ( |( conflict, offset) | {
291- * outer_entry_index += offset; // let out loop skip over entries related to the conflict
292- EntryStatus :: Conflict ( conflict)
293- } ) ,
291+ Conflict :: try_from_entry ( entries, self . path_backing , entry_index, path) . map (
292+ |( conflict, offset, entries) | {
293+ * outer_entry_index += offset; // let out loop skip over entries related to the conflict
294+ EntryStatus :: Conflict {
295+ summary : conflict,
296+ entries : Box :: new ( {
297+ let mut a: [ Option < ConflictIndexEntry > ; 3 ] = Default :: default ( ) ;
298+ let src = entries. into_iter ( ) . map ( |e| e. map ( ConflictIndexEntry :: from) ) ;
299+ for ( a, b) in a. iter_mut ( ) . zip ( src) {
300+ * a = b;
301+ }
302+ a
303+ } ) ,
304+ }
305+ } ,
306+ ) ,
294307 )
295308 } else {
296309 self . compute_status ( entry, path, diff, submodule, objects)
@@ -622,20 +635,23 @@ impl Conflict {
622635 /// Also return the amount of extra-entries that were part of the conflict declaration (not counting the entry at `start_index`)
623636 ///
624637 /// If for some reason entry at `start_index` isn't in conflicting state, `None` is returned.
625- pub fn try_from_entry (
626- entries : & [ gix_index:: Entry ] ,
638+ ///
639+ /// Return `(Self, num_consumed_entries, three_possibly_entries)`.
640+ pub fn try_from_entry < ' entry > (
641+ entries : & ' entry [ gix_index:: Entry ] ,
627642 path_backing : & gix_index:: PathStorageRef ,
628643 start_index : usize ,
629644 entry_path : & BStr ,
630- ) -> Option < ( Self , usize ) > {
645+ ) -> Option < ( Self , usize , [ Option < & ' entry gix_index :: Entry > ; 3 ] ) > {
631646 use Conflict :: * ;
632647 let mut mask = None :: < u8 > ;
648+ let mut seen: [ Option < & gix_index:: Entry > ; 3 ] = Default :: default ( ) ;
633649
634- let mut count = 0_usize ;
635- for stage in ( start_index..( start_index + 3 ) . min ( entries. len ( ) ) ) . filter_map ( |idx| {
650+ let mut num_consumed_entries = 0_usize ;
651+ for ( stage, entry ) in ( start_index..( start_index + 3 ) . min ( entries. len ( ) ) ) . filter_map ( |idx| {
636652 let entry = & entries[ idx] ;
637653 let stage = entry. stage_raw ( ) ;
638- ( stage > 0 && entry. path_in ( path_backing) == entry_path) . then_some ( stage)
654+ ( stage > 0 && entry. path_in ( path_backing) == entry_path) . then_some ( ( stage, entry ) )
639655 } ) {
640656 // This could be `1 << (stage - 1)` but let's be specific.
641657 * mask. get_or_insert ( 0 ) |= match stage {
@@ -644,7 +660,8 @@ impl Conflict {
644660 3 => 0b100 ,
645661 _ => 0 ,
646662 } ;
647- count += 1 ;
663+ num_consumed_entries = stage as usize - 1 ;
664+ seen[ num_consumed_entries] = Some ( entry) ;
648665 }
649666
650667 mask. map ( |mask| {
@@ -659,7 +676,8 @@ impl Conflict {
659676 0b111 => BothModified ,
660677 _ => unreachable ! ( "BUG: bitshifts and typical entry layout doesn't allow for more" ) ,
661678 } ,
662- count - 1 ,
679+ num_consumed_entries,
680+ seen,
663681 )
664682 } )
665683 }
0 commit comments