diff options
author | Javi Fontan <jfontan@gmail.com> | 2017-12-21 12:30:13 +0100 |
---|---|---|
committer | Javi Fontan <jfontan@gmail.com> | 2017-12-21 12:30:13 +0100 |
commit | 8d288404016a90c9b17dd8230db2c5da1a1ccfe5 (patch) | |
tree | 6e7af1cb9e0673371b525d6253f62173468d7e06 /storage | |
parent | 55b5d736682bf0e251c5bf83d1cf25c298d3ea0c (diff) | |
download | go-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>
Diffstat (limited to 'storage')
-rw-r--r-- | storage/filesystem/internal/dotgit/dotgit.go | 31 | ||||
-rw-r--r-- | storage/filesystem/internal/dotgit/dotgit_setref.go | 43 | ||||
-rw-r--r-- | storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go | 17 |
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 +} |