Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3f1cfde

Browse filesBrowse files
authored
Merge pull request #659 from MichaelMure/dotgit-race
dotgit: fix a filesystem race in Refs/walkReferencesTree
2 parents 8557a36 + 660071d commit 3f1cfde
Copy full SHA for 3f1cfde

File tree

Expand file treeCollapse file tree

2 files changed

+73
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+73
-0
lines changed

‎storage/filesystem/dotgit/dotgit.go

Copy file name to clipboardExpand all lines: storage/filesystem/dotgit/dotgit.go
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,7 @@ func (d *DotGit) walkReferencesTree(refs *[]*plumbing.Reference, relPath []strin
943943
files, err := d.fs.ReadDir(d.fs.Join(relPath...))
944944
if err != nil {
945945
if os.IsNotExist(err) {
946+
// a race happened, and our directory is gone now
946947
return nil
947948
}
948949

@@ -960,6 +961,10 @@ func (d *DotGit) walkReferencesTree(refs *[]*plumbing.Reference, relPath []strin
960961
}
961962

962963
ref, err := d.readReferenceFile(".", strings.Join(newRelPath, "/"))
964+
if os.IsNotExist(err) {
965+
// a race happened, and our file is gone now
966+
continue
967+
}
963968
if err != nil {
964969
return err
965970
}

‎storage/filesystem/dotgit/dotgit_test.go

Copy file name to clipboardExpand all lines: storage/filesystem/dotgit/dotgit_test.go
+68Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,3 +864,71 @@ func (s *SuiteDotGit) TestIncBytes(c *C) {
864864
c.Assert(overflow, Equals, test.overflow)
865865
}
866866
}
867+
868+
// this filesystem wrapper returns os.ErrNotExist if the file matches
869+
// the provided paths list
870+
type notExistsFS struct {
871+
billy.Filesystem
872+
873+
paths []string
874+
}
875+
876+
func (f *notExistsFS) matches(path string) bool {
877+
p := filepath.ToSlash(path)
878+
for _, n := range f.paths {
879+
if p == n {
880+
return true
881+
}
882+
}
883+
return false
884+
}
885+
886+
func (f *notExistsFS) Open(filename string) (billy.File, error) {
887+
if f.matches(filename) {
888+
return nil, os.ErrNotExist
889+
}
890+
891+
return f.Filesystem.Open(filename)
892+
}
893+
894+
func (f *notExistsFS) ReadDir(path string) ([]os.FileInfo, error) {
895+
if f.matches(path) {
896+
return nil, os.ErrNotExist
897+
}
898+
899+
return f.Filesystem.ReadDir(path)
900+
}
901+
902+
func (s *SuiteDotGit) TestDeletedRefs(c *C) {
903+
fs, clean := s.TemporalFilesystem()
904+
defer clean()
905+
906+
dir := New(&notExistsFS{
907+
Filesystem: fs,
908+
paths: []string{
909+
"refs/heads/bar",
910+
"refs/heads/baz",
911+
},
912+
})
913+
914+
err := dir.SetRef(plumbing.NewReferenceFromStrings(
915+
"refs/heads/foo",
916+
"e8d3ffab552895c19b9fcf7aa264d277cde33881",
917+
), nil)
918+
c.Assert(err, IsNil)
919+
err = dir.SetRef(plumbing.NewReferenceFromStrings(
920+
"refs/heads/bar",
921+
"a8d3ffab552895c19b9fcf7aa264d277cde33881",
922+
), nil)
923+
c.Assert(err, IsNil)
924+
err = dir.SetRef(plumbing.NewReferenceFromStrings(
925+
"refs/heads/baz/baz",
926+
"a8d3ffab552895c19b9fcf7aa264d277cde33881",
927+
), nil)
928+
c.Assert(err, IsNil)
929+
930+
refs, err := dir.Refs()
931+
c.Assert(err, IsNil)
932+
c.Assert(refs, HasLen, 1)
933+
c.Assert(refs[0].Name(), Equals, plumbing.ReferenceName("refs/heads/foo"))
934+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.