Skip to content
Browse files

Add Repository.ObjectDatabase.CreateCommit()

Partially fixes #127.
  • Loading branch information...
1 parent a3d5b88 commit 2401133ef6f365d3aae26a020f2754584852e558 @nulltoken committed
Showing with 74 additions and 26 deletions.
  1. +23 −0 LibGit2Sharp.Tests/ObjectDatabaseFixture.cs
  2. +8 −26 LibGit2Sharp/CommitCollection.cs
  3. +43 −0 LibGit2Sharp/ObjectDatabase.cs
View
23 LibGit2Sharp.Tests/ObjectDatabaseFixture.cs
@@ -182,5 +182,28 @@ public void CanCreateATreeContainingABlobFromAFileInTheWorkingDirectory()
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));
+ }
+ }
}
}
View
34 LibGit2Sharp/CommitCollection.cs
@@ -134,51 +134,33 @@ private static bool PointsAtTheHead(string shaOrRefName)
/// <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>
View
43 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 @@ public Tree CreateTree(TreeDefinition treeDefinition)
{
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));
+ }
}
}

0 comments on commit 2401133

Please sign in to comment.
Something went wrong with that request. Please try again.