mirror of
https://github.com/go-gitea/gitea
synced 2024-09-19 02:06:04 +00:00
08bf443016
* Inital routes to git refs api * Git refs API implementation * Update swagger * Fix copyright * Make swagger happy add basic test * Fix test * Fix test again :)
82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
package dotgit
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"runtime"
|
|
|
|
"gopkg.in/src-d/go-billy.v4"
|
|
"gopkg.in/src-d/go-git.v4/utils/ioutil"
|
|
)
|
|
|
|
func (d *DotGit) openAndLockPackedRefsMode() int {
|
|
if billy.CapabilityCheck(d.fs, billy.ReadAndWriteCapability) {
|
|
return os.O_RDWR
|
|
}
|
|
|
|
return os.O_RDONLY
|
|
}
|
|
|
|
func (d *DotGit) rewritePackedRefsWhileLocked(
|
|
tmp billy.File, pr billy.File) error {
|
|
// Try plain rename. If we aren't using the bare Windows filesystem as the
|
|
// storage layer, we might be able to get away with a rename over a locked
|
|
// file.
|
|
err := d.fs.Rename(tmp.Name(), pr.Name())
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
// If we are in a filesystem that does not support rename (e.g. sivafs)
|
|
// a full copy is done.
|
|
if err == billy.ErrNotSupported {
|
|
return d.copyNewFile(tmp, pr)
|
|
}
|
|
|
|
if runtime.GOOS != "windows" {
|
|
return err
|
|
}
|
|
|
|
// Otherwise, Windows doesn't let us rename over a locked file, so
|
|
// we have to do a straight copy. Unfortunately this could result
|
|
// in a partially-written file if the process fails before the
|
|
// copy completes.
|
|
return d.copyToExistingFile(tmp, pr)
|
|
}
|
|
|
|
func (d *DotGit) copyToExistingFile(tmp, pr billy.File) error {
|
|
_, err := pr.Seek(0, io.SeekStart)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = pr.Truncate(0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tmp.Seek(0, io.SeekStart)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = io.Copy(pr, tmp)
|
|
|
|
return err
|
|
}
|
|
|
|
func (d *DotGit) copyNewFile(tmp billy.File, pr billy.File) (err error) {
|
|
prWrite, err := d.fs.Create(pr.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer ioutil.CheckClose(prWrite, &err)
|
|
|
|
_, err = tmp.Seek(0, io.SeekStart)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = io.Copy(prWrite, tmp)
|
|
|
|
return err
|
|
}
|