8000 Introduce Diff.Compare<PatchStats>() · GiTechLab/libgit2sharp@4e43e4f · GitHub
[go: up one dir, main page]

Skip to content

Commit 4e43e4f

Browse files
committed
Introduce Diff.Compare<PatchStats>()
1 parent 0bbed21 commit 4e43e4f

File tree

6 files changed

+179
-0
lines changed

6 files changed

+179
-0
lines changed

LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<Compile Include="BlameFixture.cs" />
6262
<Compile Include="ArchiveTarFixture.cs" />
6363
<Compile Include="CheckoutFixture.cs" />
64+
<Compile Include="PatchStatsFixture.cs" />
6465
<Compile Include="RefSpecFixture.cs" />
6566
<Compile Include="EqualityFixture.cs" />
6667
<Compile Include="SignatureFixture.cs" />
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using LibGit2Sharp.Tests.TestHelpers;
2+
using Xunit;
3+
4+
namespace LibGit2Sharp.Tests
5+
{
6+
public class PatchStatsFixture : BaseFixture
7+
{
8+
[Fact]
9+
public void CanExtractStatisticsFromDiff()
10+
{
11+
using (var repo = new Repository(StandardTestRepoPath))
12+
{
13+
var oldTree = repo.Lookup<Commit>("origin/packed-test").Tree;
14+
var newTree = repo.Lookup<Commit>("HEAD").Tree;
15+
var stats = repo.Diff.Compare<PatchStats>(oldTree, newTree);
16+
17+
Assert.Equal(8, stats.TotalLinesAdded);
18+
Assert.Equal(1, stats.TotalLinesDeleted);
19+
20+
var contentStats = stats["new.txt"];
21+
Assert.Equal(1, contentStats.LinesAdded);
22+
Assert.Equal(1, contentStats.LinesDeleted);
23+
}
24+
}
25+
}
26+
}

LibGit2Sharp/ContentChangeStats.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
namespace LibGit2Sharp
2+
{
3+
/// <summary>
4+
/// Holds a summary of a change to a single file.
5+
/// </summary>
6+
public class ContentChangeStats
7+
{
8+
/// <summary>
9+
/// The number of lines added in the diff.
10+
/// </summary>
11+
public virtual int LinesAdded { get; private set; }
12+
13+
/// <summary>
14+
/// The number of lines deleted in the diff.
15+
/// </summary>
16+
public virtual int LinesDeleted { get; private set; }
17+
18+
/// <summary>
19+
/// For mocking.
20+
/// </summary>
21+
protected ContentChangeStats()
22+
{ }
23+
24+
internal ContentChangeStats(int added, int deleted)
25+
{
26+
LinesAdded = added;
27+
LinesDeleted = deleted;
28+
}
29+
}
30+
}

LibGit2Sharp/Diff.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ private static IDictionary<DiffTargets, Func<Repository, TreeComparisonHandleRet
9797
{
9898
{ typeof(Patch), diff => new Patch(diff) },
9999
{ typeof(TreeChanges), diff => new TreeChanges(diff) },
100+
{ typeof(PatchStats), diff => new PatchStats(diff) },
100101
};
101102

102103
/// <summary>

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,12 @@
7575
<Compile Include="CommitFilter.cs" />
7676
<Compile Include="CommitSortStrategies.cs" />
7777
<Compile Include="CompareOptions.cs" />
78+
<Compile Include="ContentChangeStats.cs" />
7879
<Compile Include="Core\Handles\PatchSafeHandle.cs" />
7980
<Compile Include="Core\IntPtrExtensions.cs" />
8081
<Compile Include="FetchOptions.cs" />
8182
<Compile Include="MergeResult.cs" />
83+
<Compile Include="PatchStats.cs" />
8284
<Compile Include="RefSpec.cs" />
8385
<Compile Include="RefSpecCollection.cs" />
8486
<Compile Include="Core\EncodingMarshaler.cs" />

