8000 Add basic Commit feature · joncham/libgit2sharp@3a9cb80 · GitHub
[go: up one dir, main page]

8000
Skip to content

Commit 3a9cb80

Browse files
committed
Add basic Commit feature
This should partially fix issue libgit2#32
1 parent 272b92d commit 3a9cb80

File tree

6 files changed

+119
-0
lines changed

6 files changed

+119
-0
lines changed

LibGit2Sharp.Tests/CommitFixture.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using System.Linq;
45
using LibGit2Sharp.Core;
56
using LibGit2Sharp.Tests.TestHelpers;
@@ -231,5 +232,54 @@ public void CanReadCommitWithMultipleParents()
231232
commit.Parents.Count().ShouldEqual(2);
232233
}
233234
}
235+
236+
[Test]
237+
public void CanCommitALittleBit()
238+
{
239+
using (var scd = new SelfCleaningDirectory())
240+
{
241+
var dir = Repository.Init(scd.DirectoryPath);
242+
Path.IsPathRooted(dir).ShouldBeTrue();
243+
Directory.Exists(dir).ShouldBeTrue();
244+
245+
using (var repo = new Repository(dir))
246+
{
247+
string filePath = Path.Combine(repo.Info.WorkingDirectory, "new.txt");
248+
249+
File.WriteAllText(filePath, "null");
250+
repo.Index.Stage("new.txt");
251+
File.AppendAllText(filePath, "token\n");
252+
repo.Index.Stage("new.txt");
253+
254+
var author = new Signature("Author N. Ame", "him@there.com", DateTimeOffset.Now.AddSeconds(-10));
255+
var commit = repo.Commit(author, author, "Initial egotistic commit");
256+
257+
commit.Parents.Count().ShouldEqual(0);
258+
repo.Info.IsEmpty.ShouldBeFalse();
259+
260+
File.WriteAllText(filePath, "nulltoken commits!\n");
261+
repo.Index.Stage("new.txt");
262+
263+
var author2 = new Signature(author.Name, author.Email, author.When.AddSeconds(5));
264+
var commit2 = repo.Commit(author2, author2, "Are you trying to fork me?");
265+
266+
commit2.Parents.Count().ShouldEqual(1);
267+
commit2.Parents.First().Id.ShouldEqual(commit.Id);
268+
269+
repo.CreateBranch("davidfowl-rules", commit.Id.Sha); //TODO: This cries for a shortcut method :-/
270+
repo.Branches.Checkout("davidfowl-rules"); //TODO: This cries for a shortcut method :-/
271+
272+
File.WriteAllText(filePath, "davidfowl commits!\n");
273+
274+
var author3 = new Signature("David Fowler", "david.fowler@microsoft.com", author.When.AddSeconds(2));
275+
repo.Index.Stage("new.txt");
276+
277+
var commit3 = repo.Commit(author3, author3, "I'm going to branch you backwards in time!");
278+
279+
commit3.Parents.Count().ShouldEqual(1);
280+
commit3.Parents.First().Id.ShouldEqual(commit.Id);
281+
}
282+
}
283+
}
234284
}
235285
}

LibGit2Sharp/CommitCollection.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,42 @@ private static bool PointsAtTheHead(string shaOrRefName)
9696
return ("HEAD".Equals(shaOrRefName, StringComparison.Ordinal) || "refs/heads/master".Equals(shaOrRefName, StringComparison.Ordinal));
9797
}
9898

