8000 Add Repository.ObjectDatabase.CreateCommit() · mm201/libgit2sharp@2401133 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2401133

Browse files
committed
Add Repository.ObjectDatabase.CreateCommit()
Partially fixes libgit2#127.
1 parent a3d5b88 commit 2401133

File tree

3 files changed

+74
-26
lines changed

3 files changed

+74
-26
lines changed

LibGit2Sharp.Tests/ObjectDatabaseFixture.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,28 @@ public void CanCreateATreeContainingABlobFromAFileInTheWorkingDirectory()
182182
Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", td["1/2/another new file"].TargetId.Sha);
183183
}
184184
}
185+
186+
[Fact]
187+
public void CanCreateACommit()
188+
{
189+
TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo();
190+
191+
using (var repo = new Repository(scd.RepositoryPath))
192+
{
193+
Branch head = repo.Head;
194+
195+
TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree);
196+
td.Add("1/2/readme", td["README"]);
197+
198+
Tree tree = repo.ObjectDatabase.CreateTree(td);
199+
200+
Commit commit = repo.ObjectDatabase.CreateCommit("message", DummySignature, DummySignature, tree, new[] { repo.Head.Tip });
201+
202+
Branch newHead = repo.Head;
203+
204+
Assert.Equal(head, newHead);
205+
Assert.Equal(commit, repo.Lookup<Commit>(commit.Sha));
206+
}
207+
}
185208
}
186209
}

LibGit2Sharp/CommitCollection.cs

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -134,51 +134,33 @@ private static bool PointsAtTheHead(string shaOrRefName)
134134
/// <returns>The generated <see cref = "Commit" />.</returns>
135135
public Commit Create(string message, Signature author, Signature committer, bool amendPreviousCommit)
136136
{
137-
Ensure.ArgumentNotNull(message, "message");
138-
Ensure.ArgumentNotNull(author, "author");
139-
Ensure.ArgumentNotNull(committer, "committer");
140-
141137
if (amendPreviousCommit && repo.Info.IsEmpty)
142138
{
143139
throw new LibGit2Exception("Can not amend anything. The Head doesn't point at any commit.");
144140
}
145141

146142
GitOid treeOid;
147-
int res = NativeMethods.git_tree_create_fromindex(out treeOid, repo.Index.Handle);
148-
Ensure.Success(res);
149-
150-
var parentIds = RetrieveParentIdsOfTheCommitBeingCreated(repo, amendPreviousCommit);
151-
152-
GitOid commitOid;
153-
using (var treePtr = new ObjectSafeWrapper(new ObjectId(treeOid), repo))
154-
using (var parentObjectPtrs = new DisposableEnumerable<ObjectSafeWrapper>(parentIds.Select(id => new ObjectSafeWrapper(id, repo))))
155-
using (SignatureSafeHandle authorHandle = author.BuildHandle())
156-
using (SignatureSafeHandle committerHandle = committer.BuildHandle())
157-
{
158-
string encoding = null; //TODO: Handle the encoding of the commit to be created
143+
Ensure.Success(NativeMethods.git_tree_create_fromindex(out treeOid, repo.Index.Handle));
144+
var tree = repo.Lookup<Tree>(new ObjectId(treeOid));
159145

160-
IntPtr[] parentsPtrs = parentObjectPtrs.Select(o => o.ObjectPtr.DangerousGetHandle() ).ToArray();
161-
res = NativeMethods.git_commit_create(out commitOid, repo.Handle, repo.Refs["HEAD"].CanonicalName, authorHandle,
162-
committerHandle, encoding, message, treePtr.ObjectPtr, parentObjectPtrs.Count(), parentsPtrs);
163-
Ensure.Success(res);
164-
}
146+
var parents = RetrieveParentsOfTheCommitBeingCreated(repo, amendPreviousCommit);
165147

166-
return repo.Lookup<Commit>(new ObjectId(commitOid));
148+
return repo.ObjectDatabase.CreateCommit(message, author, committer, tree, parents, "HEAD");
167149
}
168150