LibGit2Sharp/PatchStats.cs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.Globalization;
6+
using LibGit2Sharp.Core;
7+
using LibGit2Sharp.Core.Handles;
8+
9+
namespace LibGit2Sharp
10+
{
11+
/// <summary>
12+
/// Holds summary information for a diff.
13+
/// <para>The individual patches for each file can be accessed through the indexer of this class.</para>
14+
/// </summary>
15+
[DebuggerDisplay("{DebuggerDisplay,nq}")]
16+
public class PatchStats : IEnumerable<ContentChangeStats>
17+
{
18+
private readonly IDictionary<FilePath, ContentChangeStats> changes = new Dictionary<FilePath, ContentChangeStats>();
19+
private readonly int totalLinesAdded;
20+
private readonly int totalLinesDeleted;
21+
22+
/// <summary>
23+
/// For mocking.
24+
/// </summary>
25+
protected PatchStats()
26+
{ }
27+
28+
internal PatchStats(DiffSafeHandle diff)
29+
{
30+
int count = Proxy.git_diff_num_deltas(diff);
31+
for (int i = 0; i < count; i++)
32+
{
33+
using (var patch = Proxy.git_patch_from_diff(diff, i))
34+
{
35+
var delta = Proxy.git_diff_get_delta(diff, i);
36+
var pathPtr = delta.NewFile.Path != IntPtr.Zero ? delta.NewFile.Path : delta.OldFile.Path;
37+
var newFilePath = LaxFilePathMarshaler.FromNative(pathPtr);
38+
39+
var stats = Proxy.git_patch_line_stats(patch);
40+
int added = stats.Item1;
41+
int deleted = stats.Item2;
42+
changes.Add(newFilePath, new ContentChangeStats(added, deleted));
43+
totalLinesAdded += added;
44+
totalLinesDeleted += deleted;
45+
}
46+
47+
}
48+
}
49+
50+
#region IEnumerable<ContentChanges> Members
51+
52+
/// <summary>
53+
/// Returns an enumerator that iterates through the collection.
54+
/// </summary>
55+
/// <returns>An <see cref="IEnumerator{T}"/> object that can be used to iterate through the collection.</returns>
56+
public virtual IEnumerator<ContentChangeStats> GetEnumerator()
57+
{
58+
return changes.Values.GetEnumerator();
59+
}
60+
61+
/// <summary>
62+
/// Returns an enumerator that iterates through the collection.
63+
/// </summary>
64+
/// <returns>An <see cref="IEnumerator"/> object that can be used to iterate through the collection.</returns>
65+
IEnumerator IEnumerable.GetEnumerator()
66+
{
67+
return GetEnumerator();
68+
}
69+
70+
#endregion
71+
72+
/// <summary>
73+
/// Gets the <see cref="ContentChangeStats"/> corresponding to the specified <paramref name="path"/>.
74+
/// </summary>
75+
/// <param name="path"></param>
76+
public virtual ContentChangeStats this[string path]
77+
{
78+
get { return this[(FilePath) path]; }
79+
}
80+
81+
private ContentChangeStats this[FilePath path]
82+
{
83+
get
84+
{
85+
ContentChangeStats stats;
86+
if (changes.TryGetValue(path, out stats))
87+
{
88+
return stats;
89+
}
90+
return null;
91+
}
92+
}
93+
94+
/// <summary>
95+
/// The total number of lines added in this diff.
96+
/// </summary>
97+
public virtual int TotalLinesAdded
98+
{
99+
get { return totalLinesAdded; }
100+
}
101+
102+
/// <summary>
103+
/// The total number of lines deleted in this diff.
104+
/// </summary>
105+
public virtual int TotalLinesDeleted
106+
{
107+
get { return totalLinesDeleted; }
108+
}
109+
110+
private string DebuggerDisplay
111+
{
112+
get
113+
{
114+
return string.Format(CultureInfo.InvariantCulture, "+{0} -{1}",
115+
TotalLinesAdded, TotalLinesDeleted);
116+
}
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)
0