From 27c654184eff2bdf1ba38621dcb1608f3735b5c3 Mon Sep 17 00:00:00 2001 From: Tim Clem Date: Fri, 15 Jun 2012 14:51:29 -0700 Subject: [PATCH 1/5] Add in native method signatures for push/hide globs in revwalk --- LibGit2Sharp/Core/NativeMethods.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 049e03b15..376dd69f9 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -584,6 +584,9 @@ public static bool RepositoryStateChecker(RepositorySafeHandle repositoryPtr, Fu [DllImport(libgit2)] public static extern int git_revwalk_hide(RevWalkerSafeHandle walker, ref GitOid oid); + [DllImport(libgit2)] + public static extern int git_revwalk_hide_glob(RevWalkerSafeHandle walker, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string glob); + [DllImport(libgit2)] public static extern int git_revwalk_new(out RevWalkerSafeHandle walker, RepositorySafeHandle repo); @@ -593,6 +596,9 @@ public static bool RepositoryStateChecker(RepositorySafeHandle repositoryPtr, Fu [DllImport(libgit2)] public static extern int git_revwalk_push(RevWalkerSafeHandle walker, ref GitOid oid); + [DllImport(libgit2)] + public static extern int git_revwalk_push_glob(RevWalkerSafeHandle walker, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string glob); + [DllImport(libgit2)] public static extern void git_revwalk_reset(RevWalkerSafeHandle walker); From b0356e6978f39fd8c393adf9862328bd64578674 Mon Sep 17 00:00:00 2001 From: Tim Clem Date: Fri, 15 Jun 2012 15:08:08 -0700 Subject: [PATCH 2/5] Enhance revwalking to push/hide globs --- LibGit2Sharp.Tests/CommitFixture.cs | 22 +++++++++ LibGit2Sharp/CommitLog.cs | 69 ++++++++++------------------- LibGit2Sharp/Filter.cs | 69 ++++++++++++++++++++++++++++- 3 files changed, 113 insertions(+), 47 deletions(-) diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index 9f8dba4bb..ba618567a 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -289,6 +289,28 @@ public void CanEnumerateCommitsFromMixedStartingPoints() }); } + [Fact] + public void CanEnumerateCommitsUsingGlob() + { + AssertEnumerationOfCommits( + repo => new Filter { SinceGlob = "heads" }, + new[] + { + "4c062a6", "e90810b", "6dcf9bf", "a4a7dce", "be3563a", "c47800c", "9fd738e", "4a202b3", "41bc8c6", "5001298", "5b5b025", "8496071" + }); + } + + [Fact] + public void CanHideCommitsUsingGlob() + { + AssertEnumerationOfCommits( + repo => new Filter { Since = "refs/heads/packed-test", UntilGlob = "packed" }, + new[] + { + "4a202b3", "5b5b025", "8496071" + }); + } + [Fact] public void CanEnumerateCommitsFromAnAnnotatedTag() { diff --git a/LibGit2Sharp/CommitLog.cs b/LibGit2Sharp/CommitLog.cs index 4cd7c0bce..73e413f85 100644 --- a/LibGit2Sharp/CommitLog.cs +++ b/LibGit2Sharp/CommitLog.cs @@ -14,9 +14,7 @@ namespace LibGit2Sharp public class CommitLog : IQueryableCommitLog { private readonly Repository repo; - private IList includedIdentifier = new List { "HEAD" }; - private IList excludedIdentifier = new List(); - private readonly GitSortOptions sortOptions; + readonly Filter queryFilter; /// /// Initializes a new instance of the class. @@ -24,7 +22,7 @@ public class CommitLog : IQueryableCommitLog /// /// The repository. internal CommitLog(Repository repo) - : this(repo, GitSortOptions.Time) + : this(repo, new Filter()) { } @@ -32,11 +30,11 @@ internal CommitLog(Repository repo) /// Initializes a new instance of the class. /// /// The repository. - /// The sorting strategy which should be applied when enumerating the commits. - internal CommitLog(Repository repo, GitSortOptions sortingStrategy) + /// The filter to use in querying commits + internal CommitLog(Repository repo, Filter queryFilter) { this.repo = repo; - sortOptions = sortingStrategy; + this.queryFilter = queryFilter; } /// @@ -44,7 +42,7 @@ internal CommitLog(Repository repo, GitSortOptions sortingStrategy) /// public GitSortOptions SortedBy { - get { return sortOptions; } + get { return queryFilter.SortBy; } } #region IEnumerable Members @@ -55,12 +53,12 @@ public GitSortOptions SortedBy /// An object that can be used to iterate through the log. public IEnumerator GetEnumerator() { - if ((repo.Info.IsEmpty) && includedIdentifier.Any(o => PointsAtTheHead(o.ToString()))) // TODO: ToString() == fragile + if ((repo.Info.IsEmpty) && queryFilter.SinceList.Any(o => PointsAtTheHead(o.ToString()))) // TODO: ToString() == fragile { return Enumerable.Empty().GetEnumerator(); } - return new CommitEnumerator(repo, includedIdentifier, excludedIdentifier, sortOptions); + return new CommitEnumerator(repo, queryFilter); } /// @@ -85,38 +83,7 @@ public ICommitLog QueryBy(Filter filter) Ensure.ArgumentNotNull(filter.Since, "filter.Since"); Ensure.ArgumentNotNullOrEmptyString(filter.Since.ToString(), "filter.Since"); - return new CommitLog(repo, filter.SortBy) - { - includedIdentifier = ToList(filter.Since), - excludedIdentifier = ToList(filter.Until) - }; - } - - private static IList ToList(object obj) - { - var list = new List(); - - if (obj == null) - { - return list; - } - - var types = new[] - { - typeof(string), typeof(ObjectId), - typeof(Commit), typeof(TagAnnotation), - typeof(Tag), typeof(Branch), typeof(DetachedHead), - typeof(Reference), typeof(DirectReference), typeof(SymbolicReference) - }; - - if (types.Contains(obj.GetType())) - { - list.Add(obj); - return list; - } - - list.AddRange(((IEnumerable)obj).Cast()); - return list; + return new CommitLog(repo, filter); } private static bool PointsAtTheHead(string shaOrRefName) @@ -215,7 +182,7 @@ private class CommitEnumerator : IEnumerator private readonly RevWalkerSafeHandle handle; private ObjectId currentOid; - public CommitEnumerator(Repository repo, IList includedIdentifier, IList excludedIdentifier, GitSortOptions sortingStrategy) + public CommitEnumerator(Repository repo, Filter filter) { this.repo = repo; int res = NativeMethods.git_revwalk_new(out handle, repo.Handle); @@ -223,9 +190,19 @@ public CommitEnumerator(Repository repo, IList includedIdentifier, IList Ensure.Success(res); - Sort(sortingStrategy); - Push(includedIdentifier); - Hide(excludedIdentifier); + Sort(filter.SortBy); + Push(filter.SinceList); + Hide(filter.UntilList); + + if(!string.IsNullOrEmpty(filter.SinceGlob)) + { + Ensure.Success(NativeMethods.git_revwalk_push_glob(handle, filter.SinceGlob)); + } + + if(!string.IsNullOrEmpty(filter.UntilGlob)) + { + Ensure.Success(NativeMethods.git_revwalk_hide_glob(handle, filter.UntilGlob)); + } } #region IEnumerator Members diff --git a/LibGit2Sharp/Filter.cs b/LibGit2Sharp/Filter.cs index 5baa2d73c..b1968d9ce 100644 --- a/LibGit2Sharp/Filter.cs +++ b/LibGit2Sharp/Filter.cs @@ -1,10 +1,17 @@ -namespace LibGit2Sharp +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace LibGit2Sharp { /// /// Criterias used to filter out and order the commits of the repository when querying its history. /// public class Filter { + IList sinceList; + IList untilList; + /// /// Initializes a new instance of . /// @@ -33,6 +40,23 @@ public Filter() /// public object Since { get; set; } + + /// + /// Return a parsed list of Since objects. + /// + public IList SinceList + { + get + { + return sinceList ?? (sinceList = ToList(Since)); + } + } + + /// + /// A string glob to using as a starting point for the revwalk. + /// + public string SinceGlob { get; set; } + /// /// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration. /// @@ -42,5 +66,48 @@ public Filter() /// /// public object Until { get; set; } + + /// + /// Return a parsed list of Until objects. + /// + public IList UntilList + { + get + { + return untilList ?? (untilList = ToList(Until)); + } + } + + /// + /// A string glob to hide from the revwalk. + /// + public string UntilGlob { get; set; } + + static IList ToList(object obj) + { + var list = new List(); + + if (obj == null) + { + return list; + } + + var types = new[] + { + typeof(string), typeof(ObjectId), + typeof(Commit), typeof(TagAnnotation), + typeof(Tag), typeof(Branch), typeof(DetachedHead), + typeof(Reference), typeof(DirectReference), typeof(SymbolicReference) + }; + + if (types.Contains(obj.GetType())) + { + list.Add(obj); + return list; + } + + list.AddRange(((IEnumerable)obj).Cast()); + return list; + } } } From aba6add8d33e3656d52d96a1a6039ba077d47449 Mon Sep 17 00:00:00 2001 From: Tim Clem Date: Mon, 18 Jun 2012 09:13:03 -0700 Subject: [PATCH 3/5] Don't force filters to have Since --- LibGit2Sharp.Tests/CommitFixture.cs | 3 --- LibGit2Sharp/CommitLog.cs | 2 -- 2 files changed, 5 deletions(-) diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index ba618567a..78db0d995 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -98,7 +98,6 @@ public void QueryingTheCommitHistoryWithUnknownShaOrInvalidEntryPointThrows() { Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = Constants.UnknownSha }).Count()); Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = "refs/heads/deadbeef" }).Count()); - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = null }).Count()); } } @@ -120,8 +119,6 @@ public void QueryingTheCommitHistoryWithBadParamsThrows() { using (var repo = new Repository(BareTestRepoPath)) { - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = string.Empty })); - Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = null })); Assert.Throws(() => repo.Commits.QueryBy(null)); } } diff --git a/LibGit2Sharp/CommitLog.cs b/LibGit2Sharp/CommitLog.cs index 73e413f85..ab9a1b7a2 100644 --- a/LibGit2Sharp/CommitLog.cs +++ b/LibGit2Sharp/CommitLog.cs @@ -80,8 +80,6 @@ IEnumerator IEnumerable.GetEnumerator() public ICommitLog QueryBy(Filter filter) { Ensure.ArgumentNotNull(filter, "filter"); - Ensure.ArgumentNotNull(filter.Since, "filter.Since"); - Ensure.ArgumentNotNullOrEmptyString(filter.Since.ToString(), "filter.Since"); return new CommitLog(repo, filter); } From b7dc4d39b1a2da9bfe5e7dd7285202d3a58269c9 Mon Sep 17 00:00:00 2001 From: Tim Clem Date: Thu, 21 Jun 2012 11:25:34 -0700 Subject: [PATCH 4/5] Make SinceList and UntilList internal --- LibGit2Sharp/Filter.cs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/LibGit2Sharp/Filter.cs b/LibGit2Sharp/Filter.cs index b1968d9ce..913421321 100644 --- a/LibGit2Sharp/Filter.cs +++ b/LibGit2Sharp/Filter.cs @@ -40,16 +40,12 @@ public Filter() /// public object Since { get; set; } - - /// + /// /// Return a parsed list of Since objects. /// - public IList SinceList + internal IList SinceList { - get - { - return sinceList ?? (sinceList = ToList(Since)); - } + get { return sinceList ?? (sinceList = ToList(Since)); } } /// @@ -70,12 +66,9 @@ public IList SinceList /// /// Return a parsed list of Until objects. /// - public IList UntilList + internal IList UntilList { - get - { - return untilList ?? (untilList = ToList(Until)); - } + get { return untilList ?? (untilList = ToList(Until)); } } /// @@ -93,12 +86,12 @@ static IList ToList(object obj) } var types = new[] - { - typeof(string), typeof(ObjectId), - typeof(Commit), typeof(TagAnnotation), - typeof(Tag), typeof(Branch), typeof(DetachedHead), - typeof(Reference), typeof(DirectReference), typeof(SymbolicReference) - }; + { + typeof(string), typeof(ObjectId), + typeof(Commit), typeof(TagAnnotation), + typeof(Tag), typeof(Branch), typeof(DetachedHead), + typeof(Reference), typeof(DirectReference), typeof(SymbolicReference) + }; if (types.Contains(obj.GetType())) { From aec0563dd13a73a2e2bacb4abddb4670e6e1d705 Mon Sep 17 00:00:00 2001 From: Tim Clem Date: Thu, 21 Jun 2012 11:30:30 -0700 Subject: [PATCH 5/5] Check Since param if SinceGlob is not specified --- LibGit2Sharp.Tests/CommitFixture.cs | 3 +++ LibGit2Sharp/CommitLog.cs | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index 16a1edc6b..0fbf42aeb 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -98,6 +98,7 @@ public void QueryingTheCommitHistoryWithUnknownShaOrInvalidEntryPointThrows() { Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = Constants.UnknownSha }).Count()); Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = "refs/heads/deadbeef" }).Count()); + Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = null }).Count()); } } @@ -119,6 +120,8 @@ public void QueryingTheCommitHistoryWithBadParamsThrows() { using (var repo = new Repository(BareTestRepoPath)) { + Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = string.Empty })); + Assert.Throws(() => repo.Commits.QueryBy(new Filter { Since = null })); Assert.Throws(() => repo.Commits.QueryBy(null)); } } diff --git a/LibGit2Sharp/CommitLog.cs b/LibGit2Sharp/CommitLog.cs index 91619f894..e8ebaebc3 100644 --- a/LibGit2Sharp/CommitLog.cs +++ b/LibGit2Sharp/CommitLog.cs @@ -87,6 +87,12 @@ public virtual ICommitLog QueryBy(Filter filter) { Ensure.ArgumentNotNull(filter, "filter"); + if(string.IsNullOrEmpty(filter.SinceGlob)) + { + Ensure.ArgumentNotNull(filter.Since, "filter.Since"); + Ensure.ArgumentNotNullOrEmptyString(filter.Since.ToString(), "filter.Since"); + } + return new CommitLog(repo, filter); }