aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--remote.go19
-rw-r--r--remote_test.go52
-rw-r--r--repository_test.go63
-rw-r--r--storage/filesystem/internal/dotgit/dotgit.go12
-rw-r--r--storage/filesystem/internal/dotgit/dotgit_test.go15
-rw-r--r--storage/filesystem/shallow.go2
6 files changed, 158 insertions, 5 deletions
diff --git a/remote.go b/remote.go
index 666c9f5..4b86955 100644
--- a/remote.go
+++ b/remote.go
@@ -976,9 +976,24 @@ func pushHashes(
}
func (r *Remote) updateShallow(o *FetchOptions, resp *packp.UploadPackResponse) error {
- if o.Depth == 0 {
+ if o.Depth == 0 || len(resp.Shallows) == 0 {
return nil
}
- return r.s.SetShallow(resp.Shallows)
+ shallows, err := r.s.Shallow()
+ if err != nil {
+ return err
+ }
+
+outer:
+ for _, s := range resp.Shallows {
+ for _, oldS := range shallows {
+ if s == oldS {
+ continue outer
+ }
+ }
+ shallows = append(shallows, s)
+ }
+
+ return r.s.SetShallow(shallows)
}
diff --git a/remote_test.go b/remote_test.go
index e586e7a..82ec1fc 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -9,6 +9,7 @@ import (
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp"
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/storage"
"gopkg.in/src-d/go-git.v4/storage/filesystem"
@@ -741,3 +742,54 @@ func (s *RemoteSuite) TestList(c *C) {
c.Assert(found, Equals, true)
}
}
+
+func (s *RemoteSuite) TestUpdateShallows(c *C) {
+ hashes := []plumbing.Hash{
+ plumbing.NewHash("0000000000000000000000000000000000000001"),
+ plumbing.NewHash("0000000000000000000000000000000000000002"),
+ plumbing.NewHash("0000000000000000000000000000000000000003"),
+ plumbing.NewHash("0000000000000000000000000000000000000004"),
+ plumbing.NewHash("0000000000000000000000000000000000000005"),
+ plumbing.NewHash("0000000000000000000000000000000000000006"),
+ }
+
+ tests := []struct {
+ hashes []plumbing.Hash
+ result []plumbing.Hash
+ }{
+ // add to empty shallows
+ {hashes[0:2], hashes[0:2]},
+ // add new hashes
+ {hashes[2:4], hashes[0:4]},
+ // add some hashes already in shallow list
+ {hashes[2:6], hashes[0:6]},
+ // add all hashes
+ {hashes[0:6], hashes[0:6]},
+ // add empty list
+ {nil, hashes[0:6]},
+ }
+
+ remote := newRemote(memory.NewStorage(), &config.RemoteConfig{
+ Name: DefaultRemoteName,
+ })
+
+ shallows, err := remote.s.Shallow()
+ c.Assert(err, IsNil)
+ c.Assert(len(shallows), Equals, 0)
+
+ resp := new(packp.UploadPackResponse)
+ o := &FetchOptions{
+ Depth: 1,
+ }
+
+ for _, t := range tests {
+ resp.Shallows = t.hashes
+ err = remote.updateShallow(o, resp)
+ c.Assert(err, IsNil)
+
+ shallow, err := remote.s.Shallow()
+ c.Assert(err, IsNil)
+ c.Assert(len(shallow), Equals, len(t.result))
+ c.Assert(shallow, DeepEquals, t.result)
+ }
+}
diff --git a/repository_test.go b/repository_test.go
index 3e94db9..b78fbb7 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -1625,3 +1625,66 @@ func executeOnPath(path, cmd string) error {
return c.Run()
}
+
+func (s *RepositorySuite) TestBrokenMultipleShallowFetch(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ _, err := r.CreateRemote(&config.RemoteConfig{
+ Name: DefaultRemoteName,
+ URLs: []string{s.GetBasicLocalRepositoryURL()},
+ })
+ c.Assert(err, IsNil)
+
+ c.Assert(r.Fetch(&FetchOptions{
+ Depth: 2,
+ RefSpecs: []config.RefSpec{config.RefSpec("refs/heads/master:refs/heads/master")},
+ }), IsNil)
+
+ shallows, err := r.Storer.Shallow()
+ c.Assert(err, IsNil)
+ c.Assert(len(shallows), Equals, 1)
+
+ ref, err := r.Reference("refs/heads/master", true)
+ c.Assert(err, IsNil)
+ cobj, err := r.CommitObject(ref.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(cobj, NotNil)
+ err = object.NewCommitPreorderIter(cobj, nil, nil).ForEach(func(c *object.Commit) error {
+ for _, ph := range c.ParentHashes {
+ for _, h := range shallows {
+ if ph == h {
+ return storer.ErrStop
+ }
+ }
+ }
+
+ return nil
+ })
+ c.Assert(err, IsNil)
+
+ c.Assert(r.Fetch(&FetchOptions{
+ Depth: 5,
+ RefSpecs: []config.RefSpec{config.RefSpec("refs/heads/*:refs/heads/*")},
+ }), IsNil)
+
+ shallows, err = r.Storer.Shallow()
+ c.Assert(err, IsNil)
+ c.Assert(len(shallows), Equals, 3)
+
+ ref, err = r.Reference("refs/heads/master", true)
+ c.Assert(err, IsNil)
+ cobj, err = r.CommitObject(ref.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(cobj, NotNil)
+ err = object.NewCommitPreorderIter(cobj, nil, nil).ForEach(func(c *object.Commit) error {
+ for _, ph := range c.ParentHashes {
+ for _, h := range shallows {
+ if ph == h {
+ return storer.ErrStop
+ }
+ }
+ }
+
+ return nil
+ })
+ c.Assert(err, IsNil)
+}
diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go
index 6f0f1a5..52b621c 100644
--- a/storage/filesystem/internal/dotgit/dotgit.go
+++ b/storage/filesystem/internal/dotgit/dotgit.go
@@ -162,8 +162,11 @@ func (d *DotGit) ObjectPacks() ([]plumbing.Hash, error) {
n := f.Name()
h := plumbing.NewHash(n[5 : len(n)-5]) //pack-(hash).pack
+ if h.IsZero() {
+ // Ignore files with badly-formatted names.
+ continue
+ }
packs = append(packs, h)
-
}
return packs, nil
@@ -255,7 +258,12 @@ func (d *DotGit) ForEachObjectHash(fun func(plumbing.Hash) error) error {
}
for _, o := range d {
- err = fun(plumbing.NewHash(base + o.Name()))
+ h := plumbing.NewHash(base + o.Name())
+ if h.IsZero() {
+ // Ignore files with badly-formatted names.
+ continue
+ }
+ err = fun(h)
if err != nil {
return err
}
diff --git a/storage/filesystem/internal/dotgit/dotgit_test.go b/storage/filesystem/internal/dotgit/dotgit_test.go
index 2c43295..7733eef 100644
--- a/storage/filesystem/internal/dotgit/dotgit_test.go
+++ b/storage/filesystem/internal/dotgit/dotgit_test.go
@@ -151,6 +151,7 @@ func (s *SuiteDotGit) TestRefsFromReferenceFile(c *C) {
}
func BenchmarkRefMultipleTimes(b *testing.B) {
+ fixtures.Init()
fs := fixtures.Basic().ByTag(".git").One().DotGit()
refname := plumbing.ReferenceName("refs/remotes/origin/branch")
@@ -418,7 +419,7 @@ func findReference(refs []*plumbing.Reference, name string) *plumbing.Reference
return nil
}
-func (s *SuiteDotGit) TestObjectsPack(c *C) {
+func (s *SuiteDotGit) TestObjectPacks(c *C) {
f := fixtures.Basic().ByTag(".git").One()
fs := f.DotGit()
dir := New(fs)
@@ -427,6 +428,18 @@ func (s *SuiteDotGit) TestObjectsPack(c *C) {
c.Assert(err, IsNil)
c.Assert(hashes, HasLen, 1)
c.Assert(hashes[0], Equals, f.PackfileHash)
+
+ // Make sure that a random file in the pack directory doesn't
+ // break everything.
+ badFile, err := fs.Create("objects/pack/OOPS_THIS_IS_NOT_RIGHT.pack")
+ c.Assert(err, IsNil)
+ err = badFile.Close()
+ c.Assert(err, IsNil)
+
+ hashes2, err := dir.ObjectPacks()
+ c.Assert(err, IsNil)
+ c.Assert(hashes2, HasLen, 1)
+ c.Assert(hashes[0], Equals, hashes2[0])
}
func (s *SuiteDotGit) TestObjectPack(c *C) {
diff --git a/storage/filesystem/shallow.go b/storage/filesystem/shallow.go
index 4b2e2dc..173767c 100644
--- a/storage/filesystem/shallow.go
+++ b/storage/filesystem/shallow.go
@@ -41,6 +41,8 @@ func (s *ShallowStorage) Shallow() ([]plumbing.Hash, error) {
return nil, err
}
+ defer ioutil.CheckClose(f, &err)
+
var hash []plumbing.Hash
scn := bufio.NewScanner(f)