Skip to content

Commit 7750d5b

Browse files
yorahnulltoken
authored andcommitted
Move Fetch in Network namespace
1 parent 4cb81d1 commit 7750d5b

File tree

4 files changed

+81
-55
lines changed

4 files changed

+81
-55
lines changed

LibGit2Sharp.Tests/FetchFixture.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void CanFetchIntoAnEmptyRepository(string url)
3939
}
4040

4141
// Perform the actual fetch
42-
remote.Fetch(onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
42+
repo.Network.Fetch(remote, onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
4343

4444
// Verify the expected
4545
expectedFetchState.CheckUpdatedReferences(repo);
@@ -58,7 +58,7 @@ public void CanFetchIntoAnEmptyRepositoryWithCredentials()
5858
Remote remote = repo.Network.Remotes.Add(remoteName, Constants.PrivateRepoUrl);
5959

6060
// Perform the actual fetch
61-
remote.Fetch(credentials: new Credentials
61+
repo.Network.Fetch(remote, credentials: new Credentials
6262
{
6363
Username = Constants.PrivateRepoUsername,
6464
Password = Constants.PrivateRepoPassword
@@ -95,7 +95,7 @@ public void CanFetchAllTagsIntoAnEmptyRepository(string url)
9595
}
9696

9797
// Perform the actual fetch
98-
remote.Fetch(TagFetchMode.All, onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
98+
repo.Network.Fetch(remote, TagFetchMode.All, onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
9999

100100
// Verify the expected
101101
expectedFetchState.CheckUpdatedReferences(repo);

LibGit2Sharp/Network.cs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,78 @@ public virtual IEnumerable<DirectReference> ListReferences(Remote remote)
8989
return directReferences;
9090
}
9191

92+
/// <summary>
93+
/// Fetch from the <see cref = "Remote" />.
94+
/// </summary>
95+
/// <param name="remote">The remote to fetch</param>
96+
/// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param>
97+
/// <param name="onProgress">Progress callback. Corresponds to libgit2 progress callback.</param>
98+
/// <param name="onCompletion">Completion callback. Corresponds to libgit2 completion callback.</param>
99+
/// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param>
100+
/// <param name="onTransferProgress">Callback method that transfer progress will be reported through.
101+
/// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param>
102+
/// <param name="credentials">Credentials to use for username/password authentication.</param>
103+
public virtual void Fetch(
104+
Remote remote,
105+
TagFetchMode tagFetchMode = TagFetchMode.Auto,
106+
ProgressHandler onProgress = null,
107+
CompletionHandler onCompletion = null,
108+
UpdateTipsHandler onUpdateTips = null,
109+
TransferProgressHandler onTransferProgress = null,
110+
Credentials credentials = null)
111+
{
112+
Ensure.ArgumentNotNull(remote, "remote");
113+
114+
// We need to keep a reference to the git_cred_acquire_cb callback around
115+
// so it will not be garbage collected before we are done with it.
116+
// Note that we also have a GC.KeepAlive call at the end of the method.
117+
NativeMethods.git_cred_acquire_cb credentialCallback = null;
118+
119+
using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true))
120+
{
121+
var callbacks = new RemoteCallbacks(onProgress, onCompletion, onUpdateTips);
122+
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
123+
124+
Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode);
125+
126+
if (credentials != null)
127+
{
128+
credentialCallback = (out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload) =>
129+
NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password);
130+
131+
Proxy.git_remote_set_cred_acquire_cb(
132+
remoteHandle,
133+
credentialCallback,
134+
IntPtr.Zero);
135+
}
136+
137+
// It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of
138+
// the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation
139+
// to store a reference to the git_remote_callbacks structure this would introduce a subtle bug
140+
// where the managed layer could move the git_remote_callbacks to a different location in memory,
141+
// but libgit2 would still reference the old address.
142+
//
143+
// Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against
144+
// GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords.
145+
Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks);
146+
147+
try
148+
{
149+
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch);
150+
Proxy.git_remote_download(remoteHandle, onTransferProgress);
151+
Proxy.git_remote_update_tips(remoteHandle);
152+
}
153+
finally
154+
{
155+
Proxy.git_remote_disconnect(remoteHandle);
156+
}
157+
}
158+
159+
// To be safe, make sure the credential callback is kept until
160+
// alive until at least this point.
161+
GC.KeepAlive(credentialCallback);
162+
}
163+
92164
/// <summary>
93165
/// Push the objectish to the destination reference on the <see cref = "Remote" />.
94166
/// </summary>
@@ -205,7 +277,7 @@ public virtual void Push(
205277
}
206278
}
207279

