@@ -83,10 +83,8 @@ func (p *Packfile) Get(h plumbing.Hash) (plumbing.EncodedObject, error) {
8383// offset.
8484func (p * Packfile ) GetByOffset (o int64 ) (plumbing.EncodedObject , error ) {
8585 hash , err := p .FindHash (o )
86- if err == nil {
87- if obj , ok := p .deltaBaseCache .Get (hash ); ok {
88- return obj , nil
89- }
86+ if err != nil {
87+ return nil , err
9088 }
9189
9290 return p .objectAtOffset (o , hash )
@@ -180,10 +178,16 @@ func (p *Packfile) getObjectType(h *ObjectHeader) (typ plumbing.ObjectType, err
180178 err = ErrInvalidObject .AddDetails ("type %q" , h .Type )
181179 }
182180
181+ p .offsetToType [h .Offset ] = typ
182+
183183 return
184184}
185185
186186func (p * Packfile ) objectAtOffset (offset int64 , hash plumbing.Hash ) (plumbing.EncodedObject , error ) {
187+ if obj , ok := p .deltaBaseCache .Get (hash ); ok {
188+ return obj , nil
189+ }
190+
187191 h , err := p .objectHeaderAtOffset (offset )
188192 if err != nil {
189193 if err == io .EOF || isInvalid (err ) {
@@ -192,6 +196,12 @@ func (p *Packfile) objectAtOffset(offset int64, hash plumbing.Hash) (plumbing.En
192196 return nil , err
193197 }
194198
199+ return p .getNextObjectLazy (h , hash )
200+ }
201+
202+ func (p * Packfile ) getNextObjectLazy (h * ObjectHeader , hash plumbing.Hash ) (plumbing.EncodedObject , error ) {
203+ var err error
204+
195205 // If we have no filesystem, we will return a MemoryObject instead
196206 // of an FSObject.
197207 if p .fs == nil {
@@ -303,6 +313,8 @@ func (p *Packfile) getNextObject(h *ObjectHeader) (plumbing.EncodedObject, error
303313 return nil , err
304314 }
305315
316+ p .offsetToType [h .Offset ] = obj .Type ()
317+
306318 return obj , nil
307319}
308320
@@ -361,19 +373,14 @@ func (p *Packfile) fillOFSDeltaObjectContent(obj plumbing.EncodedObject, offset
361373}
362374
363375func (p * Packfile ) fillOFSDeltaObjectContentWithBuffer (obj plumbing.EncodedObject , offset int64 , buf * bytes.Buffer ) error {
364- var err error
365- var base plumbing.EncodedObject
366- var ok bool
367376 hash , err := p .FindHash (offset )
368- if err = = nil {
369- base , ok = p . cacheGet ( hash )
377+ if err ! = nil {
378+ return err
370379 }
371380
372- if ! ok {
373- base , err = p .objectAtOffset (offset , hash )
374- if err != nil {
375- return err
376- }
381+ base , err := p .objectAtOffset (offset , hash )
382+ if err != nil {
383+ return err
377384 }
378385
379386 obj .SetType (base .Type ())
@@ -475,14 +482,32 @@ func (i *objectIter) Next() (plumbing.EncodedObject, error) {
475482 return nil , err
476483 }
477484
485+ if i .typ != plumbing .AnyObject {
486+ if typ , ok := i .p .offsetToType [int64 (e .Offset )]; ok {
487+ if typ != i .typ {
488+ continue
489+ }
490+ } else {
491+ h , err := i .p .objectHeaderAtOffset (int64 (e .Offset ))
492+ if err != nil {
493+ return nil , err
494+ }
495+
496+ typ , err := i .p .getObjectType (h )
497+ if err == nil && typ != i .typ {
498+ continue
499+ }
500+
501+ return i .p .getNextObjectLazy (h , e .Hash )
502+ }
503+ }
504+
478505 obj , err := i .p .GetByOffset (int64 (e .Offset ))
479506 if err != nil {
480507 return nil , err
481508 }
482509
483- if i .typ == plumbing .AnyObject || obj .Type () == i .typ {
484- return obj , nil
485- }
510+ return obj , nil
486511 }
487512}
488513
0 commit comments