diff --git a/plumbing/object/commit_walker.go b/plumbing/object/commit_walker.go
index 92c6572..8c76557 100644
--- a/plumbing/object/commit_walker.go
+++ b/plumbing/object/commit_walker.go
@@ -186,98 +186,104 @@
 
 // commitAllIterator stands for commit iterator for all refs.
 type commitAllIterator struct {
-	// el points to the current commit.
-	el *list.Element
+	// currCommit points to the current commit.
+	currCommit *list.Element
 }
 
 // NewCommitAllIter returns a new commit iterator for all refs.
-// s is a repo Storer used to get commits and references.
-// fn is a commit iterator function, used to iterate through ref commits in chosen order
-func NewCommitAllIter(s storage.Storer, fn func(*Commit) CommitIter) (CommitIter, error) {
-	l := list.New()
-	m := make(map[plumbing.Hash]*list.Element)
-
-	// ...along with the HEAD
-	head, err := storer.ResolveReference(s, plumbing.HEAD)
-	if err != nil {
-		return nil, err
-	}
-	headCommit, err := GetCommit(s, head.Hash())
-	if err != nil {
-		return nil, err
-	}
-	err = fn(headCommit).ForEach(func(c *Commit) error {
-		el := l.PushBack(c)
-		m[c.Hash] = el
-		return nil
-	})
+// repoStorer is a repo Storer used to get commits and references.
+// commitIterFunc is a commit iterator function, used to iterate through ref commits in chosen order
+func NewCommitAllIter(repoStorer storage.Storer, commitIterFunc func(*Commit) CommitIter) (CommitIter, error) {
+	commitsPath := list.New()
+	commitsLookup := make(map[plumbing.Hash]*list.Element)
+	head, err := storer.ResolveReference(repoStorer, plumbing.HEAD)
 	if err != nil {
 		return nil, err
 	}
 
-	refIter, err := s.IterReferences()
+	// add all references along with the HEAD
+	if err = addReference(repoStorer, commitIterFunc, head, commitsPath, commitsLookup); err != nil {
+		return nil, err
+	}
+	refIter, err := repoStorer.IterReferences()
 	if err != nil {
 		return nil, err
 	}
 	defer refIter.Close()
-	err = refIter.ForEach(func(r *plumbing.Reference) error {
-		if r.Hash() == head.Hash() {
-			// we already have the HEAD
-			return nil
-		}
-
-		el, ok := m[r.Hash()]
-		if ok {
-			return nil
-		}
-
-		var refCommits []*Commit
-		c, _ := GetCommit(s, r.Hash())
-		// if it's not a commit - skip it.
-		if c == nil {
-			return nil
-		}
-		cit := fn(c)
-		for c, e := cit.Next(); e == nil; {
-			el, ok = m[c.Hash]
-			if ok {
-				break
-			}
-			refCommits = append(refCommits, c)
-			c, e = cit.Next()
-		}
-		cit.Close()
-
-		if el == nil {
-			// push back all commits from this ref.
-			for _, c := range refCommits {
-				el = l.PushBack(c)
-				m[c.Hash] = el
-			}
-		} else {
-			// insert ref's commits into the list
-			for i := len(refCommits) - 1; i >= 0; i-- {
-				c := refCommits[i]
-				el = l.InsertBefore(c, el)
-				m[c.Hash] = el
-			}
-		}
-		return nil
-	})
+	err = refIter.ForEach(
+		func(ref *plumbing.Reference) error {
+			return addReference(repoStorer, commitIterFunc, ref, commitsPath, commitsLookup)
+		},
+	)
 	if err != nil {
 		return nil, err
 	}
 
-	return &commitAllIterator{l.Front()}, nil
+	return &commitAllIterator{commitsPath.Front()}, nil
+}
+
+func addReference(
+	repoStorer storage.Storer,
+	commitIterFunc func(*Commit) CommitIter,
+	ref *plumbing.Reference,
+	commitsPath *list.List,
+	commitsLookup map[plumbing.Hash]*list.Element) error {
+
+	_, exists := commitsLookup[ref.Hash()]
+	if exists {
+		// we already have it - skip the reference.
+		return nil
+	}
+
+	refCommit, _ := GetCommit(repoStorer, ref.Hash())
+	if refCommit == nil {
+		// if it's not a commit - skip it.
+		return nil
+	}
+
+	var (
+		refCommits []*Commit
+		parent     *list.Element
+	)
+	// collect all ref commits to add
+	commitIter := commitIterFunc(refCommit)
+	for c, e := commitIter.Next(); e == nil; {
+		parent, exists = commitsLookup[c.Hash]
+		if exists {
+			break
+		}
+		refCommits = append(refCommits, c)
+		c, e = commitIter.Next()
+	}
+	commitIter.Close()
+
+	if parent == nil {
+		// common parent - not found
+		// add all commits to the path from this ref (maybe it's a HEAD and we don't have anything, yet)
+		for _, c := range refCommits {
+			parent = commitsPath.PushBack(c)
+			commitsLookup[c.Hash] = parent
+		}
+	} else {
+		// add ref's commits to the path in reverse order (from the latest)
+		for i := len(refCommits) - 1; i >= 0; i-- {
+			c := refCommits[i]
+			// insert before found common parent
+			parent = commitsPath.InsertBefore(c, parent)
+			commitsLookup[c.Hash] = parent
+		}
+	}
+
+	return nil
 }
 
 func (it *commitAllIterator) Next() (*Commit, error) {
-	if it.el == nil {
+	if it.currCommit == nil {
 		return nil, io.EOF
 	}
 
-	c := it.el.Value.(*Commit)
-	it.el = it.el.Next()
+	c := it.currCommit.Value.(*Commit)
+	it.currCommit = it.currCommit.Next()
 
 	return c, nil
 }
@@ -305,5 +311,5 @@
 }
 
 func (it *commitAllIterator) Close() {
-	it.el = nil
+	it.currCommit = nil
 }
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 @@
 import (
 	"io"
 
+	"gopkg.in/src-d/go-git.v4/plumbing"
+
 	"gopkg.in/src-d/go-git.v4/plumbing/storer"
 )
 
@@ -10,17 +12,19 @@
 	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 @@
 			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) 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()
