public static IEnumerable <DiffChunk> ParseFragment(string diff) { var reader = new LineReader(diff); string line; DiffChunk chunk = null; int diffLine = -1; int oldLine = -1; int newLine = -1; while ((line = reader.ReadLine()) != null) { var headerMatch = ChunkHeaderRegex.Match(line); if (headerMatch.Success) { if (chunk != null) { yield return(chunk); } if (diffLine == -1) { diffLine = 0; } chunk = new DiffChunk { OldLineNumber = oldLine = int.Parse(headerMatch.Groups[1].Value), NewLineNumber = newLine = int.Parse(headerMatch.Groups[2].Value), DiffLine = diffLine, }; } else if (chunk != null) { var type = GetLineChange(line[0]); // This might contain info about previous line (e.g. "\ No newline at end of file"). if (type != DiffChangeType.Control) { chunk.Lines.Add(new DiffLine { Type = type, OldLineNumber = type != DiffChangeType.Add ? oldLine : -1, NewLineNumber = type != DiffChangeType.Delete ? newLine : -1, DiffLineNumber = diffLine, Content = line, }); var lineCount = 1; lineCount += LineReader.CountCarriageReturns(line); switch (type) { case DiffChangeType.None: oldLine += lineCount; newLine += lineCount; break; case DiffChangeType.Delete: oldLine += lineCount; break; case DiffChangeType.Add: newLine += lineCount; break; } } } if (diffLine != -1) { ++diffLine; } } if (chunk != null) { yield return(chunk); } }