Skip to content

Commit a1da99d

Browse files
committed
Ensure disposal of all diff results
1 parent 7d1ba75 commit a1da99d

File tree

7 files changed

+583
-485
lines changed

7 files changed

+583
-485
lines changed

LibGit2Sharp.Tests/DiffTreeToTargetFixture.cs

Lines changed: 185 additions & 151 deletions
Large diffs are not rendered by default.

LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs

Lines changed: 247 additions & 201 deletions
Large diffs are not rendered by default.

LibGit2Sharp.Tests/DiffWorkdirToIndexFixture.cs

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ public void CanCompareTheWorkDirAgainstTheIndex()
3333
var path = SandboxStandardTestRepoGitDir();
3434
using (var repo = new Repository(path))
3535
{
36-
var changes = repo.Diff.Compare<TreeChanges>();
37-
38-
Assert.Equal(2, changes.Count());
39-
Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path);
40-
Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path);
36+
using (var changes = repo.Diff.Compare<TreeChanges>())
37+
{
38+
Assert.Equal(2, changes.Count());
39+
Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path);
40+
Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path);
41+
}
4142
}
4243
}
4344

@@ -51,11 +52,15 @@ public void CanCompareTheWorkDirAgainstTheIndexWithLaxUnmatchedExplicitPathsVali
5152
{
5253
Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath));
5354

54-
var changes = repo.Diff.Compare<TreeChanges>(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false });
55-
Assert.Equal(0, changes.Count());
55+
using (var changes = repo.Diff.Compare<TreeChanges>(new[] { relativePath }, false, new ExplicitPathsOptions { ShouldFailOnUnmatchedPath = false }))
56+
{
57+
Assert.Equal(0, changes.Count());
58+
}
5659

57-
changes = repo.Diff.Compare<TreeChanges>(new[] { relativePath });
58-
Assert.Equal(0, changes.Count());
60+
using (var changes = repo.Diff.Compare<TreeChanges>(new[] { relativePath }))
61+
{
62+
Assert.Equal(0, changes.Count());
63+
}
5964
}
6065
}
6166

@@ -85,12 +90,14 @@ public void CallbackForUnmatchedExplicitPathsIsCalledWhenSet(string relativePath
8590
{
8691
Assert.Equal(currentStatus, repo.RetrieveStatus(relativePath));
8792

88-
repo.Diff.Compare<TreeChanges>(new[] { relativePath }, false, new ExplicitPathsOptions
93+
using (var changes = repo.Diff.Compare<TreeChanges>(new[] { relativePath }, false, new ExplicitPathsOptions
8994
{
9095
ShouldFailOnUnmatchedPath = false,
91-
OnUnmatchedPath = callback.OnUnmatchedPath });
92-
93-
Assert.True(callback.WasCalled);
96+
OnUnmatchedPath = callback.OnUnmatchedPath
97+
}))
98+
{
99+
Assert.True(callback.WasCalled);
100+
}
94101
}
95102
}
96103

@@ -133,22 +140,24 @@ public void ComparingReliesOnProvidedConfigEntriesIfAny()
133140

134141
using (var repo = new Repository(path, options))
135142
{
136-
var changes = repo.Diff.Compare<TreeChanges>(new[] { file });
137-
138-
Assert.Equal(1, changes.Count());
143+
using (var changes = repo.Diff.Compare<TreeChanges>(new[] { file }))
144+
{
145+
Assert.Equal(1, changes.Count());
139146

140-
var change = changes.Modified.Single();
141-
Assert.Equal(Mode.ExecutableFile, change.OldMode);
142-
Assert.Equal(Mode.NonExecutableFile, change.Mode);
147+
var change = changes.Modified.Single();
148+
Assert.Equal(Mode.ExecutableFile, change.OldMode);
149+
Assert.Equal(Mode.NonExecutableFile, change.Mode);
150+
}
143151
}
144152

145153
options = BuildFakeSystemConfigFilemodeOption(scd, false);
146154

147155
using (var repo = new Repository(path, options))
148156
{
149-
var changes = repo.Diff.Compare<TreeChanges>(new[] { file });
150-
151-
Assert.Equal(0, changes.Count());
157+
using (var changes = repo.Diff.Compare<TreeChanges>(new[] { file }))
158+
{
159+
Assert.Equal(0, changes.Count());
160+
}
152161
}
153162
}
154163

