diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index 99603b69e..ba763fb4f 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -39,7 +39,7 @@ public void RetrievingANonExistentFileChangeReturnsNull() var changes = repo.Diff.Compare(tree, tree); - Assert.Null(changes["batman"]); + Assert.Equal(0, changes.Count(c => c.Path == "batman")); } } @@ -62,7 +62,7 @@ public void CanCompareACommitTreeAgainstItsParent() Assert.Equal(1, changes.Count()); Assert.Equal(1, changes.Added.Count()); - TreeEntryChanges treeEntryChanges = changes["1.txt"]; + TreeEntryChanges treeEntryChanges = changes.Single(c => c.Path == "1.txt"); var patch = repo.Diff.Compare(parentCommitTree, commitTree); Assert.False(patch["1.txt"].IsBinaryComparison); @@ -272,8 +272,7 @@ public void DetectsTheRenamingOfAModifiedFileByDefault() var changes = repo.Diff.Compare(rootCommitTree, commitTreeWithRenamedFile); Assert.Equal(1, changes.Count()); - Assert.Equal("super-file.txt", changes["super-file.txt"].Path); - Assert.Equal("my-name-does-not-feel-right.txt", changes["super-file.txt"].OldPath); + Assert.Equal("my-name-does-not-feel-right.txt", changes.Single(c => c.Path == "super-file.txt").OldPath); Assert.Equal(1, changes.Renamed.Count()); } } @@ -888,7 +887,7 @@ public void CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks(int contextLines, in Assert.Equal(1, changes.Deleted.Count()); Assert.Equal(1, changes.Added.Count()); - Assert.Equal(Mode.Nonexistent, changes["my-name-does-not-feel-right.txt"].Mode); + 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); @@ -904,17 +903,16 @@ public void CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks(int contextLines, in } } - [Fact] - public void CanHandleTwoTreeEntryChangesWithTheSamePath() + private void CanHandleTwoTreeEntryChangesWithTheSamePath(SimilarityOptions similarity, Action verifier) { string repoPath = InitNewRepository(); using (var repo = new Repository(repoPath)) { - Blob mainContent = OdbHelper.CreateBlob(repo, "awesome content\n"); + Blob mainContent = OdbHelper.CreateBlob(repo, "awesome content\n" + new string('b', 4096)); Blob linkContent = OdbHelper.CreateBlob(repo, "../../objc/Nu.h"); - string path = string.Format("include{0}Nu{0}Nu.h", Path.DirectorySeparatorChar); + string path = Path.Combine("include", "Nu", "Nu.h"); var tdOld = new TreeDefinition() .Add(path, linkContent, Mode.SymbolicLink) @@ -930,45 +928,61 @@ public void CanHandleTwoTreeEntryChangesWithTheSamePath() var changes = repo.Diff.Compare(treeOld, treeNew, compareOptions: new CompareOptions { - Similarity = SimilarityOptions.None, + Similarity = similarity, }); - /* - * $ git diff-tree -p 5c87b67 d5278d0 - * diff --git a/include/Nu/Nu.h b/include/Nu/Nu.h - * deleted file mode 120000 - * index 19bf568..0000000 - * --- a/include/Nu/Nu.h - * +++ /dev/null - * @@ -1 +0,0 @@ - * -../../objc/Nu.h - * \ No newline at end of file - * diff --git a/include/Nu/Nu.h b/include/Nu/Nu.h - * new file mode 100644 - * index 0000000..f9e6561 - * --- /dev/null - * +++ b/include/Nu/Nu.h - * @@ -0,0 +1 @@ - * +awesome content - * diff --git a/objc/Nu.h b/objc/Nu.h - * deleted file mode 100644 - * index f9e6561..0000000 - * --- a/objc/Nu.h - * +++ /dev/null - * @@ -1 +0,0 @@ - * -awesome content - */ + verifier(path, changes); + } + } - Assert.Equal(1, changes.Deleted.Count()); - Assert.Equal(0, changes.Modified.Count()); - Assert.Equal(1, changes.TypeChanged.Count()); + [Fact] + public void CanHandleTwoTreeEntryChangesWithTheSamePathUsingSimilarityNone() + { + // $ git diff-tree --name-status --no-renames -r 2ccccf8 e829333 + // T include/Nu/Nu.h + // D objc/Nu.h - TreeEntryChanges change = changes[path]; - Assert.Equal(Mode.SymbolicLink, change.OldMode); - Assert.Equal(Mode.NonExecutableFile, change.Mode); - Assert.Equal(ChangeKind.TypeChanged, change.Status); - Assert.Equal(path, change.Path); - } + CanHandleTwoTreeEntryChangesWithTheSamePath(SimilarityOptions.None, + (path, changes) => + { + Assert.Equal(2, changes.Count()); + Assert.Equal(1, changes.Deleted.Count()); + Assert.Equal(1, changes.TypeChanged.Count()); + + TreeEntryChanges change = changes.Single(c => c.Path== path); + Assert.Equal(Mode.SymbolicLink, change.OldMode); + Assert.Equal(Mode.NonExecutableFile, change.Mode); + Assert.Equal(ChangeKind.TypeChanged, change.Status); + Assert.Equal(path, change.Path); + }); + } + + [Fact] + public void CanHandleTwoTreeEntryChangesWithTheSamePathUsingSimilarityDefault() + { + // $ git diff-tree --name-status --find-renames -r 2ccccf8 e829333 + // T include/Nu/Nu.h + // D objc/Nu.h + + CanHandleTwoTreeEntryChangesWithTheSamePath(SimilarityOptions.Default, + (path, changes) => + { + Assert.Equal(2, changes.Count()); + Assert.Equal(1, changes.Deleted.Count()); + Assert.Equal(1, changes.Renamed.Count()); + + TreeEntryChanges renamed = changes.Renamed.Single(); + Assert.Equal(Mode.NonExecutableFile, renamed.OldMode); + Assert.Equal(Mode.NonExecutableFile, renamed.Mode); + Assert.Equal(ChangeKind.Renamed, renamed.Status); + Assert.Equal(path, renamed.Path); + + TreeEntryChanges deleted = changes.Deleted.Single(); + Assert.Equal(Mode.SymbolicLink, deleted.OldMode); + Assert.Equal(Mode.Nonexistent, deleted.Mode); + Assert.Equal(ChangeKind.Deleted, deleted.Status); + Assert.Equal(path, deleted.Path); + }); } [Fact] @@ -1104,8 +1118,8 @@ public void RetrievingDiffChangesMustAlwaysBeCaseSensitive() { 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); + Assert.Equal(ChangeKind.Modified, changes.Single(c => c.Path == "a.txt").Status); + Assert.Equal(ChangeKind.Modified, changes.Single(c => c.Path == "A.TXT").Status); } } diff --git a/LibGit2Sharp/TreeChanges.cs b/LibGit2Sharp/TreeChanges.cs index 1529a25cd..385770875 100644 --- a/LibGit2Sharp/TreeChanges.cs +++ b/LibGit2Sharp/TreeChanges.cs @@ -17,7 +17,7 @@ namespace LibGit2Sharp [DebuggerDisplay("{DebuggerDisplay,nq}")] public class TreeChanges : IEnumerable { - private readonly IDictionary changes = new Dictionary(); + private readonly List changes = new List(); private readonly List added = new List(); private readonly List deleted = new List(); private readonly List modified = new List(); @@ -64,7 +64,7 @@ private void AddFileChange(GitDiffDelta delta) var treeEntryChanges = new TreeEntryChanges(delta); fileDispatcher[treeEntryChanges.Status](this, treeEntryChanges); - changes.Add(treeEntryChanges.Path, treeEntryChanges); + changes.Add(treeEntryChanges); } #region IEnumerable Members @@ -75,7 +75,7 @@ private void AddFileChange(GitDiffDelta delta) /// An object that can be used to iterate through the collection. public virtual IEnumerator GetEnumerator() { - return changes.Values.GetEnumerator(); + return changes.GetEnumerator(); } /// @@ -89,27 +89,6 @@ IEnumerator IEnumerable.GetEnumerator() #endregion - /// - /// Gets the corresponding to the specified . - /// - public virtual TreeEntryChanges this[string path] - { - get { return this[(FilePath)path]; } - } - - private TreeEntryChanges this[FilePath path] - { - get - { - TreeEntryChanges treeEntryChanges; - if (changes.TryGetValue(path, out treeEntryChanges)) - { - return treeEntryChanges; - } - - return null; - } - } /// /// List of that have been been added.