aboutsummaryrefslogtreecommitdiffstats
path: root/storage/filesystem
diff options
context:
space:
mode:
authorJeremy Stribling <strib@alum.mit.edu>2017-11-02 16:30:51 -0700
committerJeremy Stribling <strib@alum.mit.edu>2017-11-29 10:37:30 -0800
commitd50161181583f7767038de58eff8ee204de7646d (patch)
tree108ce8becf34ffafdce7b3bb82100ef55fe0188d /storage/filesystem
parent3447303ce76caa3a22e9f510fa00e73f5143267e (diff)
downloadgo-git-d50161181583f7767038de58eff8ee204de7646d.tar.gz
dotgit: during rewriting, re-open packed-refs after locking
The file could have been completely replaced while waiting for the lock, so we need to re-open, otherwise we might be reading a stale file that has already been deleted/overwritten.
Diffstat (limited to 'storage/filesystem')
-rw-r--r--storage/filesystem/internal/dotgit/dotgit.go30
1 files changed, 21 insertions, 9 deletions
diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go
index 330f9d5..8b1df3d 100644
--- a/storage/filesystem/internal/dotgit/dotgit.go
+++ b/storage/filesystem/internal/dotgit/dotgit.go
@@ -421,18 +421,30 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e
return err
}
- doCloseF := true
- defer func() {
- if doCloseF {
- ioutil.CheckClose(f, &err)
- }
- }()
+ defer ioutil.CheckClose(f, &err)
err = f.Lock()
if err != nil {
return err
}
+ // Re-open the file after locking, since it could have been
+ // renamed over by a new file during the Lock process.
+ pr, err := d.fs.Open(packedRefsPath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+
+ return err
+ }
+ doClosePR := true
+ defer func() {
+ if doClosePR {
+ ioutil.CheckClose(pr, &err)
+ }
+ }()
+
// Creating the temp file in the same directory as the target file
// improves our chances for rename operation to be atomic.
tmp, err := d.fs.TempFile("", tmpPackedRefsPrefix)
@@ -446,7 +458,7 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e
}
}()
- s := bufio.NewScanner(f)
+ s := bufio.NewScanner(pr)
found := false
for s.Scan() {
line := s.Text()
@@ -479,8 +491,8 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e
return d.fs.Remove(tmp.Name())
}
- doCloseF = false
- if err := f.Close(); err != nil {
+ doClosePR = false
+ if err := pr.Close(); err != nil {
return err
}