diff options
Diffstat (limited to 'LibGit2Sharp')
-rw-r--r-- | LibGit2Sharp/Blob.cs | 16 | ||||
-rw-r--r-- | LibGit2Sharp/Commit.cs | 92 | ||||
-rw-r--r-- | LibGit2Sharp/Core/NativeMethods.cs | 3 | ||||
-rw-r--r-- | LibGit2Sharp/Core/Proxy.cs | 5 | ||||
-rw-r--r-- | LibGit2Sharp/GitObject.cs | 19 | ||||
-rw-r--r-- | LibGit2Sharp/Repository.cs | 18 | ||||
-rw-r--r-- | LibGit2Sharp/TagAnnotation.cs | 41 | ||||
-rw-r--r-- | LibGit2Sharp/Tree.cs | 17 | ||||
-rw-r--r-- | LibGit2Sharp/TreeEntry.cs | 10 |
9 files changed, 95 insertions, 126 deletions
diff --git a/LibGit2Sharp/Blob.cs b/LibGit2Sharp/Blob.cs index fdf01ab2..7bda0f87 100644 --- a/LibGit2Sharp/Blob.cs +++ b/LibGit2Sharp/Blob.cs @@ -1,6 +1,5 @@ using System.IO; using LibGit2Sharp.Core; -using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { @@ -11,6 +10,8 @@ namespace LibGit2Sharp { private readonly Repository repo; + private readonly ILazy<int> lazySize; + /// <summary> /// Needed for mocking purposes. /// </summary> @@ -21,12 +22,14 @@ namespace LibGit2Sharp : base(id) { this.repo = repo; + + lazySize = GitObjectLazyGroup.Singleton(repo, id, Proxy.git_blob_rawsize); } /// <summary> /// Gets the size in bytes of the contents of a blob /// </summary> - public virtual int Size { get; protected set; } + public virtual int Size { get { return lazySize.Value; } } /// <summary> /// Gets the blob content in a <see cref="byte" /> array. @@ -49,14 +52,5 @@ namespace LibGit2Sharp return Proxy.git_blob_rawcontent_stream(repo.Handle, Id, Size); } } - - internal static Blob BuildFromPtr(GitObjectSafeHandle obj, ObjectId id, Repository repo) - { - var blob = new Blob(repo, id) - { - Size = Proxy.git_blob_rawsize(obj) - }; - return blob; - } } } diff --git a/LibGit2Sharp/Commit.cs b/LibGit2Sharp/Commit.cs index 378d6f0a..6229f0e8 100644 --- a/LibGit2Sharp/Commit.cs +++ b/LibGit2Sharp/Commit.cs @@ -12,10 +12,17 @@ namespace LibGit2Sharp public class Commit : GitObject { private readonly Repository repo; - private readonly Lazy<IEnumerable<Commit>> parents; - private readonly Lazy<Tree> tree; - private readonly Lazy<string> shortMessage; - private readonly Lazy<IEnumerable<Note>> notes; + + private readonly GitObjectLazyGroup group; + private readonly ILazy<Tree> lazyTree; + private readonly ILazy<Signature> lazyAuthor; + private readonly ILazy<Signature> lazyCommitter; + private readonly ILazy<string> lazyMessage; + private readonly ILazy<string> lazyEncoding; + + private readonly Lazy<IEnumerable<Commit>> lazyParents; + private readonly Lazy<string> lazyShortMessage; + private readonly Lazy<IEnumerable<Note>> lazyNotes; /// <summary> /// Needed for mocking purposes. @@ -23,14 +30,22 @@ namespace LibGit2Sharp protected Commit() { } - internal Commit(ObjectId id, ObjectId treeId, Repository repo) + internal Commit(Repository repo, ObjectId id) : 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; + + lazyTree = GitObjectLazyGroup.Singleton(this.repo, id, obj => new Tree(this.repo, Proxy.git_commit_tree_oid(obj), null)); + + group = new GitObjectLazyGroup(this.repo, id); + lazyAuthor = group.AddLazy(Proxy.git_commit_author); + lazyCommitter = group.AddLazy(Proxy.git_commit_committer); + lazyMessage = group.AddLazy(Proxy.git_commit_message); + lazyEncoding = group.AddLazy(RetrieveEncodingOf); + + lazyParents = new Lazy<IEnumerable<Commit>>(() => RetrieveParentsOfCommit(id)); + lazyShortMessage = new Lazy<string>(ExtractShortMessage); + lazyNotes = new Lazy<IEnumerable<Note>>(() => RetrieveNotesOfCommit(id).ToList()); } /// <summary> @@ -46,56 +61,37 @@ namespace LibGit2Sharp /// <summary> /// Gets the commit message. /// </summary> - public virtual string Message { get; private set; } + public virtual string Message { get { return lazyMessage.Value; } } /// <summary> /// Gets the short commit message which is usually the first line of the commit. /// </summary> - public virtual string MessageShort - { - get { return shortMessage.Value; } - } - - private string ExtractShortMessage() - { - if (Message == null) - { - return string.Empty; //TODO: Add some test coverage - } - - return Message.Split('\n')[0]; - } + public virtual string MessageShort { get { return lazyShortMessage.Value; } } /// <summary> /// Gets the encoding of the message. /// </summary> - public virtual string Encoding { get; private set; } + public virtual string Encoding { get { return lazyEncoding.Value; } } /// <summary> /// Gets the author of this commit. /// </summary> - public virtual Signature Author { get; private set; } + public virtual Signature Author { get { return lazyAuthor.Value; } } /// <summary> /// Gets the committer. /// </summary> - public virtual Signature Committer { get; private set; } + public virtual Signature Committer { get { return lazyCommitter.Value; } } /// <summary> /// Gets the Tree associated to this commit. /// </summary> - public virtual Tree Tree - { - get { return tree.Value; } - } + public virtual Tree Tree { get { return lazyTree.Value; } } /// <summary> /// Gets the parents of this commit. This property is lazy loaded and can throw an exception if the commit no longer exists in the repo. /// </summary> - public virtual IEnumerable<Commit> Parents - { - get { return parents.Value; } - } + public virtual IEnumerable<Commit> Parents { get { return lazyParents.Value; } } /// <summary> /// Gets The count of parent commits. @@ -111,9 +107,16 @@ namespace LibGit2Sharp /// <summary> /// Gets the notes of this commit. /// </summary> - public virtual IEnumerable<Note> Notes + public virtual IEnumerable<Note> Notes { get { return lazyNotes.Value; } } + + private string ExtractShortMessage() { - get { return notes.Value; } + if (Message == null) + { + return string.Empty; //TODO: Add some test coverage + } + + return Message.Split('\n')[0]; } private IEnumerable<Commit> RetrieveParentsOfCommit(ObjectId oid) @@ -125,7 +128,7 @@ namespace LibGit2Sharp for (uint i = 0; i < parentsCount; i++) { ObjectId parentCommitId = Proxy.git_commit_parent_oid(obj.ObjectPtr, i); - yield return (Commit)repo.LookupInternal(parentCommitId, GitObjectType.Commit, null); + yield return new Commit(repo, parentCommitId); } } } @@ -135,19 +138,6 @@ namespace LibGit2Sharp return repo.Notes[oid]; } - internal static Commit BuildFromPtr(GitObjectSafeHandle obj, ObjectId id, Repository repo) - { - ObjectId treeId = Proxy.git_commit_tree_oid(obj); - - return new Commit(id, treeId, repo) - { - Message = Proxy.git_commit_message(obj), - Encoding = RetrieveEncodingOf(obj), - Author = Proxy.git_commit_author(obj), - Committer = Proxy.git_commit_committer(obj), - }; - } - private static string RetrieveEncodingOf(GitObjectSafeHandle obj) { string encoding = Proxy.git_commit_message_encoding(obj); diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index b9f7cac1..f5b1b8d6 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -790,6 +790,9 @@ namespace LibGit2Sharp.Core internal static extern OidSafeHandle git_tag_target_oid(GitObjectSafeHandle tag); [DllImport(libgit2)] + internal static extern GitObjectType git_tag_type(GitObjectSafeHandle tag); + + [DllImport(libgit2)] internal static extern void git_threads_init(); [DllImport(libgit2)] diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 12a95eff..433e20af 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -1531,7 +1531,10 @@ namespace LibGit2Sharp.Core return NativeMethods.git_tag_target_oid(tag).MarshalAsObjectId(); } - + public static GitObjectType git_tag_type(GitObjectSafeHandle tag) + { + return NativeMethods.git_tag_type(tag); + } #endregion diff --git a/LibGit2Sharp/GitObject.cs b/LibGit2Sharp/GitObject.cs index b9104fb2..f83b554a 100644 --- a/LibGit2Sharp/GitObject.cs +++ b/LibGit2Sharp/GitObject.cs @@ -1,14 +1,13 @@ using System; using System.Globalization; using LibGit2Sharp.Core; -using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { /// <summary> /// A GitObject /// </summary> - public class GitObject : IEquatable<GitObject> + public abstract class GitObject : IEquatable<GitObject> { internal static GitObjectTypeMap TypeToTypeMap = new GitObjectTypeMap @@ -51,29 +50,23 @@ namespace LibGit2Sharp get { return Id.Sha; } } - internal static GitObject BuildFromPtr(GitObjectSafeHandle obj, ObjectId id, Repository repo, FilePath path) + internal static GitObject BuildFrom(Repository repo, ObjectId id, GitObjectType type, FilePath path) { - GitObjectType type = Proxy.git_object_type(obj); switch (type) { case GitObjectType.Commit: - return Commit.BuildFromPtr(obj, id, repo); + return new Commit(repo, id); case GitObjectType.Tree: - return Tree.BuildFromPtr(obj, id, repo, path); + return new Tree(repo, id, path); case GitObjectType.Tag: - return TagAnnotation.BuildFromPtr(obj, id, repo); + return new TagAnnotation(repo, id); case GitObjectType.Blob: - return Blob.BuildFromPtr(obj, id, repo); + return new Blob(repo, id); default: throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, "Unexpected type '{0}' for object '{1}'.", type, id)); } } - internal static ObjectId ObjectIdOf(GitObjectSafeHandle gitObjHandle) - { - return Proxy.git_object_id(gitObjHandle); - } - /// <summary> /// Determines whether the specified <see cref = "Object" /> is equal to the current <see cref = "GitObject" />. /// </summary> diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index cdac54f7..238328e5 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -283,11 +283,6 @@ namespace LibGit2Sharp return LookupInternal(id, type, null); } - internal GitObject LookupTreeEntryTarget(ObjectId id, FilePath path) - { - return LookupInternal(id, GitObjectType.Any, path); - } - internal GitObject LookupInternal(ObjectId id, GitObjectType type, FilePath knownPath) { Ensure.ArgumentNotNull(id, "id"); @@ -298,7 +293,12 @@ namespace LibGit2Sharp { obj = Proxy.git_object_lookup(handle, id, type); - return obj == null ? null : GitObject.BuildFromPtr(obj, id, this, knownPath); + if (obj == null) + { + return null; + } + + return GitObject.BuildFrom(this, id, Proxy.git_object_type(obj), knownPath); } finally { @@ -350,12 +350,14 @@ namespace LibGit2Sharp return null; } - if (type != GitObjectType.Any && Proxy.git_object_type(sh) != type) + GitObjectType objType = Proxy.git_object_type(sh); + + if (type != GitObjectType.Any && objType != type) { return null; } - obj = GitObject.BuildFromPtr(sh, GitObject.ObjectIdOf(sh), this, PathFromRevparseSpec(objectish)); + obj = GitObject.BuildFrom(this, Proxy.git_object_id(sh), objType, PathFromRevparseSpec(objectish)); } if (lookUpOptions.Has(LookUpOptions.DereferenceResultToCommit)) diff --git a/LibGit2Sharp/TagAnnotation.cs b/LibGit2Sharp/TagAnnotation.cs index d934ddc7..5bb62c71 100644 --- a/LibGit2Sharp/TagAnnotation.cs +++ b/LibGit2Sharp/TagAnnotation.cs @@ -1,6 +1,4 @@ using LibGit2Sharp.Core; -using LibGit2Sharp.Core.Compat; -using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { @@ -9,7 +7,11 @@ namespace LibGit2Sharp /// </summary> public class TagAnnotation : GitObject { - private Lazy<GitObject> targetBuilder; + private readonly GitObjectLazyGroup group; + private readonly ILazy<GitObject> lazyTarget; + private readonly ILazy<string> lazyName; + private readonly ILazy<string> lazyMessage; + private readonly ILazy<Signature> lazyTagger; /// <summary> /// Needed for mocking purposes. @@ -17,45 +19,36 @@ namespace LibGit2Sharp protected TagAnnotation() { } - internal TagAnnotation(ObjectId id) + internal TagAnnotation(Repository repo, ObjectId id) : base(id) { + lazyName = GitObjectLazyGroup.Singleton(repo, id, Proxy.git_tag_name); + lazyTarget = GitObjectLazyGroup.Singleton(repo, id, + obj => GitObject.BuildFrom(repo, Proxy.git_tag_target_oid(obj), Proxy.git_tag_type(obj), null)); + + group = new GitObjectLazyGroup(repo, id); + lazyTagger = group.AddLazy(Proxy.git_tag_tagger); + lazyMessage = group.AddLazy(Proxy.git_tag_message); } /// <summary> /// Gets the name of this tag. /// </summary> - public virtual string Name { get; private set; } + public virtual string Name { get { return lazyName.Value; } } /// <summary> /// Gets the message of this tag. /// </summary> - public virtual string Message { get; private set; } + public virtual string Message { get { return lazyMessage.Value; } } /// <summary> /// Gets the <see cref = "GitObject" /> that this tag annotation points to. /// </summary> - public virtual GitObject Target - { - get { return targetBuilder.Value; } - } + public virtual GitObject Target { get { return lazyTarget.Value; } } /// <summary> /// Gets the tagger. /// </summary> - public virtual Signature Tagger { get; private set; } - - internal static TagAnnotation BuildFromPtr(GitObjectSafeHandle obj, ObjectId id, Repository repo) - { - ObjectId targetOid = Proxy.git_tag_target_oid(obj); - - return new TagAnnotation(id) - { - Message = Proxy.git_tag_message(obj), - Name = Proxy.git_tag_name(obj), - Tagger = Proxy.git_tag_tagger(obj), - targetBuilder = new Lazy<GitObject>(() => repo.Lookup<GitObject>(targetOid)) - }; - } + public virtual Signature Tagger { get { return lazyTagger.Value; } } } } diff --git a/LibGit2Sharp/Tree.cs b/LibGit2Sharp/Tree.cs index bded3a85..6bdd2614 100644 --- a/LibGit2Sharp/Tree.cs +++ b/LibGit2Sharp/Tree.cs @@ -14,24 +14,27 @@ namespace LibGit2Sharp private readonly Repository repo; private readonly FilePath path; + private readonly ILazy<int> lazyCount; + /// <summary> /// Needed for mocking purposes. /// </summary> protected Tree() { } - internal Tree(ObjectId id, FilePath path, int treeEntriesCount, Repository repository) + internal Tree(Repository repo, ObjectId id, FilePath path) : base(id) { - Count = treeEntriesCount; - repo = repository; + this.repo = repo; this.path = path ?? ""; + + lazyCount = GitObjectLazyGroup.Singleton(repo, id, Proxy.git_tree_entrycount); } /// <summary> /// Gets the number of <see cref = "TreeEntry" /> immediately under this <see cref = "Tree" />. /// </summary> - public virtual int Count { get; private set; } + public virtual int Count { get { return lazyCount.Value; } } /// <summary> /// Gets the <see cref = "TreeEntry" /> pointed at by the <paramref name = "relativePath" /> in this <see cref = "Tree" /> instance. @@ -125,11 +128,5 @@ namespace LibGit2Sharp } #endregion - - internal new static Tree BuildFromPtr(GitObjectSafeHandle obj, ObjectId id, Repository repo, FilePath path) - { - var tree = new Tree(id, path, Proxy.git_tree_entrycount(obj), repo); - return tree; - } } } diff --git a/LibGit2Sharp/TreeEntry.cs b/LibGit2Sharp/TreeEntry.cs index 8ecc940f..57dc6b23 100644 --- a/LibGit2Sharp/TreeEntry.cs +++ b/LibGit2Sharp/TreeEntry.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.Runtime.InteropServices; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Compat; -using LibGit2Sharp.Core.Handles; namespace LibGit2Sharp { @@ -59,10 +58,7 @@ namespace LibGit2Sharp /// <summary> /// Gets the <see cref = "GitObject" /> being pointed at. /// </summary> - public virtual GitObject Target - { - get { return target.Value; } - } + public virtual GitObject Target { get { return target.Value; } } internal ObjectId TargetId { @@ -81,9 +77,7 @@ namespace LibGit2Sharp throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "TreeEntry target of type '{0}' are not supported.", Type)); } - GitObject treeEntryTarget = repo.LookupTreeEntryTarget(targetOid, Path); - - return treeEntryTarget; + return GitObject.BuildFrom(repo, targetOid, Type, Path); } /// <summary> |