From 3ee9c06595522e60fec42d2136247827815a3afc Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Tue, 2 Feb 2021 17:27:20 +0100
Subject: [PATCH 1/8] Add support to retrieve remote repository's default
branch
The default branch is returned as an out parameter from ListRemoteReferences method
---
LibGit2Sharp/Core/NativeMethods.cs | 5 ++++
LibGit2Sharp/Core/Proxy.cs | 11 +++++++++
LibGit2Sharp/Repository.cs | 39 +++++++++++++++++++++++++++++-
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs
index 7dd99ac3..9fdd5db7 100644
--- a/LibGit2Sharp/Core/NativeMethods.cs
+++ b/LibGit2Sharp/Core/NativeMethods.cs
@@ -1261,6 +1261,11 @@ internal static extern unsafe int git_remote_create_with_fetchspec(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string url,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string refspec);
+ [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern unsafe int git_remote_default_branch(
+ GitBuf res,
+ git_remote* remote);
+
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_remote_delete(
git_repository* repo,
diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs
index fd070f45..d70229e1 100644
--- a/LibGit2Sharp/Core/Proxy.cs
+++ b/LibGit2Sharp/Core/Proxy.cs
@@ -2167,6 +2167,17 @@ public static unsafe void git_remote_connect(RemoteHandle remote, GitDirection d
}
}
+ public static unsafe string git_remote_default_branch(RemoteHandle remote)
+ {
+ using (var buf = new GitBuf())
+ {
+ int res = NativeMethods.git_remote_default_branch(buf, remote);
+ Ensure.ZeroResult(res);
+
+ return LaxUtf8Marshaler.FromNative(buf.ptr);
+ }
+ }
+
public static unsafe void git_remote_delete(RepositoryHandle repo, string name)
{
int res = NativeMethods.git_remote_delete(repo, name);
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index b6399af4..31dce56e 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -656,7 +656,24 @@ internal Commit LookupCommit(string committish)
/// The references in the remote repository.
public static IEnumerable ListRemoteReferences(string url)
{
- return ListRemoteReferences(url, null);
+ string _defaultBranch;
+ return ListRemoteReferences(url, null, out _defaultBranch);
+ }
+
+ ///
+ /// Lists the Remote Repository References.
+ ///
+ ///
+ /// Does not require a local Repository. The retrieved
+ ///
+ /// throws in this case.
+ ///
+ /// The url to list from.
+ /// The name of the Repository's default branch.
+ /// The references in the remote repository.
+ public static IEnumerable ListRemoteReferences(string url, out string defaultBranch)
+ {
+ return ListRemoteReferences(url, null, out defaultBranch);
}
///
@@ -671,6 +688,24 @@ public static IEnumerable ListRemoteReferences(string url)
/// The used to connect to remote repository.
/// The references in the remote repository.
public static IEnumerable ListRemoteReferences(string url, CredentialsHandler credentialsProvider)
+ {
+ string _defaultBranch;
+ return ListRemoteReferences(url, credentialsProvider, out _defaultBranch);
+ }
+
+ ///
+ /// Lists the Remote Repository References.
+ ///
+ ///
+ /// Does not require a local Repository. The retrieved
+ ///
+ /// throws in this case.
+ ///
+ /// The url to list from.
+ /// The used to connect to remote repository.
+ /// The name of the Repository's default branch.
+ /// The references in the remote repository.
+ public static IEnumerable ListRemoteReferences(string url, CredentialsHandler credentialsProvider, out string defaultBranch)
{
Ensure.ArgumentNotNull(url, "url");
@@ -687,6 +722,8 @@ public static IEnumerable ListRemoteReferences(string url, Credential
}
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions);
+
+ defaultBranch = Proxy.git_remote_default_branch(remoteHandle);
return Proxy.git_remote_ls(null, remoteHandle);
}
}
From 3deea953ff231ea85d132d33a5acc943c74c871a Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Tue, 2 Feb 2021 17:51:57 +0100
Subject: [PATCH 2/8] Update version
---
version.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/version.json b/version.json
index 36406d69..762c232a 100644
--- a/version.json
+++ b/version.json
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
- "version": "1.110.2",
+ "version": "1.110.3",
"cloudBuild": {
"buildNumber": {
"enabled": true
From 0f11e62ffab78ea6097299c545bc5afd6072c1d3 Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Sun, 7 Feb 2021 21:00:42 +0100
Subject: [PATCH 3/8] Call git_remote_ls first for better troubleshooting
---
LibGit2Sharp/Repository.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index 31dce56e..0fb302f8 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -723,8 +723,10 @@ public static IEnumerable ListRemoteReferences(string url, Credential
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions);
+ var remoteReferences = Proxy.git_remote_ls(null, remoteHandle);
defaultBranch = Proxy.git_remote_default_branch(remoteHandle);
- return Proxy.git_remote_ls(null, remoteHandle);
+
+ return remoteReferences;
}
}
From ce40cc955c134976c3a9eb2385af2d7f931530f2 Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Thu, 18 Feb 2021 15:38:52 +0100
Subject: [PATCH 4/8] Pass GitRepositoryInitOptions directly to Proxy
---
LibGit2Sharp/Core/Proxy.cs | 14 +++++---------
LibGit2Sharp/Repository.cs | 6 ++++--
2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs
index d70229e1..b9b0db93 100644
--- a/LibGit2Sharp/Core/Proxy.cs
+++ b/LibGit2Sharp/Core/Proxy.cs
@@ -2481,18 +2481,14 @@ public static unsafe IndexHandle git_repository_index(RepositoryHandle repo)
}
public static unsafe RepositoryHandle git_repository_init_ext(
- FilePath workdirPath,
FilePath gitdirPath,
- bool isBare)
+ GitRepositoryInitOptions opts)
{
- using (var opts = GitRepositoryInitOptions.BuildFrom(workdirPath, isBare))
- {
- git_repository* repo;
- int res = NativeMethods.git_repository_init_ext(out repo, gitdirPath, opts);
- Ensure.ZeroResult(res);
+ git_repository* repo;
+ int res = NativeMethods.git_repository_init_ext(out repo, gitdirPath, opts);
+ Ensure.ZeroResult(res);
- return new RepositoryHandle(repo, true);
- }
+ return new RepositoryHandle(repo, true);
}
public static unsafe bool git_repository_is_bare(RepositoryHandle repo)
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index 0fb302f8..3cced1bf 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -495,7 +495,8 @@ public static string Init(string path, bool isBare)
{
Ensure.ArgumentNotNullOrEmptyString(path, "path");
- using (RepositoryHandle repo = Proxy.git_repository_init_ext(null, path, isBare))
+ using (var opts = GitRepositoryInitOptions.BuildFrom(null, isBare))
+ using (RepositoryHandle repo = Proxy.git_repository_init_ext(path, opts))
{
FilePath repoPath = Proxy.git_repository_path(repo);
return repoPath.Native;
@@ -520,7 +521,8 @@ public static string Init(string workingDirectoryPath, string gitDirectoryPath)
// TODO: Shouldn't we ensure that the working folder isn't under the gitDir?
- using (RepositoryHandle repo = Proxy.git_repository_init_ext(wd, gitDirectoryPath, false))
+ using (var opts = GitRepositoryInitOptions.BuildFrom(wd, false))
+ using (RepositoryHandle repo = Proxy.git_repository_init_ext(gitDirectoryPath, opts))
{
FilePath repoPath = Proxy.git_repository_path(repo);
return repoPath.Native;
From ce7427967a8c90c58bbe6b2c8777211e36e6d718 Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Thu, 18 Feb 2021 15:51:34 +0100
Subject: [PATCH 5/8] Introduce InitOptions for Repository.Init
---
LibGit2Sharp/Core/GitRepositoryInitOptions.cs | 10 +++---
LibGit2Sharp/InitOptions.cs | 32 +++++++++++++++++++
LibGit2Sharp/Repository.cs | 8 +++--
3 files changed, 43 insertions(+), 7 deletions(-)
create mode 100644 LibGit2Sharp/InitOptions.cs
diff --git a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
index f639a0d8..a0fb27de 100644
--- a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
+++ b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
@@ -16,7 +16,7 @@ internal class GitRepositoryInitOptions : IDisposable
public IntPtr InitialHead;
public IntPtr OriginUrl;
- public static GitRepositoryInitOptions BuildFrom(FilePath workdirPath, bool isBare)
+ public static GitRepositoryInitOptions BuildFrom(InitOptions initOptions)
{
var opts = new GitRepositoryInitOptions
{
@@ -24,14 +24,14 @@ public static GitRepositoryInitOptions BuildFrom(FilePath workdirPath, bool isBa
Mode = 0 /* GIT_REPOSITORY_INIT_SHARED_UMASK */
};
- if (workdirPath != null)
+ if (initOptions.WorkdirPath != null)
{
- Debug.Assert(!isBare);
+ Debug.Assert(!initOptions.IsBare);
- opts.WorkDirPath = StrictFilePathMarshaler.FromManaged(workdirPath);
+ opts.WorkDirPath = StrictFilePathMarshaler.FromManaged(initOptions.WorkdirPath);
}
- if (isBare)
+ if (initOptions.IsBare)
{
opts.Flags |= GitRepositoryInitFlags.GIT_REPOSITORY_INIT_BARE;
}
diff --git a/LibGit2Sharp/InitOptions.cs b/LibGit2Sharp/InitOptions.cs
new file mode 100644
index 00000000..7d773965
--- /dev/null
+++ b/LibGit2Sharp/InitOptions.cs
@@ -0,0 +1,32 @@
+namespace LibGit2Sharp
+{
+ ///
+ /// Options controlling Repository Init behavior.
+ ///
+ public sealed class InitOptions
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Default behavior:
+ /// The workdirPath is null.
+ /// Not a bare repository.
+ ///
+ ///
+ public InitOptions()
+ {
+ WorkdirPath = null;
+ IsBare = false;
+ }
+
+ ///
+ /// The path to the working directory. Null if it's the same directory where ".git" repository is created.
+ ///
+ public string WorkdirPath { get; set; }
+
+ ///
+ /// True to initialize a bare repository. False otherwise, to initialize a standard ".git" repository.
+ ///
+ public bool IsBare { get; set; }
+ }
+}
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index 3cced1bf..aed4b28c 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -495,7 +495,9 @@ public static string Init(string path, bool isBare)
{
Ensure.ArgumentNotNullOrEmptyString(path, "path");
- using (var opts = GitRepositoryInitOptions.BuildFrom(null, isBare))
+ var initOptions = new InitOptions { IsBare = isBare };
+
+ using (var opts = GitRepositoryInitOptions.BuildFrom(initOptions))
using (RepositoryHandle repo = Proxy.git_repository_init_ext(path, opts))
{
FilePath repoPath = Proxy.git_repository_path(repo);
@@ -519,9 +521,11 @@ public static string Init(string workingDirectoryPath, string gitDirectoryPath)
// to pass a path relatively to his current directory.
string wd = Path.GetFullPath(workingDirectoryPath);
+ var initOptions = new InitOptions { WorkdirPath = wd };
+
// TODO: Shouldn't we ensure that the working folder isn't under the gitDir?
- using (var opts = GitRepositoryInitOptions.BuildFrom(wd, false))
+ using (var opts = GitRepositoryInitOptions.BuildFrom(initOptions))
using (RepositoryHandle repo = Proxy.git_repository_init_ext(gitDirectoryPath, opts))
{
FilePath repoPath = Proxy.git_repository_path(repo);
From b5f6042bfe607ec5328b0c0a9885411797536fd8 Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Thu, 18 Feb 2021 15:59:48 +0100
Subject: [PATCH 6/8] Add Repository.Init method accepting InitOptions
---
LibGit2Sharp/Repository.cs | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index aed4b28c..e67fca74 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -496,13 +496,8 @@ public static string Init(string path, bool isBare)
Ensure.ArgumentNotNullOrEmptyString(path, "path");
var initOptions = new InitOptions { IsBare = isBare };
-
- using (var opts = GitRepositoryInitOptions.BuildFrom(initOptions))
- using (RepositoryHandle repo = Proxy.git_repository_init_ext(path, opts))
- {
- FilePath repoPath = Proxy.git_repository_path(repo);
- return repoPath.Native;
- }
+
+ return Init(path, initOptions);
}
///
@@ -525,8 +520,24 @@ public static string Init(string workingDirectoryPath, string gitDirectoryPath)
// TODO: Shouldn't we ensure that the working folder isn't under the gitDir?
- using (var opts = GitRepositoryInitOptions.BuildFrom(initOptions))
- using (RepositoryHandle repo = Proxy.git_repository_init_ext(gitDirectoryPath, opts))
+ return Init(gitDirectoryPath, initOptions);
+ }
+
+ ///
+ /// Initialize a repository at the specified ,
+ /// providing optional behavioral overrides through the parameter.
+ ///
+ /// The path to the working folder when initializing a standard ".git" repository. Otherwise, when initializing a bare repository, the path to the expected location of this later.
+ /// Options controlling init behavior.
+ /// The path to the created repository.
+ public static string Init(string path, InitOptions options)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(path, "path");
+
+ options = options ?? new InitOptions();
+
+ using (var opts = GitRepositoryInitOptions.BuildFrom(options))
+ using (RepositoryHandle repo = Proxy.git_repository_init_ext(path, opts))
{
FilePath repoPath = Proxy.git_repository_path(repo);
return repoPath.Native;
From c7706079f2d3c58e24e465eea9b37ad057b7277b Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Thu, 18 Feb 2021 16:08:30 +0100
Subject: [PATCH 7/8] Add an option to set initial head to InitOptions
---
LibGit2Sharp/Core/GitRepositoryInitOptions.cs | 8 ++++++++
LibGit2Sharp/InitOptions.cs | 9 +++++++++
2 files changed, 17 insertions(+)
diff --git a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
index a0fb27de..5c1b1134 100644
--- a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
+++ b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
@@ -36,6 +36,11 @@ public static GitRepositoryInitOptions BuildFrom(InitOptions initOptions)
opts.Flags |= GitRepositoryInitFlags.GIT_REPOSITORY_INIT_BARE;
}
+ if (initOptions.InitialHead != null)
+ {
+ opts.InitialHead = StrictUtf8Marshaler.FromManaged(initOptions.InitialHead);
+ }
+
return opts;
}
@@ -43,6 +48,9 @@ public void Dispose()
{
EncodingMarshaler.Cleanup(WorkDirPath);
WorkDirPath = IntPtr.Zero;
+
+ EncodingMarshaler.Cleanup(InitialHead);
+ InitialHead = IntPtr.Zero;
}
}
diff --git a/LibGit2Sharp/InitOptions.cs b/LibGit2Sharp/InitOptions.cs
index 7d773965..6b3f3486 100644
--- a/LibGit2Sharp/InitOptions.cs
+++ b/LibGit2Sharp/InitOptions.cs
@@ -11,12 +11,14 @@ public sealed class InitOptions
/// Default behavior:
/// The workdirPath is null.
/// Not a bare repository.
+ /// Default initial head.
///
///
public InitOptions()
{
WorkdirPath = null;
IsBare = false;
+ InitialHead = null;
}
///
@@ -28,5 +30,12 @@ public InitOptions()
/// True to initialize a bare repository. False otherwise, to initialize a standard ".git" repository.
///
public bool IsBare { get; set; }
+
+ ///
+ /// The name of the head to point HEAD at.
+ /// If null, then this will be treated as "master" and the HEAD ref will be set to "refs/heads/master".
+ /// If this begins with "refs/" it will be used verbatim; otherwise "refs/heads/" will be prefixed.
+ ///
+ public string InitialHead { get; set; }
}
}
From 3178472bd862fd9971fba65c477699620f999f23 Mon Sep 17 00:00:00 2001
From: Alexander Ovchinnikov
<56644701+A-Ovchinnikov-mx@users.noreply.github.com>
Date: Mon, 22 Feb 2021 14:39:48 +0100
Subject: [PATCH 8/8] Review: initOptions null check
---
LibGit2Sharp/Core/GitRepositoryInitOptions.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
index 5c1b1134..1b7b0e66 100644
--- a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
+++ b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
@@ -24,6 +24,11 @@ public static GitRepositoryInitOptions BuildFrom(InitOptions initOptions)
Mode = 0 /* GIT_REPOSITORY_INIT_SHARED_UMASK */
};
+ if (initOptions == null)
+ {
+ return opts;
+ }
+
if (initOptions.WorkdirPath != null)
{
Debug.Assert(!initOptions.IsBare);