From 3180dff8c5618b2e146a7fb4ac36be10851c86cc Mon Sep 17 00:00:00 2001 From: kuba-- Date: Thu, 3 Jan 2019 22:47:04 +0100 Subject: Implement git log --all Signed-off-by: kuba-- --- plumbing/object/commit_walker_file.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'plumbing/object/commit_walker_file.go') diff --git a/plumbing/object/commit_walker_file.go b/plumbing/object/commit_walker_file.go index 84e738a..1af9ec1 100644 --- a/plumbing/object/commit_walker_file.go +++ b/plumbing/object/commit_walker_file.go @@ -1,23 +1,26 @@ package object import ( - "gopkg.in/src-d/go-git.v4/plumbing/storer" "io" + + "gopkg.in/src-d/go-git.v4/plumbing/storer" ) type commitFileIter struct { fileName string sourceIter CommitIter currentCommit *Commit + all 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) CommitIter { +func NewCommitFileIterFromIter(fileName string, commitIter CommitIter, all bool) CommitIter { iterator := new(commitFileIter) iterator.sourceIter = commitIter iterator.fileName = fileName + iterator.all = all return iterator } @@ -73,8 +76,24 @@ func (c *commitFileIter) getNextFileCommit() (*Commit, error) { foundChangeForFile := false for _, change := range changes { - if change.name() == c.fileName { + 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 } } -- cgit From c9609eb875fea54ca9ffe409d1581ef94a38b6bc Mon Sep 17 00:00:00 2001 From: kuba-- Date: Wed, 9 Jan 2019 14:45:56 +0100 Subject: Refine Log. Signed-off-by: kuba-- --- plumbing/object/commit_walker_file.go | 65 ++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 27 deletions(-) (limited to 'plumbing/object/commit_walker_file.go') 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() -- cgit