diff --git a/repository.go b/repository.go
index 6be07c2..de92d64 100644
--- a/repository.go
+++ b/repository.go
@@ -1027,64 +1027,83 @@
 
 // Log returns the commit history from the given LogOptions.
 func (r *Repository) Log(o *LogOptions) (object.CommitIter, error) {
-	var (
-		err            error
-		commitIterFunc func(*object.Commit) object.CommitIter
-		commitIter     object.CommitIter
-	)
-	switch o.Order {
-	case LogOrderDefault:
-		commitIterFunc = func(c *object.Commit) object.CommitIter {
-			return object.NewCommitPreorderIter(c, nil, nil)
-		}
-	case LogOrderDFS:
-		commitIterFunc = func(c *object.Commit) object.CommitIter {
-			return object.NewCommitPreorderIter(c, nil, nil)
-		}
-	case LogOrderDFSPost:
-		commitIterFunc = func(c *object.Commit) object.CommitIter {
-			return object.NewCommitPostorderIter(c, nil)
-		}
-	case LogOrderBSF:
-		commitIterFunc = func(c *object.Commit) object.CommitIter {
-			return object.NewCommitIterBSF(c, nil, nil)
-		}
-	case LogOrderCommitterTime:
-		commitIterFunc = func(c *object.Commit) object.CommitIter {
-			return object.NewCommitIterCTime(c, nil, nil)
-		}
-	default:
+	fn := commitIterFunc(o.Order)
+	if fn == nil {
 		return nil, fmt.Errorf("invalid Order=%v", o.Order)
 	}
 
+	var (
+		it  object.CommitIter
+		err error
+	)
 	if o.All {
-		commitIter, err = object.NewCommitAllIter(r.Storer, commitIterFunc)
-		if err != nil {
-			return nil, err
-		}
+		it, err = r.logAll(fn)
 	} else {
-		h := o.From
-		if o.From == plumbing.ZeroHash {
-			head, err := r.Head()
-			if err != nil {
-				return nil, err
-			}
+		it, err = r.log(o.From, fn)
+	}
 
-			h = head.Hash()
-		}
-
-		commit, err := r.CommitObject(h)
-		if err != nil {
-			return nil, err
-		}
-		commitIter = commitIterFunc(commit)
+	if err != nil {
+		return nil, err
 	}
 
 	if o.FileName != nil {
-		commitIter = object.NewCommitFileIterFromIter(*o.FileName, commitIter, o.All)
+		// for `git log --all` also check parent (if the next commit comes from the real parent)
+		it = r.logWithFile(*o.FileName, it, o.All)
 	}
 
-	return commitIter, nil
+	return it, nil
+}
+
+func (r *Repository) log(from plumbing.Hash, commitIterFunc func(*object.Commit) object.CommitIter) (object.CommitIter, error) {
+	h := from
+	if from == plumbing.ZeroHash {
+		head, err := r.Head()
+		if err != nil {
+			return nil, err
+		}
+
+		h = head.Hash()
+	}
+
+	commit, err := r.CommitObject(h)
+	if err != nil {
+		return nil, err
+	}
+	return commitIterFunc(commit), nil
+}
+
+func (r *Repository) logAll(commitIterFunc func(*object.Commit) object.CommitIter) (object.CommitIter, error) {
+	return object.NewCommitAllIter(r.Storer, commitIterFunc)
+}
+
+func (*Repository) logWithFile(fileName string, commitIter object.CommitIter, checkParent bool) object.CommitIter {
+	return object.NewCommitFileIterFromIter(fileName, commitIter, checkParent)
+}
+
+func commitIterFunc(order LogOrder) func(c *object.Commit) object.CommitIter {
+	switch order {
+	case LogOrderDefault:
+		return func(c *object.Commit) object.CommitIter {
+			return object.NewCommitPreorderIter(c, nil, nil)
+		}
+	case LogOrderDFS:
+		return func(c *object.Commit) object.CommitIter {
+			return object.NewCommitPreorderIter(c, nil, nil)
+		}
+	case LogOrderDFSPost:
+		return func(c *object.Commit) object.CommitIter {
+			return object.NewCommitPostorderIter(c, nil)
+		}
+	case LogOrderBSF:
+		return func(c *object.Commit) object.CommitIter {
+			return object.NewCommitIterBSF(c, nil, nil)
+		}
+	case LogOrderCommitterTime:
+		return func(c *object.Commit) object.CommitIter {
+			return object.NewCommitIterCTime(c, nil, nil)
+		}
+	}
+	return nil
 }
 
 // Tags returns all the tag References in a repository.
