@@ -169,22 +169,27 @@ bool TryCalculateHeight(GitCommit commit)
169169
170170 if ( pathFilters is not null )
171171 {
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 )
175176 {
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 ) )
183180 {
181+ // No need to scan further, as a positive match will never turn negative.
182+ relevantCommit = true ;
184183 break ;
185184 }
186185 }
187186
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+
188193 if ( ! relevantCommit )
189194 {
190195 height = 0 ;
@@ -214,12 +219,12 @@ private static bool IsRelevantCommit(GitRepository repository, GitCommit commit,
214219 return IsRelevantCommit (
215220 repository ,
216221 repository . GetTree ( commit . Tree ) ,
217- repository . GetTree ( parent . Tree ) ,
222+ parent != default ? repository . GetTree ( parent . Tree ) : null ,
218223 relativePath : string . Empty ,
219224 filters ) ;
220225 }
221226
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 )
223228 {
224229 // Walk over all child nodes in the current tree. If a child node was found in the parent,
225230 // 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
231236
232237 // If the entry is not present in the parent commit, it was added;
233238 // 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 )
236242 {
237243 // Determine whether the change was relevant.
238244 var fullPath = $ "{ relativePath } { entry . Name } ";
@@ -264,23 +270,27 @@ private static bool IsRelevantCommit(GitRepository repository, GitTree tree, Git
264270
265271 if ( parentEntry is not null )
266272 {
273+ Assumes . NotNull ( parent ) ;
267274 parent . Children . Remove ( child . Key ) ;
268275 }
269276 }
270277
271278 // 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 )
273280 {
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 ) ;
276285
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 ) ) ;
280289
281- if ( isRelevant )
282- {
283- return true ;
290+ if ( isRelevant )
291+ {
292+ return true ;
293+ }
284294 }
285295 }
286296
0 commit comments