forked from libgit2/libgit2sharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommitFilter.cs
More file actions
196 lines (164 loc) · 6.86 KB
/
CommitFilter.cs
File metadata and controls
196 lines (164 loc) · 6.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using LibGit2Sharp.Core;
namespace LibGit2Sharp
{
/// <summary>
/// Criterias used to filter out and order the commits of the repository when querying its history.
/// </summary>
public sealed class CommitFilter
{
/// <summary>
/// Initializes a new instance of <see cref="CommitFilter"/>.
/// </summary>
public CommitFilter()
{
SortBy = CommitSortStrategies.Time;
IncludeReachableFrom = "HEAD";
FirstParentOnly = false;
}
/// <summary>
/// The ordering stragtegy to use.
/// <para>
/// By default, the commits are shown in reverse chronological order.
/// </para>
/// </summary>
public CommitSortStrategies SortBy { get; set; }
/// <summary>
/// A pointer to a commit object or a list of pointers to consider as starting points.
/// <para>
/// Can be either a <see cref="string"/> containing the sha or reference canonical name to use,
/// a <see cref="Branch"/>, a <see cref="Reference"/>, a <see cref="Commit"/>, a <see cref="Tag"/>,
/// a <see cref="TagAnnotation"/>, an <see cref="ObjectId"/> or even a mixed collection of all of the above.
/// By default, the <see cref="Repository.Head"/> will be used as boundary.
/// </para>
/// </summary>
[Obsolete("This property will be removed in the next release. Please use IncludeReachableFrom instead.")]
public object Since
{
get { return IncludeReachableFrom; }
set { IncludeReachableFrom = value; }
}
/// <summary>
/// A pointer to a commit object or a list of pointers to consider as starting points.
/// <para>
/// Can be either a <see cref="string"/> containing the sha or reference canonical name to use,
/// a <see cref="Branch"/>, a <see cref="Reference"/>, a <see cref="Commit"/>, a <see cref="Tag"/>,
/// a <see cref="TagAnnotation"/>, an <see cref="ObjectId"/> or even a mixed collection of all of the above.
/// By default, the <see cref="Repository.Head"/> will be used as boundary.
/// </para>
/// </summary>
public object IncludeReachableFrom { get; set; }
internal IList<object> SinceList
{
get { return ToList(IncludeReachableFrom); }
}
/// <summary>
/// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration.
/// <para>
/// Can be either a <see cref="string"/> containing the sha or reference canonical name to use,
/// a <see cref="Branch"/>, a <see cref="Reference"/>, a <see cref="Commit"/>, a <see cref="Tag"/>,
/// a <see cref="TagAnnotation"/>, an <see cref="ObjectId"/> or even a mixed collection of all of the above.
/// </para>
/// </summary>
[Obsolete("This property will be removed in the next release. Please use ExcludeReachableFrom instead.")]
public object Until
{
get { return ExcludeReachableFrom; }
set { ExcludeReachableFrom = value; }
}
/// <summary>
/// A pointer to a commit object or a list of pointers which will be excluded (along with ancestors) from the enumeration.
/// <para>
/// Can be either a <see cref="string"/> containing the sha or reference canonical name to use,
/// a <see cref="Branch"/>, a <see cref="Reference"/>, a <see cref="Commit"/>, a <see cref="Tag"/>,
/// a <see cref="TagAnnotation"/>, an <see cref="ObjectId"/> or even a mixed collection of all of the above.
/// </para>
/// </summary>
public object ExcludeReachableFrom { get; set; }
internal IList<object> UntilList
{
get { return ToList(ExcludeReachableFrom); }
}
/// <summary>
/// Whether to limit the walk to each commit's first parent, instead of all of them
/// </summary>
public bool FirstParentOnly { get; set; }
private static IList<object> ToList(object obj)
{
var list = new List<object>();
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<object>());
return list;
}
public static CommitFilter Parse(string expression)
{
Ensure.ArgumentNotNullOrEmptyString(expression, "expression");
if (expression.Contains(" "))
{
throw new NotSupportedException();
}
if (expression.Contains("..."))
{
return MergeRangeParse(expression);
}
if (expression.Contains(".."))
{
return RangeParse(expression);
}
return new CommitFilter { IncludeReachableFrom = expression };
}
private static CommitFilter MergeRangeParse(string expression)
{
var parts = Strings(expression, "...");
throw new NotImplementedException();
}
private static CommitFilter RangeParse(string expression)
{
var parts = Strings(expression, "..");
return new CommitFilter { IncludeReachableFrom = parts[1], ExcludeReachableFrom = parts[0] };
}
static readonly Func<string, string> Nullify = s => s == string.Empty ? null : s;
private static string[] Strings(string expression, string rangeSeparator)
{
var parts = expression.Split(new[] { rangeSeparator }, StringSplitOptions.None);
if (parts.Length != 2)
{
throw new InvalidOperationException();
}
int nullsCount = 0;
for (int i = 0; i < parts.Length; i++)
{
string part = Nullify(parts[i]);
if (part == default(string))
{
nullsCount++;
}
if (nullsCount > 1)
{
throw new InvalidOperationException();
}
parts[i] = part;
}
return parts;
}
}
}