Exemple #1
0
        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);
        }