Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 5a6cc4e

Browse files
committed
dotgit: open+lock packed-refs file until it doesn't change
Windows doesn't like it when we re-open a file we already have locked.
1 parent c2e6b5d commit 5a6cc4e

File tree

1 file changed

+46
-18
lines changed

1 file changed

+46
-18
lines changed

storage/filesystem/internal/dotgit/dotgit.go

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -460,32 +460,60 @@ func (d *DotGit) addRefsFromPackedRefs(refs *[]*plumbing.Reference, seen map[plu
460460
return nil
461461
}
462462

463-
func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err error) {
464-
f, err := d.fs.Open(packedRefsPath)
465-
if err != nil {
466-
if os.IsNotExist(err) {
467-
return nil
463+
func (d *DotGit) openAndLockPackedRefs() (pr billy.File, err error) {
464+
var f billy.File
465+
defer func() {
466+
if err != nil && f != nil {
467+
ioutil.CheckClose(f, &err)
468468
}
469+
}()
469470

470-
return err
471-
}
472-
defer ioutil.CheckClose(f, &err)
471+
// Keep trying to open and lock the file until we're sure the file
472+
// didn't change between the open and the lock.
473+
for {
474+
f, err = d.fs.Open(packedRefsPath)
475+
if err != nil {
476+
if os.IsNotExist(err) {
477+
return nil, nil
478+
}
473479

474-
err = f.Lock()
475-
if err != nil {
476-
return err
477-
}
480+
return nil, err
481+
}
482+
fi, err := d.fs.Stat(packedRefsPath)
483+
if err != nil {
484+
return nil, err
485+
}
486+
mtime := fi.ModTime()
478487

479-
// Re-open the file after locking, since it could have been
480-
// renamed over by a new file during the Lock process.
481-
pr, err := d.fs.Open(packedRefsPath)
482-
if err != nil {
483-
if os.IsNotExist(err) {
484-
return nil
488+
err = f.Lock()
489+
if err != nil {
490+
return nil, err
491+
}
492+
493+
fi, err = d.fs.Stat(packedRefsPath)
494+
if err != nil {
495+
return nil, err
496+
}
497+
if mtime == fi.ModTime() {
498+
break
485499
}
500+
// The file has changed since we opened it. Close and retry.
501+
err = f.Close()
502+
if err != nil {
503+
return nil, err
504+
}
505+
}
506+
return f, nil
507+
}
486508

509+
func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err error) {
510+
pr, err := d.openAndLockPackedRefs()
511+
if err != nil {
487512
return err
488513
}
514+
if pr == nil {
515+
return nil
516+
}
489517
doClosePR := true
490518
defer func() {
491519
if doClosePR {

0 commit comments

Comments
 (0)