8000 Properly handle unmanaged resources cleanup in Repository constructor · JanKrivanek/libgit2sharp@cb1abb4 · GitHub
[go: up one dir, main page]

Skip to content

Commit cb1abb4

Browse files
yorahnulltoken
authored andcommitted
Properly handle unmanaged resources cleanup in Repository constructor
1 parent b845bb9 commit cb1abb4

File tree

2 files changed

+66
-50
lines changed

2 files changed

+66
-50
lines changed

LibGit2Sharp.Tests/RepositoryOptionsFixture.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,8 @@ public void CanProvideADifferentIndexToAStandardRepo()
9696
[Fact]
9797
public void OpeningABareRepoWithoutProvidingBothWorkDirAndIndexThrows()
9898
{
99-
Repository repo;
100-
101-
Assert.Throws<ArgumentException>(() => repo = new Repository(BareTestRepoPath, new RepositoryOptions { IndexPath = newIndex }));
102-
Assert.Throws<ArgumentException>(() => repo = new Repository(BareTestRepoPath, new RepositoryOptions { WorkingDirectoryPath = newWorkdir }));
99+
Assert.Throws<ArgumentException>(() => new Repository(BareTestRepoPath, new RepositoryOptions {IndexPath = newIndex}));
100+
Assert.Throws<ArgumentException>(() => new Repository(BareTestRepoPath, new RepositoryOptions {WorkingDirectoryPath = newWorkdir}));
103101
}
104102

105103
[Fact]

