1// Package filesystem is a storage backend base on filesystems
2package filesystem
3
4import (
5	"github.com/jesseduffield/go-git/v5/plumbing/cache"
6	"github.com/jesseduffield/go-git/v5/storage/filesystem/dotgit"
7
8	"github.com/go-git/go-billy/v5"
9)
10
11// Storage is an implementation of git.Storer that stores data on disk in the
12// standard git format (this is, the .git directory). Zero values of this type
13// are not safe to use, see the NewStorage function below.
14type Storage struct {
15	fs  billy.Filesystem
16	dir *dotgit.DotGit
17
18	ObjectStorage
19	ReferenceStorage
20	IndexStorage
21	ShallowStorage
22	ConfigStorage
23	ModuleStorage
24}
25
26// Options holds configuration for the storage.
27type Options struct {
28	// ExclusiveAccess means that the filesystem is not modified externally
29	// while the repo is open.
30	ExclusiveAccess bool
31	// KeepDescriptors makes the file descriptors to be reused but they will
32	// need to be manually closed calling Close().
33	KeepDescriptors bool
34	// MaxOpenDescriptors is the max number of file descriptors to keep
35	// open. If KeepDescriptors is true, all file descriptors will remain open.
36	MaxOpenDescriptors int
37}
38
39// NewStorage returns a new Storage backed by a given `fs.Filesystem` and cache.
40func NewStorage(fs billy.Filesystem, cache cache.Object) *Storage {
41	return NewStorageWithOptions(fs, cache, Options{})
42}
43
44// NewStorageWithOptions returns a new Storage with extra options,
45// backed by a given `fs.Filesystem` and cache.
46func NewStorageWithOptions(fs billy.Filesystem, cache cache.Object, ops Options) *Storage {
47	dirOps := dotgit.Options{
48		ExclusiveAccess: ops.ExclusiveAccess,
49	}
50	dir := dotgit.NewWithOptions(fs, dirOps)
51
52	return &Storage{
53		fs:  fs,
54		dir: dir,
55
56		ObjectStorage:    *NewObjectStorageWithOptions(dir, cache, ops),
57		ReferenceStorage: ReferenceStorage{dir: dir},
58		IndexStorage:     IndexStorage{dir: dir},
59		ShallowStorage:   ShallowStorage{dir: dir},
60		ConfigStorage:    ConfigStorage{dir: dir},
61		ModuleStorage:    ModuleStorage{dir: dir},
62	}
63}
64
65// Filesystem returns the underlying filesystem
66func (s *Storage) Filesystem() billy.Filesystem {
67	return s.fs
68}
69
70// Init initializes .git directory
71func (s *Storage) Init() error {
72	return s.dir.Initialize()
73}
74