Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Teach Remote to transform references using its default fetchspec #349

Closed
wants to merge 1 commit into from

3 participants

@jamill
Collaborator

Expose the refspec transform for a remote's default fetchspec.

@nulltoken
Owner

@jamill Could you please share some information describing when this feature should be used from the consumer standpoint?

@jamill
Collaborator

@nulltoken This can be used to identify the remote branch that a local branch would track when it is pushed up to the server. With the current API to set the upstream tracking branch, you have to pass in the reference to the tracked branch. This means to push up a new branch (refs/heads/new_branch) and set the upstream, you need to know the upstream branch that it will correspond to (through this transformation).

After pushing this up, I think a better way to achieve this is to expose a way to set the upstream remote / merge branch directly on a local branch (so, I could set the merge branch directly as refs/heads/new_branch on a local branch). I will submit a new PR exposing this functionality shortly.

This method still could still be useful if you wanted to check what a local branch's remote branch would be...

@jamill
Collaborator

@nulltoken - with #353, I don't think this functionality is explicity required for my scenario - but it does work and might be useful later on (or to someone else). Howe would you like to proceed? Is this functionality something that might be useful?

@nulltoken
Owner

It looks a little bit low level, but I'd hate ditching this. Can you think about a user scenario which would require such feature?
On a different topic, I'm not a huge fan of the names of the functions. How about something like MapTo[Source|Target]Reference?

/cc @carlosmn @dahlbyk

@yorah yorah referenced this pull request
Merged

Add Push overloads #385

1 of 2 tasks complete
@yorah

@jamill I included part of this PR in #385 (Remote.FetchSpecTransformToSource()). Do you see other use cases for which we would need to implement Remote.FetchSpecTransformToTarget() in libgit2sharp?

If the answer is no, maybe we could close this issue :)

@jamill
Collaborator

I don't have other use cases for this at this time. I will close it now. Thanks.

@jamill jamill closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
24 LibGit2Sharp.Tests/RemoteFixture.cs
@@ -236,5 +236,29 @@ public void CanTellIfARemoteNameIsValid(string refname, bool expectedResult)
Assert.Equal(expectedResult, repo.Network.Remotes.IsValidName(refname));
}
}
+
+ [Fact]
+ public void CanFetchSpecTransformReferenceToTarget()
+ {
+ TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoPath);
+ using (var repo = new Repository(StandardTestRepoPath))
+ {
+ Remote remote = repo.Network.Remotes["origin"];
+ Assert.NotNull(remote);
+ Assert.Equal("refs/remotes/origin/test", remote.FetchSpecTransformToTarget("refs/heads/test"));
+ }
+ }
+
+ [Fact]
+ public void CanFetchSpecTransformReferenceToSource()
+ {
+ TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoPath);
+ using (var repo = new Repository(StandardTestRepoPath))
+ {
+ Remote remote = repo.Network.Remotes["origin"];
+ Assert.NotNull(remote);
+ Assert.Equal("refs/heads/test", remote.FetchSpecTransformToSource("refs/remotes/origin/test"));
+ }
+ }
}
}
View
9 LibGit2Sharp/Core/NativeMethods.cs
@@ -670,8 +670,15 @@ private static bool IsRunningOnLinux()
internal static extern GitReferenceType git_reference_type(ReferenceSafeHandle reference);
[DllImport(libgit2)]
+ internal static extern int git_refspec_transform(
+ byte[] reference,
+ UIntPtr outlen,
+ GitFetchSpecHandle refSpec,
+ [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string name);
+
+ [DllImport(libgit2)]
internal static extern int git_refspec_rtransform(
- byte[] target,
+ byte[] reference,
UIntPtr outlen,
GitFetchSpecHandle refSpec,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string name);
View
15 LibGit2Sharp/Core/Proxy.cs
@@ -1252,6 +1252,21 @@ public static GitReferenceType git_reference_type(ReferenceSafeHandle reference)
#region git_refspec
+ public static string git_fetchspec_transform(GitFetchSpecHandle refSpecPtr, string name)
+ {
+ using (ThreadAffinity())
+ {
+ // libgit2 API does not support querying for required buffer size.
+ // Use a sufficiently large buffer until it does.
+ var buffer = new byte[1024];
+
+ int res = NativeMethods.git_refspec_transform(buffer, (UIntPtr)buffer.Length, refSpecPtr, name);
+ Ensure.ZeroResult(res);
+
+ return Utf8Marshaler.Utf8FromBuffer(buffer) ?? string.Empty;
+ }
+ }
+
public static string git_fetchspec_rtransform(GitFetchSpecHandle refSpecPtr, string name)
{
using (ThreadAffinity())
View
28 LibGit2Sharp/Remote.cs
@@ -52,6 +52,34 @@ internal static Remote BuildFromPtr(RemoteSafeHandle handle, Repository repo)
public virtual string Url { get; private set; }
/// <summary>
+ /// Transform a reference to its target reference using the <see cref = "Remote" />'s default fetchspec.
+ /// </summary>
+ /// <param name="reference">The reference to transform.</param>
+ /// <returns>The transformed reference.</returns>
+ public virtual string FetchSpecTransformToTarget(string reference)
+ {
+ using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, Name, true))
+ {
+ GitFetchSpecHandle fetchSpecPtr = Proxy.git_remote_fetchspec(remoteHandle);
+ return Proxy.git_fetchspec_transform(fetchSpecPtr, reference);
+ }
+ }
+
+ /// <summary>
+ /// Transform a reference to its source reference using the <see cref = "Remote" />'s default fetchspec.
+ /// </summary>
+ /// <param name="reference">The reference to transform.</param>
+ /// <returns>The transformed reference.</returns>
+ public virtual string FetchSpecTransformToSource(string reference)
+ {
+ using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, Name, true))
+ {
+ GitFetchSpecHandle fetchSpecPtr = Proxy.git_remote_fetchspec(remoteHandle);
+ return Proxy.git_fetchspec_rtransform(fetchSpecPtr, reference);
+ }
+ }
+
+ /// <summary>
/// Fetch from the <see cref = "Remote" />.
/// </summary>
/// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param>
Something went wrong with that request. Please try again.