diff options
author | Javi Fontan <jfontan@gmail.com> | 2019-01-30 18:50:35 +0100 |
---|---|---|
committer | Javi Fontan <jfontan@gmail.com> | 2019-01-30 18:58:38 +0100 |
commit | 51b01ef90c03c2f83126eb339723d7b7e7a6a245 (patch) | |
tree | 5af72223dcc5ff071016e16cba0967f3fa1d0293 /storage | |
parent | 434611b74cb54538088c6aeed4ed27d3044064fa (diff) | |
download | go-git-51b01ef90c03c2f83126eb339723d7b7e7a6a245.tar.gz |
storage/filesystem: check file object before using cache
If the cache is shared between several repositories getFromUnpacked can
erroneously return an object from other repository.
This decreases performance a little bit as there's an extra fs operation
when the object is in the cache but is correct when the cache is shared.
Signed-off-by: Javi Fontan <jfontan@gmail.com>
Diffstat (limited to 'storage')
-rw-r--r-- | storage/filesystem/object.go | 9 | ||||
-rw-r--r-- | storage/filesystem/object_test.go | 17 |
2 files changed, 21 insertions, 5 deletions
diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index 85bb798..3eb62a2 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -307,10 +307,6 @@ func (s *ObjectStorage) DeltaObject(t plumbing.ObjectType, } func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedObject, err error) { - if cacheObj, found := s.objectCache.Get(h); found { - return cacheObj, nil - } - f, err := s.dir.Object(h) if err != nil { if os.IsNotExist(err) { @@ -319,9 +315,12 @@ func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedOb return nil, err } - defer ioutil.CheckClose(f, &err) + if cacheObj, found := s.objectCache.Get(h); found { + return cacheObj, nil + } + obj = s.NewEncodedObject() r, err := objfile.NewReader(f) if err != nil { diff --git a/storage/filesystem/object_test.go b/storage/filesystem/object_test.go index 77eb31d..5cfb227 100644 --- a/storage/filesystem/object_test.go +++ b/storage/filesystem/object_test.go @@ -297,6 +297,23 @@ func (s *FsSuite) TestPackfileIterKeepDescriptors(c *C) { }) } +func (s *FsSuite) TestGetFromObjectFileSharedCache(c *C) { + f1 := fixtures.ByTag("worktree").One().DotGit() + f2 := fixtures.ByTag("worktree").ByTag("submodule").One().DotGit() + + ch := cache.NewObjectLRUDefault() + o1 := NewObjectStorage(dotgit.New(f1), ch) + o2 := NewObjectStorage(dotgit.New(f2), ch) + + expected := plumbing.NewHash("af2d6a6954d532f8ffb47615169c8fdf9d383a1a") + obj, err := o1.EncodedObject(plumbing.CommitObject, expected) + c.Assert(err, IsNil) + c.Assert(obj.Hash(), Equals, expected) + + obj, err = o2.EncodedObject(plumbing.CommitObject, expected) + c.Assert(err, Equals, plumbing.ErrObjectNotFound) +} + func BenchmarkPackfileIter(b *testing.B) { if err := fixtures.Init(); err != nil { b.Fatal(err) |