diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-08-29 13:25:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-29 13:25:53 +0200 |
commit | 3ca370277427c5d508f0dedacbd559523a305121 (patch) | |
tree | da025649dc74a777421ea8d05dcedca20c60485b /storage/filesystem/internal/dotgit/dotgit.go | |
parent | 7aa9d15d395282144f31a09c0fac230da3f65360 (diff) | |
parent | 51e25dde71feb355eb32f4d2208a0ae4cb5e9244 (diff) | |
download | go-git-3ca370277427c5d508f0dedacbd559523a305121.tar.gz |
Merge pull request #569 from erizocosmico/fix/race-condition-dotgit-refs
dotgit: avoid duplicated references returned by Refs
Diffstat (limited to 'storage/filesystem/internal/dotgit/dotgit.go')
-rw-r--r-- | storage/filesystem/internal/dotgit/dotgit.go | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go index b50cdab..2840bc7 100644 --- a/storage/filesystem/internal/dotgit/dotgit.go +++ b/storage/filesystem/internal/dotgit/dotgit.go @@ -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 } @@ -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 @@ -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) { @@ -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 } @@ -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 } } |