@@ -537,19 +537,17 @@ fn process_change(
537537 // <----> (added)
538538
539539 if added. end <= hunk. range_in_destination . start {
540+ // <----> (hunk)
541+ // <--> (added)
542+
540543 * offset_in_destination += added. end - added. start ;
541544 * offset_in_destination -= number_of_lines_deleted;
542- }
543545
544- let new_change = if added. end <= hunk. range_in_destination . start {
545- None
546- } else {
547- Some ( Change :: Added ( added. clone ( ) , number_of_lines_deleted) )
548- } ;
546+ ( Some ( hunk. clone ( ) ) , None )
547+ } else if hunk. range_in_destination . end <= added. start {
548+ // <--> (hunk)
549+ // <----> (added)
549550
550- if added. end <= hunk. range_in_destination . start {
551- ( Some ( hunk. clone ( ) ) , new_change)
552- } else {
553551 let line_range_in_next_destination =
554552 LineRange :: with_offset ( hunk. range_in_destination . clone ( ) , * offset_in_destination) ;
555553
@@ -558,7 +556,19 @@ fn process_change(
558556 hunk. offset ( ) + * offset_in_destination,
559557 ) ) ;
560558
561- ( None , new_change)
559+ ( None , Some ( Change :: Added ( added. clone ( ) , number_of_lines_deleted) ) )
560+ } else {
561+ // <---> (hunk)
562+ // <----------> (added)
563+ // <---> (blamed)
564+
565+ lines_blamed. push ( BlameEntry :: with_offset (
566+ hunk. range_in_destination . clone ( ) ,
567+ suspect,
568+ hunk. offset ( ) ,
569+ ) ) ;
570+
571+ ( None , Some ( Change :: Added ( added. clone ( ) , number_of_lines_deleted) ) )
562572 }
563573 }
564574 }
@@ -1604,6 +1614,37 @@ fn process_change_works_no_overlap_6() {
16041614 assert_eq ! ( offset_in_destination, Offset :: Deleted ( 1 ) ) ;
16051615}
16061616
1617+ #[ test]
1618+ fn process_change_works_enclosing_addition ( ) {
1619+ let mut lines_blamed: Vec < BlameEntry > = vec ! [ ] ;
1620+ let mut new_hunks_to_blame: Vec < UnblamedHunk > = vec ! [ ] ;
1621+ let mut offset_in_destination: Offset = Offset :: Added ( 3 ) ;
1622+ let suspect = ObjectId :: null ( gix_hash:: Kind :: Sha1 ) ;
1623+
1624+ let ( hunk, change) = process_change (
1625+ & mut lines_blamed,
1626+ & mut new_hunks_to_blame,
1627+ & mut offset_in_destination,
1628+ suspect,
1629+ // range_in_destination: 5..8
1630+ Some ( UnblamedHunk :: new ( 2 ..5 , Offset :: Deleted ( 3 ) ) ) ,
1631+ Some ( Change :: Added ( 3 ..12 , 2 ) ) ,
1632+ ) ;
1633+
1634+ assert_eq ! ( hunk, None ) ;
1635+ assert_eq ! ( change, Some ( Change :: Added ( 3 ..12 , 2 ) ) ) ;
1636+ assert_eq ! (
1637+ lines_blamed,
1638+ vec![ BlameEntry {
1639+ range_in_blamed_file: 2 ..5 ,
1640+ range_in_original_file: 5 ..8 ,
1641+ commit_id: suspect
1642+ } ]
1643+ ) ;
1644+ assert_eq ! ( new_hunks_to_blame, vec![ ] ) ;
1645+ assert_eq ! ( offset_in_destination, Offset :: Added ( 3 ) ) ;
1646+ }
1647+
16071648#[ test]
16081649fn process_change_works_unchanged_hunk ( ) {
16091650 let mut lines_blamed: Vec < BlameEntry > = vec ! [ ] ;
0 commit comments