Skip to content

Commit 5242d4d

Browse files
committed
Add specific explicit interfaces to not have to modify the test.
1 parent 95e0982 commit 5242d4d

File tree

8 files changed

+109
-126
lines changed

8 files changed

+109
-126
lines changed

LibGit2Sharp.Tests/MetaFixture.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class MetaFixture
1717
{
1818
private static readonly HashSet<Type> explicitOnlyInterfaces = new HashSet<Type>
1919
{
20-
typeof(IBelongToARepository), typeof(IDiffResult<>),
20+
typeof(IBelongToARepository), typeof(IDiffResult),
2121
};
2222

2323
[Fact]
@@ -401,6 +401,20 @@ where method.IsDefined(typeof(ExtensionAttribute), false)
401401
select method;
402402
return query;
403403
}
404+
405+
[Fact]
406+
public void AllIDiffResultsAreInChangesBuilder()
407+
{
408+
var diff = typeof(Diff).GetField("ChangesBuilders", BindingFlags.NonPublic | BindingFlags.Static);
409+
var changesBuilders = (System.Collections.IDictionary)diff.GetValue(null);
410+
411+
IEnumerable<Type> diffResults = typeof(Diff).Assembly.GetExportedTypes()
412+
.Where(type => type.GetInterface("IDiffResult") != null);
413+
414+
var nonBuilderTypes = diffResults.Where(diffResult => !changesBuilders.Contains(diffResult));
415+
Assert.False(nonBuilderTypes.Any(), "Classes which implement IDiffResult but are not registered under ChangesBuilders in Diff:" + Environment.NewLine +
416+
string.Join(Environment.NewLine, nonBuilderTypes.Select(type => type.FullName)));
417+
}
404418
}
405419

406420
internal static class TypeExtensions

LibGit2Sharp/Diff.cs

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,29 @@ private static IDictionary<DiffTargets, Func<Repository, TreeComparisonHandleRet
9595
};
9696
}
9797

