diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2016-08-23 00:37:36 +0200 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2016-08-23 00:37:36 +0200 |
commit | 9ae3c5808fcfa468d1f9394c9b16bc02f573ba79 (patch) | |
tree | 917c5dc717c02654baeebd06bef89436ad4c65ec /commit_walker.go | |
parent | 2ed3474ab8e52c98a87e390d5128d45d693a115d (diff) | |
download | go-git-9ae3c5808fcfa468d1f9394c9b16bc02f573ba79.tar.gz |
WalkCommitHistory adn Commit.History
Diffstat (limited to 'commit_walker.go')
-rw-r--r-- | commit_walker.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/commit_walker.go b/commit_walker.go new file mode 100644 index 0000000..e595a84 --- /dev/null +++ b/commit_walker.go @@ -0,0 +1,67 @@ +package git + +import ( + "io" + + "gopkg.in/src-d/go-git.v4/core" +) + +type commitWalker struct { + seen map[core.Hash]bool + stack []*CommitIter + start *Commit + cb func(*Commit) error +} + +// WalkCommitHistory walks the commit history +func WalkCommitHistory(c *Commit, cb func(*Commit) error) error { + w := &commitWalker{ + seen: make(map[core.Hash]bool), + stack: make([]*CommitIter, 0), + start: c, + cb: cb, + } + + return w.walk() +} + +func (w *commitWalker) walk() error { + var commit *Commit + + if w.start != nil { + commit = w.start + w.start = nil + } else { + current := len(w.stack) - 1 + if current < 0 { + return nil + } + + var err error + commit, err = w.stack[current].Next() + if err == io.EOF { + w.stack = w.stack[:current] + return w.walk() + } + + if err != nil { + return err + } + } + + // check and update seen + if w.seen[commit.Hash] { + return w.walk() + } + + w.seen[commit.Hash] = true + if commit.NumParents() > 0 { + w.stack = append(w.stack, commit.Parents()) + } + + if err := w.cb(commit); err != nil { + return err + } + + return w.walk() +} |