diff --git a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs index b8ff89e3f..71aad3755 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs @@ -43,23 +43,27 @@ public void CanCompareASimpleTreeAgainstTheWorkDir() { SetUpSimpleDiffContext(repo); - 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") - .Append("--- a/file.txt\n") - .Append("+++ b/file.txt\n") - .Append("@@ -1 +1,3 @@\n") - .Append(" hello\n") - .Append("+world\n") - .Append("+!!!\n"); - - Assert.Equal(expected.ToString(), patch); + using (var changes = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.WorkingDirectory)) + { + Assert.Equal(1, changes.Modified.Count()); + } + + using (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") + .Append("--- a/file.txt\n") + .Append("+++ b/file.txt\n") + .Append("@@ -1 +1,3 @@\n") + .Append(" hello\n") + .Append("+world\n") + .Append("+!!!\n"); + + Assert.Equal(expected.ToString(), patch); + } } } @@ -71,19 +75,21 @@ public void CanCompareAMoreComplexTreeAgainstTheWorkdir() { Tree tree = repo.Head.Tip.Tree; - var changes = repo.Diff.Compare(tree, DiffTargets.WorkingDirectory); - Assert.NotNull(changes); + using (var changes = repo.Diff.Compare(tree, DiffTargets.WorkingDirectory)) + { + Assert.NotNull(changes); - Assert.Equal(6, changes.Count()); + Assert.Equal(6, changes.Count()); - Assert.Equal(new[] { "deleted_staged_file.txt", "deleted_unstaged_file.txt" }, - changes.Deleted.Select(tec => tec.Path)); + Assert.Equal(new[] { "deleted_staged_file.txt", "deleted_unstaged_file.txt" }, + changes.Deleted.Select(tec => tec.Path)); - Assert.Equal(new[] { "new_tracked_file.txt", "new_untracked_file.txt" }, - changes.Added.Select(tec => tec.Path)); + Assert.Equal(new[] { "new_tracked_file.txt", "new_untracked_file.txt" }, + changes.Added.Select(tec => tec.Path)); - Assert.Equal(new[] { "modified_staged_file.txt", "modified_unstaged_file.txt" }, - changes.Modified.Select(tec => tec.Path)); + Assert.Equal(new[] { "modified_staged_file.txt", "modified_unstaged_file.txt" }, + changes.Modified.Select(tec => tec.Path)); + } } } @@ -107,23 +113,27 @@ public void CanCompareASimpleTreeAgainstTheWorkDirAndTheIndex() { SetUpSimpleDiffContext(repo); - 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") - .Append("--- a/file.txt\n") - .Append("+++ b/file.txt\n") - .Append("@@ -1 +1,3 @@\n") - .Append(" hello\n") - .Append("+world\n") - .Append("+!!!\n"); - - Assert.Equal(expected.ToString(), patch); + using (var changes = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.Index | DiffTargets.WorkingDirectory)) + { + Assert.Equal(1, changes.Modified.Count()); + } + + using (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") + .Append("--- a/file.txt\n") + .Append("+++ b/file.txt\n") + .Append("@@ -1 +1,3 @@\n") + .Append(" hello\n") + .Append("+world\n") + .Append("+!!!\n"); + + Assert.Equal(expected.ToString(), patch); + } } } @@ -165,44 +175,50 @@ public void ShowcaseTheDifferenceBetweenTheTwoKindOfComparison() FileStatus state = repo.RetrieveStatus("file.txt"); Assert.Equal(FileStatus.DeletedFromIndex | FileStatus.NewInWorkdir, 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()); - - 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("deleted file mode 100644\n") - .Append("index ce01362..0000000\n") - .Append("--- a/file.txt\n") - .Append("+++ /dev/null\n") - .Append("@@ -1 +0,0 @@\n") - .Append("-hello\n"); - - Assert.Equal(expected.ToString(), patch); - - 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") - .Append("index ce01362..4f125e3 100644\n") - .Append("--- a/file.txt\n") - .Append("+++ b/file.txt\n") - .Append("@@ -1 +1,3 @@\n") - .Append(" hello\n") - .Append("+world\n") - .Append("+!!!\n"); - - Assert.Equal(expected.ToString(), patch); + using (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()); + } + + using (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("deleted file mode 100644\n") + .Append("index ce01362..0000000\n") + .Append("--- a/file.txt\n") + .Append("+++ /dev/null\n") + .Append("@@ -1 +0,0 @@\n") + .Append("-hello\n"); + + Assert.Equal(expected.ToString(), patch); + } + + using (var wrkDirToTree = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.WorkingDirectory)) + { + Assert.Equal(0, wrkDirToTree.Deleted.Count()); + Assert.Equal(1, wrkDirToTree.Modified.Count()); + } + + using (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") + .Append("--- a/file.txt\n") + .Append("+++ b/file.txt\n") + .Append("@@ -1 +1,3 @@\n") + .Append(" hello\n") + .Append("+world\n") + .Append("+!!!\n"); + + Assert.Equal(expected.ToString(), patch); + } } } @@ -225,22 +241,26 @@ public void CanCompareASimpleTreeAgainstTheIndex() { SetUpSimpleDiffContext(repo); - 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") - .Append("--- a/file.txt\n") - .Append("+++ b/file.txt\n") - .Append("@@ -1 +1,2 @@\n") - .Append(" hello\n") - .Append("+world\n"); - - Assert.Equal(expected.ToString(), patch); + using (var changes = repo.Diff.Compare(repo.Head.Tip.Tree, + DiffTargets.Index)) + { + Assert.Equal(1, changes.Modified.Count()); + } + + using (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") + .Append("--- a/file.txt\n") + .Append("+++ b/file.txt\n") + .Append("@@ -1 +1,2 @@\n") + .Append(" hello\n") + .Append("+world\n"); + + Assert.Equal(expected.ToString(), patch); + } } } @@ -276,13 +296,15 @@ public void CanCompareAMoreComplexTreeAgainstTheIndex() { Tree tree = repo.Head.Tip.Tree; - var changes = repo.Diff.Compare(tree, DiffTargets.Index); - Assert.NotNull(changes); + using (var changes = repo.Diff.Compare(tree, DiffTargets.Index)) + { + Assert.NotNull(changes); - Assert.Equal(3, changes.Count()); - Assert.Equal("deleted_staged_file.txt", changes.Deleted.Single().Path); - Assert.Equal("new_tracked_file.txt", changes.Added.Single().Path); - Assert.Equal("modified_staged_file.txt", changes.Modified.Single().Path); + Assert.Equal(3, changes.Count()); + Assert.Equal("deleted_staged_file.txt", changes.Deleted.Single().Path); + Assert.Equal("new_tracked_file.txt", changes.Added.Single().Path); + Assert.Equal("modified_staged_file.txt", changes.Modified.Single().Path); + } } } @@ -304,13 +326,14 @@ public void CanCompareASubsetofTheTreeAgainstTheIndex() { Tree tree = repo.Head.Tip.Tree; - var changes = repo.Diff.Compare(tree, DiffTargets.Index, - new[] { "deleted_staged_file.txt", "1/branch_file.txt" }); + using (var changes = repo.Diff.Compare(tree, DiffTargets.Index, + new[] { "deleted_staged_file.txt", "1/branch_file.txt" })) + { + Assert.NotNull(changes); - Assert.NotNull(changes); - - Assert.Equal(1, changes.Count()); - Assert.Equal("deleted_staged_file.txt", changes.Deleted.Single().Path); + Assert.Equal(1, changes.Count()); + Assert.Equal("deleted_staged_file.txt", changes.Deleted.Single().Path); + } } } @@ -329,13 +352,17 @@ public void CanCompareASubsetofTheTreeAgainstTheIndexWithLaxExplicitPathsValidat { Tree tree = repo.Head.Tip.Tree; - 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, - new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" }); - AssertCanCompareASubsetOfTheTreeAgainstTheIndex(changes); + using (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); + } + + using (var changes = repo.Diff.Compare(tree, DiffTargets.Index, + new[] { "deleted_staged_file.txt", "1/branch_file.txt", "I-do/not-exist" })) + { + AssertCanCompareASubsetOfTheTreeAgainstTheIndex(changes); + } } } @@ -384,23 +411,27 @@ public void CanCopeWithEndOfFileNewlineChanges() File.AppendAllText(fullpath, "\n"); Commands.Stage(repo, "file.txt"); - 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 2e65efe..7898192 100644\n") - .Append("--- a/file.txt\n") - .Append("+++ b/file.txt\n") - .Append("@@ -1 +1 @@\n") - .Append("-a\n") - .Append("\\ No newline at end of file\n") - .Append("+a\n"); - - Assert.Equal(expected.ToString(), patch); - Assert.Equal(1, patch.LinesAdded); - Assert.Equal(1, patch.LinesDeleted); + using (var changes = repo.Diff.Compare(repo.Head.Tip.Tree, DiffTargets.Index)) + { + Assert.Equal(1, changes.Modified.Count()); + } + + using (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") + .Append("--- a/file.txt\n") + .Append("+++ b/file.txt\n") + .Append("@@ -1 +1 @@\n") + .Append("-a\n") + .Append("\\ No newline at end of file\n") + .Append("+a\n"); + + Assert.Equal(expected.ToString(), patch); + Assert.Equal(1, patch.LinesAdded); + Assert.Equal(1, patch.LinesDeleted); + } } } @@ -428,13 +459,14 @@ public void CanCompareANullTreeAgainstTheIndex() { SetUpSimpleDiffContext(repo); - var changes = repo.Diff.Compare(null, - DiffTargets.Index); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Added.Count()); + using (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("file.txt", changes.Added.Single().Path); + } } } @@ -447,13 +479,14 @@ public void CanCompareANullTreeAgainstTheWorkdir() { SetUpSimpleDiffContext(repo); - var changes = repo.Diff.Compare(null, - DiffTargets.WorkingDirectory); + using (var changes = repo.Diff.Compare(null, + DiffTargets.WorkingDirectory)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Added.Count()); - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Added.Count()); - - Assert.Equal("file.txt", changes.Added.Single().Path); + Assert.Equal("file.txt", changes.Added.Single().Path); + } } } @@ -466,13 +499,14 @@ public void CanCompareANullTreeAgainstTheWorkdirAndTheIndex() { SetUpSimpleDiffContext(repo); - var changes = repo.Diff.Compare(null, - DiffTargets.WorkingDirectory | DiffTargets.Index); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Added.Count()); + using (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("file.txt", changes.Added.Single().Path); + } } } } diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index 5be987aaf..f51def511 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -20,12 +20,16 @@ public void ComparingATreeAgainstItselfReturnsNoDifference() { Tree tree = repo.Head.Tip.Tree; - var changes = repo.Diff.Compare(tree, tree); - var patch = repo.Diff.Compare(tree, tree); + using(var changes = repo.Diff.Compare(tree, tree)) + { + Assert.Empty(changes); + } - Assert.Empty(changes); - Assert.Empty(patch); - Assert.Equal(String.Empty, patch); + using (var patch = repo.Diff.Compare(tree, tree)) + { + Assert.Empty(patch); + Assert.Equal(String.Empty, patch); + } } } @@ -37,9 +41,10 @@ public void RetrievingANonExistentFileChangeReturnsNull() { Tree tree = repo.Head.Tip.Tree; - var changes = repo.Diff.Compare(tree, tree); - - Assert.Equal(0, changes.Count(c => c.Path == "batman")); + using (var changes = repo.Diff.Compare(tree, tree)) + { + Assert.Equal(0, changes.Count(c => c.Path == "batman")); + } } } @@ -57,22 +62,25 @@ public void CanCompareACommitTreeAgainstItsParent() Tree commitTree = repo.Head.Tip.Tree; Tree parentCommitTree = repo.Head.Tip.Parents.Single().Tree; - var changes = repo.Diff.Compare(parentCommitTree, commitTree); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Added.Count()); + using (var changes = repo.Diff.Compare(parentCommitTree, commitTree)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Added.Count()); - TreeEntryChanges treeEntryChanges = changes.Single(c => c.Path == "1.txt"); + TreeEntryChanges treeEntryChanges = changes.Single(c => c.Path == "1.txt"); - 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("1.txt", treeEntryChanges.Path); - Assert.Equal(ChangeKind.Added, treeEntryChanges.Status); + Assert.Equal(treeEntryChanges.Path, changes.Added.Single().Path); - Assert.Equal(treeEntryChanges, changes.Added.Single()); + Assert.Equal(Mode.Nonexistent, treeEntryChanges.OldMode); + } - Assert.Equal(Mode.Nonexistent, treeEntryChanges.OldMode); + using (var patch = repo.Diff.Compare(parentCommitTree, commitTree)) + { + Assert.False(patch["1.txt"].IsBinaryComparison); + } } } @@ -104,14 +112,14 @@ public void CanDetectABinaryChange() File.AppendAllText(filepath, "abcdef"); - var patch = repo.Diff.Compare(commit.Tree, DiffTargets.WorkingDirectory, new[] { filename }); - Assert.True(patch[filename].IsBinaryComparison); + using(var patch = repo.Diff.Compare(commit.Tree, DiffTargets.WorkingDirectory, new[] { filename })) + Assert.True(patch[filename].IsBinaryComparison); Commands.Stage(repo, filename); var commit2 = repo.Commit("Update binary file", Constants.Signature, Constants.Signature); - var patch2 = repo.Diff.Compare(commit.Tree, commit2.Tree, new[] { filename }); - Assert.True(patch2[filename].IsBinaryComparison); + using(var patch2 = repo.Diff.Compare(commit.Tree, commit2.Tree, new[] { filename })) + Assert.True(patch2[filename].IsBinaryComparison); } } @@ -130,14 +138,14 @@ public void CanDetectABinaryDeletion() File.Delete(filepath); - var patch = repo.Diff.Compare(commit.Tree, DiffTargets.WorkingDirectory, new [] {filename}); - Assert.True(patch[filename].IsBinaryComparison); + using(var patch = repo.Diff.Compare(commit.Tree, DiffTargets.WorkingDirectory, new [] {filename})) + Assert.True(patch[filename].IsBinaryComparison); Commands.Remove(repo, filename); var commit2 = repo.Commit("Delete binary file", Constants.Signature, Constants.Signature); - var patch2 = repo.Diff.Compare(commit.Tree, commit2.Tree, new[] { filename }); - Assert.True(patch2[filename].IsBinaryComparison); + using(var patch2 = repo.Diff.Compare(commit.Tree, commit2.Tree, new[] { filename })) + Assert.True(patch2[filename].IsBinaryComparison); } } @@ -160,11 +168,13 @@ public void CanCompareASubsetofTheTreeAgainstOneOfItsAncestor() Tree tree = repo.Head.Tip.Tree; Tree ancestor = repo.Lookup("9fd738e").Tree; - var changes = repo.Diff.Compare(ancestor, tree, new[] { "1" }); - Assert.NotNull(changes); + using (var changes = repo.Diff.Compare(ancestor, tree, new[] { "1" })) + { + Assert.NotNull(changes); - Assert.Equal(1, changes.Count()); - Assert.Equal(subBranchFilePath, changes.Added.Single().Path); + Assert.Equal(1, changes.Count()); + Assert.Equal(subBranchFilePath, changes.Added.Single().Path); + } } } @@ -191,20 +201,23 @@ public void CanCompareACommitTreeAgainstATreeWithNoCommonAncestor() Tree commitTree = repo.Head.Tip.Tree; Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree; - var changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree); - - Assert.Equal(10, changes.Count()); - Assert.Equal(9, changes.Added.Count()); - Assert.Equal(1, changes.Deleted.Count()); + using (var changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree)) + { + Assert.Equal(10, changes.Count()); + Assert.Equal(9, changes.Added.Count()); + Assert.Equal(1, changes.Deleted.Count()); - Assert.Equal("readme.txt", changes.Deleted.Single().Path); - 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("readme.txt", changes.Deleted.Single().Path); + 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()); + } - var patch = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree); - Assert.Equal(9, patch.LinesAdded); - Assert.Equal(2, patch.LinesDeleted); - Assert.Equal(2, patch["readme.txt"].LinesDeleted); + using (var patch = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree)) + { + Assert.Equal(9, patch.LinesAdded); + Assert.Equal(2, patch.LinesDeleted); + Assert.Equal(2, patch["readme.txt"].LinesDeleted); + } } } @@ -217,13 +230,17 @@ public void CanCompareATreeAgainstAnotherTreeWithLaxExplicitPathsValidationAndNo Tree commitTree = repo.Head.Tip.Tree; Tree commitTreeWithDifferentAncestor = repo.Branches["refs/remotes/origin/test"].Tip.Tree; - 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()); + using (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, - new[] { "if-I-exist-this-test-is-really-unlucky.txt" }); - Assert.Equal(0, changes.Count()); + using (var changes = repo.Diff.Compare(commitTreeWithDifferentAncestor, commitTree, + new[] { "if-I-exist-this-test-is-really-unlucky.txt" })) + { + Assert.Equal(0, changes.Count()); + } } } @@ -269,11 +286,12 @@ public void DetectsTheRenamingOfAModifiedFileByDefault() Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; Tree commitTreeWithRenamedFile = repo.Lookup("4be51d6").Tree; - var changes = repo.Diff.Compare(rootCommitTree, commitTreeWithRenamedFile); - - Assert.Equal(1, changes.Count()); - Assert.Equal("my-name-does-not-feel-right.txt", changes.Single(c => c.Path == "super-file.txt").OldPath); - Assert.Equal(1, changes.Renamed.Count()); + using (var changes = repo.Diff.Compare(rootCommitTree, commitTreeWithRenamedFile)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal("my-name-does-not-feel-right.txt", changes.Single(c => c.Path == "super-file.txt").OldPath); + Assert.Equal(1, changes.Renamed.Count()); + } } } @@ -297,12 +315,13 @@ public void DetectsTheExactRenamingOfFilesByDefault() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Renamed.Count()); - Assert.Equal(originalPath, changes.Renamed.Single().OldPath); - Assert.Equal(renamedPath, changes.Renamed.Single().Path); + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Renamed.Count()); + Assert.Equal(originalPath, changes.Renamed.Single().OldPath); + Assert.Equal(renamedPath, changes.Renamed.Single().Path); + } } } @@ -344,12 +363,14 @@ public void RenameThresholdsAreObeyed() }; compareOptions.Similarity.RenameThreshold = 30; - var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: compareOptions); - Assert.True(changes.All(x => x.Status == ChangeKind.Renamed)); + + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: compareOptions)) + Assert.True(changes.All(x => x.Status == ChangeKind.Renamed)); compareOptions.Similarity.RenameThreshold = 90; - changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: compareOptions); - Assert.False(changes.Any(x => x.Status == ChangeKind.Renamed)); + + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: compareOptions)) + Assert.False(changes.Any(x => x.Status == ChangeKind.Renamed)); } } @@ -373,16 +394,17 @@ public void ExactModeDetectsExactRenames() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.Exact, - }); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Renamed.Count()); - Assert.Equal(originalPath, changes.Renamed.Single().OldPath); - Assert.Equal(renamedPath, changes.Renamed.Single().Path); + })) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Renamed.Count()); + Assert.Equal(originalPath, changes.Renamed.Single().OldPath); + Assert.Equal(renamedPath, changes.Renamed.Single().Path); + } } } @@ -407,14 +429,15 @@ public void ExactModeDetectsExactCopies() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.Exact, - }); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Copied.Count()); + })) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Copied.Count()); + } } } @@ -440,16 +463,17 @@ public void ExactModeDoesntDetectRenamesWithEdits() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.Exact, - }); - - Assert.Equal(2, changes.Count()); - Assert.Equal(0, changes.Renamed.Count()); - Assert.Equal(1, changes.Added.Count()); - Assert.Equal(1, changes.Deleted.Count()); + })) + { + Assert.Equal(2, changes.Count()); + Assert.Equal(0, changes.Renamed.Count()); + Assert.Equal(1, changes.Added.Count()); + Assert.Equal(1, changes.Deleted.Count()); + } } } @@ -476,19 +500,20 @@ public void CanIncludeUnmodifiedEntriesWhenDetectingTheExactRenamingOfFilesWhenE Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.CopiesHarder, IncludeUnmodified = true, - }); - - Assert.Equal(2, changes.Count()); - Assert.Equal(1, changes.Unmodified.Count()); - Assert.Equal(1, changes.Copied.Count()); - Assert.Equal(originalPath, changes.Copied.Single().OldPath); - Assert.Equal(copiedPath, changes.Copied.Single().Path); + })) + { + Assert.Equal(2, changes.Count()); + Assert.Equal(1, changes.Unmodified.Count()); + Assert.Equal(1, changes.Copied.Count()); + Assert.Equal(originalPath, changes.Copied.Single().OldPath); + Assert.Equal(copiedPath, changes.Copied.Single().Path); + } } } @@ -512,15 +537,16 @@ public void CanNotDetectTheExactRenamingFilesWhenNotEnabled() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.None, - }); - - Assert.Equal(2, changes.Count()); - Assert.Equal(0, changes.Renamed.Count()); + })) + { + Assert.Equal(2, changes.Count()); + Assert.Equal(0, changes.Renamed.Count()); + } } } @@ -547,17 +573,18 @@ public void CanDetectTheExactCopyingOfNonModifiedFilesWhenEnabled() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.CopiesHarder, - }); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Copied.Count()); - Assert.Equal(originalPath, changes.Copied.Single().OldPath); - Assert.Equal(copiedPath, changes.Copied.Single().Path); + })) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Copied.Count()); + Assert.Equal(originalPath, changes.Copied.Single().OldPath); + Assert.Equal(copiedPath, changes.Copied.Single().Path); + } } } @@ -584,10 +611,11 @@ public void CanNotDetectTheExactCopyingOfNonModifiedFilesWhenNotEnabled() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree); - - Assert.Equal(1, changes.Count()); - Assert.Equal(0, changes.Copied.Count()); + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(0, changes.Copied.Count()); + } } } @@ -617,17 +645,18 @@ public void CanDetectTheExactCopyingOfModifiedFilesWhenEnabled() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.Copies, - }); - - Assert.Equal(2, changes.Count()); - Assert.Equal(1, changes.Copied.Count()); - Assert.Equal(originalPath, changes.Copied.Single().OldPath); - Assert.Equal(copiedPath, changes.Copied.Single().Path); + })) + { + Assert.Equal(2, changes.Count()); + Assert.Equal(1, changes.Copied.Count()); + Assert.Equal(originalPath, changes.Copied.Single().OldPath); + Assert.Equal(copiedPath, changes.Copied.Single().Path); + } } } @@ -657,10 +686,11 @@ public void CanNotDetectTheExactCopyingOfModifiedFilesWhenNotEnabled() Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree); - - Assert.Equal(2, changes.Count()); - Assert.Equal(0, changes.Copied.Count()); + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree)) + { + Assert.Equal(2, changes.Count()); + Assert.Equal(0, changes.Copied.Count()); + } } } @@ -681,12 +711,13 @@ public void CanIncludeUnmodifiedEntriesWhenEnabled() Commands.Stage(repo, "b.txt"); Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, - compareOptions: new CompareOptions {IncludeUnmodified = true}); - - Assert.Equal(2, changes.Count()); - Assert.Equal(1, changes.Unmodified.Count()); - Assert.Equal(1, changes.Modified.Count()); + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, + compareOptions: new CompareOptions { IncludeUnmodified = true })) + { + Assert.Equal(2, changes.Count()); + Assert.Equal(1, changes.Unmodified.Count()); + Assert.Equal(1, changes.Modified.Count()); + } } } @@ -729,23 +760,24 @@ public void CanDetectTheExactRenamingExactCopyingOfNonModifiedAndModifiedFilesWh Commit @new = repo.Commit("Updated", Constants.Signature, Constants.Signature); - var changes = repo.Diff.Compare(old.Tree, @new.Tree, + using (var changes = repo.Diff.Compare(old.Tree, @new.Tree, compareOptions: new CompareOptions { Similarity = SimilarityOptions.CopiesHarder, - }); - - Assert.Equal(4, changes.Count()); - Assert.Equal(1, changes.Modified.Count()); - Assert.Equal(1, changes.Renamed.Count()); - Assert.Equal(originalPath, changes.Renamed.Single().OldPath); - Assert.Equal(renamedPath, changes.Renamed.Single().Path); - Assert.Equal(2, changes.Copied.Count()); - Assert.Equal(originalPath2, changes.Copied.ElementAt(0).OldPath); - Assert.Equal(copiedPath1, changes.Copied.ElementAt(0).Path); - Assert.Equal(originalPath3, changes.Copied.ElementAt(1).OldPath); - Assert.Equal(copiedPath2, changes.Copied.ElementAt(1).Path); + })) + { + Assert.Equal(4, changes.Count()); + Assert.Equal(1, changes.Modified.Count()); + Assert.Equal(1, changes.Renamed.Count()); + Assert.Equal(originalPath, changes.Renamed.Single().OldPath); + Assert.Equal(renamedPath, changes.Renamed.Single().Path); + Assert.Equal(2, changes.Copied.Count()); + Assert.Equal(originalPath2, changes.Copied.ElementAt(0).OldPath); + Assert.Equal(copiedPath1, changes.Copied.ElementAt(0).Path); + Assert.Equal(originalPath3, changes.Copied.ElementAt(1).OldPath); + Assert.Equal(copiedPath2, changes.Copied.ElementAt(1).Path); + } } } /* @@ -784,22 +816,24 @@ public void CanCompareTwoVersionsOfAFileWithATrailingNewlineDeletion(int context Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; Tree commitTreeWithUpdatedFile = repo.Lookup("ec9e401").Tree; - var changes = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile); - - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Modified.Count()); - - var patch = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile, - compareOptions: new CompareOptions { ContextLines = contextLines }); + using (var changes = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Modified.Count()); + } - Assert.Equal(expectedPatchLength, patch.Content.Length); + using (var patch = repo.Diff.Compare(rootCommitTree, commitTreeWithUpdatedFile, + compareOptions: new CompareOptions { ContextLines = contextLines })) + { + Assert.Equal(expectedPatchLength, patch.Content.Length); - PatchEntryChanges entryChanges = patch["numbers.txt"]; + PatchEntryChanges entryChanges = patch["numbers.txt"]; - Assert.Equal(2, entryChanges.LinesAdded); - Assert.Equal(1, entryChanges.LinesDeleted); - Assert.Equal(expectedPatchLength, entryChanges.Patch.Length); - Assert.Equal("numbers.txt", entryChanges.Path); + Assert.Equal(2, entryChanges.LinesAdded); + Assert.Equal(1, entryChanges.LinesDeleted); + Assert.Equal(expectedPatchLength, entryChanges.Patch.Length); + Assert.Equal("numbers.txt", entryChanges.Path); + } } } @@ -880,26 +914,28 @@ public void CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks(int contextLines, in Tree rootCommitTree = repo.Lookup("f8d44d7").Tree; Tree mergedCommitTree = repo.Lookup("7252fe2").Tree; - var changes = repo.Diff.Compare(rootCommitTree, mergedCommitTree, compareOptions: compareOptions); - - Assert.Equal(3, changes.Count()); - Assert.Equal(1, changes.Modified.Count()); - Assert.Equal(1, changes.Deleted.Count()); - Assert.Equal(1, changes.Added.Count()); - - Assert.Equal(Mode.Nonexistent, changes.Single(c => c.Path =="my-name-does-not-feel-right.txt").Mode); - - var patch = repo.Diff.Compare(rootCommitTree, mergedCommitTree, compareOptions: compareOptions); + using (var changes = repo.Diff.Compare(rootCommitTree, mergedCommitTree, compareOptions: compareOptions)) + { + Assert.Equal(3, changes.Count()); + Assert.Equal(1, changes.Modified.Count()); + Assert.Equal(1, changes.Deleted.Count()); + Assert.Equal(1, changes.Added.Count()); - PatchEntryChanges entryChanges = patch["numbers.txt"]; + Assert.Equal(Mode.Nonexistent, changes.Single(c => c.Path == "my-name-does-not-feel-right.txt").Mode); + } - Assert.Equal(3, entryChanges.LinesAdded); - Assert.Equal(1, entryChanges.LinesDeleted); - Assert.Equal(Expected("f8d44d7...7252fe2/numbers.txt-{0}-{1}.diff", contextLines, interhunkLines), - entryChanges.Patch); - Assert.Equal(Expected("f8d44d7...7252fe2/full-{0}-{1}.diff", contextLines, interhunkLines), - patch); - Assert.Equal("numbers.txt", entryChanges.Path); + using (var patch = repo.Diff.Compare(rootCommitTree, mergedCommitTree, compareOptions: compareOptions)) + { + PatchEntryChanges entryChanges = patch["numbers.txt"]; + + Assert.Equal(3, entryChanges.LinesAdded); + Assert.Equal(1, entryChanges.LinesDeleted); + Assert.Equal(Expected("f8d44d7...7252fe2/numbers.txt-{0}-{1}.diff", contextLines, interhunkLines), + entryChanges.Patch); + Assert.Equal(Expected("f8d44d7...7252fe2/full-{0}-{1}.diff", contextLines, interhunkLines), + patch); + Assert.Equal("numbers.txt", entryChanges.Path); + } } } @@ -925,13 +961,14 @@ private void CanHandleTwoTreeEntryChangesWithTheSamePath(SimilarityOptions simil Tree treeNew = repo.ObjectDatabase.CreateTree(tdNew); - var changes = repo.Diff.Compare(treeOld, treeNew, + using (var changes = repo.Diff.Compare(treeOld, treeNew, compareOptions: new CompareOptions { Similarity = similarity, - }); - - verifier(path, changes); + })) + { + verifier(path, changes); + } } } @@ -993,19 +1030,21 @@ public void CanCompareATreeAgainstANullTree() { Tree tree = repo.Branches["refs/remotes/origin/test"].Tip.Tree; - 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); + using (var changes = repo.Diff.Compare(tree, null)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Deleted.Count()); - changes = repo.Diff.Compare(null, tree); + Assert.Equal("readme.txt", changes.Deleted.Single().Path); + } - Assert.Equal(1, changes.Count()); - Assert.Equal(1, changes.Added.Count()); + using (var changes = repo.Diff.Compare(null, tree)) + { + Assert.Equal(1, changes.Count()); + Assert.Equal(1, changes.Added.Count()); - Assert.Equal("readme.txt", changes.Added.Single().Path); + Assert.Equal("readme.txt", changes.Added.Single().Path); + } } } @@ -1015,9 +1054,10 @@ public void ComparingTwoNullTreesReturnsAnEmptyTreeChanges() var path = SandboxStandardTestRepoGitDir(); using (var repo = new Repository(path)) { - var changes = repo.Diff.Compare(default(Tree), default(Tree)); - - Assert.Equal(0, changes.Count()); + using (var changes = repo.Diff.Compare(default(Tree), default(Tree))) + { + Assert.Equal(0, changes.Count()); + } } } @@ -1047,21 +1087,23 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path)) { SetFilemode(repo, true); - var changes = repo.Diff.Compare(new[] { file }); - - Assert.Equal(1, changes.Count()); + using(var changes = repo.Diff.Compare(new[] { file })) + { + Assert.Equal(1, changes.Count()); - var change = changes.Modified.Single(); - Assert.Equal(Mode.ExecutableFile, change.OldMode); - Assert.Equal(Mode.NonExecutableFile, change.Mode); + var change = changes.Modified.Single(); + Assert.Equal(Mode.ExecutableFile, change.OldMode); + Assert.Equal(Mode.NonExecutableFile, change.Mode); + } } using (var repo = new Repository(path)) { SetFilemode(repo, false); - var changes = repo.Diff.Compare(new[] { file }); - - Assert.Equal(0, changes.Count()); + using (var changes = repo.Diff.Compare(new[] { file })) + { + Assert.Equal(0, changes.Count()); + } } } @@ -1097,10 +1139,11 @@ public void RetrievingDiffChangesMustAlwaysBeCaseSensitive() using (var repo = new Repository(repoPath)) { - var changes = repo.Diff.Compare(repo.Lookup(treeOldOid), repo.Lookup(treeNewOid)); - - Assert.Equal(ChangeKind.Modified, changes.Single(c => c.Path == "a.txt").Status); - Assert.Equal(ChangeKind.Modified, changes.Single(c => c.Path == "A.TXT").Status); + using (var changes = repo.Diff.Compare(repo.Lookup(treeOldOid), repo.Lookup(treeNewOid))) + { + Assert.Equal(ChangeKind.Modified, changes.Single(c => c.Path == "a.txt").Status); + Assert.Equal(ChangeKind.Modified, changes.Single(c => c.Path == "A.TXT").Status); + } } } @@ -1168,9 +1211,12 @@ public void UsingPatienceAlgorithmCompareOptionProducesPatienceDiff() .Append("+cccccc\n") .Append("+cccccc\n").ToString(); - Assert.Equal(diffDefault, repo.Diff.Compare(treeOld, treeNew)); - Assert.Equal(diffPatience, repo.Diff.Compare(treeOld, treeNew, - compareOptions: new CompareOptions { Algorithm = DiffAlgorithm.Patience })); + using (var changes = repo.Diff.Compare(treeOld, treeNew)) + Assert.Equal(diffDefault, changes); + + using (var changes = repo.Diff.Compare(treeOld, treeNew, + compareOptions: new CompareOptions { Algorithm = DiffAlgorithm.Patience })) + Assert.Equal(diffPatience, changes); } } } diff --git a/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs b/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs index f08ee877a..ba7658ebc 100644 --- a/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs +++ b/LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs @@ -33,11 +33,12 @@ public void CanCompareTheWorkDirAgainstTheIndex() var path = SandboxStandardTestRepoGitDir(); using (var repo = new Repository(path)) { - var changes = repo.Diff.Compare(); - - Assert.Equal(2, changes.Count()); - Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path); - Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path); + using (var changes = repo.Diff.Compare()) + { + Assert.Equal(2, changes.Count()); + Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path); + Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path); + } } } @@ -51,11 +52,15 @@ public void CanCompareTheWorkDirAgainstTheIndexWithLaxUnmatchedExplicitPathsVali { Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - var changes = repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false }); - Assert.Equal(0, changes.Count()); + using (var changes = repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false })) + { + Assert.Equal(0, changes.Count()); + } - changes = repo.Diff.Compare(new[] { relativePath }); - Assert.Equal(0, changes.Count()); + using (var changes = repo.Diff.Compare(new[] { relativePath })) + { + Assert.Equal(0, changes.Count()); + } } } @@ -85,12 +90,14 @@ public void CallbackForUnmatchedExplicitPathsIsCalledWhenSet(string relativePath { Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath)); - repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions + using (var changes = repo.Diff.Compare(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false, - OnUnmatchedPath = callback.OnUnmatchedPath }); - - Assert.True(callback.WasCalled); + OnUnmatchedPath = callback.OnUnmatchedPath + })) + { + Assert.True(callback.WasCalled); + } } } @@ -130,21 +137,23 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny() using (var repo = new Repository(path)) { SetFilemode(repo, true); - var changes = repo.Diff.Compare(new[] { file }); - - Assert.Equal(1, changes.Count()); + using(var changes = repo.Diff.Compare(new[] { file })) + { + Assert.Equal(1, changes.Count()); - var change = changes.Modified.Single(); - Assert.Equal(Mode.ExecutableFile, change.OldMode); - Assert.Equal(Mode.NonExecutableFile, change.Mode); + var change = changes.Modified.Single(); + Assert.Equal(Mode.ExecutableFile, change.OldMode); + Assert.Equal(Mode.NonExecutableFile, change.Mode); + } } using (var repo = new Repository(path)) { SetFilemode(repo, false); - var changes = repo.Diff.Compare(new[] { file }); - - Assert.Equal(0, changes.Count()); + using(var changes = repo.Diff.Compare(new[] { file })) + { + Assert.Equal(0, changes.Count()); + } } } @@ -159,12 +168,13 @@ public void CanCompareTheWorkDirAgainstTheIndexWithUntrackedFiles() var path = SandboxStandardTestRepoGitDir(); using (var repo = new Repository(path)) { - var changes = repo.Diff.Compare(null, true); - - Assert.Equal(3, changes.Count()); - Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path); - Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path); - Assert.Equal("new_untracked_file.txt", changes.Added.Single().Path); + using (var changes = repo.Diff.Compare(null, true)) + { + Assert.Equal(3, changes.Count()); + Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path); + Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path); + Assert.Equal("new_untracked_file.txt", changes.Added.Single().Path); + } } } } diff --git a/LibGit2Sharp.Tests/PatchStatsFixture.cs b/LibGit2Sharp.Tests/PatchStatsFixture.cs index 41d3fdb23..758a08e2a 100644 --- a/LibGit2Sharp.Tests/PatchStatsFixture.cs +++ b/LibGit2Sharp.Tests/PatchStatsFixture.cs @@ -13,14 +13,15 @@ public void CanExtractStatisticsFromDiff() { var oldTree = repo.Lookup("origin/packed-test").Tree; var newTree = repo.Lookup("HEAD").Tree; - var stats = repo.Diff.Compare(oldTree, newTree); + using (var stats = repo.Diff.Compare(oldTree, newTree)) + { + Assert.Equal(8, stats.TotalLinesAdded); + Assert.Equal(1, stats.TotalLinesDeleted); - Assert.Equal(8, stats.TotalLinesAdded); - Assert.Equal(1, stats.TotalLinesDeleted); - - var contentStats = stats["new.txt"]; - Assert.Equal(1, contentStats.LinesAdded); - Assert.Equal(1, contentStats.LinesDeleted); + var contentStats = stats["new.txt"]; + Assert.Equal(1, contentStats.LinesAdded); + Assert.Equal(1, contentStats.LinesDeleted); + } } } } diff --git a/LibGit2Sharp/Commands/Remove.cs b/LibGit2Sharp/Commands/Remove.cs index 87265a2dd..939c427d1 100644 --- a/LibGit2Sharp/Commands/Remove.cs +++ b/LibGit2Sharp/Commands/Remove.cs @@ -182,58 +182,60 @@ private static void RemoveFilesAndFolders(IRepository repository, IEnumerable RemoveStagedItems(IRepository repository, IEnumerable paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null) { var removed = new List(); - var changes = repository.Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions); - var index = repository.Index; - - foreach (var treeEntryChanges in changes) + using (var changes = repository.Diff.Compare(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions)) { - var status = repository.RetrieveStatus(treeEntryChanges.Path); + var index = repository.Index; - switch (treeEntryChanges.Status) + foreach (var treeEntryChanges in changes) { - case ChangeKind.Added: - case ChangeKind.Deleted: - removed.Add(treeEntryChanges.Path); - index.Remove(treeEntryChanges.Path); - break; - - case ChangeKind.Unmodified: - if (removeFromWorkingDirectory && ( - status.HasFlag(FileStatus.ModifiedInIndex) || - status.HasFlag(FileStatus.NewInIndex))) - { - throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", - treeEntryChanges.Path); - } - removed.Add(treeEntryChanges.Path); - index.Remove(treeEntryChanges.Path); - continue; - - case ChangeKind.Modified: - if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex)) - { - throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.", - treeEntryChanges.Path); - } - if (removeFromWorkingDirectory) - { - throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", - treeEntryChanges.Path); - } - removed.Add(treeEntryChanges.Path); - index.Remove(treeEntryChanges.Path); - continue; - - default: - throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.", - treeEntryChanges.Path, - treeEntryChanges.Status); + var status = repository.RetrieveStatus(treeEntryChanges.Path); + + switch (treeEntryChanges.Status) + { + case ChangeKind.Added: + case ChangeKind.Deleted: + removed.Add(treeEntryChanges.Path); + index.Remove(treeEntryChanges.Path); + break; + + case ChangeKind.Unmodified: + if (removeFromWorkingDirectory && ( + status.HasFlag(FileStatus.ModifiedInIndex) || + status.HasFlag(FileStatus.NewInIndex))) + { + throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", + treeEntryChanges.Path); + } + removed.Add(treeEntryChanges.Path); + index.Remove(treeEntryChanges.Path); + continue; + + case ChangeKind.Modified: + if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex)) + { + throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.", + treeEntryChanges.Path); + } + if (removeFromWorkingDirectory) + { + throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.", + treeEntryChanges.Path); + } + removed.Add(treeEntryChanges.Path); + index.Remove(treeEntryChanges.Path); + continue; + + default: + throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.", + treeEntryChanges.Path, + treeEntryChanges.Status); + } } - } - index.Write(); + index.Write(); - return removed; + return removed; + } } } } diff --git a/LibGit2Sharp/Commands/Stage.cs b/LibGit2Sharp/Commands/Stage.cs index f3ff647a4..9917ca52a 100644 --- a/LibGit2Sharp/Commands/Stage.cs +++ b/LibGit2Sharp/Commands/Stage.cs @@ -74,68 +74,69 @@ public static void Stage(IRepository repository, IEnumerable paths, Stag diffModifiers |= DiffModifiers.IncludeIgnored; } - var changes = repository.Diff.Compare(diffModifiers, paths, explicitPathsOptions, - new CompareOptions { Similarity = SimilarityOptions.None }); - - var unexpectedTypesOfChanges = changes - .Where( - tec => tec.Status != ChangeKind.Added && - tec.Status != ChangeKind.Modified && - tec.Status != ChangeKind.Conflicted && - tec.Status != ChangeKind.Unmodified && - tec.Status != ChangeKind.Deleted).ToList(); - - if (unexpectedTypesOfChanges.Count > 0) + using (var changes = repository.Diff.Compare(diffModifiers, paths, explicitPathsOptions, + new CompareOptions { Similarity = SimilarityOptions.None })) { - throw new InvalidOperationException( - string.Format(CultureInfo.InvariantCulture, - "Entry '{0}' bears an unexpected ChangeKind '{1}'", - unexpectedTypesOfChanges[0].Path, unexpectedTypesOfChanges[0].Status)); - } + var unexpectedTypesOfChanges = changes + .Where( + tec => tec.Status != ChangeKind.Added && + tec.Status != ChangeKind.Modified && + tec.Status != ChangeKind.Conflicted && + tec.Status != ChangeKind.Unmodified && + tec.Status != ChangeKind.Deleted).ToList(); + + if (unexpectedTypesOfChanges.Count > 0) + { + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, + "Entry '{0}' bears an unexpected ChangeKind '{1}'", + unexpectedTypesOfChanges[0].Path, unexpectedTypesOfChanges[0].Status)); + } - /* Remove files from the index that don't exist on disk */ - foreach (TreeEntryChanges treeEntryChanges in changes) - { - switch (treeEntryChanges.Status) + /* Remove files from the index that don't exist on disk */ + foreach (TreeEntryChanges treeEntryChanges in changes) { - case ChangeKind.Conflicted: - if (!treeEntryChanges.Exists) - { + switch (treeEntryChanges.Status) + { + case ChangeKind.Conflicted: + if (!treeEntryChanges.Exists) + { + repository.Index.Remove(treeEntryChanges.Path); + } + break; + + case ChangeKind.Deleted: repository.Index.Remove(treeEntryChanges.Path); - } - break; - - case ChangeKind.Deleted: - repository.Index.Remove(treeEntryChanges.Path); - break; + break; - default: - continue; + default: + continue; + } } - } - foreach (TreeEntryChanges treeEntryChanges in changes) - { - switch (treeEntryChanges.Status) + foreach (TreeEntryChanges treeEntryChanges in changes) { - case ChangeKind.Added: - case ChangeKind.Modified: - repository.Index.Add(treeEntryChanges.Path); - break; - - case ChangeKind.Conflicted: - if (treeEntryChanges.Exists) - { + switch (treeEntryChanges.Status) + { + case ChangeKind.Added: + case ChangeKind.Modified: repository.Index.Add(treeEntryChanges.Path); - } - break; - - default: - continue; + break; + + case ChangeKind.Conflicted: + if (treeEntryChanges.Exists) + { + repository.Index.Add(treeEntryChanges.Path); + } + break; + + default: + continue; + } } - } - repository.Index.Write(); + repository.Index.Write(); + } } /// @@ -191,9 +192,8 @@ public static void Unstage(IRepository repository, IEnumerable paths, Ex if (repository.Info.IsHeadUnborn) { - var changes = repository.Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }); - - repository.Index.Replace(changes); + using (var changes = repository.Diff.Compare(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None })) + repository.Index.Replace(changes); } else { diff --git a/LibGit2Sharp/Core/FileHistory.cs b/LibGit2Sharp/Core/FileHistory.cs index 477717c79..5c10a1a24 100644 --- a/LibGit2Sharp/Core/FileHistory.cs +++ b/LibGit2Sharp/Core/FileHistory.cs @@ -163,11 +163,13 @@ private static void DetermineParentPaths(IRepository repo, Commit currentCommit, private static string ParentPath(IRepository repo, Commit currentCommit, string currentPath, Commit parentCommit) { - var treeChanges = repo.Diff.Compare(parentCommit.Tree, currentCommit.Tree); - var treeEntryChanges = treeChanges.FirstOrDefault(c => c.Path == currentPath); - return treeEntryChanges != null && treeEntryChanges.Status == ChangeKind.Renamed - ? treeEntryChanges.OldPath - : currentPath; + using (var treeChanges = repo.Diff.Compare(parentCommit.Tree, currentCommit.Tree)) + { + var treeEntryChanges = treeChanges.FirstOrDefault(c => c.Path == currentPath); + return treeEntryChanges != null && treeEntryChanges.Status == ChangeKind.Renamed + ? treeEntryChanges.OldPath + : currentPath; + } } } } diff --git a/LibGit2Sharp/Core/Handles/Libgit2Object.cs b/LibGit2Sharp/Core/Handles/Libgit2Object.cs index cbb431a98..9aae0129c 100644 --- a/LibGit2Sharp/Core/Handles/Libgit2Object.cs +++ b/LibGit2Sharp/Core/Handles/Libgit2Object.cs @@ -5,7 +5,7 @@ // // Uncomment the line below or add a conditional symbol to activate this mode -// #define LEAKS_IDENTIFYING +#define LEAKS_IDENTIFYING // This activates a more throrough mode which will show the stack trace of the // allocation code path for each handle that has been improperly released. @@ -15,7 +15,7 @@ // // Uncomment the line below or add a conditional symbol to activate this mode -// #define LEAKS_TRACKING +#define LEAKS_TRACKING using System; using System.Linq; diff --git a/LibGit2Sharp/Diff.cs b/LibGit2Sharp/Diff.cs index 4507a4499..9bf14660c 100644 --- a/LibGit2Sharp/Diff.cs +++ b/LibGit2Sharp/Diff.cs @@ -241,10 +241,17 @@ public virtual T Compare(Tree oldTree, Tree newTree, IEnumerable path } } - using (DiffHandle diff = BuildDiffList(oldTreeId, newTreeId, comparer, diffOptions, paths, explicitPathsOptions, compareOptions)) + DiffHandle diff = BuildDiffList(oldTreeId, newTreeId, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); + + try { return BuildDiffResult(diff); } + catch + { + diff.SafeDispose(); + throw; + } } /// @@ -343,10 +350,17 @@ public virtual T Compare(Tree oldTree, DiffTargets diffTargets, IEnumerable(diff); } + catch + { + diff.SafeDispose(); + throw; + } } /// @@ -462,10 +476,17 @@ internal virtual T Compare( } } - using (DiffHandle diff = BuildDiffList(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions)) + DiffHandle diff = BuildDiffList(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions); + + try { return BuildDiffResult(diff); } + catch + { + diff.SafeDispose(); + throw; + } } internal delegate DiffHandle TreeComparisonHandleRetriever(ObjectId oldTreeId, ObjectId newTreeId, GitDiffOptions options); diff --git a/LibGit2Sharp/IDiffResult.cs b/LibGit2Sharp/IDiffResult.cs index d16af711d..ed6e521fd 100644 --- a/LibGit2Sharp/IDiffResult.cs +++ b/LibGit2Sharp/IDiffResult.cs @@ -1,8 +1,10 @@ -namespace LibGit2Sharp +using System; + +namespace LibGit2Sharp { /// /// Marker interface to identify Diff results. /// - public interface IDiffResult + public interface IDiffResult: IDisposable { } } diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index 3ddc6d694..d68419ab1 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -292,8 +292,10 @@ public virtual void Replace(Commit commit, IEnumerable paths, ExplicitPa { Ensure.ArgumentNotNull(commit, "commit"); - var changes = repo.Diff.Compare(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }); - Replace(changes); + using (var changes = repo.Diff.Compare(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None })) + { + Replace(changes); + } } /// diff --git a/LibGit2Sharp/Patch.cs b/LibGit2Sharp/Patch.cs index dd668eda4..2cd4d1605 100644 --- a/LibGit2Sharp/Patch.cs +++ b/LibGit2Sharp/Patch.cs @@ -32,14 +32,17 @@ protected Patch() internal unsafe Patch(DiffHandle diff) { - int count = Proxy.git_diff_num_deltas(diff); - for (int i = 0; i < count; i++) + using (diff) { - using (var patch = Proxy.git_patch_from_diff(diff, i)) + int count = Proxy.git_diff_num_deltas(diff); + for (int i = 0; i < count; i++) { - var delta = Proxy.git_diff_get_delta(diff, i); - AddFileChange(delta); - Proxy.git_patch_print(patch, PrintCallBack); + using (var patch = Proxy.git_patch_from_diff(diff, i)) + { + var delta = Proxy.git_diff_get_delta(diff, i); + AddFileChange(delta); + Proxy.git_patch_print(patch, PrintCallBack); + } } } } @@ -180,5 +183,24 @@ private string DebuggerDisplay linesDeleted); } } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + // This doesn't do anything yet because it loads everything + // eagerly and disposes of the diff handle in the constructor. + } } } diff --git a/LibGit2Sharp/PatchStats.cs b/LibGit2Sharp/PatchStats.cs index c5404fed5..3d6bb46cd 100644 --- a/LibGit2Sharp/PatchStats.cs +++ b/LibGit2Sharp/PatchStats.cs @@ -27,23 +27,25 @@ protected PatchStats() internal unsafe PatchStats(DiffHandle diff) { - int count = Proxy.git_diff_num_deltas(diff); - for (int i = 0; i < count; i++) + using (diff) { - using (var patch = Proxy.git_patch_from_diff(diff, i)) + int count = Proxy.git_diff_num_deltas(diff); + for (int i = 0; i < count; i++) { - var delta = Proxy.git_diff_get_delta(diff, i); - var pathPtr = delta->new_file.Path != null ? delta->new_file.Path : delta->old_file.Path; - var newFilePath = LaxFilePathMarshaler.FromNative(pathPtr); + using (var patch = Proxy.git_patch_from_diff(diff, i)) + { + var delta = Proxy.git_diff_get_delta(diff, i); + var pathPtr = delta->new_file.Path != null ? delta->new_file.Path : delta->old_file.Path; + var newFilePath = LaxFilePathMarshaler.FromNative(pathPtr); - var stats = Proxy.git_patch_line_stats(patch); - int added = stats.Item1; - int deleted = stats.Item2; - changes.Add(newFilePath, new ContentChangeStats(added, deleted)); - totalLinesAdded += added; - totalLinesDeleted += deleted; + var stats = Proxy.git_patch_line_stats(patch); + int added = stats.Item1; + int deleted = stats.Item2; + changes.Add(newFilePath, new ContentChangeStats(added, deleted)); + totalLinesAdded += added; + totalLinesDeleted += deleted; + } } - } } @@ -117,5 +119,24 @@ private string DebuggerDisplay TotalLinesDeleted); } } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + // This doesn't do anything yet because it loads everything + // eagerly and disposes of the diff handle in the constructor. + } } } diff --git a/LibGit2Sharp/TreeChanges.cs b/LibGit2Sharp/TreeChanges.cs index 2e317855a..6e8a0eff5 100644 --- a/LibGit2Sharp/TreeChanges.cs +++ b/LibGit2Sharp/TreeChanges.cs @@ -17,32 +17,8 @@ namespace LibGit2Sharp [DebuggerDisplay("{DebuggerDisplay,nq}")] public class TreeChanges : IEnumerable, IDiffResult { - private readonly List changes = new List(); - private readonly List added = new List(); - private readonly List deleted = new List(); - private readonly List modified = new List(); - private readonly List typeChanged = new List(); - private readonly List unmodified = new List(); - private readonly List renamed = new List(); - private readonly List copied = new List(); - private readonly List conflicted = new List(); - - private readonly IDictionary> fileDispatcher = Build(); - - private static IDictionary> Build() - { - return new Dictionary> - { - { ChangeKind.Modified, (de, d) => de.modified.Add(d) }, - { ChangeKind.Deleted, (de, d) => de.deleted.Add(d) }, - { ChangeKind.Added, (de, d) => de.added.Add(d) }, - { ChangeKind.TypeChanged, (de, d) => de.typeChanged.Add(d) }, - { ChangeKind.Unmodified, (de, d) => de.unmodified.Add(d) }, - { ChangeKind.Renamed, (de, d) => de.renamed.Add(d) }, - { ChangeKind.Copied, (de, d) => de.copied.Add(d) }, - { ChangeKind.Conflicted, (de, d) => de.conflicted.Add(d) }, - }; - } + private readonly DiffHandle diff; + private readonly Lazy count; /// /// Needed for mocking purposes. @@ -52,21 +28,45 @@ protected TreeChanges() internal unsafe TreeChanges(DiffHandle diff) { - Proxy.git_diff_foreach(diff, FileCallback, null, null); + this.diff = diff; + this.count = new Lazy(() => Proxy.git_diff_num_deltas(diff)); } - private unsafe int FileCallback(git_diff_delta* delta, float progress, IntPtr payload) + /// + /// Enumerates the diff and yields deltas with the specified change kind. + /// + /// Change type to filter on. + private IEnumerable GetChangesOfKind(ChangeKind changeKind) { - AddFileChange(delta); - return 0; + TreeEntryChanges entry; + for (int i = 0; i < Count; i++) + { + if (TryGetEntryWithChangeTypeAt(i, changeKind, out entry)) + { + yield return entry; + } + } } - private unsafe void AddFileChange(git_diff_delta* delta) + /// + /// This is method exists to work around .net not allowing unsafe code + /// in iterators. + /// + private unsafe bool TryGetEntryWithChangeTypeAt(int index, ChangeKind changeKind, out TreeEntryChanges entry) { - var treeEntryChanges = new TreeEntryChanges(delta); + if (index < 0 || index > count.Value) + throw new ArgumentOutOfRangeException("index", "Index was out of range. Must be non-negative and less than the size of the collection."); + + var delta = Proxy.git_diff_get_delta(diff, index); + + if (TreeEntryChanges.GetStatusFromChangeKind(delta->status) == changeKind) + { + entry = new TreeEntryChanges(delta); + return true; + } - fileDispatcher[treeEntryChanges.Status](this, treeEntryChanges); - changes.Add(treeEntryChanges); + entry = null; + return false; } #region IEnumerable Members @@ -77,7 +77,22 @@ private unsafe void AddFileChange(git_diff_delta* delta) /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { - return changes.GetEnumerator(); + for (int i = 0; i < Count; i++) + { + yield return GetEntryAt(i); + } + } + + /// + /// This is method exists to work around .net not allowing unsafe code + /// in iterators. + /// + private unsafe TreeEntryChanges GetEntryAt(int index) + { + if (index < 0 || index > count.Value) + throw new ArgumentOutOfRangeException("index", "Index was out of range. Must be non-negative and less than the size of the collection."); + + return new TreeEntryChanges(Proxy.git_diff_get_delta(diff, index)); } /// @@ -96,7 +111,7 @@ IEnumerator IEnumerable.GetEnumerator() /// public virtual IEnumerable Added { - get { return added; } + get { return GetChangesOfKind(ChangeKind.Added); } } /// @@ -104,7 +119,7 @@ public virtual IEnumerable Added /// public virtual IEnumerable Deleted { - get { return deleted; } + get { return GetChangesOfKind(ChangeKind.Deleted); } } /// @@ -112,7 +127,7 @@ public virtual IEnumerable Deleted /// public virtual IEnumerable Modified { - get { return modified; } + get { return GetChangesOfKind(ChangeKind.Modified); } } /// @@ -120,7 +135,7 @@ public virtual IEnumerable Modified /// public virtual IEnumerable TypeChanged { - get { return typeChanged; } + get { return GetChangesOfKind(ChangeKind.TypeChanged); } } /// @@ -128,7 +143,7 @@ public virtual IEnumerable TypeChanged /// public virtual IEnumerable Renamed { - get { return renamed; } + get { return GetChangesOfKind(ChangeKind.Renamed); } } /// @@ -136,7 +151,7 @@ public virtual IEnumerable Renamed /// public virtual IEnumerable Copied { - get { return copied; } + get { return GetChangesOfKind(ChangeKind.Copied); } } /// @@ -144,7 +159,7 @@ public virtual IEnumerable Copied /// public virtual IEnumerable Unmodified { - get { return unmodified; } + get { return GetChangesOfKind(ChangeKind.Unmodified); } } /// @@ -152,7 +167,15 @@ public virtual IEnumerable Unmodified /// public virtual IEnumerable Conflicted { - get { return conflicted; } + get { return GetChangesOfKind(ChangeKind.Conflicted); } + } + + /// + /// Gets the number of in this comparison. + /// + public virtual int Count + { + get { return count.Value; } } private string DebuggerDisplay @@ -169,5 +192,23 @@ private string DebuggerDisplay Copied.Count()); } } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + diff.SafeDispose(); + } } } diff --git a/LibGit2Sharp/TreeEntryChanges.cs b/LibGit2Sharp/TreeEntryChanges.cs index 53f2ce49e..cfe0fd8e8 100644 --- a/LibGit2Sharp/TreeEntryChanges.cs +++ b/LibGit2Sharp/TreeEntryChanges.cs @@ -28,9 +28,23 @@ internal unsafe TreeEntryChanges(git_diff_delta* delta) Exists = (delta->new_file.Flags & GitDiffFlags.GIT_DIFF_FLAG_EXISTS) != 0; OldExists = (delta->old_file.Flags & GitDiffFlags.GIT_DIFF_FLAG_EXISTS) != 0; - Status = (delta->status == ChangeKind.Untracked || delta->status == ChangeKind.Ignored) - ? ChangeKind.Added - : delta->status; + Status = GetStatusFromChangeKind(delta->status); + } + + // This treatment of change kind was apparently introduced in order to be able + // to compare a tree against the index, see commit fdc972b. It's extracted + // here so that TreeEntry can use the same rules without having to instantiate + // a TreeEntryChanges object. + internal static ChangeKind GetStatusFromChangeKind(ChangeKind changeKind) + { + switch (changeKind) + { + case ChangeKind.Untracked: + case ChangeKind.Ignored: + return ChangeKind.Added; + default: + return changeKind; + } } ///