98+
private static readonly IDictionary<Type, Func<DiffSafeHandle, object>> ChangesBuilders = new Dictionary<Type, Func<DiffSafeHandle, object>>
99+
{
100+
{ typeof(Patch), diff => new Patch(diff) },
101+
{ typeof(TreeChanges), diff => new TreeChanges(diff) },
102+
{ typeof(PatchStats), diff => new PatchStats(diff) },
103+
};
104+
105+
106+
private static T BuildDiffResult<T>(DiffSafeHandle diff) where T : class, IDiffResult
107+
{
108+
Func<DiffSafeHandle, object> builder;
109+
110+
if (!ChangesBuilders.TryGetValue(typeof(T), out builder))
111+
{
112+
throw new LibGit2SharpException(CultureInfo.InvariantCulture,
113+
"User-defined types passed to Compare are not supported. Supported values are: {1}",
114+
typeof(T),
115+
string.Join(", ", ChangesBuilders.Keys.Select(x => x.Name)));
116+
}
117+
118+
return (T)builder(diff);
119+
}
120+
98121
/// <summary>
99122
/// Show changes between two <see cref="Blob"/>s.
100123
/// </summary>
@@ -127,7 +150,7 @@ public virtual ContentChanges Compare(Blob oldBlob, Blob newBlob, CompareOptions
127150
/// <param name="oldTree">The <see cref="Tree"/> you want to compare from.</param>
128151
/// <param name="newTree">The <see cref="Tree"/> you want to compare to.</param>
129152
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
130-
public virtual T Compare<T>(Tree oldTree, Tree newTree) where T : class, IDiffResult<T>, new()
153+
public virtual T Compare<T>(Tree oldTree, Tree newTree) where T : class, IDiffResult
131154
{
132155
return Compare<T>(oldTree, newTree, null, null, null);
133156
}
@@ -139,7 +162,7 @@ public virtual ContentChanges Compare(Blob oldBlob, Blob newBlob, CompareOptions
139162
/// <param name="newTree">The <see cref="Tree"/> you want to compare to.</param>
140163
/// <param name="paths">The list of paths (either files or directories) that should be compared.</param>
141164
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
142-
public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> paths) where T : class, IDiffResult<T>, new()
165+
public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> paths) where T : class, IDiffResult
143166
{
144167
return Compare<T>(oldTree, newTree, paths, null, null);
145168
}
@@ -156,7 +179,7 @@ public virtual ContentChanges Compare(Blob oldBlob, Blob newBlob, CompareOptions
156179
/// </param>
157180
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
158181
public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> paths,
159-
ExplicitPathsOptions explicitPathsOptions) where T : class, IDiffResult<T>, new()
182+
ExplicitPathsOptions explicitPathsOptions) where T : class, IDiffResult
160183
{
161184
return Compare<T>(oldTree, newTree, paths, explicitPathsOptions, null);
162185
}
@@ -169,7 +192,7 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
169192
/// <param name="paths">The list of paths (either files or directories) that should be compared.</param>
170193
/// <param name="compareOptions">Additional options to define patch generation behavior.</param>
171194
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
172-
public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> paths, CompareOptions compareOptions) where T : class, IDiffResult<T>, new()
195+
public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> paths, CompareOptions compareOptions) where T : class, IDiffResult
173196
{
174197
return Compare<T>(oldTree, newTree, paths, null, compareOptions);
175198
}
@@ -181,7 +204,7 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
181204
/// <param name="newTree">The <see cref="Tree"/> you want to compare to.</param>
182205
/// <param name="compareOptions">Additional options to define patch generation behavior.</param>
183206
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
184-
public virtual T Compare<T>(Tree oldTree, Tree newTree, CompareOptions compareOptions) where T : class, IDiffResult<T>, new()
207+
public virtual T Compare<T>(Tree oldTree, Tree newTree, CompareOptions compareOptions) where T : class, IDiffResult
185208
{
186209
return Compare<T>(oldTree, newTree, null, null, compareOptions);
187210
}
@@ -199,9 +222,8 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
199222
/// <param name="compareOptions">Additional options to define patch generation behavior.</param>
200223
/// <returns>A <see cref="TreeChanges"/> containing the changes between the <paramref name="oldTree"/> and the <paramref name="newTree"/>.</returns>
201224
public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> paths, ExplicitPathsOptions explicitPathsOptions,
202-
CompareOptions compareOptions) where T : class, IDiffResult<T>, new()
225+
CompareOptions compareOptions) where T : class, IDiffResult
203226
{
204-
205227
var comparer = TreeToTree(repo);
206228
ObjectId oldTreeId = oldTree != null ? oldTree.Id : null;
207229
ObjectId newTreeId = newTree != null ? newTree.Id : null;
@@ -219,10 +241,7 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
219241

220242
using (DiffSafeHandle diff = BuildDiffList(oldTreeId, newTreeId, comparer, diffOptions, paths, explicitPathsOptions, compareOptions))
221243
{
222-
using (var proxy = new DiffSafeHandleProxy(diff))
223-
{
224-
return new T().FromNative(proxy);
225-
}
244+
return BuildDiffResult<T>(diff);
226245
}
227246
}
228247

