Skip to content

Commit

Permalink
Add support to pass "initial head" on repo init
Browse files Browse the repository at this point in the history
  • Loading branch information
zentron committed Dec 3, 2021
1 parent 4daf618 commit a08b0ad
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 9 deletions.
21 changes: 21 additions & 0 deletions LibGit2Sharp.Tests/RepositoryFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,27 @@ public void CanCreateStandardRepoAndDirectlySpecifyAGitDirectory()
}
}

[Fact]
public void CanCreateStandardRepoAndDefineCustomHead()
{
var scd1 = BuildSelfCleaningDirectory();
var scd2 = BuildSelfCleaningDirectory();

var gitDir = Path.Combine(scd2.DirectoryPath, ".git/");

string repoPath = Repository.Init(scd1.DirectoryPath, gitDir, new InitOptions(){ InitialHead = "monkey"});

Assert.True(Repository.IsValid(repoPath));

using (var repo = new Repository(repoPath))
{
Assert.True(Repository.IsValid(repo.Info.WorkingDirectory));
Assert.True(Repository.IsValid(repo.Info.Path));

Assert.Equal("monkey", repo.Head.FriendlyName);
}
}

private static void CheckGitConfigFile(string dir)
{
string configFilePath = Path.Combine(dir, "config");
Expand Down
7 changes: 6 additions & 1 deletion LibGit2Sharp/Core/GitRepositoryInitOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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(FilePath workdirPath, bool isBare, string initialHead)
{
var opts = new GitRepositoryInitOptions
{
Expand All @@ -31,6 +31,11 @@ public static GitRepositoryInitOptions BuildFrom(FilePath workdirPath, bool isBa
opts.WorkDirPath = StrictFilePathMarshaler.FromManaged(workdirPath);
}

if (!string.IsNullOrEmpty(initialHead))
{
opts.InitialHead = StrictUtf8Marshaler.FromManaged(initialHead);
}

if (isBare)
{
opts.Flags |= GitRepositoryInitFlags.GIT_REPOSITORY_INIT_BARE;
Expand Down
5 changes: 3 additions & 2 deletions LibGit2Sharp/Core/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2480,9 +2480,10 @@ public static unsafe IndexHandle git_repository_index(RepositoryHandle repo)
public static unsafe RepositoryHandle git_repository_init_ext(
FilePath workdirPath,
FilePath gitdirPath,
bool isBare)
bool isBare,
string initialHead)
{
using (var opts = GitRepositoryInitOptions.BuildFrom(workdirPath, isBare))
using (var opts = GitRepositoryInitOptions.BuildFrom(workdirPath, isBare, initialHead))
{
git_repository* repo;
int res = NativeMethods.git_repository_init_ext(out repo, gitdirPath, opts);
Expand Down
14 changes: 14 additions & 0 deletions LibGit2Sharp/InitOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace LibGit2Sharp
{
/// <summary>
/// Optional parameters when invoking Init.
/// </summary>
public sealed class InitOptions
{
/// <summary>
/// Use the specified name for the initial branch in the newly created repository.
/// If not specified, fall back to the default name
/// </summary>
public string InitialHead { get; set; }
}
}
37 changes: 31 additions & 6 deletions LibGit2Sharp/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ private void Dispose(bool disposing)
/// <returns>The path to the created repository.</returns>
public static string Init(string path)
{
return Init(path, false);
return Init(path, false, new InitOptions());
}

/// <summary>
Expand All @@ -492,10 +492,34 @@ public static string Init(string path)
/// <param name="isBare">true to initialize a bare repository. False otherwise, to initialize a standard ".git" repository.</param>
/// <returns>The path to the created repository.</returns>
public static string Init(string path, bool isBare)
{
return Init(path, isBare, new InitOptions());
}


/// <summary>
/// Initialize a repository by explictly setting the path to both the working directory and the git directory.
/// </summary>
/// <param name="workingDirectoryPath">The path to the working directory.</param>
/// <param name="gitDirectoryPath">The path to the git repository to be created.</param>
/// <returns>The path to the created repository.</returns>
public static string Init(string workingDirectoryPath, string gitDirectoryPath)
{
return Init(workingDirectoryPath, gitDirectoryPath, new InitOptions());
}

/// <summary>
/// Initialize a repository at the specified <paramref name="path"/>.
/// </summary>
/// <param name="path">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.</param>
/// <param name="isBare">true to initialize a bare repository. False otherwise, to initialize a standard ".git" repository.</param>
/// <param name="options">Additional optional parameters to be passed to the Init invocation</param>
/// <returns>The path to the created repository.</returns>
public static string Init(string path, bool isBare, InitOptions options)
{
Ensure.ArgumentNotNullOrEmptyString(path, "path");

using (RepositoryHandle repo = Proxy.git_repository_init_ext(null, path, isBare))
using (RepositoryHandle repo = Proxy.git_repository_init_ext(null, path, isBare, options.InitialHead))
{
FilePath repoPath = Proxy.git_repository_path(repo);
return repoPath.Native;
Expand All @@ -507,8 +531,9 @@ public static string Init(string path, bool isBare)
/// </summary>
/// <param name="workingDirectoryPath">The path to the working directory.</param>
/// <param name="gitDirectoryPath">The path to the git repository to be created.</param>
/// <param name="options">Additional optional parameters to be passed to the Init invocation</param>
/// <returns>The path to the created repository.</returns>
public static string Init(string workingDirectoryPath, string gitDirectoryPath)
public static string Init(string workingDirectoryPath, string gitDirectoryPath, InitOptions options)
{
Ensure.ArgumentNotNullOrEmptyString(workingDirectoryPath, "workingDirectoryPath");
Ensure.ArgumentNotNullOrEmptyString(gitDirectoryPath, "gitDirectoryPath");
Expand All @@ -520,7 +545,7 @@ 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 (RepositoryHandle repo = Proxy.git_repository_init_ext(wd, gitDirectoryPath, false, options.InitialHead))
{
FilePath repoPath = Proxy.git_repository_path(repo);
return repoPath.Native;
Expand Down Expand Up @@ -1050,7 +1075,7 @@ public Commit Commit(string message, Signature author, Signature committer, Comm

if (treesame && !amendMergeCommit)
{
throw (options.AmendPreviousCommit ?
throw (options.AmendPreviousCommit ?
new EmptyCommitException("Amending this commit would produce a commit that is identical to its parent (id = {0})", parents[0].Id) :
new EmptyCommitException("No changes; nothing to commit."));
}
Expand Down Expand Up @@ -1241,7 +1266,7 @@ public MergeResult MergeFetchedRefs(Signature merger, MergeOptions options)
if (fetchHeads.Length == 0)
{
var expectedRef = this.Head.UpstreamBranchCanonicalName;
throw new MergeFetchHeadNotFoundException("The current branch is configured to merge with the reference '{0}' from the remote, but this reference was not fetched.",
throw new MergeFetchHeadNotFoundException("The current branch is configured to merge with the reference '{0}' from the remote, but this reference was not fetched.",
expectedRef);
}

Expand Down

0 comments on commit a08b0ad

Please sign in to comment.