Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e1b6166

Browse files
committed
Introduce RemoteCollection.Rename.
1 parent 05e6633 commit e1b6166

File tree

5 files changed

+156
-0
lines changed

5 files changed

+156
-0
lines changed

LibGit2Sharp.Tests/RemoteFixture.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,5 +214,95 @@ public void CanDeleteNonExistingRemote()
214214
repo.Network.Remotes.Remove("i_dont_exist");
215215
}
216216
}
217+
218+
[Fact]
219+
public void CanRenameExistingRemote()
220+
{
221+
var path = CloneStandardTestRepo();
222+
using (var repo = new Repository(path))
223+
{
224+
Assert.NotNull(repo.Network.Remotes["origin"]);
225+
Assert.Null(repo.Network.Remotes["renamed"]);
226+
Assert.NotEmpty(repo.Refs.FromGlob("refs/remotes/origin/*"));
227+
Assert.Empty(repo.Refs.FromGlob("refs/remotes/renamed/*"));
228+
229+
repo.Network.Remotes.Rename("origin", "renamed", problem => Assert.True(false));
230+
Assert.Null(repo.Network.Remotes["origin"]);
231+
Assert.Empty(repo.Refs.FromGlob("refs/remotes/origin/*"));
232+
233+
Assert.NotNull(repo.Network.Remotes["renamed"]);
234+
Assert.NotEmpty(repo.Refs.FromGlob("refs/remotes/renamed/*"));
235+
}
236+
}
237+
238+
[Fact]
239+
public void CanRenameNonExistingRemote()
240+
{
241+
using (var repo = new Repository(StandardTestRepoPath))
242+
{
243+
Assert.Null(repo.Network.Remotes["i_dont_exist"]);
244+
245+
repo.Network.Remotes.Rename("i_dont_exist", "i_dont_either", problem => Assert.True(false));
246+
Assert.Null(repo.Network.Remotes["i_dont_either"]);
247+
}
248+
}
249+
250+
[Fact]
251+
public void ReportsRemotesWithNonDefaultRefSpecs()
252+
{
253+
var path = CloneStandardTestRepo();
254+
using (var repo = new Repository(path))
255+
{
256+
Assert.NotNull(repo.Network.Remotes["origin"]);
257+
258+
repo.Network.Remotes.Update(
259+
repo.Network.Remotes["origin"],
260+
r => r.FetchRefSpecs = new[] { "+refs/heads/*:refs/remotes/upstream/*" });
261+
262+
repo.Network.Remotes.Rename("origin", "nondefault", problem => Assert.Equal("+refs/heads/*:refs/remotes/upstream/*", problem));
263+
264+
Assert.NotEmpty(repo.Refs.FromGlob("refs/remotes/nondefault/*"));
265+
Assert.Empty(repo.Refs.FromGlob("refs/remotes/upstream/*"));
266+
267+
Assert.Null(repo.Network.Remotes["origin"]);
268+
Assert.NotNull(repo.Network.Remotes["nondefault"]);
269+
}
270+
}
271+
272+
[Fact]
273+
public void DoesNotReportRemotesWithAlreadyExistingRefSpec()
274+
{
275+
var path = CloneStandardTestRepo();
276+
using (var repo = new Repository(path))
277+
{
278+
Assert.NotNull(repo.Network.Remotes["origin"]);
279+
280+
repo.Refs.Add("refs/remotes/renamed/master", "32eab9cb1f450b5fe7ab663462b77d7f4b703344");
281+
282+
repo.Network.Remotes.Rename("origin", "renamed", problem => Assert.True(false));
283+
284+
Assert.NotEmpty(repo.Refs.FromGlob("refs/remotes/renamed/*"));
285+
Assert.Empty(repo.Refs.FromGlob("refs/remotes/origin/*"));
286+
287+
Assert.Null(repo.Network.Remotes["origin"]);
288+
Assert.NotNull(repo.Network.Remotes["renamed"]);
289+
}
290+
}
291+
292+
[Fact]
293+
public void CanNotRenameWhenRemoteWithSameNameExists()
294+
{
295+
const string name = "upstream";
296+
const string url = "https://github.com/libgit2/libgit2sharp.git";
297+
298+
var path = CloneStandardTestRepo();
299+
using (var repo = new Repository(path))
300+
{
301+
Assert.NotNull(repo.Network.Remotes["origin"]);
302+
repo.Network.Remotes.Add(name, url);
303+
304+
Assert.Throws<NameConflictException>(() => repo.Network.Remotes.Rename("origin", "upstream"));
305+
}
306+
}
217307
}
218308
}

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,17 @@ internal static extern int git_branch_remote_name(
212212
RepositorySafeHandle repo,
213213
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string canonical_branch_name);
214214

