mirror of
https://github.com/go-gitea/gitea.git
synced 2024-10-18 06:33:44 -04:00
08bf443016
* Inital routes to git refs api * Git refs API implementation * Update swagger * Fix copyright * Make swagger happy add basic test * Fix test * Fix test again :)
116 lines
2.8 KiB
Go
116 lines
2.8 KiB
Go
package object
|
|
|
|
import (
|
|
"gopkg.in/src-d/go-git.v4/plumbing/storer"
|
|
"io"
|
|
)
|
|
|
|
type commitFileIter struct {
|
|
fileName string
|
|
sourceIter CommitIter
|
|
currentCommit *Commit
|
|
}
|
|
|
|
// 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) CommitIter {
|
|
iterator := new(commitFileIter)
|
|
iterator.sourceIter = commitIter
|
|
iterator.fileName = fileName
|
|
return iterator
|
|
}
|
|
|
|
func (c *commitFileIter) Next() (*Commit, error) {
|
|
if c.currentCommit == nil {
|
|
var err error
|
|
c.currentCommit, err = c.sourceIter.Next()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
commit, commitErr := c.getNextFileCommit()
|
|
|
|
// Setting current-commit to nil to prevent unwanted states when errors are raised
|
|
if commitErr != nil {
|
|
c.currentCommit = nil
|
|
}
|
|
return commit, commitErr
|
|
}
|
|
|
|
func (c *commitFileIter) getNextFileCommit() (*Commit, error) {
|
|
for {
|
|
// Parent-commit can be nil if the current-commit is the initial commit
|
|
parentCommit, parentCommitErr := c.sourceIter.Next()
|
|
if parentCommitErr != nil {
|
|
// If the parent-commit is beyond the initial commit, keep it nil
|
|
if parentCommitErr != io.EOF {
|
|
return nil, parentCommitErr
|
|
}
|
|
parentCommit = nil
|
|
}
|
|
|
|
// Fetch the trees of the current and parent commits
|
|
currentTree, currTreeErr := c.currentCommit.Tree()
|
|
if currTreeErr != nil {
|
|
return nil, currTreeErr
|
|
}
|
|
|
|
var parentTree *Tree
|
|
if parentCommit != nil {
|
|
var parentTreeErr error
|
|
parentTree, parentTreeErr = parentCommit.Tree()
|
|
if parentTreeErr != nil {
|
|
return nil, parentTreeErr
|
|
}
|
|
}
|
|
|
|
// Find diff between current and parent trees
|
|
changes, diffErr := DiffTree(currentTree, parentTree)
|
|
if diffErr != nil {
|
|
return nil, diffErr
|
|
}
|
|
|
|
foundChangeForFile := false
|
|
for _, change := range changes {
|
|
if change.name() == c.fileName {
|
|
foundChangeForFile = true
|
|
break
|
|
}
|
|
}
|
|
|
|
// 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 {
|
|
return prevCommit, nil
|
|
}
|
|
|
|
// If not matches found and if parent-commit is beyond the initial commit, then return with EOF
|
|
if parentCommit == nil {
|
|
return nil, io.EOF
|
|
}
|
|
}
|
|
}
|
|
|
|
func (c *commitFileIter) ForEach(cb func(*Commit) error) error {
|
|
for {
|
|
commit, nextErr := c.Next()
|
|
if nextErr != nil {
|
|
return nextErr
|
|
}
|
|
err := cb(commit)
|
|
if err == storer.ErrStop {
|
|
return nil
|
|
} else if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
func (c *commitFileIter) Close() {
|
|
c.sourceIter.Close()
|
|
}
|