private static Region Add(Region aTail, NGit.Blame.Candidate a, Region n) { // If there is no region on the list, use only this one. if (aTail == null) { a.regionList = n; n.next = null; return(n); } // If the prior region ends exactly where the new region begins // in both the result and the source, combine these together into // one contiguous region. This occurs when intermediate commits // have inserted and deleted lines in the middle of a region. Try // to report this region as a single region to the application, // rather than in fragments. if (aTail.resultStart + aTail.length == n.resultStart && aTail.sourceStart + aTail .length == n.sourceStart) { aTail.length += n.length; return(aTail); } // Append the region onto the end of the list. aTail.next = n; n.next = null; return(n); }
internal virtual NGit.Blame.Candidate Copy(RevCommit commit) { NGit.Blame.Candidate r = Create(commit, sourcePath); r.sourceBlob = sourceBlob; r.sourceText = sourceText; r.regionList = regionList; r.renameScore = renameScore; return(r); }
private static void Blame(EditList editList, NGit.Blame.Candidate a, NGit.Blame.Candidate b) { Region r = b.ClearRegionList(); Region aTail = null; Region bTail = null; for (int eIdx = 0; eIdx < editList.Count;) { // If there are no more regions left, neither side has any // more responsibility for the result. Remaining edits can // be safely ignored. if (r == null) { return; } Edit e = editList[eIdx]; // Edit ends before the next candidate region. Skip the edit. if (e.GetEndB() <= r.sourceStart) { eIdx++; continue; } // Next candidate region starts before the edit. Assign some // of the blame onto A, but possibly split and also on B. if (r.sourceStart < e.GetBeginB()) { int d = e.GetBeginB() - r.sourceStart; if (r.length <= d) { // Pass the blame for this region onto A. Region next = r.next; r.sourceStart = e.GetBeginA() - d; aTail = Add(aTail, a, r); r = next; continue; } // Split the region and assign some to A, some to B. aTail = Add(aTail, a, r.SplitFirst(e.GetBeginA() - d, d)); r.SlideAndShrink(d); } // At this point e.getBeginB() <= r.sourceStart. // An empty edit on the B side isn't relevant to this split, // as it does not overlap any candidate region. if (e.GetLengthB() == 0) { eIdx++; continue; } // If the region ends before the edit, blame on B. int rEnd = r.sourceStart + r.length; if (rEnd <= e.GetEndB()) { Region next = r.next; bTail = Add(bTail, b, r); r = next; if (rEnd == e.GetEndB()) { eIdx++; } continue; } // This region extends beyond the edit. Blame the first // half of the region on B, and process the rest after. int len = e.GetEndB() - r.sourceStart; bTail = Add(bTail, b, r.SplitFirst(r.sourceStart, len)); r.SlideAndShrink(len); eIdx++; } if (r == null) { return; } // For any remaining region, pass the blame onto A after shifting // the source start to account for the difference between the two. Edit e_1 = editList[editList.Count - 1]; int endB = e_1.GetEndB(); int d_1 = endB - e_1.GetEndA(); if (aTail == null) { a.regionList = r; } else { aTail.next = r; } do { if (endB <= r.sourceStart) { r.sourceStart -= d_1; } r = r.next; }while (r != null); }
internal virtual void TakeBlame(EditList editList, NGit.Blame.Candidate child) { Blame(editList, this, child); }