diff --git a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs
index f639a0d8..1b7b0e66 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,18 +24,28 @@ public static GitRepositoryInitOptions BuildFrom(FilePath workdirPath, bool isBa
Mode = 0 /* GIT_REPOSITORY_INIT_SHARED_UMASK */
};
- if (workdirPath != null)
+ if (initOptions == null)
{
- Debug.Assert(!isBare);
+ return opts;
+ }
+
+ if (initOptions.WorkdirPath != null)
+ {
+ 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;
}
+ if (initOptions.InitialHead != null)
+ {
+ opts.InitialHead = StrictUtf8Marshaler.FromManaged(initOptions.InitialHead);
+ }
+
return opts;
}
@@ -43,6 +53,9 @@ public void Dispose()
{
EncodingMarshaler.Cleanup(WorkDirPath);
WorkDirPath = IntPtr.Zero;
+
+ EncodingMarshaler.Cleanup(InitialHead);
+ InitialHead = IntPtr.Zero;
}
}
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..b9b0db93 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);
@@ -2470,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/InitOptions.cs b/LibGit2Sharp/InitOptions.cs
new file mode 100644
index 00000000..6b3f3486
--- /dev/null
+++ b/LibGit2Sharp/InitOptions.cs
@@ -0,0 +1,41 @@
+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.
+ /// Default initial head.
+ ///
+ ///
+ public InitOptions()
+ {
+ WorkdirPath = null;
+ IsBare = false;
+ InitialHead = null;
+ }
+
+ ///
+ /// 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; }
+
+ ///
+ /// 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; }
+ }
+}
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index b6399af4..e705522f 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -495,11 +495,9 @@ public static string Init(string path, bool isBare)
{
Ensure.ArgumentNotNullOrEmptyString(path, "path");
- using (RepositoryHandle repo = Proxy.git_repository_init_ext(null, path, isBare))
- {
- FilePath repoPath = Proxy.git_repository_path(repo);
- return repoPath.Native;
- }
+ var initOptions = new InitOptions { IsBare = isBare };
+
+ return Init(path, initOptions);
}
///
@@ -518,9 +516,28 @@ 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 (RepositoryHandle repo = Proxy.git_repository_init_ext(wd, gitDirectoryPath, false))
+ 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;
@@ -675,22 +692,47 @@ public static IEnumerable ListRemoteReferences(string url, Credential
Ensure.ArgumentNotNull(url, "url");
using (RepositoryHandle repositoryHandle = Proxy.git_repository_new())
- using (RemoteHandle remoteHandle = Proxy.git_remote_create_anonymous(repositoryHandle, url))
+ using (RemoteHandle remoteHandle = ConnectToAnonymousRemote(repositoryHandle, url, credentialsProvider))
{
- var gitCallbacks = new GitRemoteCallbacks { version = 1 };
- var proxyOptions = new GitProxyOptions { Version = 1 };
+ return Proxy.git_remote_ls(null, remoteHandle);
+ }
+ }
- if (credentialsProvider != null)
- {
- var callbacks = new RemoteCallbacks(credentialsProvider);
- gitCallbacks = callbacks.GenerateCallbacks();
- }
+ ///
+ /// Retrieves the name of the Remote Repository's default branch.
+ ///
+ /// The url to retrieve from.
+ /// The used to connect to remote repository.
+ /// The reference name.
+ public static string GetRemoteDefaultBranch(string url, CredentialsHandler credentialsProvider)
+ {
+ Ensure.ArgumentNotNull(url, "url");
- Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions);
- return Proxy.git_remote_ls(null, remoteHandle);
+ using (RepositoryHandle repositoryHandle = Proxy.git_repository_new())
+ using (RemoteHandle remoteHandle = ConnectToAnonymousRemote(repositoryHandle, url, credentialsProvider))
+ {
+ return Proxy.git_remote_default_branch(remoteHandle);
}
}
+ private static RemoteHandle ConnectToAnonymousRemote(RepositoryHandle repositoryHandle, string url, CredentialsHandler credentialsProvider)
+ {
+ RemoteHandle remoteHandle = Proxy.git_remote_create_anonymous(repositoryHandle, url);
+
+ var gitCallbacks = new GitRemoteCallbacks { version = 1 };
+ var proxyOptions = new GitProxyOptions { Version = 1 };
+
+ if (credentialsProvider != null)
+ {
+ var callbacks = new RemoteCallbacks(credentialsProvider);
+ gitCallbacks = callbacks.GenerateCallbacks();
+ }
+
+ Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions);
+
+ return remoteHandle;
+ }
+
///
/// Probe for a git repository.
/// The lookup start from and walk upward parent directories if nothing has been found.
diff --git a/version.json b/version.json
index 36406d69..1514aa02 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.10",
"cloudBuild": {
"buildNumber": {
"enabled": true