99+
/// <summary>
100+
/// Stores the content of the <see cref="Repository.Index"/> as a new <see cref="Commit"/> into the repository.
101+
/// </summary>
102+
/// <param name="author">The <see cref="Signature"/> of who made the change.</param>
103+
/// <param name="committer">The <see cref="Signature"/> of who added the change to the repository.</param>
104+
/// <param name="message">The description of why a change was made to the repository.</param>
105+
/// <returns>The generated <see cref="Commit"/>.</returns>
106+
public Commit Create(Signature author, Signature committer, string message)
107+
{
108+
GitOid treeOid;
109+
int res = NativeMethods.git_tree_create_fromindex(out treeOid, repo.Index.Handle);
110+
Ensure.Success(res);
111+
112+
Reference head = repo.Head;
113+
GitOid[] gitOids = RetrieveCommitParent(head);
114+
115+
GitOid commitOid;
116+
res = NativeMethods.git_commit_create(out commitOid, repo.Handle, head.CanonicalName, author.Handle,
117+
committer.Handle, message, ref treeOid, gitOids.Count(), ref gitOids);
118+
Ensure.Success(res);
119+
120+
return repo.Lookup<Commit>(new ObjectId(commitOid));
121+
}
122+
123+
private static GitOid[] RetrieveCommitParent(Reference head)
124+
{
125+
DirectReference oidRef = head.ResolveToDirectReference();
126+
if (oidRef == null)
127+
{
128+
return new GitOid[] { };
129+
}
130+
131+
var headCommitId = new ObjectId(oidRef.TargetIdentifier);
132+
return new[] { headCommitId.Oid };
133+
}
134+
99135
private class CommitEnumerator : IEnumerator<Commit>
100136
{
101137
private readonly Repository repo;

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ internal static class NativeMethods
1919
[DllImport(libgit2)]
2020
public static extern IntPtr git_commit_committer(IntPtr commit);
2121

22+
[DllImport(libgit2)]
23+
public static extern int git_commit_create(out GitOid oid, RepositorySafeHandle repo, string updateRef, GitSignature author, GitSignature committer, string message, ref GitOid treeOid, int parentCount, ref GitOid[] parents);
24+
2225
[DllImport(libgit2)]
2326
public static extern int git_commit_create_o(out GitOid oid, RepositorySafeHandle repo, string updateRef, IntPtr author, IntPtr committer, string message, IntPtr tree, int parentCount, IntPtr parents);
2427

@@ -211,6 +214,9 @@ internal static class NativeMethods
211214
[DllImport(libgit2)]
212215
public static extern IntPtr git_tag_target_oid(IntPtr tag);
213216

217+
[DllImport(libgit2)]
218+
public static extern int git_tree_create_fromindex(out GitOid treeOid, IndexSafeHandle index);
219+
214220
[DllImport(libgit2)]
215221
public static extern int git_tree_entry_2object(out IntPtr obj, RepositorySafeHandle repo, IntPtr entry);
216222

LibGit2Sharp/IQueryableCommitCollection.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,14 @@ public interface IQueryableCommitCollection : ICommitCollection //TODO: Find a n
88
/// <param name="filter">The options used to control which commits will be returned.</param>
99
/// <returns>A collection of commits, ready to be enumerated.</returns>
1010
ICommitCollection QueryBy(Filter filter);
11+
12+
/// <summary>
13+
/// Stores the content of the content as a new <see cref="Commit"/> into the repository.
14+
/// </summary>
15+
/// <param name="author">The <see cref="Signature"/> of who made the change.</param>
16+
/// <param name="committer">The <see cref="Signature"/> of who added the change to the repository.</param>
17+
/// <param name="message">The description of why a change was made to the repository.</param>
18+
/// <returns>The generated <see cref="Commit"/>.</returns>
19+
Commit Create(Signature author, Signature committer, string message);
1120
}
1221
}

LibGit2Sharp/Index.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ internal Index(Repository repo)
1919
Ensure.Success(res);
2020
}
2121

22+
internal IndexSafeHandle Handle
23+
{
24+
get { return handle; }
25+
}
26+
2227
public int Count
2328
{
2429
get { return (int)NativeMethods.git_index_entrycount(handle); }

LibGit2Sharp/RepositoryExtensions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,18 @@ public static Branch CreateBranch(this Repository repository, string branchName,
9595
{
9696
return repository.Branches.Create(branchName, target);
9797
}
98+
99+
/// <summary>
100+
/// Stores the content of the <see cref="Repository.Index"/> as a new <see cref="Commit"/> into the repository.
101+
/// </summary>
102+
/// <param name="repository">The <see cref="Repository"/> being worked with.</param>
103+
/// <param name="author">The <see cref="Signature"/> of who made the change.</param>
104+
/// <param name="committer">The <see cref="Signature"/> of who added the change to the repository.</param>
105+
/// <param name="message">The description of why a change was made to the repository.</param>
106+
/// <returns>The generated <see cref="Commit"/>.</returns>
107+
public static Commit Commit(this Repository repository, Signature author, Signature committer, string message)
108+
{
109+
return repository.Commits.Create(author, committer, message);
110+
}
98111
}
99112
}

0 commit comments

Comments
 (0)
0