@@ -238,7 +257,7 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
238257
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
239258
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
240259
/// <returns>A <typeparamref name="T"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns>
241-
public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets) where T : class, IDiffResult<T>, new()
260+
public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets) where T : class, IDiffResult
242261
{
243262
return Compare<T>(oldTree, diffTargets, null, null, null);
244263
}
@@ -256,7 +275,7 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
256275
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
257276
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
258277
/// <returns>A <typeparamref name="T"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns>
259-
public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<string> paths) where T : class, IDiffResult<T>, new()
278+
public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<string> paths) where T : class, IDiffResult
260279
{
261280
return Compare<T>(oldTree, diffTargets, paths, null, null);
262281
}
@@ -279,7 +298,7 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
279298
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
280299
/// <returns>A <typeparamref name="T"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns>
281300
public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<string> paths,
282-
ExplicitPathsOptions explicitPathsOptions) where T : class, IDiffResult<T>, new()
301+
ExplicitPathsOptions explicitPathsOptions) where T : class, IDiffResult
283302
{
284303
return Compare<T>(oldTree, diffTargets, paths, explicitPathsOptions, null);
285304
}
@@ -303,7 +322,7 @@ public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<s
303322
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
304323
/// <returns>A <typeparamref name="T"/> containing the changes between the <see cref="Tree"/> and the selected target.</returns>
305324
public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<string> paths,
306-
ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) where T : class, IDiffResult<T>, new()
325+
ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) where T : class, IDiffResult
307326
{
308327
var comparer = HandleRetrieverDispatcher[diffTargets](repo);
309328
ObjectId oldTreeId = oldTree != null ? oldTree.Id : null;
@@ -324,10 +343,7 @@ public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<s
324343

325344
using (DiffSafeHandle diff = BuildDiffList(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions))
326345
{
327-
using (var proxy = new DiffSafeHandleProxy(diff))
328-
{
329-
return new T().FromNative(proxy);
330-
}
346+
return BuildDiffResult<T>(diff);
331347
}
332348
}
333349

