aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plumbing/storer/object.go2
-rw-r--r--storage/transactional/config.go36
-rw-r--r--storage/transactional/config_test.go70
-rw-r--r--storage/transactional/object.go63
-rw-r--r--storage/transactional/object_test.go119
-rw-r--r--storage/transactional/storage.go1
6 files changed, 290 insertions, 1 deletions
diff --git a/plumbing/storer/object.go b/plumbing/storer/object.go
index 2ac9b09..98d1ec3 100644
--- a/plumbing/storer/object.go
+++ b/plumbing/storer/object.go
@@ -222,7 +222,7 @@ type MultiEncodedObjectIter struct {
}
// NewMultiEncodedObjectIter returns an object iterator for the given slice of
-// objects.
+// EncodedObjectIters.
func NewMultiEncodedObjectIter(iters []EncodedObjectIter) EncodedObjectIter {
return &MultiEncodedObjectIter{iters: iters}
}
diff --git a/storage/transactional/config.go b/storage/transactional/config.go
new file mode 100644
index 0000000..2fc6583
--- /dev/null
+++ b/storage/transactional/config.go
@@ -0,0 +1,36 @@
+package transactional
+
+import "gopkg.in/src-d/go-git.v4/config"
+
+type ConfigStorage struct {
+ config.ConfigStorer
+ temporal config.ConfigStorer
+
+ set bool
+}
+
+func NewConfigStorage(s, temporal config.ConfigStorer) *ConfigStorage {
+ return &ConfigStorage{ConfigStorer: s, temporal: temporal}
+}
+
+func (c *ConfigStorage) SetConfig(cfg *config.Config) error {
+ if err := c.temporal.SetConfig(cfg); err != nil {
+ return err
+ }
+
+ c.set = true
+ return nil
+}
+
+func (c *ConfigStorage) Commit() error {
+ if !c.set {
+ return nil
+ }
+
+ cfg, err := c.temporal.Config()
+ if err != nil {
+ return err
+ }
+
+ return c.ConfigStorer.SetConfig(cfg)
+}
diff --git a/storage/transactional/config_test.go b/storage/transactional/config_test.go
new file mode 100644
index 0000000..c178bec
--- /dev/null
+++ b/storage/transactional/config_test.go
@@ -0,0 +1,70 @@
+package transactional
+
+import (
+ "testing"
+
+ . "gopkg.in/check.v1"
+ "gopkg.in/src-d/go-git.v4/config"
+ "gopkg.in/src-d/go-git.v4/storage/memory"
+)
+
+func Test(t *testing.T) { TestingT(t) }
+
+var _ = Suite(&ConfigSuite{})
+
+type ConfigSuite struct{}
+
+func (s *ConfigSuite) TestSetConfig(c *C) {
+ cfg := config.NewConfig()
+ cfg.Core.Worktree = "foo"
+
+ base := memory.NewStorage()
+ err := base.SetConfig(cfg)
+ c.Assert(err, IsNil)
+
+ temporal := memory.NewStorage()
+
+ cfg = config.NewConfig()
+ cfg.Core.Worktree = "bar"
+
+ cs := NewConfigStorage(base, temporal)
+ err = cs.SetConfig(cfg)
+ c.Assert(err, IsNil)
+
+ baseCfg, err := base.Config()
+ c.Assert(err, IsNil)
+ c.Assert(baseCfg.Core.Worktree, Equals, "foo")
+
+ temporalCfg, err := temporal.Config()
+ c.Assert(err, IsNil)
+ c.Assert(temporalCfg.Core.Worktree, Equals, "bar")
+
+ cfg, err = cs.Config()
+ c.Assert(err, IsNil)
+ c.Assert(temporalCfg.Core.Worktree, Equals, "bar")
+}
+
+func (s *ConfigSuite) TestCommit(c *C) {
+ cfg := config.NewConfig()
+ cfg.Core.Worktree = "foo"
+
+ base := memory.NewStorage()
+ err := base.SetConfig(cfg)
+ c.Assert(err, IsNil)
+
+ temporal := memory.NewStorage()
+
+ cfg = config.NewConfig()
+ cfg.Core.Worktree = "bar"
+
+ cs := NewConfigStorage(base, temporal)
+ err = cs.SetConfig(cfg)
+ c.Assert(err, IsNil)
+
+ err = cs.Commit()
+ c.Assert(err, IsNil)
+
+ baseCfg, err := base.Config()
+ c.Assert(err, IsNil)
+ c.Assert(baseCfg.Core.Worktree, Equals, "bar")
+}
diff --git a/storage/transactional/object.go b/storage/transactional/object.go
new file mode 100644
index 0000000..2a46d3c
--- /dev/null
+++ b/storage/transactional/object.go
@@ -0,0 +1,63 @@
+package transactional
+
+import (
+ "gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/plumbing/storer"
+)
+
+type ObjectStorage struct {
+ storer.EncodedObjectStorer
+ temporal storer.EncodedObjectStorer
+}
+
+func NewObjectStorage(s, temporal storer.EncodedObjectStorer) *ObjectStorage {
+ return &ObjectStorage{EncodedObjectStorer: s, temporal: temporal}
+}
+
+func (o *ObjectStorage) SetEncodedObject(obj plumbing.EncodedObject) (plumbing.Hash, error) {
+ return o.temporal.SetEncodedObject(obj)
+}
+
+func (o *ObjectStorage) HasEncodedObject(h plumbing.Hash) error {
+ err := o.EncodedObjectStorer.HasEncodedObject(h)
+ if err == plumbing.ErrObjectNotFound {
+ return o.temporal.HasEncodedObject(h)
+ }
+
+ return err
+}
+
+func (o *ObjectStorage) EncodedObjectSize(h plumbing.Hash) (int64, error) {
+ sz, err := o.EncodedObjectStorer.EncodedObjectSize(h)
+ if err == plumbing.ErrObjectNotFound {
+ return o.temporal.EncodedObjectSize(h)
+ }
+
+ return sz, err
+}
+
+func (o *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) {
+ obj, err := o.EncodedObjectStorer.EncodedObject(t, h)
+ if err == plumbing.ErrObjectNotFound {
+ return o.temporal.EncodedObject(t, h)
+ }
+
+ return obj, err
+}
+
+func (o *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.EncodedObjectIter, error) {
+ baseIter, err := o.EncodedObjectStorer.IterEncodedObjects(t)
+ if err != nil {
+ return nil, err
+ }
+
+ temporalIter, err := o.temporal.IterEncodedObjects(t)
+ if err != nil {
+ return nil, err
+ }
+
+ return storer.NewMultiEncodedObjectIter([]storer.EncodedObjectIter{
+ baseIter,
+ temporalIter,
+ }), nil
+}
diff --git a/storage/transactional/object_test.go b/storage/transactional/object_test.go
new file mode 100644
index 0000000..ff8cd4e
--- /dev/null
+++ b/storage/transactional/object_test.go
@@ -0,0 +1,119 @@
+package transactional
+
+import (
+ . "gopkg.in/check.v1"
+ "gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/storage/memory"
+)
+
+var _ = Suite(&ObjectSuite{})
+
+type ObjectSuite struct{}
+
+func (s *ObjectSuite) TestHasEncodedObject(c *C) {
+ base := memory.NewStorage()
+ temporal := memory.NewStorage()
+
+ os := NewObjectStorage(base, temporal)
+
+ commit := base.NewEncodedObject()
+ commit.SetType(plumbing.CommitObject)
+
+ ch, err := base.SetEncodedObject(commit)
+ c.Assert(ch.IsZero(), Equals, false)
+ c.Assert(err, IsNil)
+
+ tree := base.NewEncodedObject()
+ tree.SetType(plumbing.TreeObject)
+
+ th, err := os.SetEncodedObject(tree)
+ c.Assert(th.IsZero(), Equals, false)
+ c.Assert(err, IsNil)
+
+ err = os.HasEncodedObject(th)
+ c.Assert(err, IsNil)
+
+ err = os.HasEncodedObject(ch)
+ c.Assert(err, IsNil)
+
+ err = base.HasEncodedObject(th)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+}
+
+func (s *ObjectSuite) TestEncodedObjectAndEncodedObjectSize(c *C) {
+ base := memory.NewStorage()
+ temporal := memory.NewStorage()
+
+ os := NewObjectStorage(base, temporal)
+
+ commit := base.NewEncodedObject()
+ commit.SetType(plumbing.CommitObject)
+
+ ch, err := base.SetEncodedObject(commit)
+ c.Assert(ch.IsZero(), Equals, false)
+ c.Assert(err, IsNil)
+
+ tree := base.NewEncodedObject()
+ tree.SetType(plumbing.TreeObject)
+
+ th, err := os.SetEncodedObject(tree)
+ c.Assert(th.IsZero(), Equals, false)
+ c.Assert(err, IsNil)
+
+ otree, err := os.EncodedObject(plumbing.TreeObject, th)
+ c.Assert(err, IsNil)
+ c.Assert(otree.Hash(), Equals, tree.Hash())
+
+ treeSz, err := os.EncodedObjectSize(th)
+ c.Assert(err, IsNil)
+ c.Assert(treeSz, Equals, int64(0))
+
+ ocommit, err := os.EncodedObject(plumbing.CommitObject, ch)
+ c.Assert(err, IsNil)
+ c.Assert(ocommit.Hash(), Equals, commit.Hash())
+
+ commitSz, err := os.EncodedObjectSize(ch)
+ c.Assert(err, IsNil)
+ c.Assert(commitSz, Equals, int64(0))
+
+ _, err = base.EncodedObject(plumbing.TreeObject, th)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+
+ _, err = base.EncodedObjectSize(th)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+}
+
+func (s *ObjectSuite) TestIterEncodedObjects(c *C) {
+ base := memory.NewStorage()
+ temporal := memory.NewStorage()
+
+ os := NewObjectStorage(base, temporal)
+
+ commit := base.NewEncodedObject()
+ commit.SetType(plumbing.CommitObject)
+
+ ch, err := base.SetEncodedObject(commit)
+ c.Assert(ch.IsZero(), Equals, false)
+ c.Assert(err, IsNil)
+
+ tree := base.NewEncodedObject()
+ tree.SetType(plumbing.TreeObject)
+
+ th, err := os.SetEncodedObject(tree)
+ c.Assert(th.IsZero(), Equals, false)
+ c.Assert(err, IsNil)
+
+ iter, err := os.IterEncodedObjects(plumbing.AnyObject)
+ c.Assert(err, IsNil)
+
+ var hashes []plumbing.Hash
+ err = iter.ForEach(func(obj plumbing.EncodedObject) error {
+ hashes = append(hashes, obj.Hash())
+ return nil
+ })
+
+ c.Assert(err, IsNil)
+ c.Assert(hashes, HasLen, 2)
+ c.Assert(hashes[0], Equals, ch)
+ c.Assert(hashes[1], Equals, th)
+}
diff --git a/storage/transactional/storage.go b/storage/transactional/storage.go
new file mode 100644
index 0000000..d5f5a24
--- /dev/null
+++ b/storage/transactional/storage.go
@@ -0,0 +1 @@
+package transactional