diff options
Diffstat (limited to 'plumbing/object/commit_walker_file.go')
-rw-r--r-- | plumbing/object/commit_walker_file.go | 65 |
1 files changed, 38 insertions, 27 deletions
diff --git a/plumbing/object/commit_walker_file.go b/plumbing/object/commit_walker_file.go index 1af9ec1..6f16e61 100644 --- a/plumbing/object/commit_walker_file.go +++ b/plumbing/object/commit_walker_file.go @@ -3,6 +3,8 @@ package object import ( "io" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/storer" ) @@ -10,17 +12,19 @@ type commitFileIter struct { fileName string sourceIter CommitIter currentCommit *Commit - all bool + checkParent bool } // NewCommitFileIterFromIter returns a commit iterator which performs diffTree between // successive trees returned from the commit iterator from the argument. The purpose of this is // to find the commits that explain how the files that match the path came to be. -func NewCommitFileIterFromIter(fileName string, commitIter CommitIter, all bool) CommitIter { +// If checkParent is true then the function double checks if potential parent (next commit in a path) +// is one of the parents in the tree (it's used by `git log --all`). +func NewCommitFileIterFromIter(fileName string, commitIter CommitIter, checkParent bool) CommitIter { iterator := new(commitFileIter) iterator.sourceIter = commitIter iterator.fileName = fileName - iterator.all = all + iterator.checkParent = checkParent return iterator } @@ -74,36 +78,14 @@ func (c *commitFileIter) getNextFileCommit() (*Commit, error) { return nil, diffErr } - foundChangeForFile := false - for _, change := range changes { - if change.name() != c.fileName { - continue - } - - // filename matches, now check if source iterator contains all commits (from all refs) - if c.all { - // for `git log --all` also check if the next commit comes from the same parent - for _, h := range c.currentCommit.ParentHashes { - if h == parentCommit.Hash { - foundChangeForFile = true - break - } - } - } else { - foundChangeForFile = true - } - - if foundChangeForFile { - break - } - } + found := c.hasFileChange(changes, parentCommit) // Storing the current-commit in-case a change is found, and // Updating the current-commit for the next-iteration prevCommit := c.currentCommit c.currentCommit = parentCommit - if foundChangeForFile == true { + if found { return prevCommit, nil } @@ -114,6 +96,35 @@ func (c *commitFileIter) getNextFileCommit() (*Commit, error) { } } +func (c *commitFileIter) hasFileChange(changes Changes, parent *Commit) bool { + for _, change := range changes { + if change.name() != c.fileName { + continue + } + + // filename matches, now check if source iterator contains all commits (from all refs) + if c.checkParent { + if parent != nil && isParentHash(parent.Hash, c.currentCommit) { + return true + } + continue + } + + return true + } + + return false +} + +func isParentHash(hash plumbing.Hash, commit *Commit) bool { + for _, h := range commit.ParentHashes { + if h == hash { + return true + } + } + return false +} + func (c *commitFileIter) ForEach(cb func(*Commit) error) error { for { commit, nextErr := c.Next() |