@@ -178,12 +187,13 @@ public void CanCompareTheWorkDirAgainstTheIndexWithUntrackedFiles()
178187
var path = SandboxStandardTestRepoGitDir();
179188
using (var repo = new Repository(path))
180189
{
181-
var changes = repo.Diff.Compare<TreeChanges>(null, true);
182-
183-
Assert.Equal(3, changes.Count());
184-
Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path);
185-
Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path);
186-
Assert.Equal("new_untracked_file.txt", changes.Added.Single().Path);
190+
using (var changes = repo.Diff.Compare<TreeChanges>(null, true))
191+
{
192+
Assert.Equal(3, changes.Count());
193+
Assert.Equal("deleted_unstaged_file.txt", changes.Deleted.Single().Path);
194+
Assert.Equal("modified_unstaged_file.txt", changes.Modified.Single().Path);
195+
Assert.Equal("new_untracked_file.txt", changes.Added.Single().Path);
196+
}
187197
}
188198
}
189199
}

LibGit2Sharp.Tests/PatchStatsFixture.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ public void CanExtractStatisticsFromDiff()
1313
{
1414
var oldTree = repo.Lookup<Commit>("origin/packed-test").Tree;
1515
var newTree = repo.Lookup<Commit>("HEAD").Tree;
16-
var stats = repo.Diff.Compare<PatchStats>(oldTree, newTree);
16+
using (var stats = repo.Diff.Compare<PatchStats>(oldTree, newTree))
17+
{
18+
Assert.Equal(8, stats.TotalLinesAdded);
19+
Assert.Equal(1, stats.TotalLinesDeleted);
1720

18-
Assert.Equal(8, stats.TotalLinesAdded);
19-
Assert.Equal(1, stats.TotalLinesDeleted);
20-
21-
var contentStats = stats["new.txt"];
22-
Assert.Equal(1, contentStats.LinesAdded);
23-
Assert.Equal(1, contentStats.LinesDeleted);
21+
var contentStats = stats["new.txt"];
22+
Assert.Equal(1, contentStats.LinesAdded);
23+
Assert.Equal(1, contentStats.LinesDeleted);
24+
}
2425
}
2526
}
2627
}

LibGit2Sharp/Core/FileHistory.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,13 @@ private static void DetermineParentPaths(IRepository repo, Commit currentCommit,
163163

164164
private static string ParentPath(IRepository repo, Commit currentCommit, string currentPath, Commit parentCommit)
165165
{
166-
var treeChanges = repo.Diff.Compare<TreeChanges>(parentCommit.Tree, currentCommit.Tree);
167-
var treeEntryChanges = treeChanges.FirstOrDefault(c => c.Path == currentPath);
168-
return treeEntryChanges != null && treeEntryChanges.Status == ChangeKind.Renamed
169-
? treeEntryChanges.OldPath
170-
: currentPath;
166+
using (var treeChanges = repo.Diff.Compare<TreeChanges>(parentCommit.Tree, currentCommit.Tree))
167+
{
168+
var treeEntryChanges = treeChanges.FirstOrDefault(c => c.Path == currentPath);
169+
return treeEntryChanges != null && treeEntryChanges.Status == ChangeKind.Renamed
170+
? treeEntryChanges.OldPath
171+
: currentPath;
172+
}
171173
}
172174
}
173175
}

LibGit2Sharp/Index.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,10 @@ public virtual void Replace(Commit commit, IEnumerable<string> paths, ExplicitPa
323323
{
324324
Ensure.ArgumentNotNull(commit, "commit");
325325

326-
var changes = repo.Diff.Compare<TreeChanges>(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None });
327-
Replace(changes);
326+
using (var changes = repo.Diff.Compare<TreeChanges>(commit.Tree, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }))
327+
{
328+
Replace(changes);
329+
}
328330
}
329331
}
330332
}

LibGit2Sharp/Repository.cs

Lines changed: 94 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,64 +1709,65 @@ public void Stage(IEnumerable<string> paths, StageOptions stageOptions)
17091709
diffModifiers |= DiffModifiers.IncludeIgnored;
17101710
}
17111711

