From 6c2a0daafcd6c8f3f695c8b7a2c881d3abc276b1 Mon Sep 17 00:00:00 2001 From: Antonio Jesus Navarro Perez Date: Tue, 12 Feb 2019 15:57:50 +0100 Subject: Ignore missing references on log --all To mimic the actual standard git behavior, we must ignore references that are pointing to wrong/unexistent objects. Signed-off-by: Antonio Jesus Navarro Perez --- plumbing/object/commit_walker.go | 34 +++++++++++++++------- repository_test.go | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/plumbing/object/commit_walker.go b/plumbing/object/commit_walker.go index 8c76557..fabd0c9 100644 --- a/plumbing/object/commit_walker.go +++ b/plumbing/object/commit_walker.go @@ -197,26 +197,38 @@ func NewCommitAllIter(repoStorer storage.Storer, commitIterFunc func(*Commit) Co commitsPath := list.New() commitsLookup := make(map[plumbing.Hash]*list.Element) head, err := storer.ResolveReference(repoStorer, plumbing.HEAD) - if err != nil { + if err != nil && err != plumbing.ErrReferenceNotFound { return nil, err + } else if err != plumbing.ErrReferenceNotFound { + if err = addReference(repoStorer, commitIterFunc, head, commitsPath, commitsLookup); err != nil { + return nil, err + } } // 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(ref *plumbing.Reference) error { - return addReference(repoStorer, commitIterFunc, ref, commitsPath, commitsLookup) - }, - ) - if err != nil { - return nil, err + + for { + ref, err := refIter.Next() + if err == io.EOF { + break + } + + if err == plumbing.ErrReferenceNotFound { + continue + } + + if err != nil { + return nil, err + } + + if err = addReference(repoStorer, commitIterFunc, ref, commitsPath, commitsLookup); err != nil { + return nil, err + } } return &commitAllIterator{commitsPath.Front()}, nil diff --git a/repository_test.go b/repository_test.go index 2a56dd2..1549737 100644 --- a/repository_test.go +++ b/repository_test.go @@ -1256,8 +1256,18 @@ func (s *RepositorySuite) TestLogAll(c *C) { err := r.clone(context.Background(), &CloneOptions{ URL: s.GetBasicLocalRepositoryURL(), }) + c.Assert(err, IsNil) + + rIter, err := r.Storer.IterReferences() + c.Assert(err, IsNil) + refCount := 0 + err = rIter.ForEach(func(ref *plumbing.Reference) error { + refCount++ + return nil + }) c.Assert(err, IsNil) + c.Assert(refCount, Equals, 5) cIter, err := r.Log(&LogOptions{ All: true, @@ -1286,6 +1296,58 @@ func (s *RepositorySuite) TestLogAll(c *C) { cIter.Close() } +func (s *RepositorySuite) TestLogAllMissingReferences(c *C) { + r, _ := Init(memory.NewStorage(), nil) + err := r.clone(context.Background(), &CloneOptions{ + URL: s.GetBasicLocalRepositoryURL(), + }) + c.Assert(err, IsNil) + err = r.Storer.RemoveReference(plumbing.HEAD) + c.Assert(err, IsNil) + + rIter, err := r.Storer.IterReferences() + c.Assert(err, IsNil) + + refCount := 0 + err = rIter.ForEach(func(ref *plumbing.Reference) error { + refCount++ + return nil + }) + c.Assert(err, IsNil) + c.Assert(refCount, Equals, 4) + + err = r.Storer.SetReference(plumbing.NewHashReference(plumbing.ReferenceName("DUMMY"), plumbing.NewHash("DUMMY"))) + c.Assert(err, IsNil) + + rIter, err = r.Storer.IterReferences() + c.Assert(err, IsNil) + + refCount = 0 + err = rIter.ForEach(func(ref *plumbing.Reference) error { + refCount++ + return nil + }) + c.Assert(err, IsNil) + c.Assert(refCount, Equals, 5) + + cIter, err := r.Log(&LogOptions{ + All: true, + }) + c.Assert(cIter, NotNil) + c.Assert(err, IsNil) + + cCount := 0 + cIter.ForEach(func(c *object.Commit) error { + cCount++ + return nil + }) + c.Assert(cCount, Equals, 9) + + _, err = cIter.Next() + c.Assert(err, Equals, io.EOF) + cIter.Close() +} + func (s *RepositorySuite) TestLogAllOrderByTime(c *C) { r, _ := Init(memory.NewStorage(), nil) err := r.clone(context.Background(), &CloneOptions{ -- cgit