aboutsummaryrefslogtreecommitdiffstats
path: root/storage/filesystem
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2017-08-29 13:25:53 +0200
committerGitHub <noreply@github.com>2017-08-29 13:25:53 +0200
commit3ca370277427c5d508f0dedacbd559523a305121 (patch)
treeda025649dc74a777421ea8d05dcedca20c60485b /storage/filesystem
parent7aa9d15d395282144f31a09c0fac230da3f65360 (diff)
parent51e25dde71feb355eb32f4d2208a0ae4cb5e9244 (diff)
downloadgo-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')
-rw-r--r--storage/filesystem/internal/dotgit/dotgit.go25
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
}
}