aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plumbing/storer/reference.go4
-rw-r--r--remote_test.go21
-rw-r--r--storage/filesystem/internal/dotgit/dotgit_test.go21
-rw-r--r--storage/memory/storage.go17
4 files changed, 50 insertions, 13 deletions
diff --git a/plumbing/storer/reference.go b/plumbing/storer/reference.go
index 50e5886..ae80a39 100644
--- a/plumbing/storer/reference.go
+++ b/plumbing/storer/reference.go
@@ -16,6 +16,10 @@ var ErrMaxResolveRecursion = errors.New("max. recursion level reached")
// ReferenceStorer is a generic storage of references.
type ReferenceStorer interface {
SetReference(*plumbing.Reference) error
+ // CheckAndSetReference sets the reference `new`, but if `old` is
+ // not `nil`, it first checks that the current stored value for
+ // `old.Name()` matches the given reference value in `old`. If
+ // not, it returns an error and doesn't update `new`.
CheckAndSetReference(new, old *plumbing.Reference) error
Reference(plumbing.ReferenceName) (*plumbing.Reference, error)
IterReferences() (ReferenceIter, error)
diff --git a/remote_test.go b/remote_test.go
index dff1499..e586e7a 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -308,8 +308,8 @@ func (s *RemoteSuite) doTestFetchNoErrAlreadyUpToDate(c *C, url string) {
c.Assert(err, Equals, NoErrAlreadyUpToDate)
}
-func (s *RemoteSuite) TestFetchFastForward(c *C) {
- r := newRemote(memory.NewStorage(), &config.RemoteConfig{
+func (s *RemoteSuite) testFetchFastForward(c *C, sto storage.Storer) {
+ r := newRemote(sto, &config.RemoteConfig{
URLs: []string{s.GetBasicLocalRepositoryURL()},
})
@@ -350,6 +350,23 @@ func (s *RemoteSuite) TestFetchFastForward(c *C) {
})
}
+func (s *RemoteSuite) TestFetchFastForwardMem(c *C) {
+ s.testFetchFastForward(c, memory.NewStorage())
+}
+
+func (s *RemoteSuite) TestFetchFastForwardFS(c *C) {
+ dir, err := ioutil.TempDir("", "fetch")
+ c.Assert(err, IsNil)
+
+ defer os.RemoveAll(dir) // clean up
+
+ fss, err := filesystem.NewStorage(osfs.New(dir))
+ c.Assert(err, IsNil)
+
+ // This exercises `storage.filesystem.Storage.CheckAndSetReference()`.
+ s.testFetchFastForward(c, fss)
+}
+
func (s *RemoteSuite) TestString(c *C) {
r := newRemote(nil, &config.RemoteConfig{
Name: "foo",
diff --git a/storage/filesystem/internal/dotgit/dotgit_test.go b/storage/filesystem/internal/dotgit/dotgit_test.go
index d1b04a7..446a204 100644
--- a/storage/filesystem/internal/dotgit/dotgit_test.go
+++ b/storage/filesystem/internal/dotgit/dotgit_test.go
@@ -55,10 +55,11 @@ func (s *SuiteDotGit) TestSetRefs(c *C) {
fs := osfs.New(tmp)
dir := New(fs)
- err = dir.SetRef(plumbing.NewReferenceFromStrings(
+ firstFoo := plumbing.NewReferenceFromStrings(
"refs/heads/foo",
"e8d3ffab552895c19b9fcf7aa264d277cde33881",
- ), nil)
+ )
+ err = dir.SetRef(firstFoo, nil)
c.Assert(err, IsNil)
@@ -105,6 +106,20 @@ func (s *SuiteDotGit) TestSetRefs(c *C) {
c.Assert(ref, NotNil)
c.Assert(ref.Hash().String(), Equals, "e8d3ffab552895c19b9fcf7aa264d277cde33881")
+ // Check that SetRef with a non-nil `old` works.
+ err = dir.SetRef(plumbing.NewReferenceFromStrings(
+ "refs/heads/foo",
+ "6ecf0ef2c2dffb796033e5a02219af86ec6584e5",
+ ), firstFoo)
+ c.Assert(err, IsNil)
+
+ // `firstFoo` is no longer the right `old` reference, so this
+ // should fail.
+ err = dir.SetRef(plumbing.NewReferenceFromStrings(
+ "refs/heads/foo",
+ "6ecf0ef2c2dffb796033e5a02219af86ec6584e5",
+ ), firstFoo)
+ c.Assert(err, NotNil)
}
func (s *SuiteDotGit) TestRefsFromPackedRefs(c *C) {
@@ -192,7 +207,7 @@ func (s *SuiteDotGit) TestRemoveRefFromReferenceFileAndPackedRefs(c *C) {
err := dir.SetRef(plumbing.NewReferenceFromStrings(
"refs/remotes/origin/branch",
"e8d3ffab552895c19b9fcf7aa264d277cde33881",
- ))
+ ), nil)
// Make sure it only appears once in the refs list.
refs, err := dir.Refs()
diff --git a/storage/memory/storage.go b/storage/memory/storage.go
index 69394af..c9306ee 100644
--- a/storage/memory/storage.go
+++ b/storage/memory/storage.go
@@ -204,16 +204,17 @@ func (r ReferenceStorage) SetReference(ref *plumbing.Reference) error {
}
func (r ReferenceStorage) CheckAndSetReference(ref, old *plumbing.Reference) error {
- if ref != nil {
- if old != nil {
- tmp := r[ref.Name()]
- if tmp != nil && tmp.Hash() != old.Hash() {
- return ErrRefHasChanged
- }
- }
- r[ref.Name()] = ref
+ if ref == nil {
+ return nil
}
+ if old != nil {
+ tmp := r[ref.Name()]
+ if tmp != nil && tmp.Hash() != old.Hash() {
+ return ErrRefHasChanged
+ }
+ }
+ r[ref.Name()] = ref
return nil
}