169-
private static IEnumerable<ObjectId> RetrieveParentIdsOfTheCommitBeingCreated(Repository repo, bool amendPreviousCommit)
151+
private static IEnumerable<Commit> RetrieveParentsOfTheCommitBeingCreated(Repository repo, bool amendPreviousCommit)
170152
{
171153
if (amendPreviousCommit)
172154
{
173-
return repo.Head.Tip.Parents.Select(c => c.Id);
155+
return repo.Head.Tip.Parents;
174156
}
175157

176158
if (repo.Info.IsEmpty)
177159
{
178-
return Enumerable.Empty<ObjectId>();
160+
return Enumerable.Empty<Commit>();
179161
}
180162

181-
return new[] { repo.Head.Tip.Id };
163+
return new[] { repo.Head.Tip };
182164
}
183165

184166
private class CommitEnumerator : IEnumerator<Commit>

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using LibGit2Sharp.Core;
35
using LibGit2Sharp.Core.Handles;
46

@@ -59,5 +61,46 @@ public Tree CreateTree(TreeDefinition treeDefinition)
5961
{
6062
return treeDefinition.Build(repo);
6163
}
64+
65+
/// <summary>
66+
/// Inserts a <see cref = "Commit"/> into the object database, referencing an existing <see cref = "Tree"/>.
67+
/// </summary>
68+
/// <param name = "message">The description of why a change was made to the repository.</param>
69+
/// <param name = "author">The <see cref = "Signature" /> of who made the change.</param>
70+
/// <param name = "committer">The <see cref = "Signature" /> of who added the change to the repository.</param>
71+
/// <param name = "tree">The <see cref = "Tree"/> of the <see cref = "Commit"/> to be created.</param>
72+
/// <param name = "parents">The parents of the <see cref = "Commit"/> to be created.</param>
73+
/// <returns>The created <see cref = "Commit"/>.</returns>
74+
public Commit CreateCommit(string message, Signature author, Signature committer, Tree tree, IEnumerable<Commit> parents)
75+
{
76+
return CreateCommit(message, author, committer, tree, parents, null);
77+
}
78+
79+
internal Commit CreateCommit(string message, Signature author, Signature committer, Tree tree, IEnumerable<Commit> parents, string referenceName)
80+
{
81+
Ensure.ArgumentNotNull(message, "message");
82+
Ensure.ArgumentNotNull(author, "author");
83+
Ensure.ArgumentNotNull(committer, "committer");
84+
Ensure.ArgumentNotNull(tree, "tree");
85+
Ensure.ArgumentNotNull(parents, "parents");
86+
87+
IEnumerable<ObjectId> parentIds = parents.Select(p => p.Id);
88+
89+
GitOid commitOid;
90+
using (var treePtr = new ObjectSafeWrapper(tree.Id, repo))
91+
using (var parentObjectPtrs = new DisposableEnumerable<ObjectSafeWrapper>(parentIds.Select(id => new ObjectSafeWrapper(id, repo))))
92+
using (SignatureSafeHandle authorHandle = author.BuildHandle())
93+
using (SignatureSafeHandle committerHandle = committer.BuildHandle())
94+
{
95+
string encoding = null; //TODO: Handle the encoding of the commit to be created
96+
97+
IntPtr[] parentsPtrs = parentObjectPtrs.Select(o => o.ObjectPtr.DangerousGetHandle()).ToArray();
98+
int res = NativeMethods.git_commit_create(out commitOid, repo.Handle, referenceName, authorHandle,
99+
committerHandle, encoding, message, treePtr.ObjectPtr, parentObjectPtrs.Count(), parentsPtrs);
100+
Ensure.Success(res);
101+
}
102+
103+
return repo.Lookup<Commit>(new ObjectId(commitOid));
104+
}
62105
}
63106
}

0 commit comments

Comments
 (0)
0