Skip to content

Commit c57f258

Browse files
committed
Make Diff.Compare() able to compare null Trees
1 parent da671ee commit c57f258

File tree

6 files changed

+71
-10
lines changed

6 files changed

+71
-10
lines changed

LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.IO;
1+
using System;
2+
using System.IO;
23
using System.Linq;
34
using System.Text;
45
using LibGit2Sharp.Tests.TestHelpers;
@@ -354,5 +355,39 @@ public void CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks()
354355
Assert.Equal(expected.ToString(), changes.Patch);
355356
}
356357
}
358+
359+
[Fact]
360+
public void CanCompareATreeAgainstANullTree()
361+
{
362+
using (var repo = new Repository(StandardTestRepoPath))
363+
{
364+
Tree tree = repo.Branches["refs/remotes/origin/test"].Tip.Tree;
365+
366+
TreeChanges changes = repo.Diff.Compare(tree, null);
367+
368+
Assert.Equal(1, changes.Count());
369+
Assert.Equal(1, changes.Deleted.Count());
370+
371+
Assert.Equal("readme.txt", changes.Deleted.Single().Path);
372+
373+
changes = repo.Diff.Compare(null, tree);
374+
375+
Assert.Equal(1, changes.Count());
376+
Assert.Equal(1, changes.Added.Count());
377+
378+
Assert.Equal("readme.txt", changes.Added.Single().Path);
379+
}
380+
}
381+
382+
[Fact]
383+
public void ComparingTwoNullTreesReturnsAnEmptyTreeChanges()
384+
{
385+
using (var repo = new Repository(StandardTestRepoPath))
386+
{
387+
TreeChanges changes = repo.Diff.Compare(null, null, null);
388+
389+
Assert.Equal(0, changes.Count());
390+
}
391+
}
357392
}
358393
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
3+
namespace LibGit2Sharp.Core.Handles
4+
{
5+
internal class NullGitObjectSafeHandle : GitObjectSafeHandle
6+
{
7+
public NullGitObjectSafeHandle()
8+
{
9+
handle = IntPtr.Zero;
10+
}
11+
12+
protected override bool ReleaseHandle()
13+
{
14+
// Nothing to release
15+
return true;
16+
}
17+
}
18+
}

LibGit2Sharp/Core/ObjectSafeWrapper.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ internal class ObjectSafeWrapper : IDisposable
77
{
88
private readonly GitObjectSafeHandle objectPtr;
99

10-
public ObjectSafeWrapper(ObjectId id, RepositorySafeHandle handle)
10+
public ObjectSafeWrapper(ObjectId id, RepositorySafeHandle handle, bool allowNullObjectId = false)
1111
{
12-
Ensure.ArgumentNotNull(id, "id");
1312
Ensure.ArgumentNotNull(handle, "handle");
1413

15-
objectPtr = Proxy.git_object_lookup(handle, id, GitObjectType.Any);
14+
if (allowNullObjectId && id == null)
15+
{
16+
objectPtr = new NullGitObjectSafeHandle();
17+
}
18+
else
19+
{
20+
Ensure.ArgumentNotNull(id, "id");
21+
objectPtr = Proxy.git_object_lookup(handle, id, GitObjectType.Any);
22+
}
1623
}
1724

1825
public GitObjectSafeHandle ObjectPtr

LibGit2Sharp/Core/Proxy.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,8 @@ public static DiffListSafeHandle git_diff_tree_to_tree(
550550
ObjectId newTree)
551551
{
552552
using (ThreadAffinity())
553-
using (var osw1 = new ObjectSafeWrapper(oldTree, repo))
554-
using (var osw2 = new ObjectSafeWrapper(newTree, repo))
553+
using (var osw1 = new ObjectSafeWrapper(oldTree, repo, true))
554+
using (var osw2 = new ObjectSafeWrapper(newTree, repo, true))
555555
{
556556
DiffListSafeHandle diff;
557557
int res = NativeMethods.git_diff_tree_to_tree(repo, options, osw1.ObjectPtr, osw2.ObjectPtr, out diff);

LibGit2Sharp/Diff.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ internal Diff(Repository repo)
7070
/// <returns>A <see cref = "TreeChanges"/> containing the changes between the <paramref name = "oldTree"/> and the <paramref name = "newTree"/>.</returns>
7171
public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable<string> paths = null)
7272
{
73-
Ensure.ArgumentNotNull(oldTree, "oldTree");
74-
Ensure.ArgumentNotNull(oldTree, "newTree");
75-
7673
using(GitDiffOptions options = BuildOptions(paths))
77-
using (DiffListSafeHandle diff = BuildDiffListFromTrees(oldTree.Id, newTree.Id, options))
74+
using (DiffListSafeHandle diff = BuildDiffListFromTrees(
75+
oldTree != null ? oldTree.Id : null,
76+
newTree != null ? newTree.Id : null,
77+
options))
7878
{
7979
return new TreeChanges(diff);
8080
}

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
<Compile Include="Core\GitConfigEntry.cs" />
7575
<Compile Include="Core\GitObjectLazyGroup.cs" />
7676
<Compile Include="Core\GitTransferProgress.cs" />
77+
<Compile Include="Core\Handles\NullGitObjectSafeHandle.cs" />
7778
<Compile Include="Core\ILazy.cs" />
7879
<Compile Include="Core\LazyGroup.cs" />
7980
<Compile Include="Core\Proxy.cs" />

0 commit comments

Comments
 (0)