Skip to content

Commit f7222d2

Browse files
committed
Make all DiffResults disposable, move ownership of diff handle
This will let us perform lazy loading of details in these classes, just as we do with commits and some other classes.
1 parent 3615df9 commit f7222d2

File tree

5 files changed

+93
-26
lines changed

5 files changed

+93
-26
lines changed

LibGit2Sharp/Diff.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,17 @@ public virtual T Compare<T>(Tree oldTree, Tree newTree, IEnumerable<string> path
241241
}
242242
}
243243

244-
using (DiffSafeHandle diff = BuildDiffList(oldTreeId, newTreeId, comparer, diffOptions, paths, explicitPathsOptions, compareOptions))
244+
DiffSafeHandle diff = BuildDiffList(oldTreeId, newTreeId, comparer, diffOptions, paths, explicitPathsOptions, compareOptions);
245+
246+
try
245247
{
246248
return BuildDiffResult<T>(diff);
247249
}
250+
catch
251+
{
252+
diff.SafeDispose();
253+
throw;
254+
}
248255
}
249256

250257
/// <summary>
@@ -343,10 +350,17 @@ public virtual T Compare<T>(Tree oldTree, DiffTargets diffTargets, IEnumerable<s
343350
}
344351
}
345352

346-
using (DiffSafeHandle diff = BuildDiffList(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions))
353+
DiffSafeHandle diff = BuildDiffList(oldTreeId, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions);
354+
355+
try
347356
{
348357
return BuildDiffResult<T>(diff);
349358
}
359+
catch
360+
{
361+
diff.SafeDispose();
362+
throw;
363+
}
350364
}
351365

352366
/// <summary>
@@ -462,10 +476,17 @@ internal virtual T Compare<T>(
462476
}
463477
}
464478

465-
using (DiffSafeHandle diff = BuildDiffList(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions))
479+
DiffSafeHandle diff = BuildDiffList(null, null, comparer, diffOptions, paths, explicitPathsOptions, compareOptions);
480+
481+
try
466482
{
467483
return BuildDiffResult<T>(diff);
468484
}
485+
catch
486+
{
487+
diff.SafeDispose();
488+
throw;
489+
}
469490
}
470491

471492
internal delegate DiffSafeHandle TreeComparisonHandleRetriever(ObjectId oldTreeId, ObjectId newTreeId, GitDiffOptions options);

LibGit2Sharp/IDiffResult.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
namespace LibGit2Sharp
1+
using System;
2+
3+
namespace LibGit2Sharp
24
{
35
/// <summary>
46
/// Marker interface to identify Diff results.
57
/// </summary>
6-
public interface IDiffResult
8+
public interface IDiffResult: IDisposable
79
{ }
810
}

LibGit2Sharp/Patch.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,17 @@ protected Patch()
3232

3333
internal Patch(DiffSafeHandle diff)
3434
{
35-
int count = Proxy.git_diff_num_deltas(diff);
36-
for (int i = 0; i < count; i++)
35+
using (diff)
3736
{
38-
using (var patch = Proxy.git_patch_from_diff(diff, i))
37+
int count = Proxy.git_diff_num_deltas(diff);
38+
for (int i = 0; i < count; i++)
3939
{
40-
var delta = Proxy.git_diff_get_delta(diff, i);
41-
AddFileChange(delta);
42-
Proxy.git_patch_print(patch, PrintCallBack);
40+
using (var patch = Proxy.git_patch_from_diff(diff, i))
41+
{
42+
var delta = Proxy.git_diff_get_delta(diff, i);
43+
AddFileChange(delta);
44+
Proxy.git_patch_print(patch, PrintCallBack);
45+
}
4346
}
4447
}
4548
}
@@ -180,5 +183,17 @@ private string DebuggerDisplay
180183
linesDeleted);
181184
}
182185
}
186+
187+
public void Dispose()
188+
{
189+
Dispose(true);
190+
GC.SuppressFinalize(this);
191+
}
192+
193+
protected virtual void Dispose(bool disposing)
194+
{
195+
// This doesn't do anything yet because it loads everything
196+
// eagerly and disposes of the diff handle in the constructor.
197+
}
183198
}
184199
}

LibGit2Sharp/PatchStats.cs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ namespace LibGit2Sharp
1515
[DebuggerDisplay("{DebuggerDisplay,nq}")]
1616
public class PatchStats : IEnumerable<ContentChangeStats>, IDiffResult
1717
{
18+
private readonly DiffSafeHandle diff;
19+
1820
private readonly IDictionary<FilePath, ContentChangeStats> changes = new Dictionary<FilePath, ContentChangeStats>();
1921
private readonly int totalLinesAdded;
2022
private readonly int totalLinesDeleted;
@@ -27,23 +29,25 @@ protected PatchStats()
2729

2830
internal PatchStats(DiffSafeHandle diff)
2931
{
30-
int count = Proxy.git_diff_num_deltas(diff);
31-
for (int i = 0; i < count; i++)
32+
using (diff)
3233
{
33-
using (var patch = Proxy.git_patch_from_diff(diff, i))
34+
int count = Proxy.git_diff_num_deltas(diff);
35+
for (int i = 0; i < count; i++)
3436
{
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-
}
37+
using (var patch = Proxy.git_patch_from_diff(diff, i))
38+
{
39+
var delta = Proxy.git_diff_get_delta(diff, i);
40+
var pathPtr = delta.NewFile.Path != IntPtr.Zero ? delta.NewFile.Path : delta.OldFile.Path;
41+
var newFilePath = LaxFilePathMarshaler.FromNative(pathPtr);
4642

43+
var stats = Proxy.git_patch_line_stats(patch);
44+
int added = stats.Item1;
45+
int deleted = stats.Item2;
46+
changes.Add(newFilePath, new ContentChangeStats(added, deleted));
47+
totalLinesAdded += added;
48+
totalLinesDeleted += deleted;
49+
}
50+
}
4751
}
4852
}
4953

@@ -117,5 +121,17 @@ private string DebuggerDisplay
117121
TotalLinesDeleted);
118122
}
119123
}
124+
125+
public void Dispose()
126+
{
127+
Dispose(true);
128+
GC.SuppressFinalize(this);
129+
}
130+
131+
protected virtual void Dispose(bool disposing)
132+
{
133+
// This doesn't do anything yet because it loads everything
134+
// eagerly and disposes of the diff handle in the constructor.
135+
}
120136
}
121137
}

LibGit2Sharp/TreeChanges.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ protected TreeChanges()
5252

5353
internal TreeChanges(DiffSafeHandle diff)
5454
{
55-
Proxy.git_diff_foreach(diff, FileCallback, null, null);
55+
using(diff)
56+
Proxy.git_diff_foreach(diff, FileCallback, null, null);
5657
}
5758

5859
private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload)
@@ -169,5 +170,17 @@ private string DebuggerDisplay
169170
Copied.Count());
170171
}
171172
}
173+
174+
public void Dispose()
175+
{
176+
Dispose(true);
177+
GC.SuppressFinalize(this);
178+
}
179+
180+
protected virtual void Dispose(bool disposing)
181+
{
182+
// This doesn't do anything yet because it loads everything
183+
// eagerly and disposes of the diff handle in the constructor.
184+
}
172185
}
173186
}

0 commit comments

Comments
 (0)