public SingleDiffResult(DiffResult parentDiffResult, IEnumerable <string> lines, IEnumerable <Block> blocks, string displayText) { this.parentDiffResult = parentDiffResult; this.displayText = displayText; this.lines.AddRange(lines); this.blocks.AddRange(blocks); foreach (Block b in blocks) { b.ParentResult = this; } }
public DiffResult PerformDiff(string leftText, string rightText) { List <string> leftInput = new List <string>(Common.Utility.StandardizeLineBreaks(leftText, Common.Utility.LineBreaks.Unix).Split('\n')); List <string> rightInput = new List <string>(Common.Utility.StandardizeLineBreaks(rightText, Common.Utility.LineBreaks.Unix).Split('\n')); // We need to add a blank line to the bottom of each file, or any lines that are added // at the bottom of the new files will be discarded by the diff/merge. I have spent far // too long trying to work out why, this work around works so I'm going with it. If someone // fixes the underlying problem, this should still work fine. We remove the last line of the // merged lines to compensate for this. AddHack(leftInput, rightInput); // Do the initial 2 way diff Diff diff = new Diff(leftInput.ToArray(), rightInput.ToArray(), false, true); List <string> leftResult = new List <string>(); List <string> rightResult = new List <string>(); List <string> mergedResult = new List <string>(); List <Block> leftBlocks = new List <Block>(); List <Block> rightBlocks = new List <Block>(); List <Block> mergedBlocks = new List <Block>(); List <int> conflictBlocks = new List <int>(); foreach (Diff.Hunk h in diff) { if (h.Same) { // Create a new block. leftBlocks.Add(new Block(leftResult.Count, h.Original().Count)); rightBlocks.Add(new Block(rightResult.Count, h.Original().Count)); mergedBlocks.Add(new Block(mergedResult.Count, h.Original().Count)); // Add each of the lines in the hunk to all of the result lists foreach (string line in h.Original()) { leftResult.Add(line); rightResult.Add(line); mergedResult.Add(line); } continue; } // Create a new block leftBlocks.Add(new Block(leftResult.Count, h.Left.Count)); rightBlocks.Add(new Block(rightResult.Count, h.Right.Count)); mergedBlocks.Add(new Block(mergedResult.Count, 0)); // Add a new conflict block indicator conflictBlocks.Add(leftBlocks.Count - 1); // Add the lines from the left side of the hunk to the left result foreach (string line in h.Left) { leftResult.Add(line); } // Add the lines from the right side of the hunk to the right result foreach (string line in h.Right) { rightResult.Add(line); } } // Remove our hack lines RemoveHack(leftBlocks, leftResult, rightBlocks, rightResult, mergedBlocks); DiffResult result = new DiffResult(); result.diffResults.Left = new SingleDiffResult(result, leftResult, leftBlocks, "Left"); result.diffResults.Right = new SingleDiffResult(result, rightResult, rightBlocks, "Right"); result.diffResults.Merged = new SingleDiffResult(result, mergedResult, mergedBlocks, "Merged"); foreach (var cb in conflictBlocks) { result.conflictBlocks.Add(cb); } return(result); }