aboutsummaryrefslogtreecommitdiffstats
path: root/repository_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'repository_test.go')
-rw-r--r--repository_test.go914
1 files changed, 896 insertions, 18 deletions
diff --git a/repository_test.go b/repository_test.go
index ef37e37..6d34d42 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -10,10 +10,15 @@ import (
"os/exec"
"path/filepath"
"strings"
+ "testing"
"time"
+ "golang.org/x/crypto/openpgp"
+ "golang.org/x/crypto/openpgp/armor"
+ openpgperr "golang.org/x/crypto/openpgp/errors"
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/plumbing/cache"
"gopkg.in/src-d/go-git.v4/plumbing/object"
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/storage"
@@ -50,8 +55,7 @@ func (s *RepositorySuite) TestInitNonStandardDotGit(c *C) {
fs := osfs.New(dir)
dot, _ := fs.Chroot("storage")
- storage, err := filesystem.NewStorage(dot)
- c.Assert(err, IsNil)
+ storage := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
wt, _ := fs.Chroot("worktree")
r, err := Init(storage, wt)
@@ -77,8 +81,7 @@ func (s *RepositorySuite) TestInitStandardDotGit(c *C) {
fs := osfs.New(dir)
dot, _ := fs.Chroot(".git")
- storage, err := filesystem.NewStorage(dot)
- c.Assert(err, IsNil)
+ storage := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
r, err := Init(storage, fs)
c.Assert(err, IsNil)
@@ -243,6 +246,119 @@ func (s *RepositorySuite) TestDeleteRemote(c *C) {
c.Assert(alt, IsNil)
}
+func (s *RepositorySuite) TestCreateBranchAndBranch(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ testBranch := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err := r.CreateBranch(testBranch)
+
+ c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(len(cfg.Branches), Equals, 1)
+ branch := cfg.Branches["foo"]
+ c.Assert(branch.Name, Equals, testBranch.Name)
+ c.Assert(branch.Remote, Equals, testBranch.Remote)
+ c.Assert(branch.Merge, Equals, testBranch.Merge)
+
+ branch, err = r.Branch("foo")
+ c.Assert(err, IsNil)
+ c.Assert(branch.Name, Equals, testBranch.Name)
+ c.Assert(branch.Remote, Equals, testBranch.Remote)
+ c.Assert(branch.Merge, Equals, testBranch.Merge)
+}
+
+func (s *RepositorySuite) TestCreateBranchUnmarshal(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+
+ expected := []byte(`[core]
+ bare = true
+[remote "foo"]
+ url = http://foo/foo.git
+ fetch = +refs/heads/*:refs/remotes/foo/*
+[branch "foo"]
+ remote = origin
+ merge = refs/heads/foo
+[branch "master"]
+ remote = origin
+ merge = refs/heads/master
+`)
+
+ _, err := r.CreateRemote(&config.RemoteConfig{
+ Name: "foo",
+ URLs: []string{"http://foo/foo.git"},
+ })
+ c.Assert(err, IsNil)
+ testBranch1 := &config.Branch{
+ Name: "master",
+ Remote: "origin",
+ Merge: "refs/heads/master",
+ }
+ testBranch2 := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err = r.CreateBranch(testBranch1)
+ err = r.CreateBranch(testBranch2)
+
+ c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ marshaled, err := cfg.Marshal()
+ c.Assert(string(expected), Equals, string(marshaled))
+}
+
+func (s *RepositorySuite) TestBranchInvalid(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ branch, err := r.Branch("foo")
+
+ c.Assert(err, NotNil)
+ c.Assert(branch, IsNil)
+}
+
+func (s *RepositorySuite) TestCreateBranchInvalid(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.CreateBranch(&config.Branch{})
+
+ c.Assert(err, NotNil)
+
+ testBranch := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err = r.CreateBranch(testBranch)
+ c.Assert(err, IsNil)
+ err = r.CreateBranch(testBranch)
+ c.Assert(err, NotNil)
+}
+
+func (s *RepositorySuite) TestDeleteBranch(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ testBranch := &config.Branch{
+ Name: "foo",
+ Remote: "origin",
+ Merge: "refs/heads/foo",
+ }
+ err := r.CreateBranch(testBranch)
+
+ c.Assert(err, IsNil)
+
+ err = r.DeleteBranch("foo")
+ c.Assert(err, IsNil)
+
+ b, err := r.Branch("foo")
+ c.Assert(err, Equals, ErrBranchNotFound)
+ c.Assert(b, IsNil)
+
+ err = r.DeleteBranch("foo")
+ c.Assert(err, Equals, ErrBranchNotFound)
+}
+
func (s *RepositorySuite) TestPlainInit(c *C) {
dir, err := ioutil.TempDir("", "plain-init")
c.Assert(err, IsNil)
@@ -406,6 +522,36 @@ func (s *RepositorySuite) TestPlainOpenNotExists(c *C) {
c.Assert(r, IsNil)
}
+func (s *RepositorySuite) TestPlainOpenDetectDotGit(c *C) {
+ dir, err := ioutil.TempDir("", "plain-open")
+ c.Assert(err, IsNil)
+ defer os.RemoveAll(dir)
+
+ subdir := filepath.Join(dir, "a", "b")
+ err = os.MkdirAll(subdir, 0755)
+ c.Assert(err, IsNil)
+
+ r, err := PlainInit(dir, false)
+ c.Assert(err, IsNil)
+ c.Assert(r, NotNil)
+
+ opt := &PlainOpenOptions{DetectDotGit: true}
+ r, err = PlainOpenWithOptions(subdir, opt)
+ c.Assert(err, IsNil)
+ c.Assert(r, NotNil)
+}
+
+func (s *RepositorySuite) TestPlainOpenNotExistsDetectDotGit(c *C) {
+ dir, err := ioutil.TempDir("", "plain-open")
+ c.Assert(err, IsNil)
+ defer os.RemoveAll(dir)
+
+ opt := &PlainOpenOptions{DetectDotGit: true}
+ r, err := PlainOpenWithOptions(dir, opt)
+ c.Assert(err, Equals, ErrRepositoryNotExists)
+ c.Assert(r, IsNil)
+}
+
func (s *RepositorySuite) TestPlainClone(c *C) {
r, err := PlainClone(c.MkDir(), false, &CloneOptions{
URL: s.GetBasicLocalRepositoryURL(),
@@ -416,6 +562,23 @@ func (s *RepositorySuite) TestPlainClone(c *C) {
remotes, err := r.Remotes()
c.Assert(err, IsNil)
c.Assert(remotes, HasLen, 1)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["master"].Name, Equals, "master")
+}
+
+func (s *RepositorySuite) TestPlainCloneWithRemoteName(c *C) {
+ r, err := PlainClone(c.MkDir(), false, &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ RemoteName: "test",
+ })
+
+ c.Assert(err, IsNil)
+
+ remote, err := r.Remote("test")
+ c.Assert(err, IsNil)
+ c.Assert(remote, NotNil)
}
func (s *RepositorySuite) TestPlainCloneContext(c *C) {
@@ -430,6 +593,10 @@ func (s *RepositorySuite) TestPlainCloneContext(c *C) {
}
func (s *RepositorySuite) TestPlainCloneWithRecurseSubmodules(c *C) {
+ if testing.Short() {
+ c.Skip("skipping test in short mode.")
+ }
+
dir, err := ioutil.TempDir("", "plain-clone-submodule")
c.Assert(err, IsNil)
defer os.RemoveAll(dir)
@@ -445,6 +612,7 @@ func (s *RepositorySuite) TestPlainCloneWithRecurseSubmodules(c *C) {
cfg, err := r.Config()
c.Assert(err, IsNil)
c.Assert(cfg.Remotes, HasLen, 1)
+ c.Assert(cfg.Branches, HasLen, 1)
c.Assert(cfg.Submodules, HasLen, 2)
}
@@ -580,6 +748,8 @@ func (s *RepositorySuite) TestCloneConfig(c *C) {
c.Assert(cfg.Remotes, HasLen, 1)
c.Assert(cfg.Remotes["origin"].Name, Equals, "origin")
c.Assert(cfg.Remotes["origin"].URLs, HasLen, 1)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["master"].Name, Equals, "master")
}
func (s *RepositorySuite) TestCloneSingleBranchAndNonHEAD(c *C) {
@@ -601,6 +771,13 @@ func (s *RepositorySuite) TestCloneSingleBranchAndNonHEAD(c *C) {
c.Assert(err, IsNil)
c.Assert(remotes, HasLen, 1)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["branch"].Name, Equals, "branch")
+ c.Assert(cfg.Branches["branch"].Remote, Equals, "origin")
+ c.Assert(cfg.Branches["branch"].Merge, Equals, plumbing.ReferenceName("refs/heads/branch"))
+
head, err = r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -637,6 +814,13 @@ func (s *RepositorySuite) TestCloneSingleBranch(c *C) {
c.Assert(err, IsNil)
c.Assert(remotes, HasLen, 1)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 1)
+ c.Assert(cfg.Branches["master"].Name, Equals, "master")
+ c.Assert(cfg.Branches["master"].Remote, Equals, "origin")
+ c.Assert(cfg.Branches["master"].Merge, Equals, plumbing.ReferenceName("refs/heads/master"))
+
head, err = r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -663,6 +847,10 @@ func (s *RepositorySuite) TestCloneDetachedHEAD(c *C) {
})
c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 0)
+
head, err := r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -673,7 +861,33 @@ func (s *RepositorySuite) TestCloneDetachedHEAD(c *C) {
objects, err := r.Objects()
c.Assert(err, IsNil)
objects.ForEach(func(object.Object) error { count++; return nil })
- c.Assert(count, Equals, 31)
+ c.Assert(count, Equals, 28)
+}
+
+func (s *RepositorySuite) TestCloneDetachedHEADAndSingle(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ ReferenceName: plumbing.ReferenceName("refs/tags/v1.0.0"),
+ SingleBranch: true,
+ })
+ c.Assert(err, IsNil)
+
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 0)
+
+ head, err := r.Reference(plumbing.HEAD, false)
+ c.Assert(err, IsNil)
+ c.Assert(head, NotNil)
+ c.Assert(head.Type(), Equals, plumbing.HashReference)
+ c.Assert(head.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
+
+ count := 0
+ objects, err := r.Objects()
+ c.Assert(err, IsNil)
+ objects.ForEach(func(object.Object) error { count++; return nil })
+ c.Assert(count, Equals, 28)
}
func (s *RepositorySuite) TestCloneDetachedHEADAndShallow(c *C) {
@@ -686,6 +900,10 @@ func (s *RepositorySuite) TestCloneDetachedHEADAndShallow(c *C) {
c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 0)
+
head, err := r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -707,6 +925,10 @@ func (s *RepositorySuite) TestCloneDetachedHEADAnnotatedTag(c *C) {
})
c.Assert(err, IsNil)
+ cfg, err := r.Config()
+ c.Assert(err, IsNil)
+ c.Assert(cfg.Branches, HasLen, 0)
+
head, err := r.Reference(plumbing.HEAD, false)
c.Assert(err, IsNil)
c.Assert(head, NotNil)
@@ -851,8 +1073,7 @@ func (s *RepositorySuite) TestPushDepth(c *C) {
func (s *RepositorySuite) TestPushNonExistentRemote(c *C) {
srcFs := fixtures.Basic().One().DotGit()
- sto, err := filesystem.NewStorage(srcFs)
- c.Assert(err, IsNil)
+ sto := filesystem.NewStorage(srcFs, cache.NewObjectLRUDefault())
r, err := Open(sto, srcFs)
c.Assert(err, IsNil)
@@ -870,7 +1091,7 @@ func (s *RepositorySuite) TestLog(c *C) {
c.Assert(err, IsNil)
cIter, err := r.Log(&LogOptions{
- plumbing.NewHash("b8e471f58bcbca63b07bda20e428190409c2db47"),
+ From: plumbing.NewHash("b8e471f58bcbca63b07bda20e428190409c2db47"),
})
c.Assert(err, IsNil)
@@ -930,11 +1151,150 @@ func (s *RepositorySuite) TestLogError(c *C) {
c.Assert(err, IsNil)
_, err = r.Log(&LogOptions{
- plumbing.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
+ From: plumbing.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
})
c.Assert(err, NotNil)
}
+func (s *RepositorySuite) TestLogFileNext(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ })
+
+ c.Assert(err, IsNil)
+
+ fileName := "vendor/foo.go"
+ cIter, err := r.Log(&LogOptions{FileName: &fileName})
+
+ c.Assert(err, IsNil)
+
+ commitOrder := []plumbing.Hash{
+ plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"),
+ }
+
+ for _, o := range commitOrder {
+ commit, err := cIter.Next()
+ c.Assert(err, IsNil)
+ c.Assert(commit.Hash, Equals, o)
+ }
+ _, err = cIter.Next()
+ c.Assert(err, Equals, io.EOF)
+}
+
+func (s *RepositorySuite) TestLogFileForEach(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ })
+
+ c.Assert(err, IsNil)
+
+ fileName := "php/crappy.php"
+ cIter, err := r.Log(&LogOptions{FileName: &fileName})
+
+ c.Assert(err, IsNil)
+
+ commitOrder := []plumbing.Hash{
+ plumbing.NewHash("918c48b83bd081e863dbe1b80f8998f058cd8294"),
+ }
+
+ expectedIndex := 0
+ cIter.ForEach(func(commit *object.Commit) error {
+ expectedCommitHash := commitOrder[expectedIndex]
+ c.Assert(commit.Hash.String(), Equals, expectedCommitHash.String())
+ expectedIndex += 1
+ return nil
+ })
+ c.Assert(expectedIndex, Equals, 1)
+}
+
+func (s *RepositorySuite) TestLogInvalidFile(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ })
+ c.Assert(err, IsNil)
+
+ // Throwing in a file that does not exist
+ fileName := "vendor/foo12.go"
+ cIter, err := r.Log(&LogOptions{FileName: &fileName})
+ // Not raising an error since `git log -- vendor/foo12.go` responds silently
+ c.Assert(err, IsNil)
+
+ _, err = cIter.Next()
+ c.Assert(err, Equals, io.EOF)
+}
+
+func (s *RepositorySuite) TestLogFileInitialCommit(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ })
+ c.Assert(err, IsNil)
+
+ fileName := "LICENSE"
+ cIter, err := r.Log(&LogOptions{
+ Order: LogOrderCommitterTime,
+ FileName: &fileName,
+ })
+
+ c.Assert(err, IsNil)
+
+ commitOrder := []plumbing.Hash{
+ plumbing.NewHash("b029517f6300c2da0f4b651b8642506cd6aaf45d"),
+ }
+
+ expectedIndex := 0
+ cIter.ForEach(func(commit *object.Commit) error {
+ expectedCommitHash := commitOrder[expectedIndex]
+ c.Assert(commit.Hash.String(), Equals, expectedCommitHash.String())
+ expectedIndex += 1
+ return nil
+ })
+ c.Assert(expectedIndex, Equals, 1)
+}
+
+func (s *RepositorySuite) TestLogFileWithOtherParamsFail(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ })
+ c.Assert(err, IsNil)
+
+ fileName := "vendor/foo.go"
+ cIter, err := r.Log(&LogOptions{
+ Order: LogOrderCommitterTime,
+ FileName: &fileName,
+ From: plumbing.NewHash("35e85108805c84807bc66a02d91535e1e24b38b9"),
+ })
+ c.Assert(err, IsNil)
+ _, iterErr := cIter.Next()
+ c.Assert(iterErr, Equals, io.EOF)
+}
+
+func (s *RepositorySuite) TestLogFileWithOtherParamsPass(c *C) {
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{
+ URL: s.GetBasicLocalRepositoryURL(),
+ })
+ c.Assert(err, IsNil)
+
+ fileName := "LICENSE"
+ cIter, err := r.Log(&LogOptions{
+ Order: LogOrderCommitterTime,
+ FileName: &fileName,
+ From: plumbing.NewHash("35e85108805c84807bc66a02d91535e1e24b38b9"),
+ })
+ c.Assert(err, IsNil)
+ commitVal, iterErr := cIter.Next()
+ c.Assert(iterErr, Equals, nil)
+ c.Assert(commitVal.Hash.String(), Equals, "b029517f6300c2da0f4b651b8642506cd6aaf45d")
+
+ _, iterErr = cIter.Next()
+ c.Assert(iterErr, Equals, io.EOF)
+}
+
func (s *RepositorySuite) TestCommit(c *C) {
r, _ := Init(memory.NewStorage(), nil)
err := r.clone(context.Background(), &CloneOptions{
@@ -1068,10 +1428,396 @@ func (s *RepositorySuite) TestTags(c *C) {
c.Assert(count, Equals, 5)
}
+func (s *RepositorySuite) TestCreateTagLightweight(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ expected, err := r.Head()
+ c.Assert(err, IsNil)
+
+ ref, err := r.CreateTag("foobar", expected.Hash(), nil)
+ c.Assert(err, IsNil)
+ c.Assert(ref, NotNil)
+
+ actual, err := r.Tag("foobar")
+ c.Assert(err, IsNil)
+
+ c.Assert(expected.Hash(), Equals, actual.Hash())
+}
+
+func (s *RepositorySuite) TestCreateTagLightweightExists(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ expected, err := r.Head()
+ c.Assert(err, IsNil)
+
+ ref, err := r.CreateTag("lightweight-tag", expected.Hash(), nil)
+ c.Assert(ref, IsNil)
+ c.Assert(err, Equals, ErrTagExists)
+}
+
+func (s *RepositorySuite) TestCreateTagAnnotated(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ h, err := r.Head()
+ c.Assert(err, IsNil)
+
+ expectedHash := h.Hash()
+
+ ref, err := r.CreateTag("foobar", expectedHash, &CreateTagOptions{
+ Tagger: defaultSignature(),
+ Message: "foo bar baz qux",
+ })
+ c.Assert(err, IsNil)
+
+ tag, err := r.Tag("foobar")
+ c.Assert(err, IsNil)
+
+ obj, err := r.TagObject(tag.Hash())
+ c.Assert(err, IsNil)
+
+ c.Assert(ref, DeepEquals, tag)
+ c.Assert(obj.Hash, Equals, ref.Hash())
+ c.Assert(obj.Type(), Equals, plumbing.TagObject)
+ c.Assert(obj.Target, Equals, expectedHash)
+}
+
+func (s *RepositorySuite) TestCreateTagAnnotatedBadOpts(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ h, err := r.Head()
+ c.Assert(err, IsNil)
+
+ expectedHash := h.Hash()
+
+ ref, err := r.CreateTag("foobar", expectedHash, &CreateTagOptions{
+ Message: "foo bar baz qux",
+ })
+ c.Assert(ref, IsNil)
+ c.Assert(err, Equals, ErrMissingTagger)
+
+ ref, err = r.CreateTag("foobar", expectedHash, &CreateTagOptions{
+ Tagger: defaultSignature(),
+ })
+ c.Assert(ref, IsNil)
+ c.Assert(err, Equals, ErrMissingMessage)
+}
+
+func (s *RepositorySuite) TestCreateTagAnnotatedBadHash(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ ref, err := r.CreateTag("foobar", plumbing.ZeroHash, &CreateTagOptions{
+ Tagger: defaultSignature(),
+ Message: "foo bar baz qux",
+ })
+ c.Assert(ref, IsNil)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+}
+
+func (s *RepositorySuite) TestCreateTagSigned(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ h, err := r.Head()
+ c.Assert(err, IsNil)
+
+ key := commitSignKey(c, true)
+ _, err = r.CreateTag("foobar", h.Hash(), &CreateTagOptions{
+ Tagger: defaultSignature(),
+ Message: "foo bar baz qux",
+ SignKey: key,
+ })
+ c.Assert(err, IsNil)
+
+ tag, err := r.Tag("foobar")
+ c.Assert(err, IsNil)
+
+ obj, err := r.TagObject(tag.Hash())
+ c.Assert(err, IsNil)
+
+ // Verify the tag.
+ pks := new(bytes.Buffer)
+ pkw, err := armor.Encode(pks, openpgp.PublicKeyType, nil)
+ c.Assert(err, IsNil)
+
+ err = key.Serialize(pkw)
+ c.Assert(err, IsNil)
+ err = pkw.Close()
+ c.Assert(err, IsNil)
+
+ actual, err := obj.Verify(pks.String())
+ c.Assert(err, IsNil)
+ c.Assert(actual.PrimaryKey, DeepEquals, key.PrimaryKey)
+}
+
+func (s *RepositorySuite) TestCreateTagSignedBadKey(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ h, err := r.Head()
+ c.Assert(err, IsNil)
+
+ key := commitSignKey(c, false)
+ _, err = r.CreateTag("foobar", h.Hash(), &CreateTagOptions{
+ Tagger: defaultSignature(),
+ Message: "foo bar baz qux",
+ SignKey: key,
+ })
+ c.Assert(err, Equals, openpgperr.InvalidArgumentError("signing key is encrypted"))
+}
+
+func (s *RepositorySuite) TestCreateTagCanonicalize(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ h, err := r.Head()
+ c.Assert(err, IsNil)
+
+ key := commitSignKey(c, true)
+ _, err = r.CreateTag("foobar", h.Hash(), &CreateTagOptions{
+ Tagger: defaultSignature(),
+ Message: "\n\nfoo bar baz qux\n\nsome message here",
+ SignKey: key,
+ })
+ c.Assert(err, IsNil)
+
+ tag, err := r.Tag("foobar")
+ c.Assert(err, IsNil)
+
+ obj, err := r.TagObject(tag.Hash())
+ c.Assert(err, IsNil)
+
+ // Assert the new canonicalized message.
+ c.Assert(obj.Message, Equals, "foo bar baz qux\n\nsome message here\n")
+
+ // Verify the tag.
+ pks := new(bytes.Buffer)
+ pkw, err := armor.Encode(pks, openpgp.PublicKeyType, nil)
+ c.Assert(err, IsNil)
+
+ err = key.Serialize(pkw)
+ c.Assert(err, IsNil)
+ err = pkw.Close()
+ c.Assert(err, IsNil)
+
+ actual, err := obj.Verify(pks.String())
+ c.Assert(err, IsNil)
+ c.Assert(actual.PrimaryKey, DeepEquals, key.PrimaryKey)
+}
+
+func (s *RepositorySuite) TestTagLightweight(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ expected := plumbing.NewHash("f7b877701fbf855b44c0a9e86f3fdce2c298b07f")
+
+ tag, err := r.Tag("lightweight-tag")
+ c.Assert(err, IsNil)
+
+ actual := tag.Hash()
+ c.Assert(expected, Equals, actual)
+}
+
+func (s *RepositorySuite) TestTagLightweightMissingTag(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ tag, err := r.Tag("lightweight-tag-tag")
+ c.Assert(tag, IsNil)
+ c.Assert(err, Equals, ErrTagNotFound)
+}
+
+func (s *RepositorySuite) TestDeleteTag(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ err = r.DeleteTag("lightweight-tag")
+ c.Assert(err, IsNil)
+
+ _, err = r.Tag("lightweight-tag")
+ c.Assert(err, Equals, ErrTagNotFound)
+}
+
+func (s *RepositorySuite) TestDeleteTagMissingTag(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ r, _ := Init(memory.NewStorage(), nil)
+ err := r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ err = r.DeleteTag("lightweight-tag-tag")
+ c.Assert(err, Equals, ErrTagNotFound)
+}
+
+func (s *RepositorySuite) TestDeleteTagAnnotated(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ dir, err := ioutil.TempDir("", "go-git-test-deletetag-annotated")
+ c.Assert(err, IsNil)
+
+ defer os.RemoveAll(dir) // clean up
+
+ fss := filesystem.NewStorage(osfs.New(dir), cache.NewObjectLRUDefault())
+
+ r, _ := Init(fss, nil)
+ err = r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ ref, err := r.Tag("annotated-tag")
+ c.Assert(ref, NotNil)
+ c.Assert(err, IsNil)
+
+ obj, err := r.TagObject(ref.Hash())
+ c.Assert(obj, NotNil)
+ c.Assert(err, IsNil)
+
+ err = r.DeleteTag("annotated-tag")
+ c.Assert(err, IsNil)
+
+ _, err = r.Tag("annotated-tag")
+ c.Assert(err, Equals, ErrTagNotFound)
+
+ // Run a prune (and repack, to ensure that we are GCing everything regardless
+ // of the fixture in use) and try to get the tag object again.
+ //
+ // The repo needs to be re-opened after the repack.
+ err = r.Prune(PruneOptions{Handler: r.DeleteObject})
+ c.Assert(err, IsNil)
+
+ err = r.RepackObjects(&RepackConfig{})
+ c.Assert(err, IsNil)
+
+ r, err = PlainOpen(dir)
+ c.Assert(r, NotNil)
+ c.Assert(err, IsNil)
+
+ // Now check to see if the GC was effective in removing the tag object.
+ obj, err = r.TagObject(ref.Hash())
+ c.Assert(obj, IsNil)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+}
+
+func (s *RepositorySuite) TestDeleteTagAnnotatedUnpacked(c *C) {
+ url := s.GetLocalRepositoryURL(
+ fixtures.ByURL("https://github.com/git-fixtures/tags.git").One(),
+ )
+
+ dir, err := ioutil.TempDir("", "go-git-test-deletetag-annotated-unpacked")
+ c.Assert(err, IsNil)
+
+ defer os.RemoveAll(dir) // clean up
+
+ fss := filesystem.NewStorage(osfs.New(dir), cache.NewObjectLRUDefault())
+
+ r, _ := Init(fss, nil)
+ err = r.clone(context.Background(), &CloneOptions{URL: url})
+ c.Assert(err, IsNil)
+
+ // Create a tag for the deletion test. This ensures that the ultimate loose
+ // object will be unpacked (as we aren't doing anything that should pack it),
+ // so that we can effectively test that a prune deletes it, without having to
+ // resort to a repack.
+ h, err := r.Head()
+ c.Assert(err, IsNil)
+
+ expectedHash := h.Hash()
+
+ ref, err := r.CreateTag("foobar", expectedHash, &CreateTagOptions{
+ Tagger: defaultSignature(),
+ Message: "foo bar baz qux",
+ })
+ c.Assert(err, IsNil)
+
+ tag, err := r.Tag("foobar")
+ c.Assert(err, IsNil)
+
+ obj, err := r.TagObject(tag.Hash())
+ c.Assert(obj, NotNil)
+ c.Assert(err, IsNil)
+
+ err = r.DeleteTag("foobar")
+ c.Assert(err, IsNil)
+
+ _, err = r.Tag("foobar")
+ c.Assert(err, Equals, ErrTagNotFound)
+
+ // As mentioned, only run a prune. We are not testing for packed objects
+ // here.
+ err = r.Prune(PruneOptions{Handler: r.DeleteObject})
+ c.Assert(err, IsNil)
+
+ // Now check to see if the GC was effective in removing the tag object.
+ obj, err = r.TagObject(ref.Hash())
+ c.Assert(obj, IsNil)
+ c.Assert(err, Equals, plumbing.ErrObjectNotFound)
+}
+
func (s *RepositorySuite) TestBranches(c *C) {
f := fixtures.ByURL("https://github.com/git-fixtures/root-references.git").One()
- sto, err := filesystem.NewStorage(f.DotGit())
- c.Assert(err, IsNil)
+ sto := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
r, err := Open(sto, f.DotGit())
c.Assert(err, IsNil)
@@ -1288,8 +2034,7 @@ func (s *RepositorySuite) TestWorktreeBare(c *C) {
func (s *RepositorySuite) TestResolveRevision(c *C) {
f := fixtures.ByURL("https://github.com/git-fixtures/basic.git").One()
- sto, err := filesystem.NewStorage(f.DotGit())
- c.Assert(err, IsNil)
+ sto := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
r, err := Open(sto, f.DotGit())
c.Assert(err, IsNil)
@@ -1313,6 +2058,7 @@ func (s *RepositorySuite) TestResolveRevision(c *C) {
"branch~1": "918c48b83bd081e863dbe1b80f8998f058cd8294",
"v1.0.0~1": "918c48b83bd081e863dbe1b80f8998f058cd8294",
"master~1": "918c48b83bd081e863dbe1b80f8998f058cd8294",
+ "918c48b83bd081e863dbe1b80f8998f058cd8294": "918c48b83bd081e863dbe1b80f8998f058cd8294",
}
for rev, hash := range datas {
@@ -1332,10 +2078,19 @@ func (s *RepositorySuite) TestResolveRevisionWithErrors(c *C) {
err := r.clone(context.Background(), &CloneOptions{URL: url})
c.Assert(err, IsNil)
+ headRef, err := r.Head()
+ c.Assert(err, IsNil)
+
+ ref := plumbing.NewHashReference("refs/heads/918c48b83bd081e863dbe1b80f8998f058cd8294", headRef.Hash())
+ err = r.Storer.SetReference(ref)
+ c.Assert(err, IsNil)
+
datas := map[string]string{
- "efs/heads/master~": "reference not found",
- "HEAD^3": `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
- "HEAD^{/whatever}": `No commit message match regexp : "whatever"`,
+ "efs/heads/master~": "reference not found",
+ "HEAD^3": `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
+ "HEAD^{/whatever}": `No commit message match regexp : "whatever"`,
+ "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83": "reference not found",
+ "918c48b83bd081e863dbe1b80f8998f058cd8294": `refname "918c48b83bd081e863dbe1b80f8998f058cd8294" is ambiguous`,
}
for rev, rerr := range datas {
@@ -1350,8 +2105,7 @@ func (s *RepositorySuite) testRepackObjects(
srcFs := fixtures.ByTag("unpacked").One().DotGit()
var sto storage.Storer
var err error
- sto, err = filesystem.NewStorage(srcFs)
- c.Assert(err, IsNil)
+ sto = filesystem.NewStorage(srcFs, cache.NewObjectLRUDefault())
los := sto.(storer.LooseObjectStorer)
c.Assert(los, NotNil)
@@ -1396,10 +2150,18 @@ func (s *RepositorySuite) testRepackObjects(
}
func (s *RepositorySuite) TestRepackObjects(c *C) {
+ if testing.Short() {
+ c.Skip("skipping test in short mode.")
+ }
+
s.testRepackObjects(c, time.Time{}, 1)
}
func (s *RepositorySuite) TestRepackObjectsWithNoDelete(c *C) {
+ if testing.Short() {
+ c.Skip("skipping test in short mode.")
+ }
+
s.testRepackObjects(c, time.Unix(0, 1), 3)
}
@@ -1426,3 +2188,119 @@ 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)
+}
+
+func BenchmarkObjects(b *testing.B) {
+ if err := fixtures.Init(); err != nil {
+ b.Fatal(err)
+ }
+
+ defer func() {
+ if err := fixtures.Clean(); err != nil {
+ b.Fatal(err)
+ }
+ }()
+
+ for _, f := range fixtures.ByTag("packfile") {
+ if f.DotGitHash == plumbing.ZeroHash {
+ continue
+ }
+
+ b.Run(f.URL, func(b *testing.B) {
+ fs := f.DotGit()
+ storer := filesystem.NewStorage(fs, cache.NewObjectLRUDefault())
+
+ worktree, err := fs.Chroot(filepath.Dir(fs.Root()))
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ repo, err := Open(storer, worktree)
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ for i := 0; i < b.N; i++ {
+ iter, err := repo.Objects()
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ for {
+ _, err := iter.Next()
+ if err == io.EOF {
+ break
+ }
+
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+
+ iter.Close()
+ }
+ })
+ }
+}