208-
// To be safe, make sure the credential callback is kept until
280+
// To be safe, make sure the credential callback is kept
209281
// alive until at least this point.
210282
GC.KeepAlive(credentialCallback);
211283
}

LibGit2Sharp/Remote.cs

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ protected Remote()
2727
private Remote(Repository repository, string name, string url)
2828
{
2929
this.repository = repository;
30-
this.Name = name;
31-
this.Url = url;
30+
Name = name;
31+
Url = url;
3232
}
3333

3434
internal static Remote BuildFromPtr(RemoteSafeHandle handle, Repository repo)
@@ -61,6 +61,7 @@ internal static Remote BuildFromPtr(RemoteSafeHandle handle, Repository repo)
6161
/// <param name="onTransferProgress">Callback method that transfer progress will be reported through.
6262
/// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param>
6363
/// <param name="credentials">Credentials to use for username/password authentication.</param>
64+
[Obsolete("This method will be removed in the next release. Please use Repository.Network.Fetch() instead.")]
6465
public virtual void Fetch(
6566
TagFetchMode tagFetchMode = TagFetchMode.Auto,
6667
ProgressHandler onProgress = null,
@@ -69,54 +70,7 @@ public virtual void Fetch(
6970
TransferProgressHandler onTransferProgress = null,
7071
Credentials credentials = null)
7172
{
72-
// We need to keep a reference to the git_cred_acquire_cb callback around
73-
// so it will not be garbage collected before we are done with it.
74-
// Note that we also have a GC.KeepAlive call at the end of the method.
75-
NativeMethods.git_cred_acquire_cb credentialCallback = null;
76-
77-
using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, this.Name, true))
78-
{
79-
var callbacks = new RemoteCallbacks(onProgress, onCompletion, onUpdateTips);
80-
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
81-
82-
Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode);
83-
84-
if (credentials != null)
85-
{
86-
credentialCallback = (out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload) =>
87-
NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password);
88-
89-
Proxy.git_remote_set_cred_acquire_cb(
90-
remoteHandle,
91-
credentialCallback,
92-
IntPtr.Zero);
93-
}
94-
95-
// It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of
96-
// the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation
97-
// to store a reference to the git_remote_callbacks structure this would introduce a subtle bug
98-
// where the managed layer could move the git_remote_callbacks to a different location in memory,
99-
// but libgit2 would still reference the old address.
100-
//
101-
// Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against
102-
// GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords.
103-
Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks);
104-
105-
try
106-
{
107-
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch);
108-
Proxy.git_remote_download(remoteHandle, onTransferProgress);
109-
Proxy.git_remote_update_tips(remoteHandle);
110-
}
111-
finally
112-
{
113-
Proxy.git_remote_disconnect(remoteHandle);
114-
}
115-
}
116-
117-
// To be safe, make sure the credential callback is kept until
118-
// alive until at least this point.
119-
GC.KeepAlive(credentialCallback);
73+
repository.Network.Fetch(this, tagFetchMode, onProgress, onCompletion, onUpdateTips, onTransferProgress, credentials);
12074
}
12175

12276
/// <summary>

LibGit2Sharp/RepositoryExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public static void Fetch(this IRepository repository, string remoteName,
216216
Ensure.ArgumentNotNullOrEmptyString(remoteName, "remoteName");
217217

218218
Remote remote = repository.Network.Remotes.RemoteForName(remoteName, true);
219-
remote.Fetch(tagFetchMode, onProgress, onCompletion, onUpdateTips,
219+
repository.Network.Fetch(remote, tagFetchMode, onProgress, onCompletion, onUpdateTips,
220220
onTransferProgress, credentials);
221221
}
222222

0 commit comments

Comments
 (0)