Skip to content

Commit

Permalink
Merge pull request src-d#569 from erizocosmico/fix/race-condition-dot…
Browse files Browse the repository at this point in the history
…git-refs

dotgit: avoid duplicated references returned by Refs
  • Loading branch information
mcuadros authored Aug 29, 2017
2 parents 7aa9d15 + 51e25dd commit 3ca3702
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions storage/filesystem/internal/dotgit/dotgit.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,12 @@ func (d *DotGit) SetRef(r *plumbing.Reference) error {
// Symbolic references are resolved and included in the output.
func (d *DotGit) Refs() ([]*plumbing.Reference, error) {
var refs []*plumbing.Reference
if err := d.addRefsFromPackedRefs(&refs); err != nil {
var seen = make(map[plumbing.ReferenceName]bool)
if err := d.addRefsFromRefDir(&refs, seen); err != nil {
return nil, err
}

if err := d.addRefsFromRefDir(&refs); err != nil {
if err := d.addRefsFromPackedRefs(&refs, seen); err != nil {
return nil, err
}

Expand Down Expand Up @@ -359,13 +360,16 @@ func (d *DotGit) RemoveRef(name plumbing.ReferenceName) error {
return d.rewritePackedRefsWithoutRef(name)
}

func (d *DotGit) addRefsFromPackedRefs(refs *[]*plumbing.Reference) (err error) {
func (d *DotGit) addRefsFromPackedRefs(refs *[]*plumbing.Reference, seen map[plumbing.ReferenceName]bool) (err error) {
if err := d.syncPackedRefs(); err != nil {
return err
}

for _, ref := range d.cachedPackedRefs {
*refs = append(*refs, ref)
for name, ref := range d.cachedPackedRefs {
if !seen[name] {
*refs = append(*refs, ref)
seen[name] = true
}
}

return nil
Expand Down Expand Up @@ -448,11 +452,11 @@ func (d *DotGit) processLine(line string) (*plumbing.Reference, error) {
}
}

func (d *DotGit) addRefsFromRefDir(refs *[]*plumbing.Reference) error {
return d.walkReferencesTree(refs, []string{refsPath})
func (d *DotGit) addRefsFromRefDir(refs *[]*plumbing.Reference, seen map[plumbing.ReferenceName]bool) error {
return d.walkReferencesTree(refs, []string{refsPath}, seen)
}

func (d *DotGit) walkReferencesTree(refs *[]*plumbing.Reference, relPath []string) error {
func (d *DotGit) walkReferencesTree(refs *[]*plumbing.Reference, relPath []string, seen map[plumbing.ReferenceName]bool) error {
files, err := d.fs.ReadDir(d.fs.Join(relPath...))
if err != nil {
if os.IsNotExist(err) {
Expand All @@ -465,7 +469,7 @@ func (d *DotGit) walkReferencesTree(refs *[]*plumbing.Reference, relPath []strin
for _, f := range files {
newRelPath := append(append([]string(nil), relPath...), f.Name())
if f.IsDir() {
if err = d.walkReferencesTree(refs, newRelPath); err != nil {
if err = d.walkReferencesTree(refs, newRelPath, seen); err != nil {
return err
}

Expand All @@ -477,8 +481,9 @@ func (d *DotGit) walkReferencesTree(refs *[]*plumbing.Reference, relPath []strin
return err
}

if ref != nil {
if ref != nil && !seen[ref.Name()] {
*refs = append(*refs, ref)
seen[ref.Name()] = true
}
}

Expand Down

0 comments on commit 3ca3702

Please sign in to comment.