Skip to content

WIP - Notes #140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions LibGit2Sharp.Tests/CommitFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,9 @@ public void CanEnumerateAllCommits()
repo => new Filter { Since = repo.Refs },
new[]
{
"4c062a6", "e90810b", "6dcf9bf", "a4a7dce",
"be3563a", "c47800c", "9fd738e", "4a202b3",
"44d5d18", "bb65291", "532740a", "503a16f", "3dfd6fd",
"4409de1", "902c60b", "4c062a6", "e90810b", "6dcf9bf",
"a4a7dce", "be3563a", "c47800c", "9fd738e", "4a202b3",
"41bc8c6", "5001298", "5b5b025", "8496071",
});
}
Expand Down
1 change: 1 addition & 0 deletions LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<Compile Include="ConfigurationFixture.cs" />
<Compile Include="AttributesFixture.cs" />
<Compile Include="CommitAncestorFixture.cs" />
<Compile Include="NoteFixture.cs" />
<Compile Include="DiffBlobToBlobFixture.cs" />
<Compile Include="DiffTreeToTargetFixture.cs" />
<Compile Include="ObjectDatabaseFixture.cs" />
Expand Down
243 changes: 243 additions & 0 deletions LibGit2Sharp.Tests/NoteFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
using System;
using System.Linq;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Compat;
using LibGit2Sharp.Tests.TestHelpers;
using Xunit;

