Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit f05ca32

Browse files
authored
Merge pull request #1178 from github/fixes/1149-comments-not-displaying
Fix diff line matching when there's a partial match
2 parents 52152f6 + c373444 commit f05ca32

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

src/GitHub.Exports/Models/DiffUtilities.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,27 +82,28 @@ public static IEnumerable<DiffChunk> ParseFragment(string diff)
8282

8383
public static DiffLine Match(IEnumerable<DiffChunk> diff, IList<DiffLine> target)
8484
{
85-
int j = 0;
86-
8785
if (target.Count == 0)
8886
{
8987
return null; // no lines to match
9088
}
9189

9290
foreach (var source in diff)
9391
{
92+
var matches = 0;
9493
for (var i = source.Lines.Count - 1; i >= 0; --i)
9594
{
96-
if (source.Lines[i].Content == target[j].Content)
95+
if (source.Lines[i].Content == target[matches].Content)
9796
{
98-
if (++j == target.Count || i == 0)
97+
matches++;
98+
if (matches == target.Count || i == 0)
9999
{
100-
return source.Lines[i + j - 1];
100+
return source.Lines[i + matches - 1];
101101
}
102102
}
103103
else
104104
{
105-
j = 0;
105+
i += matches;
106+
matches = 0;
106107
}
107108
}
108109
}

test/GitHub.InlineReviews.UnitTests/Models/DiffUtilitiesTests.cs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,30 +185,41 @@ public void InvalidDiffLineChangeChar(string line, string expectMessage)
185185

186186
public class TheMatchMethod
187187
{
188+
/// <param name="diffLines">Target diff chunk with header (with '.' as line separator)</param>
189+
/// <param name="matchLines">Diff lines to match (with '.' as line separator)</param>
190+
/// <param name="expectedDiffLineNumber">The DiffLineNumber that the last line of matchLines falls on</param>
188191
[Theory]
189-
[InlineData(" 1", " 1", 0)]
190-
[InlineData(" 1. 2", " 2", 1)]
191-
[InlineData(" 1. 1", " 1", 1)] // match the later line
192+
[InlineData(" 1", " 1", 1)]
193+
[InlineData(" 1. 2", " 2", 2)]
194+
[InlineData(" 1. 1", " 1", 2)] // match the later line
192195
[InlineData("+x", "-x", -1)]
193196
[InlineData("", " x", -1)]
194197
[InlineData(" x", "", -1)]
195198

196-
[InlineData(" 1. 2.", " 2. 1.", 1)] // matched full context
197-
[InlineData(" 1. 2.", " 2. 3.", -1)] // didn't match full context
198-
[InlineData(" 2.", " 2. 1.", 0)] // match if we run out of context lines
199-
public void MatchLine(string lines1, string lines2, int skip /* -1 for no match */)
199+
[InlineData(" 1. 2.", " 1. 2.", 2)] // matched full context
200+
[InlineData(" 1. 2.", " 3. 2.", -1)] // didn't match full context
201+
[InlineData(" 2.", " 1. 2.", 1)] // match if we run out of context lines
202+
203+
// Tests for https://github.com/github/VisualStudio/issues/1149
204+
// Matching algorithm got confused when there was a partial match.
205+
[InlineData("+a.+x.+x.", "+a.+x.", 2)]
206+
[InlineData("+a.+x.+x.", "+a.+x.+x.", 3)]
207+
[InlineData("+a.+x.+x.+b.+x.+x.", "+a.+x.", 2)]
208+
[InlineData("+a.+x.+x.+b.+x.+x.", "+b.+x.", 5)]
209+
[InlineData("+a.+b.+x", "+a.+x.", -1)] // backtrack when there is a failed match
210+
public void MatchLine(string diffLines, string matchLines, int expectedDiffLineNumber /* -1 for no match */)
200211
{
201212
var header = "@@ -1 +1 @@";
202-
lines1 = lines1.Replace(".", "\r\n");
203-
lines2 = lines2.Replace(".", "\r\n");
204-
var chunks1 = DiffUtilities.ParseFragment(header + "\n" + lines1).ToList();
205-
var chunks2 = DiffUtilities.ParseFragment(header + "\n" + lines2).ToList();
206-
var expectLine = (skip != -1) ? chunks1.First().Lines.Skip(skip).First() : null;
207-
var targetLines = chunks2.First().Lines;
213+
diffLines = diffLines.Replace(".", "\r\n");
214+
matchLines = matchLines.Replace(".", "\r\n");
215+
var chunks1 = DiffUtilities.ParseFragment(header + "\n" + diffLines).ToList();
216+
var chunks2 = DiffUtilities.ParseFragment(header + "\n" + matchLines).ToList();
217+
var targetLines = chunks2.First().Lines.Reverse().ToList();
208218

209219
var line = DiffUtilities.Match(chunks1, targetLines);
210220

211-
Assert.Equal(expectLine, line);
221+
var diffLineNumber = (line != null) ? line.DiffLineNumber : -1;
222+
Assert.Equal(expectedDiffLineNumber, diffLineNumber);
212223
}
213224

214225
[Fact]

0 commit comments

Comments
 (0)