@@ -13,6 +13,7 @@ use gix_diff::tree_with_rewrites::Change;
1313use gix_hash:: ObjectId ;
1414use gix_object:: tree:: { EntryKind , EntryMode } ;
1515use gix_object:: { tree, FindExt } ;
16+ use std:: borrow:: Cow ;
1617use std:: convert:: Infallible ;
1718
1819/// Perform a merge between `our_tree` and `their_tree`, using `base_tree` as merge-base.
@@ -876,122 +877,83 @@ where
876877 their_tree. remove_existing_leaf ( source_location. as_bstr ( ) ) ;
877878 }
878879
879- let their_rewritten_location =
880- possibly_rewritten_location ( our_tree, their_location. as_bstr ( ) , our_changes) ;
881- let our_rewritten_location =
882- possibly_rewritten_location ( their_tree, our_location. as_bstr ( ) , their_changes) ;
883- let ( our_addition, their_addition) =
884- match ( our_rewritten_location, their_rewritten_location) {
885- ( None , Some ( location) ) => (
886- None ,
887- Some ( Change :: Addition {
888- location,
880+ let their_location =
881+ possibly_rewritten_location ( our_tree, their_location. as_bstr ( ) , our_changes)
882+ . map_or ( Cow :: Borrowed ( their_location. as_bstr ( ) ) , Cow :: Owned ) ;
883+ let our_location =
884+ possibly_rewritten_location ( their_tree, our_location. as_bstr ( ) , their_changes)
885+ . map_or ( Cow :: Borrowed ( our_location. as_bstr ( ) ) , Cow :: Owned ) ;
886+ let ( our_addition, their_addition) = if our_location == their_location {
887+ (
888+ None ,
889+ Some ( Change :: Addition {
890+ location : our_location. into_owned ( ) ,
891+ relation : None ,
892+ entry_mode : merged_mode,
893+ id : merged_blob_id,
894+ } ) ,
895+ )
896+ } else {
897+ if should_fail_on_conflict ( Conflict :: without_resolution (
898+ ResolutionFailure :: OursRenamedTheirsRenamedDifferently {
899+ merged_blob : resolution. take ( ) . map ( |resolution| ContentMerge {
900+ resolution,
901+ merged_blob_id,
902+ } ) ,
903+ } ,
904+ ( ours, theirs, Original , outer_side) ,
905+ [
906+ index_entry_at_path (
907+ source_entry_mode,
908+ source_id,
909+ ConflictIndexEntryPathHint :: Source ,
910+ ) ,
911+ index_entry_at_path (
912+ our_mode,
913+ & merged_blob_id,
914+ ConflictIndexEntryPathHint :: Current ,
915+ ) ,
916+ index_entry_at_path (
917+ their_mode,
918+ & merged_blob_id,
919+ ConflictIndexEntryPathHint :: RenamedOrTheirs ,
920+ ) ,
921+ ] ,
922+ ) ) {
923+ break ' outer;
924+ } ;
925+ match tree_conflicts {
926+ None => {
927+ let our_addition = Change :: Addition {
928+ location : our_location. into_owned ( ) ,
889929 relation : None ,
890930 entry_mode : merged_mode,
891931 id : merged_blob_id,
892- } ) ,
893- ) ,
894- ( Some ( location) , None ) => (
895- None ,
896- Some ( Change :: Addition {
897- location,
932+ } ;
933+ let their_addition = Change :: Addition {
934+ location : their_location. into_owned ( ) ,
898935 relation : None ,
899936 entry_mode : merged_mode,
900937 id : merged_blob_id,
901- } ) ,
902- ) ,
903- ( Some ( _ours) , Some ( _theirs) ) => {
904- gix_trace:: debug!(
905- "Found two rewritten locations, '{_ours}' and '{_theirs}'"
906- ) ;
907- // Pretend this is the end of the loop and keep this as conflict.
908- // If this happens in the wild, we'd want to reproduce it.
909- if let Some ( ResolveWith :: Ours ) = tree_conflicts {
910- apply_our_resolution ( ours, theirs, outer_side, & mut editor) ?;
911- }
912- if should_fail_on_conflict ( Conflict :: unknown ( (
913- ours, theirs, Original , outer_side,
914- ) ) ) {
915- break ' outer;
916938 } ;
917- their_changes[ theirs_idx] . was_written = true ;
918- our_changes[ ours_idx] . was_written = true ;
919- continue ;
939+ ( Some ( our_addition) , Some ( their_addition) )
920940 }
921- ( None , None ) => {
922- if our_location == their_location {
923- (
924- None ,
925- Some ( Change :: Addition {
926- location : our_location. to_owned ( ) ,
927- relation : None ,
928- entry_mode : merged_mode,
929- id : merged_blob_id,
930- } ) ,
931- )
932- } else {
933- if should_fail_on_conflict ( Conflict :: without_resolution (
934- ResolutionFailure :: OursRenamedTheirsRenamedDifferently {
935- merged_blob : resolution. take ( ) . map ( |resolution| ContentMerge {
936- resolution,
937- merged_blob_id,
938- } ) ,
939- } ,
940- ( ours, theirs, Original , outer_side) ,
941- [
942- index_entry_at_path (
943- source_entry_mode,
944- source_id,
945- ConflictIndexEntryPathHint :: Source ,
946- ) ,
947- index_entry_at_path (
948- our_mode,
949- & merged_blob_id,
950- ConflictIndexEntryPathHint :: Current ,
951- ) ,
952- index_entry_at_path (
953- their_mode,
954- & merged_blob_id,
955- ConflictIndexEntryPathHint :: RenamedOrTheirs ,
956- ) ,
957- ] ,
958- ) ) {
959- break ' outer;
960- } ;
961- match tree_conflicts {
962- None => {
963- let our_addition = Change :: Addition {
964- location : our_location. to_owned ( ) ,
965- relation : None ,
966- entry_mode : merged_mode,
967- id : merged_blob_id,
968- } ;
969- let their_addition = Change :: Addition {
970- location : their_location. to_owned ( ) ,
971- relation : None ,
972- entry_mode : merged_mode,
973- id : merged_blob_id,
974- } ;
975- ( Some ( our_addition) , Some ( their_addition) )
976- }
977- Some ( ResolveWith :: Ancestor ) => ( None , None ) ,
978- Some ( ResolveWith :: Ours ) => {
979- let our_addition = Change :: Addition {
980- location : match outer_side {
981- Original => our_location,
982- Swapped => their_location,
983- }
984- . to_owned ( ) ,
985- relation : None ,
986- entry_mode : merged_mode,
987- id : merged_blob_id,
988- } ;
989- ( Some ( our_addition) , None )
990- }
941+ Some ( ResolveWith :: Ancestor ) => ( None , None ) ,
942+ Some ( ResolveWith :: Ours ) => {
943+ let our_addition = Change :: Addition {
944+ location : match outer_side {
945+ Original => our_location,
946+ Swapped => their_location,
991947 }
992- }
948+ . into_owned ( ) ,
949+ relation : None ,
950+ entry_mode : merged_mode,
951+ id : merged_blob_id,
952+ } ;
953+ ( Some ( our_addition) , None )
993954 }
994- } ;
955+ }
956+ } ;
995957
996958 if let Some ( resolution) = resolution {
997959 if should_fail_on_conflict ( Conflict :: with_resolution (
0 commit comments