namespace LibGit2Sharp.Tests
{
public class NoteFixture : BaseFixture
{
private static readonly Signature signatureNullToken = new Signature("nulltoken", "[email protected]", DateTimeOffset.UtcNow);
private static readonly Signature signatureYorah = new Signature("yorah", "[email protected]", Epoch.ToDateTimeOffset(1300557894, 60));

[Fact]
public void RetrievingNotesFromANonExistingGitObjectYieldsNoResult()
{
using (var repo = new Repository(BareTestRepoPath))
{
var notes = repo.Notes[ObjectId.Zero];

Assert.Equal(0, notes.Count());
}
}

[Fact]
public void RetrievingNotesFromAGitObjectWhichHasNoNoteYieldsNoResult()
{
using (var repo = new Repository(BareTestRepoPath))
{
var notes = repo.Notes[new ObjectId("4c062a6361ae6959e06292c1fa5e2822d9c96345")];

Assert.Equal(0, notes.Count());
}
}

/*
* $ git show 4a202 --show-notes=*
* commit 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
* Author: Scott Chacon <[email protected]>
* Date: Mon May 24 10:19:04 2010 -0700
*
* a third commit
*
* Notes:
* Just Note, don't you understand?
*
* Notes (answer):
* Nope
*
* Notes (answer2):
* Not Nope, Note!
*/
[Fact]
public void CanRetrieveNotesFromAGitObject()
{
var expectedMessages = new [] { "Just Note, don't you understand?\n", "Nope\n", "Not Nope, Note!\n" };

using (var repo = new Repository(BareTestRepoPath))
{
var notes = repo.Notes[new ObjectId("4a202b346bb0fb0db7eff3cffeb3c70babbd2045")];

Assert.NotNull(notes);
Assert.Equal(3, notes.Count());
Assert.Equal(expectedMessages, notes.Select(n => n.Message));
}
}

[Fact]
public void CanGetListOfNotesNamespaces()
{
var expectedNamespaces = new[] { "commits", "answer", "answer2" };

using (var repo = new Repository(BareTestRepoPath))
{
Assert.Equal(expectedNamespaces, repo.Notes.Namespaces);
Assert.Equal(repo.Notes.DefaultNamespace, repo.Notes.Namespaces.First());
}
}

/*
* $ git show 4a202b346bb0fb0db7eff3cffeb3c70babbd2045 --show-notes=*
* commit 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
* Author: Scott Chacon <[email protected]>
* Date: Mon May 24 10:19:04 2010 -0700
*
* a third commit
*
* Notes:
* Just Note, don't you understand?
*
* Notes (answer):
* Nope
*
* Notes (answer2):
* Not Nope, Note!
*/
[Fact]
public void CanAccessNotesFromACommit()
{
var expectedNamespaces = new[] { "Just Note, don't you understand?\n", "Nope\n", "Not Nope, Note!\n" };

TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo();
using (var repo = new Repository(path.RepositoryPath))
{
var commit = repo.Lookup<Commit>("4a202b346bb0fb0db7eff3cffeb3c70babbd2045");

Assert.Equal(expectedNamespaces, commit.Notes.Select(n => n.Message));

// Make sure that Commit.Notes is not refreshed automatically
repo.Notes.Create(commit.Id, "I'm batman!\n", signatureNullToken, signatureYorah, "batmobile");

Assert.Equal(expectedNamespaces, commit.Notes.Select(n => n.Message));
}
}

[Fact]
public void CanCreateANoteOnAGitObject()
{
TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo();
using (var repo = new Repository(path.RepositoryPath))
{
var commit = repo.Lookup<Commit>("9fd738e8f7967c078dceed8190330fc8648ee56a");
var note = repo.Notes.Create(commit.Id, "I'm batman!\n", signatureNullToken, signatureYorah, "batmobile");

var newNote = commit.Notes.Single();
Assert.Equal(note, newNote);

Assert.Equal("I'm batman!\n", newNote.Message);
Assert.Equal("batmobile", newNote.Namespace);
}
}

[Fact]
public void CreatingANoteWhichAlreadyExistsOverwritesThePreviousNote()
{
TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo();
using (var repo = new Repository(path.RepositoryPath))
{
var commit = repo.Lookup<Commit>("5b5b025afb0b4c913b4c338a42934a3863bf3644");
Assert.NotNull(commit.Notes.FirstOrDefault(x => x.Namespace == "answer"));

repo.Notes.Create(commit.Id, "I'm batman!\n", signatureNullToken, signatureYorah, "answer");
var note = repo.Notes[new ObjectId("5b5b025afb0b4c913b4c338a42934a3863bf3644")].FirstOrDefault(x => x.Namespace == "answer");

Assert.NotNull(note);

Assert.Equal("I'm batman!\n", note.Message);
Assert.Equal("answer", note.Namespace);
}
}

[Fact]
public void CanCompareTwoUniqueNotes()
{
TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo();
using (var repo = new Repository(path.RepositoryPath))
{
var commit = repo.Lookup<Commit>("9fd738e8f7967c078dceed8190330fc8648ee56a");

var firstNote = repo.Notes.Create(commit.Id, "I'm batman!\n", signatureNullToken, signatureYorah, "batmobile");
var secondNote = repo.Notes.Create(commit.Id, "I'm batman!\n", signatureNullToken, signatureYorah, "batmobile");
Assert.Equal(firstNote, secondNote);

var firstNoteWithAnotherNamespace = repo.Notes.Create(commit.Id, "I'm batman!\n", signatureNullToken, signatureYorah, "batmobile2");
Assert.NotEqual(firstNote, firstNoteWithAnotherNamespace);

var firstNoteWithAnotherMessage = repo.Notes.Create(commit.Id, "I'm ironman!\n", signatureNullToken, signatureYorah, "batmobile");
Assert.NotEqual(firstNote, firstNoteWithAnotherMessage);

var anotherCommit = repo.Lookup<Commit>("c47800c7266a2be04c571c04d5a6614691ea99bd");
var firstNoteOnAnotherCommit = repo.Notes.Create(anotherCommit.Id, "I'm batman!\n", signatureNullToken, signatureYorah, "batmobile");
Assert.NotEqual(firstNote, firstNoteOnAnotherCommit);
}
}

/*
* $ git log 8496071c1b46c854b31185ea97743be6a8774479
* commit 8496071c1b46c854b31185ea97743be6a8774479
* Author: Scott Chacon <[email protected]>
* Date: Sat May 8 16:13:06 2010 -0700
*
* testing
*
* Notes:
* Hi, I'm Note.
*/
[Fact]
public void CanRemoveANoteFromAGitObject()
{
TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo();
using (var repo = new Repository(path.RepositoryPath))
{
var commit = repo.Lookup<Commit>("8496071c1b46c854b31185ea97743be6a8774479");
var notes = repo.Notes[commit.Id];

Assert.NotEmpty(notes);

repo.Notes.Delete(commit.Id, signatureNullToken, signatureYorah, repo.Notes.DefaultNamespace);

Assert.Empty(notes);
}
}

/*
* $ git show 5b5b025afb0b4c913b4c338a42934a3863bf3644 --notes=answer
* commit 5b5b025afb0b4c913b4c338a42934a3863bf3644
* Author: Scott Chacon <[email protected]>
* Date: Tue May 11 13:38:42 2010 -0700
*
* another commit
*
* Notes (answer):
* Not what?
*/
[Fact]
public void RemovingANonExistingNoteDoesntThrow()
{
TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo();
using (var repo = new Repository(path.RepositoryPath))
{
var commit = repo.Lookup<Commit>("5b5b025afb0b4c913b4c338a42934a3863bf3644");

repo.Notes.Delete(commit.Id, signatureNullToken, signatureYorah, "answer2");
}
}

[Fact]
public void CanRetrieveTheListOfNotesForAGivenNamespace()
{
var expectedNotes = new[] { new Tuple<string, string>("1a550e416326cdb4a8e127a04dd69d7a01b11cf4", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"),
new Tuple<string, string>("272a41cf2b22e57f2bc5bf6ef37b63568cd837e4", "8496071c1b46c854b31185ea97743be6a8774479") };

using (var repo = new Repository(BareTestRepoPath))
{
Assert.Equal(expectedNotes, repo.Notes["commits"].Select(n => new Tuple<string, string>(n.BlobId.Sha, n.TargetObjectId.Sha)).ToArray());

Assert.Equal("commits", repo.Notes.DefaultNamespace);
Assert.Equal(expectedNotes, repo.Notes.Select(n => new Tuple<string, string>(n.BlobId.Sha, n.TargetObjectId.Sha)).ToArray());
}
}
}
}
5 changes: 3 additions & 2 deletions LibGit2Sharp.Tests/ReferenceFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public class ReferenceFixture : BaseFixture
private readonly string[] expectedRefs = new[]
{
"refs/heads/br2", "refs/heads/deadbeef", "refs/heads/master", "refs/heads/packed", "refs/heads/packed-test",
"refs/heads/test", "refs/tags/e90810b", "refs/tags/lw", "refs/tags/point_to_blob", "refs/tags/test",
"refs/heads/test", "refs/notes/answer", "refs/notes/answer2", "refs/notes/commits", "refs/tags/e90810b",
"refs/tags/lw", "refs/tags/point_to_blob", "refs/tags/test"
};

[Fact]
Expand Down Expand Up @@ -214,7 +215,7 @@ public void CanListAllReferencesEvenCorruptedOnes()

Assert.Equal(expectedRefs, repo.Refs.Select(r => r.CanonicalName).ToArray());

repo.Refs.Count().ShouldEqual(10);
repo.Refs.Count().ShouldEqual(13);
}
}

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x��Kj1��)z�E���i}�� wPK-π52����=Y�Y��{k��؏9D�b������k6ѓb8E\�V��l�z�!���&;d"bKȚ�D�$_�ƥ8���T�~����H+\~��kM��~����Ϲ�/�֒��#�'Du�c����OyB*E
� N�����N���M
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
x��A
� E���ˢ�h�����i ��.r��E/�Ճ��}Ni��]ja��4�ѻ�28�a��Ć-J��i6ڒp�s�3��E�+��u,ɭ[�s�jM�Q
�RI)�m���i�3W>������}���>�
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x��M
� ����ˢƨ�B)=A�0��bk�}��(<x���{!��U��\ja��3�,Y3�-�v���ڪ�M@B���k.p�B+ܾ���J�};K�m�CNw�J��X�,\q@�������+��b���niߏ���@@
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x��MjC1 ���)�ˢ��1����%�=����.r��=Ba`�cfJom��Bx�C<KIR(�]���J��f�DP-���/UV�QqNkt�FJ��))�K2�=�>��o��k���hzߏ�[��~.������M����,�N�O�|��_�"*p}�鶾Le�'�ߢN�
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
x��M
� ����ˢ5&B)=A�0��j,�.r��E/�Ճ���{!��UPF�ja���3Yk4c��c�) ��W�pD��I��
�H��"N>�V+qb��8����*A��G.����_�$~l�mI�=���P���贃�TR�F������+��b���ni_���J%M�
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
x��K
1D]��s! ��L@�x��t��Db\x{G���Q�R�ym`�;�*��=�.E4ab
����(3�&�Tek�ђ�;���:RHD}�G��d��'E���
�Ri��7r�P�r_��i�w�� hk}����� ��� ���[i�b���y�����ڎ�k]M�
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
532740a931e8f9140b26b93cb0a2d81f6943741a
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
44d5d1881ebcb31173b1f89ef7c2ea955c3b1a3b
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bb65291c2f528ddcd2a3c950582449c57d196dec
17 changes: 16 additions & 1 deletion LibGit2Sharp/Commit.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Linq;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Compat;
using LibGit2Sharp.Core.Handles;
Expand All @@ -16,13 +16,15 @@ public class Commit : GitObject
private readonly Lazy<IEnumerable<Commit>> parents;
private readonly Lazy<Tree> tree;
private readonly Lazy<string> shortMessage;
private readonly Lazy<IEnumerable<Note>> notes;