@@ -341,7 +357,7 @@ public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<s
341357
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
342358
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
343359
/// <returns>A <typeparamref name="T"/> containing the changes between the working directory and the index.</returns>
344-
public virtual T Compare<T>() where T : class, IDiffResult<T>, new()
360+
public virtual T Compare<T>() where T : class, IDiffResult
345361
{
346362
return Compare<T>(DiffModifiers.None);
347363
}
@@ -357,7 +373,7 @@ public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<s
357373
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
358374
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
359375
/// <returns>A <typeparamref name="T"/> containing the changes between the working directory and the index.</returns>
360-
public virtual T Compare<T>(IEnumerable<string> paths) where T : class, IDiffResult<T>, new()
376+
public virtual T Compare<T>(IEnumerable<string> paths) where T : class, IDiffResult
361377
{
362378
return Compare<T>(DiffModifiers.None, paths);
363379
}
@@ -374,7 +390,7 @@ public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<s
374390
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
375391
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
376392
/// <returns>A <typeparamref name="T"/> containing the changes between the working directory and the index.</returns>
377-
public virtual T Compare<T>(IEnumerable<string> paths, bool includeUntracked) where T : class, IDiffResult<T>, new()
393+
public virtual T Compare<T>(IEnumerable<string> paths, bool includeUntracked) where T : class, IDiffResult
378394
{
379395
return Compare<T>(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths);
380396
}
@@ -395,7 +411,7 @@ public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<s
395411
/// <typeparam name="T">Can be either a <see cref="TreeChanges"/> if you are only interested in the list of files modified, added, ..., or
396412
/// a <see cref="Patch"/> if you want the actual patch content for the whole diff and for individual files.</typeparam>
397413
/// <returns>A <typeparamref name="T"/> containing the changes between the working directory and the index.</returns>
398-
public virtual T Compare<T>(IEnumerable<string> paths, bool includeUntracked, ExplicitPathsOptions explicitPathsOptions) where T : class, IDiffResult<T>, new()
414+
public virtual T Compare<T>(IEnumerable<string> paths, bool includeUntracked, ExplicitPathsOptions explicitPathsOptions) where T : class, IDiffResult
399415
{
400416
return Compare<T>(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions);
401417
}
@@ -421,7 +437,7 @@ public virtual T Compare<T>(
421437
IEnumerable<string> paths,
422438
bool includeUntracked,
423439
ExplicitPathsOptions explicitPathsOptions,
424-
CompareOptions compareOptions) where T : class, IDiffResult<T>, new()
440+
CompareOptions compareOptions) where T : class, IDiffResult
425441
{
426442
return Compare<T>(includeUntracked ? DiffModifiers.IncludeUntracked : DiffModifiers.None, paths, explicitPathsOptions, compareOptions);
427443
}
@@ -430,7 +446,7 @@ internal virtual T Compare<T>(
430446
DiffModifiers diffOptions,
431447
IEnumerable<string> paths = null,
432448
ExplicitPathsOptions explicitPathsOptions = null,
433-
CompareOptions compareOptions = null) where T : class, IDiffResult<T>, new()
449+
CompareOptions compareOptions = null) where T : class, IDiffResult
434450
{
435451
var comparer = WorkdirToIndex(repo);
436452

@@ -446,10 +462,7 @@ internal virtual T Compare<T>(
446462

447463
using (DiffSafeHandle diff = BuildDiffList(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions))
448464
{
449-
using (var proxy = new DiffSafeHandleProxy(diff))
450-
{
451-
return new T().FromNative(proxy);
452-
}
465+
return BuildDiffResult<T>(diff);
453466
}
454467
}
455468

LibGit2Sharp/DiffSafeHandleProxy.cs

Lines changed: 0 additions & 25 deletions
This file was deleted.

LibGit2Sharp/IDiffResult.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
using System;
2-
3-
namespace LibGit2Sharp
1+
namespace LibGit2Sharp
42
{
5-
public interface IDiffResult<T> where T:class
6-
{
7-
T FromNative(DiffSafeHandleProxy diff);
8-
}
3+
public interface IDiffResult
4+
{ }
95
}
106

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,6 @@
381381
<Compile Include="Core\GitCertificateSshType.cs" />
382382
<Compile Include="CertificateSsh.cs" />
383383
<Compile Include="IDiffResult.cs" />
384-
<Compile Include="DiffSafeHandleProxy.cs" />
385384
</ItemGroup>
386385
<ItemGroup>
387386
<CodeAnalysisDictionary Include="CustomDictionary.xml" />

LibGit2Sharp/Patch.cs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace LibGit2Sharp
1616
/// deleted, modified, ..., then consider using a simpler <see cref="TreeChanges"/>.</para>
1717
/// </summary>
1818
[DebuggerDisplay("{DebuggerDisplay,nq}")]
19-
public class Patch : IEnumerable<PatchEntryChanges>, IDiffResult<Patch>
19+
public class Patch : IEnumerable<PatchEntryChanges>, IDiffResult
2020
{
2121
private readonly StringBuilder fullPatchBuilder = new StringBuilder();
2222

@@ -27,9 +27,23 @@ public class Patch : IEnumerable<PatchEntryChanges>, IDiffResult<Patch>
2727
/// <summary>
2828
/// Needed for mocking purposes.
2929
/// </summary>
30-
public Patch()
30+
protected Patch()
3131
{ }
3232

33+
internal Patch(DiffSafeHandle diff)
34+
{
35+
int count = Proxy.git_diff_num_deltas(diff);
36+
for (int i = 0; i < count; i++)
37+
{
38+
using (var patch = Proxy.git_patch_from_diff(diff, i))
39+
{
40+
var delta = Proxy.git_diff_get_delta(diff, i);
41+
AddFileChange(delta);
42+
Proxy.git_patch_print(patch, PrintCallBack);
43+
}
44+
}
45+
}
46+
3347
private void AddFileChange(GitDiffDelta delta)
3448
{
3549
var treeEntryChanges = new TreeEntryChanges(delta);
@@ -100,25 +114,6 @@ IEnumerator IEnumerable.GetEnumerator()
100114

101115
#endregion
102116

103-
#region IDiffResult implementation
104-
105-
Patch IDiffResult<Patch>.FromNative(DiffSafeHandleProxy diff)
106-
{
107-
int count = Proxy.git_diff_num_deltas(diff.nativeHandle);
108-
for (int i = 0; i < count; i++)
109-
{
110-
using (var patch = Proxy.git_patch_from_diff(diff.nativeHandle, i))
111-
{
112-
var delta = Proxy.git_diff_get_delta(diff.nativeHandle, i);
113-
AddFileChange(delta);
114-
Proxy.git_patch_print(patch, PrintCallBack);
115-
}
116-
}
117-
return this;
118-
}
119-
120-
#endregion
121-
122117
/// <summary>
123118
/// Gets the <see cref="ContentChanges"/> corresponding to the specified <paramref name="path"/>.
124119
/// </summary>

0 commit comments

Comments
 (0)