aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/object/commit_walker_file.go
diff options
context:
space:
mode:
Diffstat (limited to 'plumbing/object/commit_walker_file.go')
-rw-r--r--plumbing/object/commit_walker_file.go65
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()