git/odb: use pack.(*Set) over git.(*ObjectScanner)
This commit is contained in:
parent
1542bf94ea
commit
6eb5a7872d
@ -2,7 +2,6 @@ package odb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -10,7 +9,7 @@ import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/git-lfs/git-lfs/errors"
|
||||
"github.com/git-lfs/git-lfs/git"
|
||||
"github.com/git-lfs/git-lfs/git/odb/pack"
|
||||
"github.com/git-lfs/git-lfs/lfs"
|
||||
)
|
||||
|
||||
@ -19,14 +18,14 @@ import (
|
||||
type ObjectDatabase struct {
|
||||
// s is the storage backend which opens/creates/reads/writes.
|
||||
s storer
|
||||
// packs are the set of packfiles which contain all packed objects
|
||||
// within this repository.
|
||||
packs *pack.Set
|
||||
|
||||
// closed is a uint32 managed by sync/atomic's <X>Uint32 methods. It
|
||||
// yields a value of 0 if the *ObjectDatabase it is stored upon is open,
|
||||
// and a value of 1 if it is closed.
|
||||
closed uint32
|
||||
// objectScanner is the running instance of `*git.ObjectScanner` used to
|
||||
// scan packed objects not found in .git/objects/xx/... directly.
|
||||
objectScanner *git.ObjectScanner
|
||||
}
|
||||
|
||||
// FromFilesystem constructs an *ObjectDatabase instance that is backed by a
|
||||
@ -34,14 +33,14 @@ type ObjectDatabase struct {
|
||||
//
|
||||
// /absolute/repo/path/.git/objects
|
||||
func FromFilesystem(root string) (*ObjectDatabase, error) {
|
||||
os, err := git.NewObjectScanner()
|
||||
packs, err := pack.NewSet(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ObjectDatabase{
|
||||
s: newFileStorer(root),
|
||||
objectScanner: os,
|
||||
s: newFileStorer(root),
|
||||
packs: packs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -55,7 +54,7 @@ func (o *ObjectDatabase) Close() error {
|
||||
return errors.New("git/odb: *ObjectDatabase already closed")
|
||||
}
|
||||
|
||||
if err := o.objectScanner.Close(); err != nil {
|
||||
if err := o.packs.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -219,21 +218,27 @@ func (o *ObjectDatabase) open(sha []byte) (*ObjectReader, error) {
|
||||
// load its contents from the *git.ObjectScanner by leveraging
|
||||
// `git-cat-file --batch`.
|
||||
if atomic.LoadUint32(&o.closed) == 1 {
|
||||
return nil, errors.New("git/odb: cannot use closed *git.ObjectScanner")
|
||||
return nil, errors.New("git/odb: cannot use closed *pack.Set")
|
||||
}
|
||||
|
||||
if !o.objectScanner.Scan(hex.EncodeToString(sha)) {
|
||||
return nil, o.objectScanner.Err()
|
||||
packed, err := o.packs.Object(sha)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unpacked, err := packed.Unpack()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewUncompressedObjectReader(io.MultiReader(
|
||||
// Git object header:
|
||||
strings.NewReader(fmt.Sprintf("%s %d\x00",
|
||||
o.objectScanner.Type(), o.objectScanner.Size(),
|
||||
packed.Type(), len(unpacked),
|
||||
)),
|
||||
|
||||
// Git object (uncompressed) contents:
|
||||
o.objectScanner.Contents(),
|
||||
bytes.NewReader(unpacked),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/git-lfs/git-lfs/git"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -167,25 +166,6 @@ func TestWriteCommit(t *testing.T) {
|
||||
assert.NotNil(t, fs.fs[hex.EncodeToString(sha)])
|
||||
}
|
||||
|
||||
func TestReadingAMissingObject(t *testing.T) {
|
||||
sha, _ := hex.DecodeString("af5626b4a114abcb82d63db7c8082c3c4756e51b")
|
||||
out := strings.NewReader(fmt.Sprintf("%x blob 14\nHello, world!\n", sha))
|
||||
|
||||
db := &ObjectDatabase{
|
||||
s: newMemoryStorer(nil),
|
||||
objectScanner: git.NewObjectScannerFrom(out),
|
||||
}
|
||||
|
||||
blob, err := db.Blob(sha)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.EqualValues(t, 14, blob.Size)
|
||||
|
||||
contents, err := ioutil.ReadAll(blob.Contents)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Hello, world!\n", string(contents))
|
||||
}
|
||||
|
||||
func TestReadingAMissingObjectAfterClose(t *testing.T) {
|
||||
sha, _ := hex.DecodeString("af5626b4a114abcb82d63db7c8082c3c4756e51b")
|
||||
|
||||
@ -195,7 +175,7 @@ func TestReadingAMissingObjectAfterClose(t *testing.T) {
|
||||
}
|
||||
|
||||
blob, err := db.Blob(sha)
|
||||
assert.EqualError(t, err, "git/odb: cannot use closed *git.ObjectScanner")
|
||||
assert.EqualError(t, err, "git/odb: cannot use closed *pack.Set")
|
||||
assert.Nil(t, blob)
|
||||
}
|
||||
|
||||
@ -203,11 +183,6 @@ func TestClosingAnObjectDatabaseMoreThanOnce(t *testing.T) {
|
||||
db, err := FromFilesystem("/tmp")
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Make db's objectScanner field be nil, since /tmp doesn't contain a
|
||||
// Git repository, which will cause closing `git-cat-file(1) --batch` to
|
||||
// fail.
|
||||
db.objectScanner = nil
|
||||
|
||||
assert.Nil(t, db.Close())
|
||||
assert.EqualError(t, db.Close(), "git/odb: *ObjectDatabase already closed")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user