Skip to content

Commit

Permalink
Fix object not found error in OFS deltas
Browse files Browse the repository at this point in the history
Unfortunately the code in go-git#303 was incorrect for large objects in OFS deltas.

The underlying fault is that the seeker in the packfile was seeking away whilst the
delta was being read.

This PR simply reads the delta into a buffer.

Fix go-git#323

Signed-off-by: Andrew Thornton <art27@cantab.net>
  • Loading branch information
zeripath committed May 27, 2021
1 parent db4233e commit 91658e7
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 17 deletions.
28 changes: 12 additions & 16 deletions plumbing/format/packfile/packfile.go
Expand Up @@ -293,24 +293,28 @@ func (p *Packfile) getReaderDirect(h *ObjectHeader) (io.ReadCloser, error) {
case plumbing.CommitObject, plumbing.TreeObject, plumbing.BlobObject, plumbing.TagObject:
return p.s.ReadObject()
case plumbing.REFDeltaObject:
deltaRC, err := p.s.ReadObject()
deltaBuf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(deltaBuf)
deltaBuf.Reset()
_, _, err := p.s.NextObject(deltaBuf)
if err != nil {
return nil, err
}
r, err := p.readREFDeltaObjectContent(h, deltaRC)
r, err := p.readREFDeltaObjectContent(h, deltaBuf)
if err != nil {
_ = deltaRC.Close()
return nil, err
}
return r, nil
case plumbing.OFSDeltaObject:
deltaRC, err := p.s.ReadObject()
deltaBuf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(deltaBuf)
deltaBuf.Reset()
_, _, err := p.s.NextObject(deltaBuf)
if err != nil {
return nil, err
}
r, err := p.readOFSDeltaObjectContent(h, deltaRC)
r, err := p.readOFSDeltaObjectContent(h, deltaBuf)
if err != nil {
_ = deltaRC.Close()
return nil, err
}
return r, nil
Expand Down Expand Up @@ -371,7 +375,7 @@ func (p *Packfile) fillREFDeltaObjectContent(obj plumbing.EncodedObject, ref plu
return p.fillREFDeltaObjectContentWithBuffer(obj, ref, buf)
}

func (p *Packfile) readREFDeltaObjectContent(h *ObjectHeader, deltaRC io.ReadCloser) (io.ReadCloser, error) {
func (p *Packfile) readREFDeltaObjectContent(h *ObjectHeader, deltaRC io.Reader) (io.ReadCloser, error) {
var err error

base, ok := p.cacheGet(h.Reference)
Expand Down Expand Up @@ -415,7 +419,7 @@ func (p *Packfile) fillOFSDeltaObjectContent(obj plumbing.EncodedObject, offset
return p.fillOFSDeltaObjectContentWithBuffer(obj, offset, buf)
}

func (p *Packfile) readOFSDeltaObjectContent(h *ObjectHeader, deltaRC io.ReadCloser) (io.ReadCloser, error) {
func (p *Packfile) readOFSDeltaObjectContent(h *ObjectHeader, deltaRC io.Reader) (io.ReadCloser, error) {
hash, err := p.FindHash(h.OffsetReference)
if err != nil {
return nil, err
Expand All @@ -426,14 +430,6 @@ func (p *Packfile) readOFSDeltaObjectContent(h *ObjectHeader, deltaRC io.ReadClo
return nil, err
}

base, ok := p.cacheGet(h.Reference)
if !ok {
base, err = p.Get(h.Reference)
if err != nil {
return nil, err
}
}

return ReaderFromDelta(h, base, deltaRC)
}

Expand Down
2 changes: 1 addition & 1 deletion plumbing/format/packfile/patch_delta.go
Expand Up @@ -75,7 +75,7 @@ func PatchDelta(src, delta []byte) ([]byte, error) {
return b.Bytes(), nil
}

func ReaderFromDelta(h *ObjectHeader, base plumbing.EncodedObject, deltaRC io.ReadCloser) (io.ReadCloser, error) {
func ReaderFromDelta(h *ObjectHeader, base plumbing.EncodedObject, deltaRC io.Reader) (io.ReadCloser, error) {
deltaBuf := bufio.NewReaderSize(deltaRC, 1024)
srcSz, err := decodeLEB128ByteReader(deltaBuf)
if err != nil {
Expand Down

0 comments on commit 91658e7

Please sign in to comment.