internal Commit(ObjectId id, ObjectId treeId, Repository repo)
: base(id)
{
tree = new Lazy<Tree>(() => repo.Lookup<Tree>(treeId));
parents = new Lazy<IEnumerable<Commit>>(() => RetrieveParentsOfCommit(id));
shortMessage = new Lazy<string>(ExtractShortMessage);
notes = new Lazy<IEnumerable<Note>>(() => RetrieveNotesOfCommit(id).ToList());
this.repo = repo;
}

Expand Down Expand Up @@ -104,6 +106,14 @@ public int ParentsCount
}
}

/// <summary>
/// Gets the notes of this commit.
/// </summary>
public IEnumerable<Note> Notes
{
get { return notes.Value; }
}

private IEnumerable<Commit> RetrieveParentsOfCommit(ObjectId oid)
{
using (var obj = new ObjectSafeWrapper(oid, repo))
Expand All @@ -119,6 +129,11 @@ private IEnumerable<Commit> RetrieveParentsOfCommit(ObjectId oid)
}
}

private IEnumerable<Note> RetrieveNotesOfCommit(ObjectId oid)
{
return repo.Notes[oid];
}

internal static Commit BuildFromPtr(GitObjectSafeHandle obj, ObjectId id, Repository repo)
{
ObjectId treeId = NativeMethods.git_commit_tree_oid(obj).MarshalAsObjectId();
Expand Down
11 changes: 11 additions & 0 deletions LibGit2Sharp/Core/GitNoteData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Runtime.InteropServices;

namespace LibGit2Sharp.Core
{
[StructLayout(LayoutKind.Sequential)]
internal class GitNoteData
{
public GitOid BlobOid;
public GitOid TargetOid;
}
}
11 changes: 11 additions & 0 deletions LibGit2Sharp/Core/Handles/NoteSafeHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace LibGit2Sharp.Core.Handles
{
internal class NoteSafeHandle : SafeHandleBase
{
protected override bool ReleaseHandle()
{
NativeMethods.git_note_free(handle);
return true;
}
}
}
Loading