@@ -24,8 +24,9 @@ type ObjectStorage struct {
24
24
// loaded loose objects
25
25
objectCache cache.Object
26
26
27
- dir * dotgit.DotGit
28
- index map [plumbing.Hash ]idxfile.Index
27
+ dir * dotgit.DotGit
28
+ index map [plumbing.Hash ]idxfile.Index
29
+ packfiles map [plumbing.Hash ]* packfile.Packfile
29
30
}
30
31
31
32
// NewObjectStorage creates a new ObjectStorage with the given .git directory and cache.
@@ -215,14 +216,7 @@ func (s *ObjectStorage) encodedObjectSizeFromPackfile(h plumbing.Hash) (
215
216
return 0 , err
216
217
}
217
218
218
- var p * packfile.Packfile
219
- if s .objectCache != nil {
220
- p = packfile .NewPackfileWithCache (idx , s .dir .Fs (), f , s .objectCache )
221
- } else {
222
- p = packfile .NewPackfile (idx , s .dir .Fs (), f )
223
- }
224
-
225
- return p .GetSizeByOffset (offset )
219
+ return s .getPackfile (f , idx , pack ).GetSizeByOffset (offset )
226
220
}
227
221
228
222
// EncodedObjectSize returns the plaintext size of the given object,
@@ -372,16 +366,37 @@ func (s *ObjectStorage) getFromPackfile(h plumbing.Hash, canBeDelta bool) (
372
366
373
367
idx := s .index [pack ]
374
368
if canBeDelta {
375
- return s .decodeDeltaObjectAt (f , idx , offset , hash )
369
+ return s .decodeDeltaObjectAt (f , idx , offset , hash , pack )
376
370
}
377
371
378
- return s .decodeObjectAt (f , idx , offset )
372
+ return s .decodeObjectAt (f , idx , offset , hash , pack )
373
+ }
374
+
375
+ func (s * ObjectStorage ) getPackfile (f billy.File , idx idxfile.Index , pack plumbing.Hash ) * packfile.Packfile {
376
+ var p * packfile.Packfile
377
+ var ok bool
378
+
379
+ if p , ok = s .packfiles [pack ]; ! ok {
380
+ if s .objectCache != nil {
381
+ p = packfile .NewPackfileWithCache (idx , s .dir .Fs (), f , s .objectCache )
382
+ } else {
383
+ p = packfile .NewPackfile (idx , s .dir .Fs (), f )
384
+ }
385
+
386
+ if s .options .KeepDescriptors {
387
+ s .packfiles [pack ] = p
388
+ }
389
+ }
390
+
391
+ return p
379
392
}
380
393
381
394
func (s * ObjectStorage ) decodeObjectAt (
382
395
f billy.File ,
383
396
idx idxfile.Index ,
384
397
offset int64 ,
398
+ hash plumbing.Hash ,
399
+ pack plumbing.Hash ,
385
400
) (plumbing.EncodedObject , error ) {
386
401
hash , err := idx .FindHash (offset )
387
402
if err == nil {
@@ -410,6 +425,7 @@ func (s *ObjectStorage) decodeDeltaObjectAt(
410
425
idx idxfile.Index ,
411
426
offset int64 ,
412
427
hash plumbing.Hash ,
428
+ pack plumbing.Hash ,
413
429
) (plumbing.EncodedObject , error ) {
414
430
if _ , err := f .Seek (0 , io .SeekStart ); err != nil {
415
431
return nil , err
@@ -434,7 +450,7 @@ func (s *ObjectStorage) decodeDeltaObjectAt(
434
450
return nil , err
435
451
}
436
452
default :
437
- return s .decodeObjectAt (f , idx , offset )
453
+ return s .decodeObjectAt (f , idx , offset , hash , pack )
438
454
}
439
455
440
456
obj := & plumbing.MemoryObject {}
@@ -515,6 +531,11 @@ func (s *ObjectStorage) buildPackfileIters(
515
531
516
532
// Close closes all opened files.
517
533
func (s * ObjectStorage ) Close () error {
534
+ for _ , p := range s .packfiles {
535
+ p .Close ()
536
+ }
537
+ s .packfiles = make (map [plumbing.Hash ]* packfile.Packfile )
538
+
518
539
return s .dir .Close ()
519
540
}
520
541
0 commit comments