This document covers storage backends and interfaces in go-git for persisting Git objects and references.
go-git provides abstraction over Git object and reference storage through the Storer interface. This allows different storage implementations:
type Storer interface {
storer.EncodedObjectStorer
storer.ReferenceStorer
}The main storage interface combines object storage and reference storage.
type EncodedObjectStorer interface {
NewEncodedObject() plumbing.EncodedObject
SetEncodedObject(plumbing.EncodedObject) (plumbing.Hash, error)
EncodedObject(plumbing.ObjectType, plumbing.Hash) (plumbing.EncodedObject, error)
IterEncodedObjects(plumbing.ObjectType) (EncodedObjectIter, error)
HasEncodedObject(plumbing.Hash) error
EncodedObjectSize(plumbing.Hash) (int64, error)
AddAlternate(string) error
}Stores Git objects (commits, trees, blobs, tags).
type ReferenceStorer interface {
SetReference(*plumbing.Reference) error
CheckAndSetReference(*plumbing.Reference, *plumbing.Reference) error
Reference(plumbing.ReferenceName) (*plumbing.Reference, error)
IterReferences() (ReferenceIter, error)
RemoveReference(plumbing.ReferenceName) error
CountLooseRefs() (int, error)
PackRefs() error
}Stores Git references (branches, tags, HEAD).
type ShallowStorer interface {
SetShallow([]plumbing.Hash) error
Shallow() ([]plumbing.Hash, error)
}
type IndexStorer interface {
SetIndex(*index.Index) error
Index() (*index.Index, error)
}
type ModuleStorer interface {
Module(string) (Storer, error)
}Standard Git storage using filesystem.
import "github.com/go-git/go-git/v5/storage/filesystem"
type Storage struct {
ObjectStorage ObjectStorage
ReferenceStorage ReferenceStorage
IndexStorage IndexStorage
ShallowStorage ShallowStorage
ConfigStorage ConfigStorage
ModuleStorage ModuleStorage
}
func NewStorage(fs billy.Filesystem, cache cache.Object) *Storage
func NewStorageWithOptions(fs billy.Filesystem, cache cache.Object, ops Options) *StorageExample:
package main
import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/go-git/go-billy/v5/osfs"
)
func main() {
// Create filesystem storage
fs := osfs.New("/tmp/repo/.git")
storage := filesystem.NewStorage(fs, nil)
// Use with repository
r, err := git.Open(storage, nil)
if err != nil {
panic(err)
}
_ = r
}type Options struct {
ExclusiveAccess bool
KeepDescriptors bool
MaxOpenDescriptors int
LargeObjectThreshold int64
AlternatesFS billy.Filesystem
}Example with Options:
package main
import (
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/go-git/go-billy/v5/osfs"
)
func main() {
fs := osfs.New("/tmp/repo/.git")
storage := filesystem.NewStorageWithOptions(fs, nil, filesystem.Options{
ExclusiveAccess: false,
KeepDescriptors: true,
MaxOpenDescriptors: 100,
LargeObjectThreshold: 5 * 1024 * 1024, // 5MB
})
_ = storage
}In-memory storage for testing or temporary repositories.
import "github.com/go-git/go-git/v5/storage/memory"
type Storage struct {
ConfigStorage ConfigStorage
ObjectStorage ObjectStorage
ShallowStorage ShallowStorage
IndexStorage IndexStorage
ReferenceStorage ReferenceStorage
ModuleStorage ModuleStorage
}
func NewStorage() *StorageExample:
package main
import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/storage/memory"
"github.com/go-git/go-billy/v5/memfs"
)
func main() {
// Create in-memory storage
storage := memory.NewStorage()
fs := memfs.New()
// Clone to memory
r, err := git.Clone(storage, fs, &git.CloneOptions{
URL: "https://github.com/user/repo",
})
if err != nil {
panic(err)
}
_ = r
}Provides transaction support for storage operations.
import "github.com/go-git/go-git/v5/storage/transactional"
type ObjectStorage struct {
// contains filtered or unexported fields
}
func NewObjectStorage(s storer.EncodedObjectStorer) *ObjectStorage
type Storage struct {
// contains filtered or unexported fields
}
func NewStorage(s storage.Storer) *StorageExample:
package main
import (
"github.com/go-git/go-git/v5/storage/memory"
"github.com/go-git/go-git/v5/storage/transactional"
)
func main() {
base := memory.NewStorage()
storage := transactional.NewStorage(base)
// Use transactional storage
_ = storage
}Improve performance with object caching.
import "github.com/go-git/go-git/v5/plumbing/cache"
type Object interface {
Put(plumbing.EncodedObject)
Get(plumbing.Hash) plumbing.EncodedObject
Clear()
}
func NewObjectLRU(size int) Object
func NewObjectLRUDefault() ObjectExample:
package main
import (
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/go-git/go-git/v5/plumbing/cache"
"github.com/go-git/go-billy/v5/osfs"
)
func main() {
fs := osfs.New("/tmp/repo/.git")
// Create cache (256MB)
cache := cache.NewObjectLRU(256 * 1024 * 1024)
// Create storage with cache
storage := filesystem.NewStorage(fs, cache)
_ = storage
}package main
import (
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/go-git/go-git/v5/plumbing/cache"
"github.com/go-git/go-billy/v5/osfs"
)
func main() {
fs := osfs.New("/large/repo/.git")
cache := cache.NewObjectLRU(512 * 1024 * 1024) // 512MB cache
storage := filesystem.NewStorage(fs, cache)
_ = storage
}package main
import (
"testing"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/storage/memory"
"github.com/go-git/go-billy/v5/memfs"
)
func TestGitOperations(t *testing.T) {
storage := memory.NewStorage()
fs := memfs.New()
r, err := git.Init(storage, fs)
if err != nil {
t.Fatal(err)
}
// Test operations
_ = r
}package main
import (
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/go-git/go-billy/v5/osfs"
)
func main() {
fs := osfs.New("/tmp/repo/.git")
storage := filesystem.NewStorageWithOptions(fs, nil, filesystem.Options{
LargeObjectThreshold: 10 * 1024 * 1024, // 10MB
})
_ = storage
}