@@ -336,7 +336,7 @@ public static IEnumerable<Commit> GetCommitsFromVersion(this Repository repo, Ve
336336 Requires . NotNull ( version , nameof ( version ) ) ;
337337
338338 var tracker = new GitWalkTracker ( repoRelativeProjectDirectory ) ;
339- var possibleCommits = from commit in GetCommitsReachableFromRefs ( repo ) . Distinct ( )
339+ var possibleCommits = from commit in GetCommitsReachableFromRefs ( repo )
340340 let commitVersionOptions = tracker . GetVersion ( commit )
341341 where commitVersionOptions != null
342342 where ! IsCommitIdMismatch ( version , commitVersionOptions , commit )
@@ -830,45 +830,29 @@ private static IEnumerable<Commit> GetCommitsReachableFromRefs(Repository repo)
830830 {
831831 Requires . NotNull ( repo , nameof ( repo ) ) ;
832832
833- var commits = new HashSet < Commit > ( ) ;
833+ var visitedCommitIds = new HashSet < ObjectId > ( ) ;
834+ var breadthFirstQueue = new Queue < Commit > ( ) ;
835+
836+ // Start the discovery with HEAD, and all commits that have refs pointing to them.
837+ breadthFirstQueue . Enqueue ( repo . Head . Tip ) ;
834838 foreach ( var reference in repo . Refs )
835839 {
836840 var commit = reference . ResolveToDirectReference ( ) ? . Target as Commit ;
837- if ( commit != null )
841+ if ( commit is object )
838842 {
839- AddReachableCommitsFrom ( commit , commits ) ;
843+ breadthFirstQueue . Enqueue ( commit ) ;
840844 }
841845 }
842846
843- return commits ;
844- }
845-
846- /// <summary>
847- /// Adds a commit and all its ancestors to a set.
848- /// </summary>
849- /// <param name="startingCommit">The starting commit to add.</param>
850- /// <param name="set">
851- /// The set into which the <paramref name="startingCommit"/>
852- /// and all its ancestors are to be added.
853- /// </param>
854- private static void AddReachableCommitsFrom ( Commit startingCommit , HashSet < Commit > set )
855- {
856- Requires . NotNull ( startingCommit , nameof ( startingCommit ) ) ;
857- Requires . NotNull ( set , nameof ( set ) ) ;
858-
859- var stack = new Stack < Commit > ( ) ;
860- stack . Push ( startingCommit ) ;
861- while ( stack . Count > 0 )
847+ while ( breadthFirstQueue . Count > 0 )
862848 {
863- var currentCommit = stack . Pop ( ) ;
864- if ( set . Add ( currentCommit ) )
849+ Commit head = breadthFirstQueue . Dequeue ( ) ;
850+ if ( visitedCommitIds . Add ( head . Id ) )
865851 {
866- foreach ( var parent in currentCommit . Parents )
852+ yield return head ;
853+ foreach ( Commit parent in head . Parents )
867854 {
868- if ( ! set . Contains ( parent ) )
869- {
870- stack . Push ( parent ) ;
871- }
855+ breadthFirstQueue . Enqueue ( parent ) ;
872856 }
873857 }
874858 }
0 commit comments