diff options
author | Jeremy Stribling <strib@alum.mit.edu> | 2017-11-28 10:15:33 -0800 |
---|---|---|
committer | Jeremy Stribling <strib@alum.mit.edu> | 2017-11-28 10:15:33 -0800 |
commit | 83e7046d0c1ce12f5394a1d5a4e28cad32aa666d (patch) | |
tree | 2d7b4409bc984ef87d8acfc9b17817a1834424d3 /storage | |
parent | d3f5eaf71b01b9f7f823470ac22958bd5fabbbcd (diff) | |
parent | 6dda959c4bda3a422a9a1c6425f92efa914c4d82 (diff) | |
download | go-git-83e7046d0c1ce12f5394a1d5a4e28cad32aa666d.tar.gz |
Merge remote-tracking branch 'src-d/master' into gh-fast-forward-fetch
Diffstat (limited to 'storage')
-rw-r--r-- | storage/filesystem/internal/dotgit/dotgit.go | 42 | ||||
-rw-r--r-- | storage/filesystem/internal/dotgit/dotgit_test.go | 40 |
2 files changed, 76 insertions, 6 deletions
diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go index cb3adc8..78aa9a2 100644 --- a/storage/filesystem/internal/dotgit/dotgit.go +++ b/storage/filesystem/internal/dotgit/dotgit.go @@ -322,7 +322,7 @@ func (d *DotGit) Refs() ([]*plumbing.Reference, error) { return nil, err } - if err := d.addRefsFromPackedRefs(&refs); err != nil { + if err := d.addRefsFromPackedRefs(&refs, seen); err != nil { return nil, err } @@ -390,7 +390,8 @@ func (d *DotGit) RemoveRef(name plumbing.ReferenceName) error { path := d.fs.Join(".", name.String()) _, err := d.fs.Stat(path) if err == nil { - return d.fs.Remove(path) + err = d.fs.Remove(path) + // Drop down to remove it from the packed refs file, too. } if err != nil && !os.IsNotExist(err) { @@ -400,13 +401,18 @@ 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) { packedRefs, err := d.findPackedRefs() if err != nil { return err } - *refs = append(*refs, packedRefs...) + for _, ref := range packedRefs { + if !seen[ref.Name()] { + *refs = append(*refs, ref) + seen[ref.Name()] = true + } + } return nil } @@ -419,6 +425,17 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e return err } + doCloseF := true + defer func() { + if doCloseF { + ioutil.CheckClose(f, &err) + } + }() + + err = f.Lock() + if err != nil { + return err + } // Creating the temp file in the same directory as the target file // improves our chances for rename operation to be atomic. @@ -426,6 +443,12 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e if err != nil { return err } + doCloseTmp := true + defer func() { + if doCloseTmp { + ioutil.CheckClose(tmp, &err) + } + }() s := bufio.NewScanner(f) found := false @@ -451,14 +474,21 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e } if !found { - return nil + doCloseTmp = false + ioutil.CheckClose(tmp, &err) + if err != nil { + return err + } + // Delete the temp file if nothing needed to be removed. + return d.fs.Remove(tmp.Name()) } + doCloseF = false if err := f.Close(); err != nil { - ioutil.CheckClose(tmp, &err) return err } + doCloseTmp = false if err := tmp.Close(); err != nil { return err } diff --git a/storage/filesystem/internal/dotgit/dotgit_test.go b/storage/filesystem/internal/dotgit/dotgit_test.go index 119d952..d1b04a7 100644 --- a/storage/filesystem/internal/dotgit/dotgit_test.go +++ b/storage/filesystem/internal/dotgit/dotgit_test.go @@ -184,6 +184,46 @@ func (s *SuiteDotGit) TestRemoveRefFromPackedRefs(c *C) { "e8d3ffab552895c19b9fcf7aa264d277cde33881 refs/remotes/origin/branch\n") } +func (s *SuiteDotGit) TestRemoveRefFromReferenceFileAndPackedRefs(c *C) { + fs := fixtures.Basic().ByTag(".git").One().DotGit() + dir := New(fs) + + // Make a ref file for a ref that's already in `packed-refs`. + err := dir.SetRef(plumbing.NewReferenceFromStrings( + "refs/remotes/origin/branch", + "e8d3ffab552895c19b9fcf7aa264d277cde33881", + )) + + // Make sure it only appears once in the refs list. + refs, err := dir.Refs() + c.Assert(err, IsNil) + found := false + for _, ref := range refs { + if ref.Name() == "refs/remotes/origin/branch" { + c.Assert(found, Equals, false) + found = true + } + } + + name := plumbing.ReferenceName("refs/remotes/origin/branch") + err = dir.RemoveRef(name) + c.Assert(err, IsNil) + + b, err := ioutil.ReadFile(filepath.Join(fs.Root(), packedRefsPath)) + c.Assert(err, IsNil) + + c.Assert(string(b), Equals, ""+ + "# pack-refs with: peeled fully-peeled \n"+ + "6ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/heads/master\n"+ + "6ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/remotes/origin/master\n") + + refs, err = dir.Refs() + c.Assert(err, IsNil) + + ref := findReference(refs, string(name)) + c.Assert(ref, IsNil) +} + func (s *SuiteDotGit) TestRemoveRefNonExistent(c *C) { fs := fixtures.Basic().ByTag(".git").One().DotGit() dir := New(fs) |