215+
[DllImport(libgit2)]
216+
internal static extern int git_remote_rename(
217+
RemoteSafeHandle remote,
218+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string new_name,
219+
git_remote_rename_problem_cb callback,
220+
IntPtr payload);
221+
222+
internal delegate int git_remote_rename_problem_cb(
223+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(LaxUtf8NoCleanupMarshaler))] string problematic_refspec,
224+
IntPtr payload);
225+
215226
[DllImport(libgit2)]
216227
internal static extern int git_branch_upstream_name(
217228
GitBuf buf,

LibGit2Sharp/Core/Proxy.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Runtime.InteropServices;
77
using System.Threading;
88
using LibGit2Sharp.Core.Handles;
9+
using LibGit2Sharp.Handlers;
910

1011
// ReSharper disable InconsistentNaming
1112
namespace LibGit2Sharp.Core
@@ -1958,6 +1959,33 @@ public static string git_remote_name(RemoteSafeHandle remote)
19581959
return NativeMethods.git_remote_name(remote);
19591960
}
19601961

1962+
public static void git_remote_rename(RepositorySafeHandle repo, string name, string new_name, RemoteRenameFailureHandler callback)
1963+
{
1964+
using (ThreadAffinity())
1965+
{
1966+
using (RemoteSafeHandle remote = git_remote_load(repo, name, false))
1967+
{
1968+
if (remote == null)
1969+
{
1970+
return;
1971+
}
1972+
1973+
if (callback == null)
1974+
{
1975+
callback = (problem) => {};
1976+
}
1977+
1978+
int res = NativeMethods.git_remote_rename(
1979+
remote,
1980+
new_name,
1981+
(problem, payload) => { callback(problem); return 0; },
1982+
IntPtr.Zero);
1983+
1984+
Ensure.ZeroResult(res);
1985+
}
1986+
}
1987+
}
1988+
19611989
public static void git_remote_save(RemoteSafeHandle remote)
19621990
{
19631991
using (ThreadAffinity())

LibGit2Sharp/Handlers.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@
7878
/// <param name="unmatchedPath">The unmatched path.</param>
7979
public delegate void UnmatchedPathHandler(string unmatchedPath);
8080

81+
/// <summary>
82+
/// Delegate definition for remote rename failure callback.
83+
/// <para>
84+
/// This callback will be called to notify the caller of fetch refspecs
85+
/// that haven't been automatically updated and need potential manual tweaking.
86+
/// </para>
87+
/// </summary>
88+
/// <param name="problematicRefspec">The refspec which didn't match the default.</param>
89+
public delegate void RemoteRenameFailureHandler(string problematicRefspec);
90+
8191
/// <summary>
8292
/// The stages of pack building.
8393
/// </summary>

LibGit2Sharp/RemoteCollection.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using LibGit2Sharp.Core;
88
using LibGit2Sharp.Core.Handles;
9+
using LibGit2Sharp.Handlers;
910

1011
namespace LibGit2Sharp
1112
{
@@ -138,6 +139,22 @@ public virtual void Remove(string name)
138139
Proxy.git_remote_delete(repository.Handle, name);
139140
}
140141

142+
/// <summary>
143+
/// Renames an existing <see cref="Remote"/>.
144+
/// </summary>
145+
/// <param name="name">The current remote name.</param>
146+
/// <param name="newName">The new name the existing remote should bear.</param>
147+
/// <param name"renameCallback">The callback to be used when problems with renaming occur. (e.g. non-default fetch refspecs)</para>
148+
/// <returns>A new <see cref="Remote"/>.</returns>
149+
public virtual Remote Rename(string name, string newName, RemoteRenameFailureHandler callback = null)
150+
{
151+
Ensure.ArgumentNotNull(name, "name");
152+
Ensure.ArgumentNotNull(newName, "newName");
153+
154+
Proxy.git_remote_rename(repository.Handle, name, newName, callback);
155+
return this[newName];
156+
}
157+
141158
private string DebuggerDisplay
142159
{
143160
get

0 commit comments

Comments
 (0)