Skip to content

Commit b0356e6

Browse files
committed
Enhance revwalking to push/hide globs
1 parent 27c6541 commit b0356e6

File tree

3 files changed

+113
-47
lines changed

3 files changed

+113
-47
lines changed

LibGit2Sharp.Tests/CommitFixture.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,28 @@ public void CanEnumerateCommitsFromMixedStartingPoints()
289289
});
290290
}
291291

292+
[Fact]
293+
public void CanEnumerateCommitsUsingGlob()
294+
{
295+
AssertEnumerationOfCommits(
296+
repo => new Filter { SinceGlob = "heads" },
297+
new[]
298+
{
299+
"4c062a6", "e90810b", "6dcf9bf", "a4a7dce", "be3563a", "c47800c", "9fd738e", "4a202b3", "41bc8c6", "5001298", "5b5b025", "8496071"
300+
});
301+
}
302+
303+
[Fact]
304+
public void CanHideCommitsUsingGlob()
305+
{
306+
AssertEnumerationOfCommits(
307+
repo => new Filter { Since = "refs/heads/packed-test", UntilGlob = "packed" },
308+
new[]
309+
{
310+
"4a202b3", "5b5b025", "8496071"
311+
});
312+
}
313+
292314
[Fact]
293315
public void CanEnumerateCommitsFromAnAnnotatedTag()
294316
{

LibGit2Sharp/CommitLog.cs

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,35 @@ namespace LibGit2Sharp
1414
public class CommitLog : IQueryableCommitLog
1515
{
1616
private readonly Repository repo;
17-
private IList<object> includedIdentifier = new List<object> { "HEAD" };
18-
private IList<object> excludedIdentifier = new List<object>();
19-
private readonly GitSortOptions sortOptions;
17+
readonly Filter queryFilter;
2018

2119
/// <summary>
2220
/// Initializes a new instance of the <see cref = "CommitLog" /> class.
2321
/// The commits will be enumerated according in reverse chronological order.
2422
/// </summary>
2523
/// <param name = "repo">The repository.</param>
2624
internal CommitLog(Repository repo)
27-
: this(repo, GitSortOptions.Time)
25+
: this(repo, new Filter())
2826
{
2927
}
3028

3129
/// <summary>
3230
/// Initializes a new instance of the <see cref = "CommitLog" /> class.
3331
/// </summary>
3432
/// <param name = "repo">The repository.</param>
35-
/// <param name = "sortingStrategy">The sorting strategy which should be applied when enumerating the commits.</param>
36-
internal CommitLog(Repository repo, GitSortOptions sortingStrategy)
33+
/// <param name="queryFilter">The filter to use in querying commits</param>
34+
internal CommitLog(Repository repo, Filter queryFilter)
3735
{
3836
this.repo = repo;
39-
sortOptions = sortingStrategy;
37+
this.queryFilter = queryFilter;
4038
}
4139

4240
/// <summary>
4341
/// Gets the current sorting strategy applied when enumerating the log
4442
/// </summary>
4543
public GitSortOptions SortedBy
4644
{
47-
get { return sortOptions; }
45+
get { return queryFilter.SortBy; }
4846
}
4947

5048
#region IEnumerable<Commit> Members
@@ -55,12 +53,12 @@ public GitSortOptions SortedBy
5553
/// <returns>An <see cref = "IEnumerator{T}" /> object that can be used to iterate through the log.</returns>
5654
public IEnumerator<Commit> GetEnumerator()
5755
{
58-
if ((repo.Info.IsEmpty) && includedIdentifier.Any(o => PointsAtTheHead(o.ToString()))) // TODO: ToString() == fragile
56+
if ((repo.Info.IsEmpty) && queryFilter.SinceList.Any(o => PointsAtTheHead(o.ToString()))) // TODO: ToString() == fragile
5957
{
6058
return Enumerable.Empty<Commit>().GetEnumerator();
6159
}
6260

63-
return new CommitEnumerator(repo, includedIdentifier, excludedIdentifier, sortOptions);
61+
return new CommitEnumerator(repo, queryFilter);
6462
}
6563

6664
/// <summary>
@@ -85,38 +83,7 @@ public ICommitLog QueryBy(Filter filter)
8583
Ensure.ArgumentNotNull(filter.Since, "filter.Since");
8684
Ensure.ArgumentNotNullOrEmptyString(filter.Since.ToString(), "filter.Since");
8785

88-
return new CommitLog(repo, filter.SortBy)
89-
{
90-
includedIdentifier = ToList(filter.Since),
91-
excludedIdentifier = ToList(filter.Until)
92-
};
93-
}
94-
95-
private static IList<object> ToList(object obj)
96-
{
97-
var list = new List<object>();
98-
99-
if (obj == null)
100-
{
101-
return list;
102-
}
103-
104-
var types = new[]
105-
{
106-
typeof(string), typeof(ObjectId),
107-
typeof(Commit), typeof(TagAnnotation),
108-
typeof(Tag), typeof(Branch), typeof(DetachedHead),
109-
typeof(Reference), typeof(DirectReference), typeof(SymbolicReference)
110-
};
111-
112-
if (types.Contains(obj.GetType()))
113-
{
114-
list.Add(obj);
115-
return list;
116-
}
117-
118-
list.AddRange(((IEnumerable)obj).Cast<object>());
119-
return list;
86+
return new CommitLog(repo, filter);
12087
}
12188

12289
private static bool PointsAtTheHead(string shaOrRefName)
@@ -215,17 +182,27 @@ private class CommitEnumerator : IEnumerator<Commit>
215182
private readonly RevWalkerSafeHandle handle;
216183
private ObjectId currentOid;
217184

218-
public CommitEnumerator(Repository repo, IList<object> includedIdentifier, IList<object> excludedIdentifier, GitSortOptions sortingStrategy)
185+
public CommitEnumerator(Repository repo, Filter filter)
219186
{
220187
this.repo = repo;
221188
int res = NativeMethods.git_revwalk_new(out handle, repo.Handle);
222189
repo.RegisterForCleanup(handle);
223190

224191
Ensure.Success(res);
225192

226-
Sort(sortingStrategy);
227-
Push(includedIdentifier);
228-
Hide(excludedIdentifier);
193+
Sort(filter.SortBy);
194+
Push(filter.SinceList);
195+
Hide(filter.UntilList);
196+
197+
if(!string.IsNullOrEmpty(filter.SinceGlob))
198+
{
199+
Ensure.Success(NativeMethods.git_revwalk_push_glob(handle, filter.SinceGlob));
200+
}
201+
202+
if(!string.IsNullOrEmpty(filter.UntilGlob))
203+
{
204+
Ensure.Success(NativeMethods.git_revwalk_hide_glob(handle, filter.UntilGlob));
205+
}
229206
}
230207

231208
#region IEnumerator<Commit> Members

LibGit2Sharp/Filter.cs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
namespace LibGit2Sharp
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace LibGit2Sharp
26
{
37
/// <summary>
48
/// Criterias used to filter out and order the commits of the repository when querying its history.
59
/// </summary>
610
public class Filter
711
{
12+
IList<object> sinceList;
13+
IList<object> untilList;
14+
815
/// <summary>
916
/// Initializes a new instance of <see cref = "Filter" />.
1017
/// </summary>
@@ -33,6 +40,23 @@ public Filter()
3340
/// </summary>
3441
public object Since { get; set; }
3542

43+
44+
/// <summary>
45+
/// Return a parsed list of Since objects.
46+
/// </summary>
47+
public IList<object> SinceList
48+
{
49+
get
50+
{
51+
return sinceList ?? (sinceList = ToList(Since));
52+
}
53+
}
54+
55+
/// <summary>
56+
/// A string glob to using as a starting point for the revwalk.
57+
/// </summary>
58+
public string SinceGlob { get; set; }
59+
3660
/// <summary>
3761
/// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration.
3862
/// <para>
@@ -42,5 +66,48 @@ public Filter()
4266
/// </para>
4367
/// </summary>
4468
public object Until { get; set; }
69+
70+
/// <summary>
71+
/// Return a parsed list of Until objects.
72+
/// </summary>
73+
public IList<object> UntilList
74+
{
75+
get
76+
{
77+
return untilList ?? (untilList = ToList(Until));
78+
}
79+
}
80+
81+
/// <summary>
82+
/// A string glob to hide from the revwalk.
83+
/// </summary>
84+
public string UntilGlob { get; set; }
85+
86+
static IList<object> ToList(object obj)
87+
{
88+
var list = new List<object>();
89+
90+
if (obj == null)
91+
{
92+
return list;
93+
}
94+
95+
var types = new[]
96+
{
97+
typeof(string), typeof(ObjectId),
98+
typeof(Commit), typeof(TagAnnotation),
99+
typeof(Tag), typeof(Branch), typeof(DetachedHead),
100+
typeof(Reference), typeof(DirectReference), typeof(SymbolicReference)
101+
};
102+
103+
if (types.Contains(obj.GetType()))
104+
{
105+
list.Add(obj);
106+
return list;
107+
}
108+
109+
list.AddRange(((IEnumerable)obj).Cast<object>());
110+
return list;
111+
}
45112
}
46113
}

0 commit comments

Comments
 (0)