@@ -8,11 +8,12 @@ use crate::types::{BlameEntry, Change, Either, LineRange, Offset, UnblamedHunk};
88
99pub ( super )  mod  function; 
1010
11- /// Compare a section from the *Blamed  File* (`hunk`) with a change from a diff and see if there  
12- /// is an intersection with `change`. Based on that intersection, we may generate a [`BlameEntry`] for `out`  
13- /// and/or split the `hunk` into multiple. 
11+ /// Compare a section from a potential *Source  File* (`hunk`) with a change from a diff and see if 
12+ /// there  is an intersection with `change`. Based on that intersection, we may generate a 
13+ /// [`BlameEntry`] for `out`  and/or split the `hunk` into multiple. 
1414/// 
15- /// This is the core of the blame implementation as it matches regions in *Source File* to the *Blamed File*. 
15+ /// This is the core of the blame implementation as it matches regions in *Blamed File* to 
16+ /// corresponding regions in one or more than one *Source File*. 
1617fn  process_change ( 
1718    new_hunks_to_blame :  & mut  Vec < UnblamedHunk > , 
1819    offset :  & mut  Offset , 
@@ -320,36 +321,41 @@ fn process_change(
320321
321322/// Consume `hunks_to_blame` and `changes` to pair up matches ranges (also overlapping) with each other. 
322323/// Once a match is found, it's pushed onto `out`. 
324+ /// 
325+ /// `process_changes` assumes that ranges coming from the same *Source File* can and do 
326+ /// occasionally overlap. If it were a desirable property of the blame algorithm as a whole to 
327+ /// never have two different lines from a *Blamed File* mapped to the same line in a *Source File*, 
328+ /// this property would need to be enforced at a higher level than `process_changes`. 
329+ /// Then the nested loops could potentially be flattened into one. 
323330fn  process_changes ( 
324331    hunks_to_blame :  Vec < UnblamedHunk > , 
325332    changes :  Vec < Change > , 
326333    suspect :  ObjectId , 
327334    parent :  ObjectId , 
328335)  -> Vec < UnblamedHunk >  { 
329-     let  mut  hunks_iter = hunks_to_blame. into_iter ( ) ; 
330-     let  mut  changes_iter = changes. into_iter ( ) ; 
336+     let  mut  new_hunks_to_blame = Vec :: new ( ) ; 
331337
332-     let  mut  hunk = hunks_iter . next ( ) ; 
333-     let  mut  change  = changes_iter . next ( ) ; 
338+     for  mut  hunk in  hunks_to_blame . into_iter ( ) . map ( Some )   { 
339+          let  mut  offset_in_destination  = Offset :: Added ( 0 ) ; 
334340
335-     let  mut  new_hunks_to_blame  = Vec :: new ( ) ; 
336-     let  mut  offset_in_destination  = Offset :: Added ( 0 ) ; 
337- 
338-     loop  { 
339-         ( hunk,  change)  = process_change ( 
340-             & mut  new_hunks_to_blame, 
341-             & mut  offset_in_destination, 
342-             suspect, 
343-             parent, 
344-             hunk, 
345-             change, 
346-         ) ; 
347- 
348-         hunk = hunk . or_else ( || hunks_iter . next ( ) ) ; 
349-         change = change . or_else ( || changes_iter . next ( ) ) ; 
350- 
351-         if  hunk . is_none ( )  && change . is_none ( )   { 
352-             break ; 
341+          let  mut  changes_iter  = changes . iter ( ) . cloned ( ) ; 
342+          let  mut  change  = changes_iter . next ( ) ; 
343+ 
344+          loop  { 
345+              ( hunk,  change)  = process_change ( 
346+                  & mut  new_hunks_to_blame, 
347+                  & mut  offset_in_destination, 
348+                  suspect, 
349+                  parent, 
350+                  hunk, 
351+                  change, 
352+              ) ; 
353+ 
354+             change = change . or_else ( || changes_iter . next ( ) ) ; 
355+ 
356+              if  hunk . is_none ( )   { 
357+                  break ; 
358+             } 
353359        } 
354360    } 
355361    new_hunks_to_blame
0 commit comments