diff --git a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs index 37b3f669f..0367ce1ae 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs @@ -43,9 +43,12 @@ public void CanCompareASimpleTreeAgainstTheWorkDir() { SetUpSimpleDiffContext(repo); - TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree, + var changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory); + Assert.Equal(1, changes.Modified.Count()); + var patch = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.WorkingDirectory); var expected = new StringBuilder() .Append("diff --git a/file.txt b/file.txt\n") .Append("index ce01362..4f125e3 100644\n") @@ -56,7 +59,7 @@ public void CanCompareASimpleTreeAgainstTheWorkDir() .Append("+world\n") .Append("+!!!\n"); - Assert.Equal(expected.ToString(), changes.Patch); + Assert.Equal(expected.ToString(), patch); } } @@ -67,7 +70,7 @@ public void CanCompareAMoreComplexTreeAgainstTheWorkdir() { Tree tree = repo.Head.Tip.Tree; - TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.WorkingDirectory); + var changes = repo.Diff.Compare(tree, DiffTargets.WorkingDirectory); Assert.NotNull(changes); Assert.Equal(6, changes.Count()); @@ -103,9 +106,12 @@ public void CanCompareASimpleTreeAgainstTheWorkDirAndTheIndex() { SetUpSimpleDiffContext(repo); - TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree, + var changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index | DiffTargets.WorkingDirectory); + Assert.Equal(1, changes.Modified.Count()); + var patch = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.Index | DiffTargets.WorkingDirectory); var expected = new StringBuilder() .Append("diff --git a/file.txt b/file.txt\n") .Append("index ce01362..4f125e3 100644\n") @@ -116,7 +122,7 @@ public void CanCompareASimpleTreeAgainstTheWorkDirAndTheIndex() .Append("+world\n") .Append("+!!!\n"); - Assert.Equal(expected.ToString(), changes.Patch); + Assert.Equal(expected.ToString(), patch); } } @@ -158,8 +164,13 @@ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison() FileStatus state = repo.Index.RetrieveStatus("file.txt"); Assert.Equal(FileStatus.Removed | FileStatus.Untracked, state); + var wrkDirToIdxToTree = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.Index | DiffTargets.WorkingDirectory); + + Assert.Equal(1, wrkDirToIdxToTree.Deleted.Count()); + Assert.Equal(0, wrkDirToIdxToTree.Modified.Count()); - TreeChanges wrkDirToIdxToTree = repo.Diff.Compare(repo.Head.Tip.Tree, + var patch = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index | DiffTargets.WorkingDirectory); var expected = new StringBuilder() .Append("diff --git a/file.txt b/file.txt\n") @@ -170,9 +181,15 @@ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison() .Append("@@ -1 +0,0 @@\n") .Append("-hello\n"); - Assert.Equal(expected.ToString(), wrkDirToIdxToTree.Patch); + Assert.Equal(expected.ToString(), patch); - TreeChanges wrkDirToTree = repo.Diff.Compare(repo.Head.Tip.Tree, + var wrkDirToTree = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.WorkingDirectory); + + Assert.Equal(0, wrkDirToTree.Deleted.Count()); + Assert.Equal(1, wrkDirToTree.Modified.Count()); + + patch = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory); expected = new StringBuilder() .Append("diff --git a/file.txt b/file.txt\n") @@ -184,7 +201,7 @@ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison() .Append("+world\n") .Append("+!!!\n"); - Assert.Equal(expected.ToString(), wrkDirToTree.Patch); + Assert.Equal(expected.ToString(), patch); } } @@ -207,9 +224,12 @@ public void CanCompareASimpleTreeAgainstTheIndex() { SetUpSimpleDiffContext(repo); - TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree, + var changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index); + Assert.Equal(1, changes.Modified.Count()); + var patch = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.Index); var expected = new StringBuilder() .Append("diff --git a/file.txt b/file.txt\n") .Append("index ce01362..94954ab 100644\n") @@ -219,7 +239,7 @@ public void CanCompareASimpleTreeAgainstTheIndex() .Append(" hello\n") .Append("+world\n"); - Assert.Equal(expected.ToString(), changes.Patch); + Assert.Equal(expected.ToString(), patch); } } @@ -254,7 +274,7 @@ public void CanCompareAMoreComplexTreeAgainstTheIndex() { Tree tree = repo.Head.Tip.Tree; - TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.Index); + var changes = repo.Diff.Compare(tree, DiffTargets.Index); Assert.NotNull(changes); Assert.Equal(3, changes.Count()); @@ -281,7 +301,7 @@ public void CanCompareASubsetofTheTreeAgainstTheIndex() { Tree tree = repo.Head.Tip.Tree; - TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.Index, + var changes = repo.Diff.Compare(tree, DiffTargets.Index, new[] { "deleted_staged_file.txt", "1/branch_file.txt" }); Assert.NotNull(changes); @@ -305,11 +325,11 @@ public void CanCompareASubsetofTheTreeAgainstTheIndexWithLaxExplicitPathsValidat { Tree tree = repo.Head.Tip.Tree; - TreeChanges changes = repo.Diff.Compare(tree, DiffTargets.Index, + var changes = repo.Diff.Compare(tree, DiffTargets.Index, new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" }, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false }); AssertCanCompareASubsetOfTheTreeAgainstTheIndex(changes); - changes = repo.Diff.Compare(tree, DiffTargets.Index, + changes = repo.Diff.Compare(tree, DiffTargets.Index, new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" }); AssertCanCompareASubsetOfTheTreeAgainstTheIndex(changes); } @@ -322,7 +342,7 @@ public void ComparingASubsetofTheTreeAgainstTheIndexWithStrictExplicitPathsValid { Tree tree = repo.Head.Tip.Tree; - Assert.Throws(() => repo.Diff.Compare(tree, DiffTargets.Index, + Assert.Throws(() => repo.Diff.Compare(tree, DiffTargets.Index, new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" }, new ExplicitPathsOptions())); } } @@ -359,11 +379,10 @@ public void CanCopeWithEndOfFileNewlineChanges() File.AppendAllText(fullpath, "\n"); repo.Index.Stage("file.txt"); - TreeChanges changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index); + var changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index); Assert.Equal(1, changes.Modified.Count()); - Assert.Equal(1, changes.LinesAdded); - Assert.Equal(1, changes.LinesDeleted); + var patch = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index); var expected = new StringBuilder() .Append("diff --git a/file.txt b/file.txt\n") .Append("index 2e65efe..7898192 100644\n") @@ -374,7 +393,9 @@ public void CanCopeWithEndOfFileNewlineChanges() .Append("\\ No newline at end of file\n") .Append("+a\n"); - Assert.Equal(expected.ToString(), changes.Patch); + Assert.Equal(expected.ToString(), patch); + Assert.Equal(1, patch.LinesAdded); + Assert.Equal(1, patch.LinesDeleted); } } @@ -384,11 +405,11 @@ public void ComparingATreeInABareRepositoryAgainstTheWorkDirOrTheIndexThrows() using (var repo = new Repository(BareTestRepoPath)) { Assert.Throws( - () => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory)); + () => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory)); Assert.Throws( - () => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index)); + () => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index)); Assert.Throws( - () => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory | DiffTargets.Index)); + () => repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.WorkingDirectory | DiffTargets.Index)); } } @@ -401,14 +422,13 @@ public void CanCompareANullTreeAgainstTheIndex() { SetUpSimpleDiffContext(repo); - TreeChanges changes = repo.Diff.Compare(null, + var changes = repo.Diff.Compare(null, DiffTargets.Index); Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Added.Count()); Assert.Equal("file.txt", changes.Added.Single().Path); - Assert.Equal(2, changes.Added.Single().LinesAdded); } } @@ -421,14 +441,13 @@ public void CanCompareANullTreeAgainstTheWorkdir() { SetUpSimpleDiffContext(repo); - TreeChanges changes = repo.Diff.Compare(null, + var changes = repo.Diff.Compare(null, DiffTargets.WorkingDirectory); Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Added.Count()); Assert.Equal("file.txt", changes.Added.Single().Path); - Assert.Equal(3, changes.Added.Single().LinesAdded); } } @@ -441,14 +460,13 @@ public void CanCompareANullTreeAgainstTheWorkdirAndTheIndex() { SetUpSimpleDiffContext(repo); - TreeChanges changes = repo.Diff.Compare(null, + var changes = repo.Diff.Compare(null, DiffTargets.WorkingDirectory | DiffTargets.Index); Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Added.Count()); Assert.Equal("file.txt", changes.Added.Single().Path); - Assert.Equal(3, changes.Added.Single().LinesAdded); } } } diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index 4ed88ea69..289650f70 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -19,10 +19,12 @@ public void ComparingATreeAgainstItselfReturnsNoDifference() { Tree tree = repo.Head.Tip.Tree; - TreeChanges changes = repo.Diff.Compare(tree, tree); + var changes = repo.Diff.Compare(tree, tree); + var patch = repo.Diff.Compare(tree, tree); Assert.Empty(changes); - Assert.Equal(string.Empty, changes.Patch); + Assert.Empty(patch); + Assert.Equal(String.Empty, patch); } } @@ -33,7 +35,7 @@ public void RetrievingANonExistentFileChangeReturnsNull() { Tree tree = repo.Head.Tip.Tree; - TreeChanges changes = repo.Diff.Compare(tree, tree); + var changes = repo.Diff.Compare(tree, tree); Assert.Null(changes["batman"]); } @@ -52,19 +54,20 @@ public void CanCompareACommitTreeAgainstItsParent() Tree commitTree = repo.Head.Tip.Tree; Tree parentCommitTree = repo.Head.Tip.Parents.Single().Tree; - TreeChanges changes = repo.Diff.Compare(parentCommitTree, commitTree); + var changes = repo.Diff.Compare(parentCommitTree, commitTree); Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Added.Count()); TreeEntryChanges treeEntryChanges = changes["1.txt"]; - Assert.False(treeEntryChanges.IsBinaryComparison); + + var patch = repo.Diff.Compare(parentCommitTree, commitTree); + Assert.False(patch["1.txt"].IsBinaryComparison); Assert.Equal("1.txt", treeEntryChanges.Path); Assert.Equal(ChangeKind.Added, treeEntryChanges.Status); Assert.Equal(treeEntryChanges, changes.Added.Single()); - Assert.Equal(1, treeEntryChanges.LinesAdded); Assert.Equal(Mode.Nonexistent, treeEntryChanges.OldMode); } @@ -88,7 +91,7 @@ public void CanCompareASubsetofTheTreeAgainstOneOfItsAncestor() Tree tree = repo.Head.Tip.Tree; Tree ancestor = repo.Lookup("9fd738e").Tree; - TreeChanges changes = repo.Diff.Compare(ancestor, tree, new[]{ "1" }); + var changes = repo.Diff.Compare(ancestor, tree, new[] { "1" }); Assert.NotNull(changes); Assert.Equal(1, changes.Count()); @@ -118,7 +121,7 @@ public void CanCompareACommitTreeAgainstATreeWithNoCommonAncestor() Tree commitTree = repo.Head.Tip.Tree; Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree; - TreeChanges changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree); + var changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree); Assert.Equal(10, changes.Count()); Assert.Equal(9, changes.Added.Count()); @@ -128,9 +131,10 @@ public void CanCompareACommitTreeAgainstATreeWithNoCommonAncestor() Assert.Equal(new[] { "1.txt", subBranchFilePath, "README", "branch_file.txt", "deleted_staged_file.txt", "deleted_unstaged_file.txt", "modified_staged_file.txt", "modified_unstaged_file.txt", "new.txt" }, changes.Added.Select(x => x.Path).OrderBy(p => p, StringComparer.Ordinal).ToArray()); - Assert.Equal(9, changes.LinesAdded); - Assert.Equal(2, changes.LinesDeleted); - Assert.Equal(2, changes["readme.txt"].LinesDeleted); + var patch = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree); + Assert.Equal(9, patch.LinesAdded); + Assert.Equal(2, patch.LinesDeleted); + Assert.Equal(2, patch["readme.txt"].LinesDeleted); } } @@ -142,11 +146,11 @@ public void CanCompareATreeAgainstAnotherTreeWithLaxExplicitPathsValidationAndNo Tree commitTree = repo.Head.Tip.Tree; Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree; - TreeChanges changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree, + var changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree, new[] { "if-I-exist-this-test-is-really-unlucky.txt" }, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false }); Assert.Equal(0, changes.Count()); - changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree, + changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree, new[] { "if-I-exist-this-test-is-really-unlucky.txt" }); Assert.Equal(0, changes.Count()); } @@ -161,7 +165,7 @@ public void ComparingATreeAgainstAnotherTreeWithStrictExplicitPathsValidationThr Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree; Assert.Throws(() => - repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree, + repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree, new[] { "if-I-exist-this-test-is-really-unlucky.txt" }, new ExplicitPathsOptions())); } } @@ -192,7 +196,7 @@ public void CanDetectTheRenamingOfAModifiedFile() Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; Tree commitTreeWithRenamedFile = repo.Lookup("4be51d6").Tree; - TreeChanges changes = repo.Diff.Compare(rootCommitTree, commitTreeWithRenamedFile); + var changes = repo.Diff.Compare(rootCommitTree, commitTreeWithRenamedFile); Assert.Equal(1, changes.Count()); Assert.Equal("super-file.txt", changes["super-file.txt"].Path); @@ -236,18 +240,21 @@ public void CanCompareTwoVersionsOfAFileWithATrailingNewlineDeletion(int context Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; Tree commitTreeWithUpdatedFile = repo.Lookup("ec9e401").Tree; - TreeChanges changes = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile, - compareOptions: new CompareOptions { ContextLines = contextLines }); + var changes = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile); Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Modified.Count()); - Assert.Equal(expectedPatchLength, changes.Patch.Length); - TreeEntryChanges treeEntryChanges = changes.Modified.Single(); + var patch = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile, + compareOptions: new CompareOptions { ContextLines = contextLines }); + + Assert.Equal(expectedPatchLength, patch.Content.Length); - Assert.Equal(2, treeEntryChanges.LinesAdded); - Assert.Equal(1, treeEntryChanges.LinesDeleted); - Assert.Equal(expectedPatchLength, treeEntryChanges.Patch.Length); + ContentChanges contentChanges = patch["numbers.txt"]; + + Assert.Equal(2, contentChanges.LinesAdded); + Assert.Equal(1, contentChanges.LinesDeleted); + Assert.Equal(expectedPatchLength, contentChanges.Patch.Length); } } @@ -326,23 +333,25 @@ public void CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks(int contextLines, in Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; Tree mergedCommitTree = repo.Lookup("7252fe2").Tree; - TreeChanges changes = repo.Diff.Compare(rootCommitTree, mergedCommitTree, compareOptions: compareOptions); + var changes = repo.Diff.Compare(rootCommitTree, mergedCommitTree); Assert.Equal(3, changes.Count()); Assert.Equal(1, changes.Modified.Count()); Assert.Equal(1, changes.Deleted.Count()); Assert.Equal(1, changes.Added.Count()); - TreeEntryChanges treeEntryChanges = changes["numbers.txt"]; + Assert.Equal(Mode.Nonexistent, changes["my-name-does-not-feel-right.txt"].Mode); - Assert.Equal(3, treeEntryChanges.LinesAdded); - Assert.Equal(1, treeEntryChanges.LinesDeleted); + var patch = repo.Diff.Compare(rootCommitTree, mergedCommitTree, compareOptions: compareOptions); - Assert.Equal(Mode.Nonexistent, changes["my-name-does-not-feel-right.txt"].Mode); + ContentChanges contentChanges = patch["numbers.txt"]; + + Assert.Equal(3, contentChanges.LinesAdded); + Assert.Equal(1, contentChanges.LinesDeleted); Assert.Equal(Expected("f8d44d7...7252fe2/numbers.txt-{0}-{1}.diff", contextLines, interhunkLines), - treeEntryChanges.Patch); + contentChanges.Patch); Assert.Equal(Expected("f8d44d7...7252fe2/full-{0}-{1}.diff", contextLines, interhunkLines), - changes.Patch); + patch); } } @@ -369,7 +378,7 @@ public void CanHandleTwoTreeEntryChangesWithTheSamePath() Tree treeNew = repo.ObjectDatabase.CreateTree(tdNew); - TreeChanges changes = repo.Diff.Compare(treeOld, treeNew); + var changes = repo.Diff.Compare(treeOld, treeNew); /* * $ git diff-tree -p 5c87b67 d5278d0 @@ -416,14 +425,14 @@ public void CanCompareATreeAgainstANullTree() { Tree tree = repo.Branches["refs/remotes/origin/test"].Tip.Tree; - TreeChanges changes = repo.Diff.Compare(tree, null); + var changes = repo.Diff.Compare(tree, null); Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Deleted.Count()); Assert.Equal("readme.txt", changes.Deleted.Single().Path); - changes = repo.Diff.Compare(null, tree); + changes = repo.Diff.Compare(null, tree); Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Added.Count()); @@ -437,7 +446,7 @@ public void ComparingTwoNullTreesReturnsAnEmptyTreeChanges() { using (var repo = new Repository(StandardTestRepoPath)) { - TreeChanges changes = repo.Diff.Compare(default(Tree), default(Tree)); + var changes = repo.Diff.Compare(default(Tree), default(Tree)); Assert.Equal(0, changes.Count()); } @@ -460,7 +469,7 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() File.WriteAllBytes(fullpath, ((Blob)(entry.Target)).Content); // Unset the local core.filemode, if any. - repo.Config.Unset("core.filemode", ConfigurationLevel.Local); + repo.Config.Unset("core.filemode"); } SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); @@ -469,7 +478,7 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path, options)) { - TreeChanges changes = repo.Diff.Compare(new []{ file }); + var changes = repo.Diff.Compare(new[] { file }); Assert.Equal(1, changes.Count()); @@ -482,7 +491,7 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path, options)) { - TreeChanges changes = repo.Diff.Compare(new[] { file }); + var changes = repo.Diff.Compare(new[] { file }); Assert.Equal(0, changes.Count()); } @@ -535,11 +544,21 @@ public void RetrievingDiffChangesMustAlwaysBeCaseSensitive() using (var repo = new Repository(repoPath)) { - var changes = repo.Diff.Compare(repo.Lookup(treeOldOid), repo.Lookup(treeNewOid)); + var changes = repo.Diff.Compare(repo.Lookup(treeOldOid), repo.Lookup(treeNewOid)); Assert.Equal(ChangeKind.Modified, changes["a.txt"].Status); Assert.Equal(ChangeKind.Modified, changes["A.TXT"].Status); } } + + [Fact] + public void CallingCompareWithAnUnsupportedGenericParamThrows() + { + using (var repo = new Repository(StandardTestRepoPath)) + { + Assert.Throws(() => repo.Diff.Compare(default(Tree), default(Tree))); + Assert.Throws(() => repo.Diff.Compare()); + } + } } } diff --git a/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs b/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs index 5232ef2a1..a8578d043 100644 --- a/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs +++ b/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs @@ -32,7 +32,7 @@ public void CanCompareTheWorkDirAgainstTheIndex() { using (var repo = new Repository(StandardTestRepoPath)) { - TreeChanges changes = repo.Diff.Compare(); + var changes = repo.Diff.Compare(); Assert.Equal(2, changes.Count()); Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path); @@ -49,10 +49,10 @@ public void CanCompareTheWorkDirAgainstTheIndexWithLaxUnmatchedExplicitPathsVali { Assert.Equal(currentStatus, repo.Index.RetrieveStatus(relativePath)); - TreeChanges changes = repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false }); + var changes = repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false }); Assert.Equal(0, changes.Count()); - changes = repo.Diff.Compare(new[] { relativePath }); + changes = repo.Diff.Compare(new[] { relativePath }); Assert.Equal(0, changes.Count()); } } @@ -66,7 +66,7 @@ public void ComparingTheWorkDirAgainstTheIndexWithStrictUnmatchedExplicitPathsVa { Assert.Equal(currentStatus, repo.Index.RetrieveStatus(relativePath)); - Assert.Throws(() => repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions())); + Assert.Throws(() => repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions())); } } @@ -81,7 +81,9 @@ public void CallbackForUnmatchedExplicitPathsIsCalledWhenSet(string relativePath { Assert.Equal(currentStatus, repo.Index.RetrieveStatus(relativePath)); - repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false, + repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions + { + ShouldFailOnUnmatchedPath = false, OnUnmatchedPath = callback.OnUnmatchedPath }); Assert.True(callback.WasCalled); @@ -124,7 +126,7 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path, options)) { - TreeChanges changes = repo.Diff.Compare(new[] { file }); + var changes = repo.Diff.Compare(new[] { file }); Assert.Equal(1, changes.Count()); @@ -137,7 +139,7 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path, options)) { - TreeChanges changes = repo.Diff.Compare(new[] { file }); + var changes = repo.Diff.Compare(new[] { file }); Assert.Equal(0, changes.Count()); } @@ -168,7 +170,7 @@ public void CanCompareTheWorkDirAgainstTheIndexWithUntrackedFiles() { using (var repo = new Repository(StandardTestRepoPath)) { - TreeChanges changes = repo.Diff.Compare(null, true); + var changes = repo.Diff.Compare(null, true); Assert.Equal(3, changes.Count()); Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path); diff --git a/LibGit2Sharp/Changes.cs b/LibGit2Sharp/Changes.cs deleted file mode 100644 index 0a1a5f014..000000000 --- a/LibGit2Sharp/Changes.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Diagnostics; -using System.Globalization; -using System.Text; - -namespace LibGit2Sharp -{ - /// - /// Base class for changes. - /// - [DebuggerDisplay("{DebuggerDisplay,nq}")] - public abstract class Changes - { - private readonly StringBuilder patchBuilder = new StringBuilder(); - - internal void AppendToPatch(string patch) - { - patchBuilder.Append(patch); - } - - /// - /// The number of lines added. - /// - public virtual int LinesAdded { get; internal set; } - - /// - /// The number of lines deleted. - /// - public virtual int LinesDeleted { get; internal set; } - - /// - /// The patch corresponding to these changes. - /// - public virtual string Patch - { - get { return patchBuilder.ToString(); } - } - - /// - /// Determines if at least one side of the comparison holds binary content. - /// - public virtual bool IsBinaryComparison { get; protected set; } - - private string DebuggerDisplay - { - get - { - return string.Format(CultureInfo.InvariantCulture, - @"{{+{0}, -{1}}}", LinesAdded, LinesDeleted); - } - } - } -} diff --git a/LibGit2Sharp/CompareOptions.cs b/LibGit2Sharp/CompareOptions.cs index a9c03265d..3205aa9e6 100644 --- a/LibGit2Sharp/CompareOptions.cs +++ b/LibGit2Sharp/CompareOptions.cs @@ -12,7 +12,6 @@ public CompareOptions() { ContextLines = 3; InterhunkLines = 0; - SkipPatchBuilding = false; } /// @@ -26,11 +25,5 @@ public CompareOptions() /// (Default = 0) /// public int InterhunkLines { get; set; } - - /// - /// Flag to skip patch building. May be used if only file name and status required. - /// (Default = false) - /// - internal bool SkipPatchBuilding { get; set; } } } diff --git a/LibGit2Sharp/ContentChanges.cs b/LibGit2Sharp/ContentChanges.cs index 55e6f58c1..68134696f 100644 --- a/LibGit2Sharp/ContentChanges.cs +++ b/LibGit2Sharp/ContentChanges.cs @@ -1,4 +1,6 @@ using System; +using System.Diagnostics; +using System.Globalization; using System.Text; using LibGit2Sharp.Core; @@ -7,8 +9,12 @@ namespace LibGit2Sharp /// /// Holds the changes between two s. /// - public class ContentChanges : Changes + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class ContentChanges { + private readonly StringBuilder patchBuilder = new StringBuilder(); + private bool isBinaryComparison; + /// /// Needed for mocking purposes. /// @@ -23,6 +29,43 @@ internal ContentChanges(Repository repo, Blob oldBlob, Blob newBlob, GitDiffOpti options, FileCallback, HunkCallback, LineCallback); } + internal ContentChanges(bool isBinaryComparison) + { + this.isBinaryComparison = isBinaryComparison; + } + + internal void AppendToPatch(string patch) + { + patchBuilder.Append(patch); + } + + /// + /// The number of lines added. + /// + public virtual int LinesAdded { get; internal set; } + + /// + /// The number of lines deleted. + /// + public virtual int LinesDeleted { get; internal set; } + + /// + /// The patch corresponding to these changes. + /// + public virtual string Patch + { + get { return patchBuilder.ToString(); } + } + + /// + /// Determines if at least one side of the comparison holds binary content. + /// + public virtual bool IsBinaryComparison + { + get { return isBinaryComparison; } + private set { isBinaryComparison = value; } + } + private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload) { IsBinaryComparison = delta.IsBinary(); @@ -76,5 +119,14 @@ private int LineCallback(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrig AppendToPatch(decodedContent); return 0; } + + private string DebuggerDisplay + { + get + { + return string.Format(CultureInfo.InvariantCulture, + @"{{+{0}, -{1}}}", LinesAdded, LinesDeleted); + } + } } } diff --git a/LibGit2Sharp/Diff.cs b/LibGit2Sharp/Diff.cs index 29034b001..ffe7e3fab 100644 --- a/LibGit2Sharp/Diff.cs +++ b/LibGit2Sharp/Diff.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; using LibGit2Sharp.Core; @@ -77,6 +78,39 @@ internal Diff(Repository repo) this.repo = repo; } + private static readonly IDictionary> HandleRetrieverDispatcher = BuildHandleRetrieverDispatcher(); + + private static IDictionary> BuildHandleRetrieverDispatcher() + { + return new Dictionary> + { + { DiffTargets.Index, IndexToTree }, + { DiffTargets.WorkingDirectory, WorkdirToTree }, + { DiffTargets.Index | DiffTargets.WorkingDirectory, WorkdirAndIndexToTree }, + }; + } + + private static readonly IDictionary> ChangesBuilders = new Dictionary> + { + { typeof(Patch), diff => new Patch(diff) }, + { typeof(TreeChanges), diff => new TreeChanges(diff) }, + }; + + /// + /// Show changes between two s. + /// + /// The you want to compare from. + /// The you want to compare to. + /// Additional options to define comparison behavior. + /// A containing the changes between the and the . + public virtual ContentChanges Compare(Blob oldBlob, Blob newBlob, CompareOptions compareOptions = null) + { + using (GitDiffOptions options = BuildOptions(DiffModifiers.None, compareOptions: compareOptions)) + { + return new ContentChanges(repo, oldBlob, newBlob, options); + } + } + /// /// Show changes between two s. /// @@ -87,10 +121,20 @@ internal Diff(Repository repo) /// If set, the passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// - /// Additional options to define comparison behavior. + /// Additional options to define patch generation behavior. /// A containing the changes between the and the . - public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) + public virtual T Compare(Tree oldTree, Tree newTree, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, + CompareOptions compareOptions = null) where T : class { + Func builder; + + if (!ChangesBuilders.TryGetValue(typeof (T), out builder)) + { + throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, + "Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof (T), + typeof (TreeChanges), typeof (Patch))); + } + var comparer = TreeToTree(repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; ObjectId newTreeId = newTree != null ? newTree.Id : null; @@ -107,38 +151,19 @@ public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable - /// Show changes between two s. - /// - /// The you want to compare from. - /// The you want to compare to. - /// Additional options to define comparison behavior. - /// A containing the changes between the and the . - public virtual ContentChanges Compare(Blob oldBlob, Blob newBlob, CompareOptions compareOptions = null) - { - using (GitDiffOptions options = BuildOptions(DiffModifiers.None, compareOptions: compareOptions)) + using (DiffListSafeHandle diffList = BuildDiffList(oldTreeId, newTreeId, comparer, + diffOptions, paths, explicitPathsOptions, compareOptions)) { - return new ContentChanges(repo, oldBlob, newBlob, options); + return (T)builder(diffList); } } - private readonly IDictionary> handleRetrieverDispatcher = BuildHandleRetrieverDispatcher(); - - private static IDictionary> BuildHandleRetrieverDispatcher() - { - return new Dictionary> - { - { DiffTargets.Index, IndexToTree }, - { DiffTargets.WorkingDirectory, WorkdirToTree }, - { DiffTargets.Index | DiffTargets.WorkingDirectory, WorkdirAndIndexToTree }, - }; - } - /// /// Show changes between a and the Index, the Working Directory, or both. + /// + /// The level of diff performed can be specified by passing either a + /// or type as the generic parameter. + /// /// /// The to compare from. /// The targets to compare to. @@ -147,15 +172,28 @@ private static IDictionary will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// - /// Additional options to define comparison behavior. - /// A containing the changes between the and the selected target. - public virtual TreeChanges Compare(Tree oldTree, DiffTargets diffTargets, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) + /// Additional options to define patch generation behavior. + /// Can be either a if you are only interested in the list of files modified, added, ..., or + /// a if you want the actual patch content for the whole diff and for individual files. + /// A containing the changes between the and the selected target. + public virtual T Compare(Tree oldTree, DiffTargets diffTargets, IEnumerable paths = null, + ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class { - var comparer = handleRetrieverDispatcher[diffTargets](repo); + Func builder; + + if (!ChangesBuilders.TryGetValue(typeof (T), out builder)) + { + throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, + "Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof (T), + typeof (TreeChanges), typeof (Patch))); + } + + var comparer = HandleRetrieverDispatcher[diffTargets](repo); ObjectId oldTreeId = oldTree != null ? oldTree.Id : null; - DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) ? - DiffModifiers.IncludeUntracked : DiffModifiers.None; + DiffModifiers diffOptions = diffTargets.HasFlag(DiffTargets.WorkingDirectory) + ? DiffModifiers.IncludeUntracked + : DiffModifiers.None; if (explicitPathsOptions != null) { @@ -168,11 +206,19 @@ public virtual TreeChanges Compare(Tree oldTree, DiffTargets diffTargets, IEnume } } - return BuildTreeChangesFromComparer(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); + using (DiffListSafeHandle diffList = BuildDiffList(oldTreeId, null, comparer, + diffOptions, paths, explicitPathsOptions, compareOptions)) + { + return (T)builder(diffList); + } } /// /// Show changes between the working directory and the index. + /// + /// The level of diff performed can be specified by passing either a + /// or type as the generic parameter. + /// /// /// The list of paths (either files or directories) that should be compared. /// If true, include untracked files from the working dir as additions. Otherwise ignore them. @@ -180,16 +226,28 @@ public virtual TreeChanges Compare(Tree oldTree, DiffTargets diffTargets, IEnume /// If set, the passed will be treated as explicit paths. /// Use these options to determine how unmatched explicit paths should be handled. /// - /// Additional options to define comparison behavior. - /// A containing the changes between the working directory and the index. - public virtual TreeChanges Compare(IEnumerable paths = null, bool includeUntracked = false, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) + /// Additional options to define patch generation behavior. + /// Can be either a if you are only interested in the list of files modified, added, ..., or + /// a if you want the actual patch content for the whole diff and for individual files. + /// A containing the changes between the working directory and the index. + public virtual T Compare(IEnumerable paths = null, bool includeUntracked = false, ExplicitPathsOptions explicitPathsOptions = null, + CompareOptions compareOptions = null) where T : class { - return Compare(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions, compareOptions); + return Compare(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions); } - internal virtual TreeChanges Compare(DiffModifiers diffOptions, IEnumerable paths = null, - ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) + internal virtual T Compare(DiffModifiers diffOptions, IEnumerable paths = null, + ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) where T : class { + Func builder; + + if (!ChangesBuilders.TryGetValue(typeof (T), out builder)) + { + throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, + "Unexpected type '{0}' passed to Compare. Supported values are either '{1}' or '{2}'.", typeof (T), + typeof (TreeChanges), typeof (Patch))); + } + var comparer = WorkdirToIndex(repo); if (explicitPathsOptions != null) @@ -203,10 +261,14 @@ internal virtual TreeChanges Compare(DiffModifiers diffOptions, IEnumerable Proxy.git_diff_tree_to_index(repo.Handle, repo.Index.Handle, oh, o); } - private TreeChanges BuildTreeChangesFromComparer( - ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, - DiffModifiers diffOptions, IEnumerable paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null) + private DiffListSafeHandle BuildDiffList(ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, + DiffModifiers diffOptions, IEnumerable paths, ExplicitPathsOptions explicitPathsOptions, + CompareOptions compareOptions) { var matchedPaths = new MatchedPathsAggregator(); var filePaths = repo.ToFilePaths(paths); using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions)) - using (DiffListSafeHandle diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options)) { - if (explicitPathsOptions != null) + var diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options); + + try { - DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths); + if (explicitPathsOptions != null) + { + DispatchUnmatchedPaths(explicitPathsOptions, filePaths, matchedPaths); + } + } + catch + { + diffList.Dispose(); + throw; } - bool skipPatchBuilding = (compareOptions != null) && compareOptions.SkipPatchBuilding; - return new TreeChanges(diffList, skipPatchBuilding); + return diffList; } } diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index a863e777c..dde8b28a4 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -156,8 +156,7 @@ public virtual void Stage(IEnumerable paths, ExplicitPathsOptions explic { Ensure.ArgumentNotNull(paths, "paths"); - var compareOptions = new CompareOptions { SkipPatchBuilding = true }; - TreeChanges changes = repo.Diff.Compare(DiffModifiers.IncludeUntracked | DiffModifiers.IncludeIgnored, paths, explicitPathsOptions, compareOptions); + var changes = repo.Diff.Compare(DiffModifiers.IncludeUntracked | DiffModifiers.IncludeIgnored, paths, explicitPathsOptions); foreach (var treeEntryChanges in changes) { @@ -214,8 +213,7 @@ public virtual void Unstage(IEnumerable paths, ExplicitPathsOptions expl if (repo.Info.IsHeadUnborn) { - var compareOptions = new CompareOptions { SkipPatchBuilding = true }; - TreeChanges changes = repo.Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions, compareOptions); + var changes = repo.Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions); Reset(changes); } @@ -350,8 +348,7 @@ public virtual void Remove(string path, bool removeFromWorkingDirectory = true, public virtual void Remove(IEnumerable paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { var pathsList = paths.ToList(); - var compareOptions = new CompareOptions { SkipPatchBuilding = true }; - TreeChanges changes = repo.Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, pathsList, explicitPathsOptions, compareOptions); + var changes = repo.Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, pathsList, explicitPathsOptions); var pathsTodelete = pathsList.Where(p => Directory.Exists(Path.Combine(repo.Info.WorkingDirectory, p))).ToList(); diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 98339318b..d38c5eed3 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -64,7 +64,6 @@ - @@ -83,6 +82,7 @@ + diff --git a/LibGit2Sharp/Patch.cs b/LibGit2Sharp/Patch.cs new file mode 100644 index 000000000..af2559d56 --- /dev/null +++ b/LibGit2Sharp/Patch.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Text; +using LibGit2Sharp.Core; +using LibGit2Sharp.Core.Handles; + +namespace LibGit2Sharp +{ + /// + /// Holds the patch between two trees. + /// The individual patches for each file can be accessed through the indexer of this class. + /// Building a patch is an expensive operation. If you only need to know which files have been added, + /// deleted, modified, ..., then consider using a simpler . + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class Patch : IEnumerable + { + private readonly StringBuilder fullPatchBuilder = new StringBuilder(); + + private readonly IDictionary changes = new Dictionary(); + private int linesAdded; + private int linesDeleted; + + /// + /// Needed for mocking purposes. + /// + protected Patch() + { } + + internal Patch(DiffListSafeHandle diff) + { + Proxy.git_diff_foreach(diff, FileCallback, null, DataCallback); + + Proxy.git_diff_print_patch(diff, PrintCallBack); + } + + private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload) + { + AddFileChange(delta); + return 0; + } + + private void AddFileChange(GitDiffDelta delta) + { + var newFilePath = FilePathMarshaler.FromNative(delta.NewFile.Path); + + changes.Add(newFilePath, new ContentChanges(delta.IsBinary())); + } + + private int DataCallback(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineOrigin, IntPtr content, + UIntPtr contentLen, IntPtr payload) + { + var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path); + AddLineChange(this[filePath], lineOrigin); + + return 0; + } + + private void AddLineChange(ContentChanges currentChange, GitDiffLineOrigin lineOrigin) + { + switch (lineOrigin) + { + case GitDiffLineOrigin.GIT_DIFF_LINE_ADDITION: + linesAdded++; + currentChange.LinesAdded++; + break; + + case GitDiffLineOrigin.GIT_DIFF_LINE_DELETION: + linesDeleted++; + currentChange.LinesDeleted++; + break; + } + } + + private int PrintCallBack(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineorigin, IntPtr content, UIntPtr contentlen, IntPtr payload) + { + string formattedoutput = Utf8Marshaler.FromNative(content, (int)contentlen); + var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path); + + fullPatchBuilder.Append(formattedoutput); + this[filePath].AppendToPatch(formattedoutput); + + return 0; + } + + #region IEnumerable Members + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An object that can be used to iterate through the collection. + public virtual IEnumerator GetEnumerator() + { + return changes.Values.GetEnumerator(); + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// An object that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + + /// + /// Gets the corresponding to the specified . + /// + public virtual ContentChanges this[string path] + { + get { return this[(FilePath)path]; } + } + + private ContentChanges this[FilePath path] + { + get + { + ContentChanges contentChanges; + if (changes.TryGetValue(path, out contentChanges)) + { + return contentChanges; + } + + return null; + } + } + + /// + /// The total number of lines added in this diff. + /// + public virtual int LinesAdded + { + get { return linesAdded; } + } + + /// + /// The total number of lines added in this diff. + /// + public virtual int LinesDeleted + { + get { return linesDeleted; } + } + + /// + /// The full patch file of this diff. + /// + public virtual string Content + { + get { return fullPatchBuilder.ToString(); } + } + + /// + /// Implicit operator for string conversion. + /// + /// . + /// The patch content as string. + public static implicit operator string(Patch patch) + { + return patch.fullPatchBuilder.ToString(); + } + + private string DebuggerDisplay + { + get + { + return string.Format(CultureInfo.InvariantCulture, + "+{0} -{1}", linesAdded, linesDeleted); + } + } + } +} diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 9835283ea..93b726f88 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -841,7 +841,7 @@ public void Reset(Commit commit, IEnumerable paths = null, ExplicitPaths Ensure.ArgumentNotNull(commit, "commit"); - TreeChanges changes = Diff.Compare(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions); + var changes = Diff.Compare(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions); Index.Reset(changes); } diff --git a/LibGit2Sharp/TreeChanges.cs b/LibGit2Sharp/TreeChanges.cs index 5f79f59e7..4a399d4a9 100644 --- a/LibGit2Sharp/TreeChanges.cs +++ b/LibGit2Sharp/TreeChanges.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Globalization; using System.Linq; -using System.Text; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; @@ -13,6 +12,7 @@ namespace LibGit2Sharp /// /// Holds the result of a diff between two trees. /// Changes at the granularity of the file can be obtained through the different sub-collections , and . + /// To obtain the actual patch of the diff, use the class when calling Compare.. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public class TreeChanges : IEnumerable @@ -23,13 +23,9 @@ public class TreeChanges : IEnumerable private readonly List modified = new List(); private readonly List typeChanged = new List(); private readonly List unmodified = new List(); - private int linesAdded; - private int linesDeleted; private readonly IDictionary> fileDispatcher = Build(); - private readonly StringBuilder fullPatchBuilder = new StringBuilder(); - private static IDictionary> Build() { return new Dictionary> @@ -48,23 +44,9 @@ private static IDictionary> Bu protected TreeChanges() { } - internal TreeChanges(DiffListSafeHandle diff, bool skipPatchBuilding = false) + internal TreeChanges(DiffListSafeHandle diff) { - Proxy.git_diff_foreach(diff, FileCallback, null, DataCallback); - - if (!skipPatchBuilding) - { - Proxy.git_diff_print_patch(diff, PrintCallBack); - } - } - - private int DataCallback(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineOrigin, IntPtr content, UIntPtr contentLen, IntPtr payload) - { - var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path); - - AddLineChange(this[filePath], lineOrigin); - - return 0; + Proxy.git_diff_foreach(diff, FileCallback, null, null); } private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload) @@ -73,33 +55,6 @@ private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload) return 0; } - private int PrintCallBack(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineorigin, IntPtr content, UIntPtr contentlen, IntPtr payload) - { - string formattedoutput = Utf8Marshaler.FromNative(content, (int)contentlen); - var filePath = FilePathMarshaler.FromNative(delta.NewFile.Path); - - fullPatchBuilder.Append(formattedoutput); - this[filePath].AppendToPatch(formattedoutput); - - return 0; - } - - private void AddLineChange(Changes currentChange, GitDiffLineOrigin lineOrigin) - { - switch (lineOrigin) - { - case GitDiffLineOrigin.GIT_DIFF_LINE_ADDITION: - linesAdded++; - currentChange.LinesAdded++; - break; - - case GitDiffLineOrigin.GIT_DIFF_LINE_DELETION: - linesDeleted++; - currentChange.LinesDeleted++; - break; - } - } - private void AddFileChange(GitDiffDelta delta) { var newFilePath = FilePathMarshaler.FromNative(delta.NewFile.Path); @@ -115,13 +70,13 @@ private void AddFileChange(GitDiffDelta delta) delta.Status = ChangeKind.Added; } - var diffFile = new TreeEntryChanges(newFilePath, newMode, newOid, delta.Status, oldFilePath, oldMode, oldOid, delta.IsBinary()); + var diffFile = new TreeEntryChanges(newFilePath, newMode, newOid, delta.Status, oldFilePath, oldMode, oldOid); fileDispatcher[delta.Status](this, diffFile); changes.Add(newFilePath, diffFile); } - #region IEnumerable Members + #region IEnumerable Members /// /// Returns an enumerator that iterates through the collection. @@ -197,30 +152,6 @@ public virtual IEnumerable TypeChanged get { return typeChanged; } } - /// - /// The total number of lines added in this diff. - /// - public virtual int LinesAdded - { - get { return linesAdded; } - } - - /// - /// The total number of lines added in this diff. - /// - public virtual int LinesDeleted - { - get { return linesDeleted; } - } - - /// - /// The full patch file of this diff. - /// - public virtual string Patch - { - get { return fullPatchBuilder.ToString(); } - } - private string DebuggerDisplay { get diff --git a/LibGit2Sharp/TreeEntryChanges.cs b/LibGit2Sharp/TreeEntryChanges.cs index 4ce5547d4..62e76f04c 100644 --- a/LibGit2Sharp/TreeEntryChanges.cs +++ b/LibGit2Sharp/TreeEntryChanges.cs @@ -8,7 +8,7 @@ namespace LibGit2Sharp /// Holds the changes between two versions of a tree entry. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] - public class TreeEntryChanges : Changes + public class TreeEntryChanges { /// /// Needed for mocking purposes. @@ -16,7 +16,7 @@ public class TreeEntryChanges : Changes protected TreeEntryChanges() { } - internal TreeEntryChanges(FilePath path, Mode mode, ObjectId oid, ChangeKind status, FilePath oldPath, Mode oldMode, ObjectId oldOid, bool isBinaryComparison) + internal TreeEntryChanges(FilePath path, Mode mode, ObjectId oid, ChangeKind status, FilePath oldPath, Mode oldMode, ObjectId oldOid) { Path = path.Native; Mode = mode; @@ -25,7 +25,6 @@ internal TreeEntryChanges(FilePath path, Mode mode, ObjectId oid, ChangeKind sta OldPath = oldPath.Native; OldMode = oldMode; OldOid = oldOid; - IsBinaryComparison = isBinaryComparison; } ///