mirror of
https://github.com/go-gitea/gitea
synced 2024-09-19 02:06:04 +00:00
4183c846e3
Bumps [gopkg.in/src-d/go-git.v4](https://github.com/src-d/go-git) from 4.8.0 to 4.10.0. - [Release notes](https://github.com/src-d/go-git/releases) - [Commits](https://github.com/src-d/go-git/compare/v4.8.0...v4.10.0)
91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package dotgit
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
|
"gopkg.in/src-d/go-git.v4/utils/ioutil"
|
|
|
|
"gopkg.in/src-d/go-billy.v4"
|
|
)
|
|
|
|
func (d *DotGit) setRef(fileName, content string, old *plumbing.Reference) (err error) {
|
|
if billy.CapabilityCheck(d.fs, billy.ReadAndWriteCapability) {
|
|
return d.setRefRwfs(fileName, content, old)
|
|
}
|
|
|
|
return d.setRefNorwfs(fileName, content, old)
|
|
}
|
|
|
|
func (d *DotGit) setRefRwfs(fileName, content string, old *plumbing.Reference) (err 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
|
|
}
|
|
|
|
// There are some filesystems that don't support opening files in RDWD mode.
|
|
// In these filesystems the standard SetRef function can not be used as it
|
|
// reads the reference file to check that it's not modified before updating it.
|
|
//
|
|
// This version of the function writes the reference without extra checks
|
|
// making it compatible with these simple filesystems. This is usually not
|
|
// a problem as they should be accessed by only one process at a time.
|
|
func (d *DotGit) setRefNorwfs(fileName, content string, old *plumbing.Reference) error {
|
|
_, err := d.fs.Stat(fileName)
|
|
if err == nil && old != nil {
|
|
fRead, err := d.fs.Open(fileName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ref, err := d.readReferenceFrom(fRead, old.Name().String())
|
|
fRead.Close()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if ref.Hash() != old.Hash() {
|
|
return fmt.Errorf("reference has changed concurrently")
|
|
}
|
|
}
|
|
|
|
f, err := d.fs.Create(fileName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
_, err = f.Write([]byte(content))
|
|
return err
|
|
}
|