1712-
var changes = Diff.Compare<TreeChanges>(diffModifiers, paths, explicitPathsOptions,
1713-
new CompareOptions { Similarity = SimilarityOptions.None });
1714-
1715-
var unexpectedTypesOfChanges = changes
1716-
.Where(
1717-
tec => tec.Status != ChangeKind.Added &&
1718-
tec.Status != ChangeKind.Modified &&
1719-
tec.Status != ChangeKind.Conflicted &&
1720-
tec.Status != ChangeKind.Unmodified &&
1721-
tec.Status != ChangeKind.Deleted).ToList();
1722-
1723-
if (unexpectedTypesOfChanges.Count > 0)
1724-
{
1725-
throw new InvalidOperationException(
1726-
string.Format(CultureInfo.InvariantCulture,
1727-
"Entry '{0}' bears an unexpected ChangeKind '{1}'",
1728-
unexpectedTypesOfChanges[0].Path, unexpectedTypesOfChanges[0].Status));
1729-
}
1712+
using (var changes = Diff.Compare<TreeChanges>(diffModifiers, paths, explicitPathsOptions,
1713+
new CompareOptions { Similarity = SimilarityOptions.None }))
1714+
{
1715+
var unexpectedTypesOfChanges = changes
1716+
.Where(
1717+
tec => tec.Status != ChangeKind.Added &&
1718+
tec.Status != ChangeKind.Modified &&
1719+
tec.Status != ChangeKind.Conflicted &&
1720+
tec.Status != ChangeKind.Unmodified &&
1721+
tec.Status != ChangeKind.Deleted).ToList();
1722+
1723+
if (unexpectedTypesOfChanges.Count > 0)
1724+
{
1725+
throw new InvalidOperationException(
1726+
string.Format(CultureInfo.InvariantCulture,
1727+
"Entry '{0}' bears an unexpected ChangeKind '{1}'",
1728+
unexpectedTypesOfChanges[0].Path, unexpectedTypesOfChanges[0].Status));
1729+
}
17301730

1731-
/* Remove files from the index that don't exist on disk */
1732-
foreach (TreeEntryChanges treeEntryChanges in changes)
1733-
{
1734-
switch (treeEntryChanges.Status)
1731+
/* Remove files from the index that don't exist on disk */
1732+
foreach (TreeEntryChanges treeEntryChanges in changes)
17351733
{
1736-
case ChangeKind.Conflicted:
1737-
if (!treeEntryChanges.Exists)
1738-
{
1734+
switch (treeEntryChanges.Status)
1735+
{
1736+
case ChangeKind.Conflicted:
1737+
if (!treeEntryChanges.Exists)
1738+
{
1739+
RemoveFromIndex(treeEntryChanges.Path);
1740+
}
1741+
break;
1742+
1743+
case ChangeKind.Deleted:
17391744
RemoveFromIndex(treeEntryChanges.Path);
1740-
}
1741-
break;
1742-
1743-
case ChangeKind.Deleted:
1744-
RemoveFromIndex(treeEntryChanges.Path);
1745-
break;
1745+
break;
17461746

1747-
default:
1748-
continue;
1747+
default:
1748+
continue;
1749+
}
17491750
}
1750-
}
17511751

1752-
foreach (TreeEntryChanges treeEntryChanges in changes)
1753-
{
1754-
switch (treeEntryChanges.Status)
1752+
foreach (TreeEntryChanges treeEntryChanges in changes)
17551753
{
1756-
case ChangeKind.Added:
1757-
case ChangeKind.Modified:
1758-
AddToIndex(treeEntryChanges.Path);
1759-
break;
1760-
1761-
case ChangeKind.Conflicted:
1762-
if (treeEntryChanges.Exists)
1763-
{
1754+
switch (treeEntryChanges.Status)
1755+
{
1756+
case ChangeKind.Added:
1757+
case ChangeKind.Modified:
17641758
AddToIndex(treeEntryChanges.Path);
1765-
}
1766-
break;
1759+
break;
1760+
1761+
case ChangeKind.Conflicted:
1762+
if (treeEntryChanges.Exists)
1763+
{
1764+
AddToIndex(treeEntryChanges.Path);
1765+
}
1766+
break;
17671767

1768-
default:
1769-
continue;
1768+
default:
1769+
continue;
1770+
}
17701771
}
17711772
}
17721773

@@ -1802,9 +1803,10 @@ public void Unstage(IEnumerable<string> paths, ExplicitPathsOptions explicitPath
18021803

18031804
if (Info.IsHeadUnborn)
18041805
{
1805-
var changes = Diff.Compare<TreeChanges>(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None });
1806-
1807-
Index.Replace(changes);
1806+
using (var changes = Diff.Compare<TreeChanges>(null, DiffTargets.Index, paths, explicitPathsOptions, new CompareOptions { Similarity = SimilarityOptions.None }))
1807+
{
1808+
Index.Replace(changes);
1809+
}
18081810
}
18091811
else
18101812
{
@@ -2087,48 +2089,49 @@ private void RemoveFilesAndFolders(IEnumerable<string> pathsList)
20872089
private IEnumerable<string> RemoveStagedItems(IEnumerable<string> paths, bool removeFromWorkingDirectory = true, ExplicitPathsOptions explicitPathsOptions = null)
20882090
{
20892091
var removed = new List<string>();
2090-
var changes = Diff.Compare<TreeChanges>(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions);
2091-
2092-
foreach (var treeEntryChanges in changes)
2092+
using (var changes = Diff.Compare<TreeChanges>(DiffModifiers.IncludeUnmodified | DiffModifiers.IncludeUntracked, paths, explicitPathsOptions))
20932093
{
2094-
var status = RetrieveStatus(treeEntryChanges.Path);
2095-
2096-
switch (treeEntryChanges.Status)
2094+
foreach (var treeEntryChanges in changes)
20972095
{
2098-
case ChangeKind.Added:
2099-
case ChangeKind.Deleted:
2100-
removed.Add(RemoveFromIndex(treeEntryChanges.Path));
2101-
break;
2102-
2103-
case ChangeKind.Unmodified:
2104-
if (removeFromWorkingDirectory && (
2105-
status.HasFlag(FileStatus.ModifiedInIndex) ||
2106-
status.HasFlag(FileStatus.NewInIndex)))
2107-
{
2108-
throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.",
2109-
treeEntryChanges.Path);
2110-
}
2111-
removed.Add(RemoveFromIndex(treeEntryChanges.Path));
2112-
continue;
2113-
2114-
case ChangeKind.Modified:
2115-
if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex))
2116-
{
2117-
throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.",
2118-
treeEntryChanges.Path);
2119-
}
2120-
if (removeFromWorkingDirectory)
2121-
{
2122-
throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.",
2123-
treeEntryChanges.Path);
2124-
}
2125-
removed.Add(RemoveFromIndex(treeEntryChanges.Path));
2126-
continue;
2096+
var status = RetrieveStatus(treeEntryChanges.Path);
21272097

