Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

White space diff options #1778 #1779

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 66 additions & 1 deletion LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Text;
using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
using Xunit.Extensions;

namespace LibGit2Sharp.Tests
{
Expand Down Expand Up @@ -1219,5 +1218,71 @@ public void UsingPatienceAlgorithmCompareOptionProducesPatienceDiff()
Assert.Equal(diffPatience, changes);
}
}

[Fact]
public void PatchWhitespaceModeIsObeyed()
{
string repoPath = InitNewRepository();

var compareOptions = Enum
.GetValues(typeof(PatchWhitespaceMode))
.Cast<PatchWhitespaceMode>()
.Select(whitespaceOption => new CompareOptions() { PatchWhitespaceMode = whitespaceOption });

using (var repo = new Repository(repoPath))
{
const string fileName = "file.txt";
var commits = new System.Collections.Generic.List<Commit>();

Touch(repo.Info.WorkingDirectory, fileName, "White space is not wastedspace.");
Commands.Stage(repo, fileName);
commits.Add(repo.Commit("Initial", Constants.Signature, Constants.Signature));

Touch(repo.Info.WorkingDirectory, fileName, "White space is not wastedspace. \t");
Commands.Stage(repo, fileName);
commits.Add(repo.Commit("Add trailing whitespace.", Constants.Signature, Constants.Signature));

Touch(repo.Info.WorkingDirectory, fileName, "White space\tis not wastedspace. ");
Commands.Stage(repo, fileName);
commits.Add(repo.Commit("Change whitespace.", Constants.Signature, Constants.Signature));

Touch(repo.Info.WorkingDirectory, fileName, " Whitespace is not wasted space.");
Commands.Stage(repo, fileName);
commits.Add(repo.Commit("Insert whitespace.", Constants.Signature, Constants.Signature));

Touch(repo.Info.WorkingDirectory, fileName, "Completely different content.");
Commands.Stage(repo, fileName);
commits.Add(repo.Commit("Completely different.", Constants.Signature, Constants.Signature));

var commitPairs = commits
.Select((oldCommit, index) => new { oldCommit, index })
.Zip(commits.Skip(1), (old, newCommit) => new { old.oldCommit, newCommit, old.index });

foreach (var commitPair in commitPairs)
foreach (var compareOption in compareOptions)
using (var patch = repo.Diff.Compare<Patch>(commitPair.oldCommit.Tree, commitPair.newCommit.Tree, compareOption))
{
int expectedDiffLines;
switch (compareOption.PatchWhitespaceMode)
{
case PatchWhitespaceMode.DontIgnoreWhitespace:
expectedDiffLines = 1;
break;
case PatchWhitespaceMode.IgnoreAllWhitespace:
expectedDiffLines = commitPair.index > 2 ? 1 : 0;
break;
case PatchWhitespaceMode.IgnoreWhitespaceChange:
expectedDiffLines = commitPair.index > 1 ? 1 : 0;
break;
case PatchWhitespaceMode.IgnoreWhitespaceEol:
expectedDiffLines = commitPair.index > 0 ? 1 : 0;
break;
default:
throw new Exception("Unexpected " + nameof(PatchWhitespaceMode));
}
Assert.Equal(expectedDiffLines, patch.LinesAdded);
}
}
}
}
}
29 changes: 29 additions & 0 deletions LibGit2Sharp/CompareOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

namespace LibGit2Sharp
{
/// <summary>
/// Represents a mode for handling whitespace while creating a patch.
/// </summary>
public enum PatchWhitespaceMode
{
/// <summary>
/// Do not ignore changes in whitespace when comparing lines.
/// </summary>
DontIgnoreWhitespace = 0,
/// <summary>
/// Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none.
/// </summary>
IgnoreAllWhitespace = 1,
/// <summary>
/// Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent.
/// </summary>
IgnoreWhitespaceChange = 2,
/// <summary>
/// Ignore changes in whitespace at EOL.
/// </summary>
IgnoreWhitespaceEol = 3,
}

/// <summary>
/// Options to define file comparison behavior.
/// </summary>
Expand All @@ -14,6 +37,7 @@ public CompareOptions()
{
ContextLines = 3;
InterhunkLines = 0;
PatchWhitespaceMode = PatchWhitespaceMode.DontIgnoreWhitespace;
Algorithm = DiffAlgorithm.Myers;
}

Expand All @@ -29,6 +53,11 @@ public CompareOptions()
/// </summary>
public int InterhunkLines { get; set; }

/// <summary>
/// The mode for handling whitespace when comparing lines
/// </summary>
public PatchWhitespaceMode PatchWhitespaceMode { get; set; }

/// <summary>
/// Options for rename detection. If null, the `diff.renames` configuration setting is used.
/// </summary>
Expand Down
15 changes: 15 additions & 0 deletions LibGit2Sharp/Diff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ private static GitDiffOptions BuildOptions(DiffModifiers diffOptions, FilePath[]
options.Flags |= GitDiffOptionFlags.GIT_DIFF_INDENT_HEURISTIC;
}

switch (compareOptions.PatchWhitespaceMode)
{
case PatchWhitespaceMode.DontIgnoreWhitespace:
break;
case PatchWhitespaceMode.IgnoreAllWhitespace:
options.Flags |= GitDiffOptionFlags.GIT_DIFF_IGNORE_WHITESPACE;
break;
case PatchWhitespaceMode.IgnoreWhitespaceChange:
options.Flags |= GitDiffOptionFlags.GIT_DIFF_IGNORE_WHITESPACE_CHANGE;
break;
case PatchWhitespaceMode.IgnoreWhitespaceEol:
options.Flags |= GitDiffOptionFlags.GIT_DIFF_IGNORE_WHITESPACE_EOL;
break;
}

if (matchedPathsAggregator != null)
{
options.NotifyCallback = matchedPathsAggregator.OnGitDiffNotify;
Expand Down