diff --git a/LibGit2Sharp.Tests/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index 5c551fabd..2b9e7c9d5 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -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"); diff --git a/LibGit2Sharp/Core/GitRepositoryInitOptions.cs b/LibGit2Sharp/Core/GitRepositoryInitOptions.cs index f639a0d8d..f3a035e3f 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(FilePath workdirPath, bool isBare, string initialHead) { var opts = new GitRepositoryInitOptions { @@ -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; diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index ca9a69f6d..98a007c39 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -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); diff --git a/LibGit2Sharp/InitOptions.cs b/LibGit2Sharp/InitOptions.cs new file mode 100644 index 000000000..6be335c62 --- /dev/null +++ b/LibGit2Sharp/InitOptions.cs @@ -0,0 +1,14 @@ +namespace LibGit2Sharp +{ + /// + /// Optional parameters when invoking Init. + /// + public sealed class InitOptions + { + /// + /// Use the specified name for the initial branch in the newly created repository. + /// If not specified, fall back to the default name + /// + public string InitialHead { get; set; } + } +} diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 721133cc6..6abc423a5 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -482,7 +482,7 @@ private void Dispose(bool disposing) /// The path to the created repository. public static string Init(string path) { - return Init(path, false); + return Init(path, false, new InitOptions()); } /// @@ -492,10 +492,34 @@ public static string Init(string path) /// true to initialize a bare repository. False otherwise, to initialize a standard ".git" repository. /// The path to the created repository. public static string Init(string path, bool isBare) + { + return Init(path, isBare, new InitOptions()); + } + + + /// + /// Initialize a repository by explictly setting the path to both the working directory and the git directory. + /// + /// The path to the working directory. + /// The path to the git repository to be created. + /// The path to the created repository. + public static string Init(string workingDirectoryPath, string gitDirectoryPath) + { + return Init(workingDirectoryPath, gitDirectoryPath, new InitOptions()); + } + + /// + /// Initialize a repository at the specified . + /// + /// 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. + /// true to initialize a bare repository. False otherwise, to initialize a standard ".git" repository. + /// Additional optional parameters to be passed to the Init invocation + /// The path to the created repository. + 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; @@ -507,8 +531,9 @@ public static string Init(string path, bool isBare) /// /// The path to the working directory. /// The path to the git repository to be created. + /// Additional optional parameters to be passed to the Init invocation /// The path to the created repository. - 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"); @@ -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; @@ -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.")); } @@ -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); }