Skip to content

Commit

Permalink
Defer loading of Tag.Annotation and Tag.Target properties
Browse files Browse the repository at this point in the history
  • Loading branch information
nulltoken committed Sep 14, 2011
1 parent 5295b22 commit 75ae7f9
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 24 deletions.
21 changes: 12 additions & 9 deletions LibGit2Sharp.Tests/TagFixture.cs
Expand Up @@ -10,7 +10,7 @@ namespace LibGit2Sharp.Tests
[TestFixture]
public class TagFixture : BaseFixture
{
private readonly List<string> expectedTags = new List<string> {"test", "e90810b", "lw"};
private readonly List<string> expectedTags = new List<string> { "test", "e90810b", "lw" };

private static readonly Signature signatureTim = new Signature("Tim Clem", "timothy.clem@gmail.com", DateTimeOffset.UtcNow);
private static readonly Signature signatureNtk = new Signature("nulltoken", "emeric.fermas@gmail.com", Epoch.ToDateTimeOffset(1300557894, 60));
Expand Down Expand Up @@ -76,12 +76,15 @@ public void CanCreateATagWithNameContainingASlash()
var lwTag = repo.Tags.Create(lwTagName, commitE90810BSha);
lwTag.ShouldNotBeNull();
lwTag.IsAnnotated.ShouldBeFalse();
lwTag.Target.Sha.ShouldEqual(commitE90810BSha);
lwTag.Name.ShouldEqual(lwTagName);

const string anTagName = lwTagName + "_as_well";
var anTag = repo.Tags.Create(anTagName, commitE90810BSha, signatureNtk, "a nice message");
anTag.ShouldNotBeNull();
anTag.IsAnnotated.ShouldBeTrue();
anTag.Target.Sha.ShouldEqual(commitE90810BSha);
anTag.Annotation.Target.ShouldEqual(anTag.Target);
anTag.Name.ShouldEqual(anTagName);
}
}
Expand Down Expand Up @@ -158,9 +161,10 @@ public void CreatingAnAnnotatedTagIsDeterministic()
using (var repo = new Repository(path.RepositoryPath))
{
var newTag = repo.Tags.Create(tagName, commitE90810BSha, signatureNtk, tagMessage);
newTag.Target.Sha.ShouldEqual("24f6de34a108d931c6056fc4687637fe36c6bd6b");
newTag.Target.Sha.ShouldEqual(commitE90810BSha);
newTag.IsAnnotated.ShouldBeTrue();
newTag.Annotation.Sha.ShouldEqual("24f6de34a108d931c6056fc4687637fe36c6bd6b");
newTag.Annotation.Target.Sha.ShouldEqual(commitE90810BSha);
}
}

Expand Down Expand Up @@ -284,7 +288,7 @@ public void CanCreateATagPointingToATree()
using (var path = new TemporaryCloneOfTestRepo())
using (var repo = new Repository(path.RepositoryPath))
{
var headCommit = (Commit)repo.Head.Tip;
var headCommit = repo.Head.Tip;
var tree = headCommit.Tree;

var tag = repo.ApplyTag("tree-tag", tree.Sha);
Expand Down Expand Up @@ -328,10 +332,10 @@ public void CreatingALightweightTagPointingToATagAnnotationGeneratesAnAnnotatedT
var tag = repo.ApplyTag("lightweight-tag", annotation.Sha);
tag.ShouldNotBeNull();
tag.IsAnnotated.ShouldBeTrue();
tag.Target.Id.ShouldEqual(annotation.Id);
tag.Target.Id.ShouldEqual(annotation.Target.Id);
tag.Annotation.ShouldEqual(annotation);

repo.Lookup(tag.Target.Id).ShouldEqual(annotation);
repo.Lookup(tag.Annotation.Id).ShouldEqual(annotation);
repo.Tags[tag.Name].ShouldEqual(tag);
}
}
Expand All @@ -348,10 +352,9 @@ public void CanCreateAnAnnotatedTagPointingToATagAnnotation()
var tag = repo.ApplyTag("annotatedtag-tag", annotation.Sha, signatureNtk, "A new annotation");
tag.ShouldNotBeNull();
tag.IsAnnotated.ShouldBeTrue();
tag.Annotation.TargetId.ShouldEqual(annotation.Id);
tag.Annotation.Target.Id.ShouldEqual(annotation.Id);
tag.Annotation.ShouldNotEqual(annotation);

repo.Lookup(tag.Target.Id).ShouldEqual(tag.Annotation);
repo.Tags[tag.Name].ShouldEqual(tag);
}
}
Expand Down Expand Up @@ -597,15 +600,15 @@ public void CanLookupAnAnnotatedTag()
var tag = repo.Tags["e90810b"];
tag.ShouldNotBeNull();
tag.Name.ShouldEqual("e90810b");
tag.Target.Sha.ShouldEqual(tagE90810BSha);
tag.Target.Sha.ShouldEqual(commitE90810BSha);

tag.IsAnnotated.ShouldBeTrue();
tag.Annotation.Sha.ShouldEqual(tagE90810BSha);
tag.Annotation.Tagger.Email.ShouldEqual("tanoku@gmail.com");
tag.Annotation.Tagger.Name.ShouldEqual("Vicent Marti");
tag.Annotation.Tagger.When.ShouldEqual(DateTimeOffset.Parse("2010-08-12 03:59:17 +0200"));
tag.Annotation.Message.ShouldEqual("This is a very simple tag.\n");
tag.Annotation.TargetId.Sha.ShouldEqual(commitE90810BSha);
tag.Annotation.Target.Sha.ShouldEqual(commitE90810BSha);
}
}

