aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavi Fontan <jfontan@gmail.com>2017-12-21 12:30:13 +0100
committerJavi Fontan <jfontan@gmail.com>2017-12-21 12:30:13 +0100
commit8d288404016a90c9b17dd8230db2c5da1a1ccfe5 (patch)
tree6e7af1cb9e0673371b525d6253f62173468d7e06
parent55b5d736682bf0e251c5bf83d1cf25c298d3ea0c (diff)
downloadgo-git-8d288404016a90c9b17dd8230db2c5da1a1ccfe5.tar.gz
Add a setRef version that supports non rw fs
There are some filesystems that do not support opening the files in read and write modes at the same time. The method SetRef is split in files with an extra version that only writes the reference. It can be activated with -tags norwfs on building. Signed-off-by: Javi Fontan <jfontan@gmail.com>
-rw-r--r--storage/filesystem/internal/dotgit/dotgit.go31
-rw-r--r--storage/filesystem/internal/dotgit/dotgit_setref.go43
-rw-r--r--storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go17
3 files changed, 62 insertions, 29 deletions
diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go
index d644810..643a5d6 100644
--- a/storage/filesystem/internal/dotgit/dotgit.go
+++ b/storage/filesystem/internal/dotgit/dotgit.go
@@ -323,36 +323,9 @@ func (d *DotGit) SetRef(r, old *plumbing.Reference) error {
content = fmt.Sprintln(r.Hash().String())
}
- // If we are not checking an old ref, just truncate the file.
- mode := os.O_RDWR | os.O_CREATE
- if old == nil {
- mode |= os.O_TRUNC
- }
-
- f, err := d.fs.OpenFile(r.Name().String(), mode, 0666)
- if err != nil {
- return err
- }
-
- defer ioutil.CheckClose(f, &err)
-
- // Lock is unlocked by the deferred Close above. This is because Unlock
- // does not imply a fsync and thus there would be a race between
- // Unlock+Close and other concurrent writers. Adding Sync to go-billy
- // could work, but this is better (and avoids superfluous syncs).
- err = f.Lock()
- if err != nil {
- return err
- }
-
- // this is a no-op to call even when old is nil.
- err = d.checkReferenceAndTruncate(f, old)
- if err != nil {
- return err
- }
+ fileName := r.Name().String()
- _, err = f.Write([]byte(content))
- return err
+ return d.setRef(fileName, content, old)
}
// Refs scans the git directory collecting references, which it returns.
diff --git a/storage/filesystem/internal/dotgit/dotgit_setref.go b/storage/filesystem/internal/dotgit/dotgit_setref.go
new file mode 100644
index 0000000..c732c9f
--- /dev/null
+++ b/storage/filesystem/internal/dotgit/dotgit_setref.go
@@ -0,0 +1,43 @@
+// +build !norwfs
+
+package dotgit
+
+import (
+ "os"
+
+ "gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/utils/ioutil"
+)
+
+func (d *DotGit) setRef(fileName, content string, old *plumbing.Reference) error {
+ // If we are not checking an old ref, just truncate the file.
+ mode := os.O_RDWR | os.O_CREATE
+ if old == nil {
+ mode |= os.O_TRUNC
+ }
+
+ f, err := d.fs.OpenFile(fileName, mode, 0666)
+ if err != nil {
+ return err
+ }
+
+ defer ioutil.CheckClose(f, &err)
+
+ // Lock is unlocked by the deferred Close above. This is because Unlock
+ // does not imply a fsync and thus there would be a race between
+ // Unlock+Close and other concurrent writers. Adding Sync to go-billy
+ // could work, but this is better (and avoids superfluous syncs).
+ err = f.Lock()
+ if err != nil {
+ return err
+ }
+
+ // this is a no-op to call even when old is nil.
+ err = d.checkReferenceAndTruncate(f, old)
+ if err != nil {
+ return err
+ }
+
+ _, err = f.Write([]byte(content))
+ return err
+}
diff --git a/storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go b/storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go
new file mode 100644
index 0000000..b22166c
--- /dev/null
+++ b/storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go
@@ -0,0 +1,17 @@
+// +build norwfs
+
+package dotgit
+
+import "gopkg.in/src-d/go-git.v4/plumbing"
+
+func (d *DotGit) setRef(fileName, content string, old *plumbing.Reference) error {
+ f, err := d.fs.Create(fileName)
+ if err != nil {
+ return err
+ }
+
+ defer f.Close()
+
+ _, err = f.Write([]byte(content))
+ return err
+}