diff options
author | Daniel Martí <mvdan@mvdan.cc> | 2017-03-12 21:52:29 +0000 |
---|---|---|
committer | Daniel Martí <mvdan@mvdan.cc> | 2017-03-27 11:29:19 +0100 |
commit | 33db30d79702b717324574a34bd262fc655234ef (patch) | |
tree | 9406b5fe98a828805036a75fdcf5b26fe8107506 /plumbing/object/commit_walker.go | |
parent | 4eef16a98d093057f1e4c560da4ed3bbba67cd76 (diff) | |
download | go-git-33db30d79702b717324574a34bd262fc655234ef.tar.gz |
plumbing/object: add WalkCommitHistoryPost func
Also add a test. Make both the pre-order and post-order tests not sort
commits, to actually test the order in which the commit history is
walked.
Fixes #223.
Diffstat (limited to 'plumbing/object/commit_walker.go')
-rw-r--r-- | plumbing/object/commit_walker.go | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/plumbing/object/commit_walker.go b/plumbing/object/commit_walker.go index b986067..681ea5e 100644 --- a/plumbing/object/commit_walker.go +++ b/plumbing/object/commit_walker.go @@ -69,3 +69,28 @@ func (w *commitWalker) walk() error { return w.walk() } + +// WalkCommitHistoryPost walks the commit history like WalkCommitHistory +// but in post-order. This means that after walking a merge commit, the +// merged commit will be walked before the base it was merged on. This +// can be useful if you wish to see the history in chronological order. +func WalkCommitHistoryPost(c *Commit, cb func(*Commit) error) error { + stack := []*Commit{c} + seen := make(map[plumbing.Hash]bool) + for len(stack) > 0 { + c := stack[len(stack)-1] + stack = stack[:len(stack)-1] + if seen[c.Hash] { + continue + } + seen[c.Hash] = true + if err := cb(c); err != nil { + return err + } + c.Parents().ForEach(func(pcm *Commit) error { + stack = append(stack, pcm) + return nil + }) + } + return nil +} |