Expand Down
4 changes: 2 additions & 2 deletions LibGit2Sharp/CommitCollection.cs
Expand Up @@ -315,7 +315,7 @@ private ObjectId DereferenceToCommit(string identifier)

if (obj is TagAnnotation)
{
return DereferenceToCommit(((TagAnnotation)obj).TargetId.Sha);
return DereferenceToCommit(((TagAnnotation)obj).Target.Sha);
}

throw new InvalidOperationException();
Expand Down Expand Up @@ -343,7 +343,7 @@ private IEnumerable<ObjectId> RetrieveCommitOids(object identifier)

if (identifier is TagAnnotation)
{
yield return DereferenceToCommit(((TagAnnotation)identifier).TargetId.Sha);
yield return DereferenceToCommit(((TagAnnotation)identifier).Target.Id.Sha);
yield break;
}

Expand Down
2 changes: 1 addition & 1 deletion LibGit2Sharp/GitObject.cs
Expand Up @@ -56,7 +56,7 @@ internal static GitObject CreateFromPtr(IntPtr obj, ObjectId id, Repository repo
case GitObjectType.Tree:
return Tree.BuildFromPtr(obj, id, repo);
case GitObjectType.Tag:
return TagAnnotation.BuildFromPtr(obj, id);
return TagAnnotation.BuildFromPtr(obj, id, repo);
case GitObjectType.Blob:
return Blob.BuildFromPtr(obj, id, repo);
default:
Expand Down
3 changes: 1 addition & 2 deletions LibGit2Sharp/Reference.cs
Expand Up @@ -74,8 +74,7 @@ public abstract class Reference : IEquatable<Reference>

if (Equals(typeof(T), typeof(Tag)))
{
GitObject targetGitObject = repo.Lookup(targetIdentifier);
return new Tag(reference.CanonicalName, targetGitObject, targetGitObject as TagAnnotation) as T;
return new Tag(reference.CanonicalName, targetOid, repo) as T;
}

if (Equals(typeof(T), typeof(Branch)))
Expand Down
26 changes: 20 additions & 6 deletions LibGit2Sharp/Tag.cs
Expand Up @@ -11,21 +11,23 @@ public class Tag : IEquatable<Tag>
private static readonly LambdaEqualityHelper<Tag> equalityHelper =
new LambdaEqualityHelper<Tag>(new Func<Tag, object>[] { x => x.CanonicalName, x => x.Target });

internal Tag(string canonicalName, GitObject target, TagAnnotation tagAnnotation)
private readonly Lazy<GitObject> targetBuilder;

internal Tag(string canonicalName, ObjectId targetId, Repository repo)
{
Ensure.ArgumentNotNullOrEmptyString(canonicalName, "canonicalName");
Ensure.ArgumentNotNull(target, "target");
Ensure.ArgumentNotNull(targetId, "targetId");
Ensure.ArgumentNotNull(repo, "repo");

CanonicalName = canonicalName;
Target = target;
Annotation = tagAnnotation;
targetBuilder = new Lazy<GitObject>(() => repo.Lookup<GitObject>(targetId));
}

/// <summary>
/// Gets the optional information associated to this tag.
/// <para>When the <see cref="Tag"/> is a lightweight tag, <c>null</c> is returned.</para>
/// </summary>
public TagAnnotation Annotation { get; private set; }
public TagAnnotation Annotation { get { return targetBuilder.Value as TagAnnotation; } }

/// <summary>
/// Gets the full name of this branch.
Expand All @@ -40,7 +42,19 @@ internal Tag(string canonicalName, GitObject target, TagAnnotation tagAnnotation
/// <summary>
/// Gets the <see cref="GitObject"/> that this tag points to.
/// </summary>
public GitObject Target { get; private set; }
public GitObject Target {
get
{
var target = targetBuilder.Value;

if ((!(target is TagAnnotation)))
{
return target;
}

return ((TagAnnotation)target).Target;
}
}

/// <summary>
/// Indicates whether the tag holds any metadata.
Expand Down
10 changes: 6 additions & 4 deletions LibGit2Sharp/TagAnnotation.cs
Expand Up @@ -9,6 +9,8 @@ namespace LibGit2Sharp
/// </summary>
public class TagAnnotation : GitObject
{
private Lazy<GitObject> targetBuilder;

internal TagAnnotation(ObjectId id)
: base(id)
{
Expand All @@ -25,16 +27,16 @@ internal TagAnnotation(ObjectId id)
public string Message { get; private set; }

/// <summary>
/// Gets the target id that this tag points to.
/// Gets the <see cref="GitObject"/> that this tag annotation points to.
/// </summary>
public ObjectId TargetId { get; private set; }
public GitObject Target { get { return targetBuilder.Value; } }

/// <summary>
/// Gets the tagger.
/// </summary>
public Signature Tagger { get; private set; }

internal static TagAnnotation BuildFromPtr(IntPtr obj, ObjectId id)
internal static TagAnnotation BuildFromPtr(IntPtr obj, ObjectId id, Repository repo)
{
var oidPtr = NativeMethods.git_tag_target_oid(obj);
var oid = (GitOid)Marshal.PtrToStructure(oidPtr, typeof(GitOid));
Expand All @@ -44,7 +46,7 @@ internal static TagAnnotation BuildFromPtr(IntPtr obj, ObjectId id)
Message = NativeMethods.git_tag_message(obj).MarshallAsString(),
Name = NativeMethods.git_tag_name(obj).MarshallAsString(),
Tagger = new Signature(NativeMethods.git_tag_tagger(obj)),
TargetId = new ObjectId(oid)
targetBuilder = new Lazy<GitObject>(() => repo.Lookup<GitObject>(new ObjectId(oid)))
};
}
}
Expand Down

0 comments on commit 75ae7f9

Please sign in to comment.