LibGit2Sharp/Repository.cs

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -52,63 +52,76 @@ public Repository(string path, RepositoryOptions options = null)
5252
{
5353
Ensure.ArgumentNotNullOrEmptyString(path, "path");
5454

55-
handle = Proxy.git_repository_open(path);
56-
RegisterForCleanup(handle);
57-
58-
isBare = Proxy.git_repository_is_bare(handle);
55+
try
56+
{
57+
handle = Proxy.git_repository_open(path);
58+
RegisterForCleanup(handle);
5959

60-
Func<Index> indexBuilder = () => new Index(this);
60+
isBare = Proxy.git_repository_is_bare(handle);
6161

62-
string configurationGlobalFilePath = null;
63-
string configurationXDGFilePath = null;
64-
string configurationSystemFilePath = null;
62+
Func<Index> indexBuilder = () => new Index(this);
6563

66-
if (options != null)
67-
{
68-
bool isWorkDirNull = string.IsNullOrEmpty(options.WorkingDirectoryPath);
69-
bool isIndexNull = string.IsNullOrEmpty(options.IndexPath);
64+
string configurationGlobalFilePath = null;
65+
string configurationXDGFilePath = null;
66+
string configurationSystemFilePath = null;
7067

71-
if (isBare && (isWorkDirNull ^ isIndexNull))
68+
if (options != null)
7269
{
73-
throw new ArgumentException("When overriding the opening of a bare repository, both RepositoryOptions.WorkingDirectoryPath an RepositoryOptions.IndexPath have to be provided.");
74-
}
70+
bool isWorkDirNull = string.IsNullOrEmpty(options.WorkingDirectoryPath);
71+
bool isIndexNull = string.IsNullOrEmpty(options.IndexPath);
7572

76-
isBare = false;
73+
if (isBare && (isWorkDirNull ^ isIndexNull))
74+
{
75+
throw new ArgumentException(
76+
"When overriding the opening of a bare repository, both RepositoryOptions.WorkingDirectoryPath an RepositoryOptions.IndexPath have to be provided.");
77+
}
7778

78-
if (!isIndexNull)
79-
{
80-
indexBuilder = () => new Index(this, options.IndexPath);
79+
isBare = false;
80+
81+
if (!isIndexNull)
82+
{
83+
indexBuilder = () => new Index(this, options.IndexPath);
84+
}
85+
86+
if (!isWorkDirNull)
87+
{
88+
Proxy.git_repository_set_workdir(handle, options.WorkingDirectoryPath);
89+
}
90+
91+
configurationGlobalFilePath = options.GlobalConfigurationLocation;
92+
configurationXDGFilePath = options.XdgConfigurationLocation;
93+
configurationSystemFilePath = options.SystemConfigurationLocation;
8194
}
8295

83-
if (!isWorkDirNull)
96+
if (!isBare)
8497
{
85-
Proxy.git_repository_set_workdir(handle, options.WorkingDirectoryPath);
98+
index = indexBuilder();
99+
conflicts = new ConflictCollection(this);
86100
}
87101

88-
configurationGlobalFilePath = options.GlobalConfigurationLocation;
89-
configurationXDGFilePath = options.XdgConfigurationLocation;
90-
configurationSystemFilePath = options.SystemConfigurationLocation;
91-
}
102+
commits = new CommitLog(this);
103+
refs = new ReferenceCollection(this);
104+
branches = new BranchCollection(this);
105+
tags = new TagCollection(this);
106+
info = new Lazy<RepositoryInformation>(() => new RepositoryInformation(this, isBare));
107+
config =
108+
new Lazy<Configuration>(
109+
() =>
110+
RegisterForCleanup(new Configuration(this, configurationGlobalFilePath, configurationXDGFilePath,
111+
configurationSystemFilePath)));
112+
odb = new Lazy<ObjectDatabase>(() => new ObjectDatabase(this));
113+
diff = new Diff(this);
114+
notes = new NoteCollection(this);
115+
ignore = new Ignore(this);
116+
network = new Lazy<Network>(() => new Network(this));
92117

93-
if (!isBare)
118+
EagerlyLoadTheConfigIfAnyPathHaveBeenPassed(options);
119+
}
120+
catch
94121
{
95-
index = indexBuilder();
96-
conflicts = new ConflictCollection(this);
122+
CleanupDisposableDependencies();
123+
throw;
97124
}
98-
< F438 /td>
99-
commits = new CommitLog(this);
100-
refs = new ReferenceCollection(this);
101-
branches = new BranchCollection(this);
102-
tags = new TagCollection(this);
103-
info = new Lazy<RepositoryInformation>(() => new RepositoryInformation(this, isBare));
104-
config = new Lazy<Configuration>(() => RegisterForCleanup(new Configuration(this, configurationGlobalFilePath, configurationXDGFilePath, configurationSystemFilePath)));
105-
odb = new Lazy<ObjectDatabase>(() => new ObjectDatabase(this));
106-
diff = new Diff(this);
107-
notes = new NoteCollection(this);
108-
ignore = new Ignore(this);
109-
network = new Lazy<Network>(() => new Network(this));
110-
111-
EagerlyLoadTheConfigIfAnyPathHaveBeenPassed(options);
112125
}
113126

114127
private void EagerlyLoadTheConfigIfAnyPathHaveBeenPassed(RepositoryOptions options)
@@ -312,10 +325,7 @@ public void Dispose()
312325
/// </summary>
313326
protected virtual void Dispose(bool disposing)
314327
{
315-
while (toCleanup.Count > 0)
316-
{
317-
toCleanup.Pop().SafeDispose();
318-
}
328+
CleanupDisposableDependencies();
319329
}
320330

321331
#endregion
@@ -701,6 +711,14 @@ public virtual void RemoveUntrackedFiles()
701711
Proxy.git_checkout_index(Handle, new NullGitObjectSafeHandle(), ref options);
702712
}
703713

714+
private void CleanupDisposableDependencies()
715+
{
716+
while (toCleanup.Count > 0)
717+
{
718+
toCleanup.Pop().SafeDispose();
719+
}
720+
}
721+
704722
internal T RegisterForCleanup<T>(T disposable) where T : IDisposable
705723
{
706724
toCleanup.Push(disposable);

0 commit comments

Comments
 (0)
0