package transactional import ( "io" "github.com/go-git/go-git/v5/plumbing/storer" "github.com/go-git/go-git/v5/storage" ) // Storage is a transactional implementation of git.Storer, it demux the write // and read operation of two separate storers, allowing to merge content calling // Storage.Commit. // // The API and functionality of this package are considered EXPERIMENTAL and is // not considered stable nor production ready. type Storage interface { storage.Storer Commit() error } // basic implements the Storage interface. type basic struct { s, temporal storage.Storer *ObjectStorage *ReferenceStorage *IndexStorage *ShallowStorage *ConfigStorage } // packageWriter implements storer.PackfileWriter interface over // a Storage with a temporal storer that supports it. type packageWriter struct { *basic pw storer.PackfileWriter } // NewStorage returns a new Storage based on two repositories, base is the base // repository where the read operations are read and temporal is were all // the write operations are stored. func NewStorage(base, temporal storage.Storer) Storage { st := &basic{ s: base, temporal: temporal, ObjectStorage: NewObjectStorage(base, temporal), ReferenceStorage: NewReferenceStorage(base, temporal), IndexStorage: NewIndexStorage(base, temporal), ShallowStorage: NewShallowStorage(base, temporal), ConfigStorage: NewConfigStorage(base, temporal), } pw, ok := temporal.(storer.PackfileWriter) if ok { return &packageWriter{ basic: st, pw: pw, } } return st } // Module it honors the storage.ModuleStorer interface. func (s *basic) Module(name string) (storage.Storer, error) { base, err := s.s.Module(name) if err != nil { return nil, err } temporal, err := s.temporal.Module(name) if err != nil { return nil, err } return NewStorage(base, temporal), nil } // Commit it copies the content of the temporal storage into the base storage. func (s *basic) Commit() error { for _, c := range []interface{ Commit() error }{ s.ObjectStorage, s.ReferenceStorage, s.IndexStorage, s.ShallowStorage, s.ConfigStorage, } { if err := c.Commit(); err != nil { return err } } return nil } // PackfileWriter honors storage.PackfileWriter. func (s *packageWriter) PackfileWriter() (io.WriteCloser, error) { return s.pw.PackfileWriter() }