@@ -188,6 +188,20 @@ func printAction(p runAction) {
188188 }
189189}
190190
191+ // getCommitParents returns the list of *unique* commit parents.
192+ // Yes, it *is* possible to have several identical parents, and Hercules used to crash because of that.
193+ func getCommitParents (commit * object.Commit ) []plumbing.Hash {
194+ result := make ([]plumbing.Hash , 0 , len (commit .ParentHashes ))
195+ parents := map [plumbing.Hash ]bool {}
196+ for _ , parent := range commit .ParentHashes {
197+ if _ , exists := parents [parent ]; ! exists {
198+ parents [parent ] = true
199+ result = append (result , parent )
200+ }
201+ }
202+ return result
203+ }
204+
191205// buildDag generates the raw commit DAG and the commit hash map.
192206func buildDag (commits []* object.Commit ) (
193207 map [string ]* object.Commit , map [plumbing.Hash ][]* object.Commit ) {
@@ -201,7 +215,8 @@ func buildDag(commits []*object.Commit) (
201215 if _ , exists := dag [commit .Hash ]; ! exists {
202216 dag [commit .Hash ] = make ([]* object.Commit , 0 , 1 )
203217 }
204- for _ , parent := range commit .ParentHashes {
218+
219+ for _ , parent := range getCommitParents (commit ) {
205220 if _ , exists := hashes [parent .String ()]; ! exists {
206221 continue
207222 }
@@ -242,7 +257,7 @@ func leaveRootComponent(
242257 }
243258 }
244259 if commit , exists := hashes [head .String ()]; exists {
245- for _ , p := range commit . ParentHashes {
260+ for _ , p := range getCommitParents ( commit ) {
246261 if ! visited [p ] {
247262 if _ , exists := hashes [p .String ()]; exists {
248263 queue = append (queue , p )
0 commit comments