Skip to content

Commit 10826a3

Browse files
authored
Merge pull request #183 from jfontan/fix/history_idx_loop
history_idx: do not visit a parent more than once
2 parents 7c500a6 + a5590f2 commit 10826a3

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

internal/function/history_idx.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func (f *HistoryIdx) repoHistoryIdx(repo *git.Repository, start, target plumbing
127127
// history. Because the frame keeps track of which was its index, we can
128128
// return accurate indexes even if there are multiple branches.
129129
stack := []*stackFrame{{0, 0, []plumbing.Hash{start}}}
130+
visitedHashes := make(map[plumbing.Hash]struct{})
130131

131132
for {
132133
if len(stack) == 0 {
@@ -135,7 +136,12 @@ func (f *HistoryIdx) repoHistoryIdx(repo *git.Repository, start, target plumbing
135136

136137
frame := stack[len(stack)-1]
137138

138-
c, err := repo.CommitObject(frame.hashes[frame.pos])
139+
h := frame.hashes[frame.pos]
140+
if _, ok := visitedHashes[h]; !ok {
141+
visitedHashes[h] = struct{}{}
142+
}
143+
144+
c, err := repo.CommitObject(h)
139145
if err == plumbing.ErrObjectNotFound {
140146
return -1, nil
141147
}
@@ -155,7 +161,16 @@ func (f *HistoryIdx) repoHistoryIdx(repo *git.Repository, start, target plumbing
155161
}
156162

157163
if c.NumParents() > 0 {
158-
stack = append(stack, &stackFrame{frame.idx + 1, 0, c.ParentHashes})
164+
newParents := make([]plumbing.Hash, 0, c.NumParents())
165+
for _, h = range c.ParentHashes {
166+
if _, ok := visitedHashes[h]; !ok {
167+
newParents = append(newParents, h)
168+
}
169+
}
170+
171+
if len(newParents) > 0 {
172+
stack = append(stack, &stackFrame{frame.idx + 1, 0, newParents})
173+
}
159174
}
160175
}
161176
}

0 commit comments

Comments
 (0)