diff options
-rw-r--r-- | plumbing/format/packfile/decoder.go | 7 | ||||
-rw-r--r-- | plumbing/format/packfile/decoder_test.go | 65 | ||||
-rw-r--r-- | storage/filesystem/object.go | 9 |
3 files changed, 71 insertions, 10 deletions
diff --git a/plumbing/format/packfile/decoder.go b/plumbing/format/packfile/decoder.go index 9f2174b..475d24d 100644 --- a/plumbing/format/packfile/decoder.go +++ b/plumbing/format/packfile/decoder.go @@ -225,13 +225,6 @@ func (d *Decoder) decodeIfSpecificType(h *ObjectHeader) (plumbing.EncodedObject, realType, err = d.ofsDeltaType(h.OffsetReference) case plumbing.REFDeltaObject: realType, err = d.refDeltaType(h.Reference) - - // If a reference delta is not found, it means that it isn't of - // the type we are looking for, because we don't have any reference - // and it is not present into the object storer - if err == plumbing.ErrObjectNotFound { - return nil, nil - } default: realType = h.Type } diff --git a/plumbing/format/packfile/decoder_test.go b/plumbing/format/packfile/decoder_test.go index 6bb49aa..bc40b30 100644 --- a/plumbing/format/packfile/decoder_test.go +++ b/plumbing/format/packfile/decoder_test.go @@ -47,6 +47,65 @@ func (s *ReaderSuite) TestDecode(c *C) { }) } +func (s *ReaderSuite) TestDecodeByTypeRefDelta(c *C) { + f := fixtures.Basic().ByTag("ref-delta").One() + + storage := memory.NewStorage() + scanner := packfile.NewScanner(f.Packfile()) + d, err := packfile.NewDecoderForType(scanner, storage, plumbing.CommitObject) + c.Assert(err, IsNil) + + // Specific offset elements needed to decode correctly the ref-delta + offsets := map[plumbing.Hash]int64{ + plumbing.NewHash("a8d315b2b1c615d43042c3a62402b8a54288cf5c"): 84880, + plumbing.NewHash("fb72698cab7617ac416264415f13224dfd7a165e"): 85141, + plumbing.NewHash("eba74343e2f15d62adedfd8c883ee0262b5c8021"): 85300, + } + + d.SetOffsets(offsets) + + defer d.Close() + + _, count, err := scanner.Header() + c.Assert(err, IsNil) + + var i uint32 + for i = 0; i < count; i++ { + obj, err := d.DecodeObject() + c.Assert(err, IsNil) + + if obj != nil { + c.Assert(obj.Type(), Equals, plumbing.CommitObject) + } + } +} + +func (s *ReaderSuite) TestDecodeByTypeRefDeltaError(c *C) { + fixtures.Basic().ByTag("ref-delta").Test(c, func(f *fixtures.Fixture) { + storage := memory.NewStorage() + scanner := packfile.NewScanner(f.Packfile()) + d, err := packfile.NewDecoderForType(scanner, storage, plumbing.CommitObject) + c.Assert(err, IsNil) + + defer d.Close() + + _, count, err := scanner.Header() + c.Assert(err, IsNil) + + isError := false + var i uint32 + for i = 0; i < count; i++ { + _, err := d.DecodeObject() + if err != nil { + isError = true + break + } + } + c.Assert(isError, Equals, true) + }) + +} + func (s *ReaderSuite) TestDecodeByType(c *C) { ts := []plumbing.ObjectType{ plumbing.CommitObject, @@ -61,6 +120,12 @@ func (s *ReaderSuite) TestDecodeByType(c *C) { scanner := packfile.NewScanner(f.Packfile()) d, err := packfile.NewDecoderForType(scanner, storage, t) c.Assert(err, IsNil) + + // when the packfile is ref-delta based, the offsets are required + if f.Is("ref-delta") { + d.SetOffsets(getOffsetsFromIdx(f.Idx())) + } + defer d.Close() _, count, err := scanner.Header() diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index 2975c1e..904f6fe 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -233,7 +233,7 @@ func (s *ObjectStorage) buildPackfileIters( return nil, err } - iter, err := newPackfileIter(pack, t, seen) + iter, err := newPackfileIter(pack, t, seen, s.index[h]) if err != nil { return nil, err } @@ -272,10 +272,11 @@ type packfileIter struct { } func NewPackfileIter(f billy.File, t plumbing.ObjectType) (storer.EncodedObjectIter, error) { - return newPackfileIter(f, t, make(map[plumbing.Hash]bool)) + return newPackfileIter(f, t, make(map[plumbing.Hash]bool), nil) } -func newPackfileIter(f billy.File, t plumbing.ObjectType, seen map[plumbing.Hash]bool) (storer.EncodedObjectIter, error) { +func newPackfileIter(f billy.File, t plumbing.ObjectType, seen map[plumbing.Hash]bool, + index idx) (storer.EncodedObjectIter, error) { s := packfile.NewScanner(f) _, total, err := s.Header() if err != nil { @@ -287,6 +288,8 @@ func newPackfileIter(f billy.File, t plumbing.ObjectType, seen map[plumbing.Hash return nil, err } + d.SetOffsets(index) + return &packfileIter{ f: f, d: d, |