Skip to content

Commit c2d1815

Browse files
committed
make GitObject not implement IDisposable
This requires that all GitObjects eager load their properties. Handles to the C git objects are used and immediately closed now.
1 parent cfb05a9 commit c2d1815

File tree

3 files changed

+76
-94
lines changed

3 files changed

+76
-94
lines changed

LibGit2Sharp.Tests/RepositoryFixture.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,6 @@ public void CanCreateRepo()
4444
}
4545
}
4646

47-
[Test]
48-
public void CanDisposeObjects()
49-
{
50-
using (var repo = new Repository(Constants.TestRepoPath))
51-
{
52-
using (var commit = repo.Lookup(commitSha))
53-
{
54-
}
55-
}
56-
}
57-
5847
[Test]
5948
public void CanLookupByReference()
6049
{

LibGit2Sharp/Commit.cs

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,74 @@
33

44
namespace LibGit2Sharp
55
{
6+
/// <summary>
7+
/// A Commit
8+
/// </summary>
69
public class Commit : GitObject
710
{
811
//public Commit(Repository repo, Signature author, Signature committer, string message = null, Tree tree = null, IEnumerable<Commit> parents = null, string updateRefName = null)
912
//{
1013
//}
1114

12-
private Signature author;
13-
private Signature committer;
14-
private string message;
15-
private string messageShort;
15+
private readonly Repository repo;
1616
private List<Commit> parents;
1717

18-
internal Commit(IntPtr obj, ObjectId id = null)
18+
internal Commit(IntPtr obj, Repository repo, ObjectId id = null)
1919
: base(obj, id)
2020
{
21+
this.repo = repo;
22+
Message = NativeMethods.git_commit_message(obj);
23+
MessageShort = NativeMethods.git_commit_message_short(obj);
24+
Author = new Signature(NativeMethods.git_commit_author(obj));
25+
Committer = new Signature(NativeMethods.git_commit_committer(obj));
2126
}
2227

23-
public string Message
24-
{
25-
get { return message ?? (message = NativeMethods.git_commit_message(Obj)); }
26-
}
28+
/// <summary>
29+
/// Gets the commit message.
30+
/// </summary>
31+
public string Message { get; private set; }
2732

28-
public string MessageShort
29-
{
30-
get { return messageShort ?? (messageShort = NativeMethods.git_commit_message_short(Obj)); }
31-
}
33+
/// <summary>
34+
/// Gets the short commit message which is usually the first line of the commit.
35+
/// </summary>
36+
public string MessageShort { get; private set; }
3237

33-
public Signature Author
34-
{
35-
get { return author ?? (author = new Signature(NativeMethods.git_commit_author(Obj))); }
36-
}
38+
/// <summary>
39+
/// Gets the author of this commit.
40+
/// </summary>
41+
public Signature Author { get; private set; }
3742

38-
public Signature Committer
39-
{
40-
get { return committer ?? (committer = new Signature(NativeMethods.git_commit_committer(Obj))); }
41-
}
43+
/// <summary>
44+
/// Gets the committer.
45+
/// </summary>
46+
public Signature Committer { get; private set; }
4247

48+
/// <summary>
49+
/// Gets the parents of this commit. This property is lazy loaded and can throw an exception if the commit no longer exists in the repo.
50+
/// </summary>
4351
public List<Commit> Parents
4452
{
4553
get
4654
{
4755
if (parents == null)
4856
{
49-
IntPtr parentCommit;
50-
parents = new List<Commit>();
51-
for (uint i = 0; NativeMethods.git_commit_parent(out parentCommit, Obj, i) == (int) GitErrorCode.GIT_SUCCESS; i++)
57+
var oid = Id.Oid;
58+
IntPtr obj;
59+
var res = NativeMethods.git_object_lookup(out obj, repo.RepoPtr, ref oid, GitObjectType.Commit);
60+
Ensure.Success(res);
61+
62+
try
63+
{
64+
IntPtr parentCommit;
65+
parents = new List<Commit>();
66+
for (uint i = 0; NativeMethods.git_commit_parent(out parentCommit, obj, i) == (int) GitErrorCode.GIT_SUCCESS; i++)
67+
{
68+
parents.Add(new Commit(parentCommit, repo));
69+
}
70+
}
71+
finally
5272
{
53-
parents.Add(new Commit(parentCommit));
73+
NativeMethods.git_object_close(obj);
5474
}
5575
}
5676
return parents;

LibGit2Sharp/GitObject.cs

Lines changed: 31 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
namespace LibGit2Sharp
55
{
6-
public class GitObject : IDisposable
6+
/// <summary>
7+
/// A GitObject
8+
/// </summary>
9+
public class GitObject
710
{
811
public static GitObjectTypeMap TypeToTypeMap =
912
new GitObjectTypeMap
@@ -15,82 +18,60 @@ public class GitObject : IDisposable
1518
{typeof (GitObject), GitObjectType.Any},
1619
};
1720

18-
protected IntPtr Obj = IntPtr.Zero;
19-
private bool disposed;
20-
2121
protected GitObject(IntPtr obj, ObjectId id = null)
2222
{
23-
Obj = obj;
2423
if (id == null)
2524
{
26-
var ptr = NativeMethods.git_object_id(Obj);
27-
id = new ObjectId((GitOid)Marshal.PtrToStructure(ptr, typeof(GitOid)));
25+
var ptr = NativeMethods.git_object_id(obj);
26+
id = new ObjectId((GitOid) Marshal.PtrToStructure(ptr, typeof (GitOid)));
2827
}
2928
Id = id;
3029
}
3130

31+
/// <summary>
32+
/// Gets the id of this object
33+
/// </summary>
3234
public ObjectId Id { get; private set; }
3335

36+
/// <summary>
37+
/// Gets the 40 character sha1 of this object.
38+
/// </summary>
3439
public string Sha
3540
{
3641
get { return Id.Sha; }
3742
}
3843

39-
#region IDisposable Members
40-
41-
public void Dispose()
42-
{
43-
Dispose(true);
44-
GC.SuppressFinalize(this);
45-
}
46-
47-
#endregion
48-
4944
internal static GitObject CreateFromPtr(IntPtr obj, ObjectId id, Repository repo)
5045
{
51-
var type = NativeMethods.git_object_type(obj);
52-
switch (type)
53-
{
54-
case GitObjectType.Commit:
55-
return new Commit(obj, id);
56-
case GitObjectType.Tree:
57-
return new Tree(obj, id);
58-
case GitObjectType.Tag:
59-
return new Tag(obj, id);
60-
case GitObjectType.Blob:
61-
return new Blob(obj, id);
62-
default:
63-
return new GitObject(obj, id);
64-
}
65-
}
66-
67-
private void Dispose(bool disposing)
68-
{
69-
// Check to see if Dispose has already been called.
70-
if (!disposed)
46+
try
7147
{
72-
// If disposing equals true, dispose all managed
73-
// and unmanaged resources.
74-
if (disposing)
48+
var type = NativeMethods.git_object_type(obj);
49+
switch (type)
7550
{
76-
// Dispose managed resources.
51+
case GitObjectType.Commit:
52+
return new Commit(obj, repo, id);
53+
case GitObjectType.Tree:
54+
return new Tree(obj, id);
55+
case GitObjectType.Tag:
56+
return new Tag(obj, id);
57+
case GitObjectType.Blob:
58+
return new Blob(obj, id);
59+
default:
60+
return new GitObject(obj, id);
7761
}
78-
79-
// Call the appropriate methods to clean up
80-
// unmanaged resources here.
81-
NativeMethods.git_object_close(Obj);
82-
83-
// Note disposing has been done.
84-
disposed = true;
62+
}
63+
finally
64+
{
65+
NativeMethods.git_object_close(obj);
8566
}
8667
}
8768

8869
public override bool Equals(object obj)
8970
{
9071
if (ReferenceEquals(null, obj)) return false;
9172
if (ReferenceEquals(this, obj)) return true;
92-
if (obj.GetType() != typeof(GitObject)) return false;
93-
return Equals((GitObject)obj);
73+
if (obj.GetType() != typeof (GitObject)) return false;
74+
return Equals((GitObject) obj);
9475
}
9576

9677
public bool Equals(GitObject other)
@@ -100,14 +81,6 @@ public bool Equals(GitObject other)
10081
return other.Id.Equals(Id);
10182
}
10283

103-
~GitObject()
104-
{
105-
// Do not re-create Dispose clean-up code here.
106-
// Calling Dispose(false) is optimal in terms of
107-
// readability and maintainability.
108-
Dispose(false);
109-
}
110-
11184
public override int GetHashCode()
11285
{
11386
return Id.GetHashCode();

0 commit comments

Comments
 (0)