@@ -169,22 +169,27 @@ bool TryCalculateHeight(GitCommit commit)
169
169
170
170
if ( pathFilters is not null )
171
171
{
172
- var relevantCommit = true ;
173
-
174
- foreach ( var parentId in commit . Parents )
172
+ // If the diff between this commit and any of its parents
173
+ // touches a path that we care about, bump the height.
174
+ bool relevantCommit = false , anyParents = false ;
175
+ foreach ( GitObjectId parentId in commit . Parents )
175
176
{
176
- var parent = repository . GetCommit ( parentId ) ;
177
- relevantCommit = IsRelevantCommit ( repository , commit , parent , pathFilters ) ;
178
-
179
- // If the diff between this commit and any of its parents
180
- // does not touch a path that we care about, don't bump the
181
- // height.
182
- if ( ! relevantCommit )
177
+ anyParents = true ;
178
+ GitCommit parent = repository . GetCommit ( parentId ) ;
179
+ if ( IsRelevantCommit ( repository , commit , parent , pathFilters ) )
183
180
{
181
+ // No need to scan further, as a positive match will never turn negative.
182
+ relevantCommit = true ;
184
183
break ;
185
184
}
186
185
}
187
186
187
+ if ( ! anyParents )
188
+ {
189
+ // A no-parent commit is relevant if it introduces anything in the filtered path.
190
+ relevantCommit = IsRelevantCommit ( repository , commit , parent : default ( GitCommit ) , pathFilters ) ;
191
+ }
192
+
188
193
if ( ! relevantCommit )
189
194
{
190
195
height = 0 ;
@@ -214,12 +219,12 @@ private static bool IsRelevantCommit(GitRepository repository, GitCommit commit,
214
219
return IsRelevantCommit (
215
220
repository ,
216
221
repository . GetTree ( commit . Tree ) ,
217
- repository . GetTree ( parent . Tree ) ,
222
+ parent != default ? repository . GetTree ( parent . Tree ) : null ,
218
223
relativePath : string . Empty ,
219
224
filters ) ;
220
225
}
221
226
222
- private static bool IsRelevantCommit ( GitRepository repository , GitTree tree , GitTree parent , string relativePath , IReadOnlyList < FilterPath > filters )
227
+ private static bool IsRelevantCommit ( GitRepository repository , GitTree tree , GitTree ? parent , string relativePath , IReadOnlyList < FilterPath > filters )
223
228
{
224
229
// Walk over all child nodes in the current tree. If a child node was found in the parent,
225
230
// remove it, so that after the iteration the parent contains all nodes which have been
@@ -231,8 +236,9 @@ private static bool IsRelevantCommit(GitRepository repository, GitTree tree, Git
231
236
232
237
// If the entry is not present in the parent commit, it was added;
233
238
// if the Sha does not match, it was modified.
234
- if ( ! parent . Children . TryGetValue ( child . Key , out parentEntry )
235
- || parentEntry . Sha != child . Value . Sha )
239
+ if ( parent is null ||
240
+ ! parent . Children . TryGetValue ( child . Key , out parentEntry ) ||
241
+ parentEntry . Sha != child . Value . Sha )
236
242
{
237
243
// Determine whether the change was relevant.
238
244
var fullPath = $ "{ relativePath } { entry . Name } ";
@@ -264,23 +270,27 @@ private static bool IsRelevantCommit(GitRepository repository, GitTree tree, Git
264
270
265
271
if ( parentEntry is not null )
266
272
{
273
+ Assumes . NotNull ( parent ) ;
267
274
parent . Children . Remove ( child . Key ) ;
268
275
}
269
276
}
270
277
271
278
// Inspect removed entries (i.e. present in parent but not in the current tree)
272
- foreach ( var child in parent . Children )
279
+ if ( parent is not null )
273
280
{
274
- // Determine whether the change was relevant.
275
- var fullPath = Path . Combine ( relativePath , child . Key ) ;
281
+ foreach ( var child in parent . Children )
282
+ {
283
+ // Determine whether the change was relevant.
284
+ var fullPath = Path . Combine ( relativePath , child . Key ) ;
276
285
277
- bool isRelevant =
278
- filters . Any ( f => f . Includes ( fullPath , repository . IgnoreCase ) )
279
- && ! filters . Any ( f => f . Excludes ( fullPath , repository . IgnoreCase ) ) ;
286
+ bool isRelevant =
287
+ filters . Any ( f => f . Includes ( fullPath , repository . IgnoreCase ) )
288
+ && ! filters . Any ( f => f . Excludes ( fullPath , repository . IgnoreCase ) ) ;
280
289
281
- if ( isRelevant )
282
- {
283
- return true ;
290
+ if ( isRelevant )
291
+ {
292
+ return true ;
293
+ }
284
294
}
285
295
}
286
296
0 commit comments