aboutsummaryrefslogtreecommitdiffstats
path: root/storage/filesystem
diff options
context:
space:
mode:
authorJeremy Stribling <strib@alum.mit.edu>2017-11-28 10:15:33 -0800
committerJeremy Stribling <strib@alum.mit.edu>2017-11-28 10:15:33 -0800
commit83e7046d0c1ce12f5394a1d5a4e28cad32aa666d (patch)
tree2d7b4409bc984ef87d8acfc9b17817a1834424d3 /storage/filesystem
parentd3f5eaf71b01b9f7f823470ac22958bd5fabbbcd (diff)
parent6dda959c4bda3a422a9a1c6425f92efa914c4d82 (diff)
downloadgo-git-83e7046d0c1ce12f5394a1d5a4e28cad32aa666d.tar.gz
Merge remote-tracking branch 'src-d/master' into gh-fast-forward-fetch
Diffstat (limited to 'storage/filesystem')
-rw-r--r--storage/filesystem/internal/dotgit/dotgit.go42
-rw-r--r--storage/filesystem/internal/dotgit/dotgit_test.go40
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)