Skip to content

Commit 4bb5f5f

Browse files
committed
Keep the remote and refspec handle around
Refspecs aren't just read-only, we need the objects around for some operations (added in a later commit). The memory is owned by the remote object so we need to keep that around as well.
1 parent 4b8d5ad commit 4bb5f5f

File tree

4 files changed

+63
-50
lines changed

4 files changed

+63
-50
lines changed

LibGit2Sharp/RefSpec.cs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Diagnostics;
1+
using System;
2+
using System.Diagnostics;
23
using System.Globalization;
34
using LibGit2Sharp.Core;
45
using LibGit2Sharp.Core.Handles;
@@ -11,17 +12,13 @@ namespace LibGit2Sharp
1112
[DebuggerDisplay("{DebuggerDisplay,nq}")]
1213
public class RefSpec
1314
{
14-
private RefSpec(string refSpec, RefSpecDirection direction, string source, string destination, bool forceUpdate)
15-
{
16-
Ensure.ArgumentNotNullOrEmptyString(refSpec, "refSpec");
17-
Ensure.ArgumentNotNull(source, "source");
18-
Ensure.ArgumentNotNull(destination, "destination");
15+
readonly Remote remote;
16+
readonly GitRefSpecHandle handle;
1917

20-
Specification = refSpec;
21-
Direction = direction;
22-
Source = source;
23-
Destination = destination;
24-
ForceUpdate = forceUpdate;
18+
internal RefSpec(Remote remote, GitRefSpecHandle handle)
19+
{
20+
this.remote = remote;
21+
this.handle = handle;
2522
}
2623

2724
/// <summary>
@@ -30,38 +27,60 @@ private RefSpec(string refSpec, RefSpecDirection direction, string source, strin
3027
protected RefSpec()
3128
{ }
3229

33-
internal static RefSpec BuildFromPtr(GitRefSpecHandle handle)
34-
{
35-
Ensure.ArgumentNotNull(handle, "handle");
36-
37-
return new RefSpec(Proxy.git_refspec_string(handle), Proxy.git_refspec_direction(handle),
38-
Proxy.git_refspec_src(handle), Proxy.git_refspec_dst(handle), Proxy.git_refspec_force(handle));
39-
}
40-
4130
/// <summary>
4231
/// Gets the pattern describing the mapping between remote and local references
4332
/// </summary>
44-
public virtual string Specification { get; private set; }
33+
public virtual string Specification
34+
{
35+
get
36+
{
37+
return Proxy.git_refspec_string(this.handle);
38+
}
39+
}
4540

4641
/// <summary>
4742
/// Indicates whether this <see cref="RefSpec"/> is intended to be used during a Push or Fetch operation
4843
/// </summary>
49-
public virtual RefSpecDirection Direction { get; private set; }
44+
public virtual RefSpecDirection Direction
45+
{
46+
get
47+
{
48+
return Proxy.git_refspec_direction(this.handle);
49+
}
50+
}
5051

5152
/// <summary>
5253
/// The source reference specifier
5354
/// </summary>
54-
public virtual string Source { get; private set; }
55+
public virtual string Source
56+
{
57+
get
58+
{
59+
return Proxy.git_refspec_src(this.handle);
60+
}
61+
}
5562

5663
/// <summary>
5764
/// The target reference specifier
5865
/// </summary>
59-
public virtual string Destination { get; private set; }
66+
public virtual string Destination
67+
{
68+
get
69+
{
70+
return Proxy.git_refspec_dst(this.handle);
71+
}
72+
}
6073

6174
/// <summary>
6275
/// Indicates whether the destination will be force-updated if fast-forwarding is not possible
6376
/// </summary>
64-
public virtual bool ForceUpdate { get; private set; }
77+
public virtual bool ForceUpdate
78+
{
79+
get
80+
{
81+
return Proxy.git_refspec_force(this.handle);
82+
}
83+
}
6584

6685
private string DebuggerDisplay
6786
{

LibGit2Sharp/RefSpecCollection.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,24 @@ public class RefSpecCollection : IEnumerable<RefSpec>
2222
protected RefSpecCollection()
2323
{ }
2424

25-
internal RefSpecCollection(RemoteSafeHandle handle)
25+
internal RefSpecCollection(Remote remote, RemoteSafeHandle handle)
2626
{
2727
Ensure.ArgumentNotNull(handle, "handle");
2828

29-
refspecs = RetrieveRefSpecs(handle);
29+
refspecs = RetrieveRefSpecs(remote, handle);
3030
}
3131

32-
static IList<RefSpec> RetrieveRefSpecs(RemoteSafeHandle remoteHandle)
32+
static IList<RefSpec> RetrieveRefSpecs(Remote remote, RemoteSafeHandle remoteHandle)
3333
{
3434
int count = Proxy.git_remote_refspec_count(remoteHandle);
3535
List<RefSpec> refSpecs = new List<RefSpec>();
3636

3737
for (int i = 0; i < count; i++)
3838
{
39-
using (GitRefSpecHandle handle = Proxy.git_remote_get_refspec(remoteHandle, i))
40-
{
41-
refSpecs.Add(RefSpec.BuildFromPtr(handle));
42-
}
39+
refSpecs.Add(new RefSpec(remote, Proxy.git_remote_get_refspec(remoteHandle, i)));
4340
}
4441

4542
return refSpecs;
46-
4743
}
4844

4945
/// <summary>

LibGit2Sharp/Remote.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,31 @@ public class Remote : IEquatable<Remote>, IBelongToARepository
2222
private readonly RefSpecCollection refSpecs;
2323
private string pushUrl;
2424

25+
readonly RemoteSafeHandle handle;
26+
2527
/// <summary>
2628
/// Needed for mocking purposes.
2729
/// </summary>
2830
protected Remote()
2931
{ }
3032

31-
private Remote(RemoteSafeHandle handle, Repository repository)
33+
internal Remote(RemoteSafeHandle handle, Repository repository)
3234
{
3335
this.repository = repository;
36+
this.handle = handle;
3437
Name = Proxy.git_remote_name(handle);
3538
Url = Proxy.git_remote_url(handle);
3639
PushUrl = Proxy.git_remote_pushurl(handle);
3740
TagFetchMode = Proxy.git_remote_autotag(handle);
38-
refSpecs = new RefSpecCollection(handle);
41+
refSpecs = new RefSpecCollection(this, handle);
3942
}
4043

41-
internal static Remote BuildFromPtr(RemoteSafeHandle handle, Repository repo)
44+
~Remote()
4245
{
43-
var remote = new Remote(handle, repo);
44-
45-
return remote;
46+
if (handle != null)
47+
{
48+
handle.Dispose();
49+
}
4650
}
4751

4852
/// <summary>

LibGit2Sharp/RemoteCollection.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ internal Remote RemoteForName(string name, bool shouldThrowIfNotFound = true)
4343
{
4444
Ensure.ArgumentNotNull(name, "name");
4545

46-
using (RemoteSafeHandle handle = Proxy.git_remote_lookup(repository.Handle, name, shouldThrowIfNotFound))
47-
{
48-
return handle == null ? null : Remote.BuildFromPtr(handle, this.repository);
49-
}
46+
RemoteSafeHandle handle = Proxy.git_remote_lookup(repository.Handle, name, shouldThrowIfNotFound);
47+
return handle == null ? null : new Remote(handle, this.repository);
5048
}
5149

5250
/// <summary>
@@ -102,10 +100,8 @@ public virtual Remote Add(string name, string url)
102100
Ensure.ArgumentNotNull(name, "name");
103101
Ensure.ArgumentNotNull(url, "url");
104102

105-
using (RemoteSafeHandle handle = Proxy.git_remote_create(repository.Handle, name, url))
106-
{
107-
return Remote.BuildFromPtr(handle, this.repository);
108-
}
103+
RemoteSafeHandle handle = Proxy.git_remote_create(repository.Handle, name, url);
104+
return new Remote(handle, this.repository);
109105
}
110106

111107
/// <summary>
@@ -121,10 +117,8 @@ public virtual Remote Add(string name, string url, string fetchRefSpec)
121117
Ensure.ArgumentNotNull(url, "url");
122118
Ensure.ArgumentNotNull(fetchRefSpec, "fetchRefSpec");
123119

124-
using (RemoteSafeHandle handle = Proxy.git_remote_create_with_fetchspec(repository.Handle, name, url, fetchRefSpec))
125-
{
126-
return Remote.BuildFromPtr(handle, this.repository);
127-
}
120+
RemoteSafeHandle handle = Proxy.git_remote_create_with_fetchspec(repository.Handle, name, url, fetchRefSpec);
121+
return new Remote(handle, this.repository);
128122
}
129123

130124
/// <summary>

0 commit comments

Comments
 (0)