2128-
default:
2129-
throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.",
2130-
treeEntryChanges.Path,
2131-
treeEntryChanges.Status);
2098+
switch (treeEntryChanges.Status)
2099+
{
2100+
case ChangeKind.Added:
2101+
case ChangeKind.Deleted:
2102+
removed.Add(RemoveFromIndex(treeEntryChanges.Path));
2103+
break;
2104+
2105+
case ChangeKind.Unmodified:
2106+
if (removeFromWorkingDirectory && (
2107+
status.HasFlag(FileStatus.ModifiedInIndex) ||
2108+
status.HasFlag(FileStatus.NewInIndex)))
2109+
{
2110+
throw new RemoveFromIndexException("Unable to remove file '{0}', as it has changes staged in the index. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.",
2111+
treeEntryChanges.Path);
2112+
}
2113+
removed.Add(RemoveFromIndex(treeEntryChanges.Path));
2114+
continue;
2115+
2116+
case ChangeKind.Modified:
2117+
if (status.HasFlag(FileStatus.ModifiedInWorkdir) && status.HasFlag(FileStatus.ModifiedInIndex))
2118+
{
2119+
throw new RemoveFromIndexException("Unable to remove file '{0}', as it has staged content different from both the working directory and the HEAD.",
2120+
treeEntryChanges.Path);
2121+
}
2122+
if (removeFromWorkingDirectory)
2123+
{
2124+
throw new RemoveFromIndexException("Unable to remove file '{0}', as it has local modifications. You can call the Remove() method with removeFromWorkingDirectory=false if you want to remove it from the index only.",
2125+
treeEntryChanges.Path);
2126+
}
2127+
removed.Add(RemoveFromIndex(treeEntryChanges.Path));
2128+
continue;
2129+
2130+
default:
2131+
throw new RemoveFromIndexException("Unable to remove file '{0}'. Its current status is '{1}'.",
2132+
treeEntryChanges.Path,
2133+
treeEntryChanges.Status);
2134+
}
21322135
}
21332136
}
21342137

0 commit comments

Comments
 (0)