diff options
author | nulltoken <emeric.fermas@gmail.com> | 2012-04-21 23:37:24 +0400 |
---|---|---|
committer | nulltoken <emeric.fermas@gmail.com> | 2012-04-28 05:32:19 +0400 |
commit | 2401133ef6f365d3aae26a020f2754584852e558 (patch) | |
tree | ea01f38dbcd56ca75304e04d1aafcbe11fa0ef11 | |
parent | a3d5b885eeb3d1fac1bf69c95196e7d8ef167e28 (diff) |
Add Repository.ObjectDatabase.CreateCommit()
Partially fixes #127.
-rw-r--r-- | LibGit2Sharp.Tests/ObjectDatabaseFixture.cs | 23 | ||||
-rw-r--r-- | LibGit2Sharp/CommitCollection.cs | 34 | ||||
-rw-r--r-- | LibGit2Sharp/ObjectDatabase.cs | 43 |
3 files changed, 74 insertions, 26 deletions
diff --git a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs index f7b83f42..5102f616 100644 --- a/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs +++ b/LibGit2Sharp.Tests/ObjectDatabaseFixture.cs @@ -182,5 +182,28 @@ namespace LibGit2Sharp.Tests Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", td["1/2/another new file"].TargetId.Sha); } } + + [Fact] + public void CanCreateACommit() + { + TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo(); + + using (var repo = new Repository(scd.RepositoryPath)) + { + Branch head = repo.Head; + + TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); + td.Add("1/2/readme", td["README"]); + + Tree tree = repo.ObjectDatabase.CreateTree(td); + + Commit commit = repo.ObjectDatabase.CreateCommit("message", DummySignature, DummySignature, tree, new[] { repo.Head.Tip }); + + Branch newHead = repo.Head; + + Assert.Equal(head, newHead); + Assert.Equal(commit, repo.Lookup<Commit>(commit.Sha)); + } + } } } diff --git a/LibGit2Sharp/CommitCollection.cs b/LibGit2Sharp/CommitCollection.cs index 1853a987..4c8698d9 100644 --- a/LibGit2Sharp/CommitCollection.cs +++ b/LibGit2Sharp/CommitCollection.cs @@ -134,51 +134,33 @@ namespace LibGit2Sharp /// <returns>The generated <see cref = "Commit" />.</returns> public Commit Create(string message, Signature author, Signature committer, bool amendPreviousCommit) { - Ensure.ArgumentNotNull(message, "message"); - Ensure.ArgumentNotNull(author, "author"); - Ensure.ArgumentNotNull(committer, "committer"); - if (amendPreviousCommit && repo.Info.IsEmpty) { throw new LibGit2Exception("Can not amend anything. The Head doesn't point at any commit."); } GitOid treeOid; - int res = NativeMethods.git_tree_create_fromindex(out treeOid, repo.Index.Handle); - Ensure.Success(res); - - var parentIds = RetrieveParentIdsOfTheCommitBeingCreated(repo, amendPreviousCommit); - - GitOid commitOid; - using (var treePtr = new ObjectSafeWrapper(new ObjectId(treeOid), repo)) - using (var parentObjectPtrs = new DisposableEnumerable<ObjectSafeWrapper>(parentIds.Select(id => new ObjectSafeWrapper(id, repo)))) - using (SignatureSafeHandle authorHandle = author.BuildHandle()) - using (SignatureSafeHandle committerHandle = committer.BuildHandle()) - { - string encoding = null; //TODO: Handle the encoding of the commit to be created + Ensure.Success(NativeMethods.git_tree_create_fromindex(out treeOid, repo.Index.Handle)); + var tree = repo.Lookup<Tree>(new ObjectId(treeOid)); - IntPtr[] parentsPtrs = parentObjectPtrs.Select(o => o.ObjectPtr.DangerousGetHandle() ).ToArray(); - res = NativeMethods.git_commit_create(out commitOid, repo.Handle, repo.Refs["HEAD"].CanonicalName, authorHandle, - committerHandle, encoding, message, treePtr.ObjectPtr, parentObjectPtrs.Count(), parentsPtrs); - Ensure.Success(res); - } + var parents = RetrieveParentsOfTheCommitBeingCreated(repo, amendPreviousCommit); - return repo.Lookup<Commit>(new ObjectId(commitOid)); + return repo.ObjectDatabase.CreateCommit(message, author, committer, tree, parents, "HEAD"); } - private static IEnumerable<ObjectId> RetrieveParentIdsOfTheCommitBeingCreated(Repository repo, bool amendPreviousCommit) + private static IEnumerable<Commit> RetrieveParentsOfTheCommitBeingCreated(Repository repo, bool amendPreviousCommit) { if (amendPreviousCommit) { - return repo.Head.Tip.Parents.Select(c => c.Id); + return repo.Head.Tip.Parents; } if (repo.Info.IsEmpty) { - return Enumerable.Empty<ObjectId>(); + return Enumerable.Empty<Commit>(); } - return new[] { repo.Head.Tip.Id }; + return new[] { repo.Head.Tip }; } private class CommitEnumerator : IEnumerator<Commit> diff --git a/LibGit2Sharp/ObjectDatabase.cs b/LibGit2Sharp/ObjectDatabase.cs index 1a430440..dfaf565d 100644 --- a/LibGit2Sharp/ObjectDatabase.cs +++ b/LibGit2Sharp/ObjectDatabase.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; @@ -59,5 +61,46 @@ namespace LibGit2Sharp { return treeDefinition.Build(repo); } + + /// <summary> + /// Inserts a <see cref = "Commit"/> into the object database, referencing an existing <see cref = "Tree"/>. + /// </summary> + /// <param name = "message">The description of why a change was made to the repository.</param> + /// <param name = "author">The <see cref = "Signature" /> of who made the change.</param> + /// <param name = "committer">The <see cref = "Signature" /> of who added the change to the repository.</param> + /// <param name = "tree">The <see cref = "Tree"/> of the <see cref = "Commit"/> to be created.</param> + /// <param name = "parents">The parents of the <see cref = "Commit"/> to be created.</param> + /// <returns>The created <see cref = "Commit"/>.</returns> + public Commit CreateCommit(string message, Signature author, Signature committer, Tree tree, IEnumerable<Commit> parents) + { + return CreateCommit(message, author, committer, tree, parents, null); + } + + internal Commit CreateCommit(string message, Signature author, Signature committer, Tree tree, IEnumerable<Commit> parents, string referenceName) + { + Ensure.ArgumentNotNull(message, "message"); + Ensure.ArgumentNotNull(author, "author"); + Ensure.ArgumentNotNull(committer, "committer"); + Ensure.ArgumentNotNull(tree, "tree"); + Ensure.ArgumentNotNull(parents, "parents"); + + IEnumerable<ObjectId> parentIds = parents.Select(p => p.Id); + + GitOid commitOid; + using (var treePtr = new ObjectSafeWrapper(tree.Id, repo)) + using (var parentObjectPtrs = new DisposableEnumerable<ObjectSafeWrapper>(parentIds.Select(id => new ObjectSafeWrapper(id, repo)))) + using (SignatureSafeHandle authorHandle = author.BuildHandle()) + using (SignatureSafeHandle committerHandle = committer.BuildHandle()) + { + string encoding = null; //TODO: Handle the encoding of the commit to be created + + IntPtr[] parentsPtrs = parentObjectPtrs.Select(o => o.ObjectPtr.DangerousGetHandle()).ToArray(); + int res = NativeMethods.git_commit_create(out commitOid, repo.Handle, referenceName, authorHandle, + committerHandle, encoding, message, treePtr.ObjectPtr, parentObjectPtrs.Count(), parentsPtrs); + Ensure.Success(res); + } + + return repo.Lookup<Commit>(new ObjectId(commitOid)); + } } } |