diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2018-12-25 08:06:43 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-25 08:06:43 +0300 |
commit | ac599f46a092f07632a6fa288f7d9eda3c04bdc6 (patch) | |
tree | 34e896dbb41bc27b277e20862f8bb29767626dcb | |
parent | e5fdf1b8be0fd4d75fb2bd62a53fdd9a81bb84f6 (diff) | |
parent | 2f583cbf16dee63fcbcf16f0d6fcace8a81f3a2c (diff) |
Merge pull request #1652 from jcansdale/fixes/git-diff-indent-heuristic
Add support for git diff --indent-heuristic option
-rw-r--r-- | LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs | 81 | ||||
-rw-r--r-- | LibGit2Sharp/CompareOptions.cs | 6 | ||||
-rw-r--r-- | LibGit2Sharp/Core/GitDiff.cs | 15 | ||||
-rw-r--r-- | LibGit2Sharp/Diff.cs | 7 |
4 files changed, 104 insertions, 5 deletions
diff --git a/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs b/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs index 00ef0ab2..fea0bbb7 100644 --- a/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs +++ b/LibGit2Sharp.Tests/DiffBlobToBlobFixture.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Linq; using System.Text; using LibGit2Sharp.Tests.TestHelpers; using Xunit; @@ -126,5 +127,85 @@ namespace LibGit2Sharp.Tests Assert.Equal(0, changes.LinesDeleted); } } + + [Fact] + public void ComparingBlobsWithNoSpacesAndIndentHeuristicOptionMakesADifference() + { + var path = SandboxStandardTestRepoGitDir(); + using (var repo = new Repository(path)) + { + // Based on test diff indent heuristic from: + // https://github.com/git/git/blob/433860f3d0beb0c6f205290bd16cda413148f098/t/t4061-diff-indent.sh#L17 + var oldContent = +@" 1 + 2 + a + + b + 3 + 4"; + var newContent = +@" 1 + 2 + a + + b + a + + b + 3 + 4"; + var oldBlob = repo.ObjectDatabase.CreateBlob(new MemoryStream(Encoding.UTF8.GetBytes(oldContent))); + var newBlob = repo.ObjectDatabase.CreateBlob(new MemoryStream(Encoding.UTF8.GetBytes(newContent))); + var noIndentHeuristicOption = new CompareOptions { IndentHeuristic = false }; + var indentHeuristicOption = new CompareOptions { IndentHeuristic = true }; + + ContentChanges changes0 = repo.Diff.Compare(oldBlob, newBlob, noIndentHeuristicOption); + ContentChanges changes1 = repo.Diff.Compare(oldBlob, newBlob, indentHeuristicOption); + + Assert.NotEqual(changes0.Patch, changes1.Patch); + Assert.Equal(CanonicalChangedLines(changes0), CanonicalChangedLines(changes1)); + } + } + + [Fact] + public void ComparingBlobsWithNoSpacesIndentHeuristicOptionMakesNoDifference() + { + var path = SandboxStandardTestRepoGitDir(); + using (var repo = new Repository(path)) + { + var oldContent = +@" 1 + 2 + a + b + 3 + 4"; + var newContent = +@" 1 + 2 + a + b + a + b + 3 + 4"; + var oldBlob = repo.ObjectDatabase.CreateBlob(new MemoryStream(Encoding.UTF8.GetBytes(oldContent))); + var newBlob = repo.ObjectDatabase.CreateBlob(new MemoryStream(Encoding.UTF8.GetBytes(newContent))); + var noIndentHeuristicOption = new CompareOptions { IndentHeuristic = false }; + var indentHeuristicOption = new CompareOptions { IndentHeuristic = true }; + + ContentChanges changes0 = repo.Diff.Compare(oldBlob, newBlob, noIndentHeuristicOption); + ContentChanges changes1 = repo.Diff.Compare(oldBlob, newBlob, indentHeuristicOption); + + Assert.Equal(changes0.Patch, changes1.Patch); + } + } + + static string CanonicalChangedLines(ContentChanges changes) + { + // Create an ordered representation of lines that have been added or removed + return string.Join("\n", changes.Patch.Split('\n').Where(l => l.StartsWith("+") || l.StartsWith("-")).OrderBy(l => l)); + } } } diff --git a/LibGit2Sharp/CompareOptions.cs b/LibGit2Sharp/CompareOptions.cs index fbd147c7..fb423443 100644 --- a/LibGit2Sharp/CompareOptions.cs +++ b/LibGit2Sharp/CompareOptions.cs @@ -44,5 +44,11 @@ namespace LibGit2Sharp /// By default, <see cref="DiffAlgorithm.Myers"/> will be used. /// </summary> public DiffAlgorithm Algorithm { get; set; } + + /// <summary> + /// Enable --indent-heuristic Diff option, that attempts to produce more aesthetically pleasing diffs. + /// By default, this option will be false. + /// </summary> + public bool IndentHeuristic { get; set; } } } diff --git a/LibGit2Sharp/Core/GitDiff.cs b/LibGit2Sharp/Core/GitDiff.cs index eb21d688..956bc89a 100644 --- a/LibGit2Sharp/Core/GitDiff.cs +++ b/LibGit2Sharp/Core/GitDiff.cs @@ -134,6 +134,13 @@ namespace LibGit2Sharp.Core */ /// <summary> + /// Use a heuristic that takes indentation and whitespace into account + /// which generally can produce better diffs when dealing with ambiguous + /// diff hunks. + /// </summary> + GIT_DIFF_INDENT_HEURISTIC = (1 << 18), + + /// <summary> /// Treat all files as text, disabling binary attributes and detection /// </summary> GIT_DIFF_FORCE_TEXT = (1 << 20), @@ -304,11 +311,11 @@ namespace LibGit2Sharp.Core enum GitDiffFormat { - GIT_DIFF_FORMAT_PATCH = 1, // < full git diff + GIT_DIFF_FORMAT_PATCH = 1, // < full git diff GIT_DIFF_FORMAT_PATCH_HEADER = 2, // < just the file headers of patch - GIT_DIFF_FORMAT_RAW = 3, // < like git diff --raw - GIT_DIFF_FORMAT_NAME_ONLY = 4, // < like git diff --name-only - GIT_DIFF_FORMAT_NAME_STATUS = 5, // < like git diff --name-status + GIT_DIFF_FORMAT_RAW = 3, // < like git diff --raw + GIT_DIFF_FORMAT_NAME_ONLY = 4, // < like git diff --name-only + GIT_DIFF_FORMAT_NAME_STATUS = 5, // < like git diff --name-status } [Flags] diff --git a/LibGit2Sharp/Diff.cs b/LibGit2Sharp/Diff.cs index 9bf14660..087ee8d6 100644 --- a/LibGit2Sharp/Diff.cs +++ b/LibGit2Sharp/Diff.cs @@ -63,6 +63,11 @@ namespace LibGit2Sharp options.Flags |= GitDiffOptionFlags.GIT_DIFF_DISABLE_PATHSPEC_MATCH; } + if (compareOptions.IndentHeuristic) + { + options.Flags |= GitDiffOptionFlags.GIT_DIFF_INDENT_HEURISTIC; + } + if (matchedPathsAggregator != null) { options.NotifyCallback = matchedPathsAggregator.OnGitDiffNotify; @@ -351,7 +356,7 @@ namespace LibGit2Sharp } DiffHandle diff = BuildDiffList(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); - + try { return BuildDiffResult<T>(diff); |