aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common_test.go14
-rw-r--r--core/reference.go14
-rw-r--r--core/reference_test.go7
-rw-r--r--objects_test.go11
-rw-r--r--options.go14
-rw-r--r--remote.go24
-rw-r--r--remote_test.go82
-rw-r--r--repository.go45
-rw-r--r--repository_test.go135
9 files changed, 226 insertions, 120 deletions
diff --git a/common_test.go b/common_test.go
index f7416e0..e0d11b5 100644
--- a/common_test.go
+++ b/common_test.go
@@ -20,7 +20,9 @@ func Test(t *testing.T) { TestingT(t) }
type BaseSuite struct{}
func (s *BaseSuite) SetUpTest(c *C) {
- clients.InstallProtocol("mock", &MockGitUploadPackService{})
+ clients.InstallProtocol("mock", func(end common.Endpoint) common.GitUploadPackService {
+ return &MockGitUploadPackService{conected: end}
+ })
}
const RepositoryFixture = "mock://formats/packfile/fixtures/git-fixture.ref-delta"
@@ -30,15 +32,11 @@ type MockGitUploadPackService struct {
auth common.AuthMethod
}
-func (p *MockGitUploadPackService) Connect(url common.Endpoint) error {
- p.conected = url
+func (p *MockGitUploadPackService) Connect() error {
return nil
}
-func (p *MockGitUploadPackService) ConnectWithAuth(
- url common.Endpoint, auth common.AuthMethod,
-) error {
- p.conected = url
+func (p *MockGitUploadPackService) ConnectWithAuth(auth common.AuthMethod) error {
p.auth = auth
return nil
}
@@ -50,11 +48,13 @@ func (p *MockGitUploadPackService) Info() (*common.GitUploadPackInfo, error) {
c.Decode("6ecf0ef2c2dffb796033e5a02219af86ec6584e5 HEADmulti_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2:2.4.8~dbussink-fix-enterprise-tokens-compilation-1167-gc7006cf")
ref := core.ReferenceName("refs/heads/master")
+ tag := core.ReferenceName("refs/tags/v1.0.0")
return &common.GitUploadPackInfo{
Capabilities: c,
Refs: map[core.ReferenceName]*core.Reference{
core.HEAD: core.NewSymbolicReference(core.HEAD, ref),
ref: core.NewHashReference(ref, h),
+ tag: core.NewHashReference(tag, h),
},
}, nil
}
diff --git a/core/reference.go b/core/reference.go
index 4be4971..7d3f378 100644
--- a/core/reference.go
+++ b/core/reference.go
@@ -34,6 +34,20 @@ const (
// ReferenceName reference name's
type ReferenceName string
+// AsRemote returns a new remote reference name using current one as base
+func (r ReferenceName) AsRemote(remote string) ReferenceName {
+ return ReferenceName(refRemotePrefix + remote + "/" + r.alias())
+}
+
+func (r ReferenceName) String() string {
+ return string(r)
+}
+
+func (r ReferenceName) alias() string {
+ parts := strings.Split(string(r), "/")
+ return parts[len(parts)-1]
+}
+
const (
HEAD ReferenceName = "HEAD"
)
diff --git a/core/reference_test.go b/core/reference_test.go
index 05d20b4..5d88f0e 100644
--- a/core/reference_test.go
+++ b/core/reference_test.go
@@ -10,6 +10,13 @@ const (
ExampleReferenceName ReferenceName = "refs/heads/v4"
)
+func (s *ReferenceSuite) TestReferenceNameAsRemote(c *C) {
+ c.Assert(
+ ExampleReferenceName.AsRemote("foo").String(),
+ Equals, "refs/remotes/foo/v4",
+ )
+}
+
func (s *ReferenceSuite) TestNewReferenceFromStrings(c *C) {
r := NewReferenceFromStrings("refs/heads/v4", "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
c.Assert(r.Type(), Equals, HashReference)
diff --git a/objects_test.go b/objects_test.go
index aeaceea..d24aa7b 100644
--- a/objects_test.go
+++ b/objects_test.go
@@ -10,23 +10,22 @@ import (
)
type ObjectsSuite struct {
+ BaseSuite
r *Repository
}
var _ = Suite(&ObjectsSuite{})
-/*
func (s *ObjectsSuite) SetUpTest(c *C) {
+ s.BaseSuite.SetUpTest(c)
+
var err error
- s.r, err = NewRepository(RepositoryFixture, nil)
+ s.r, err = NewMemoryRepository()
c.Assert(err, IsNil)
- s.r.Remotes["origin"].upSrv = &MockGitUploadPackService{}
-
- err = s.r.Pull("origin", "refs/heads/master")
+ err = s.r.Clone(&CloneOptions{URL: RepositoryFixture})
c.Assert(err, IsNil)
}
-*/
func (s *ObjectsSuite) TestNewCommit(c *C) {
hash := core.NewHash("a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69")
diff --git a/options.go b/options.go
index 300f1a1..c4185ca 100644
--- a/options.go
+++ b/options.go
@@ -11,6 +11,14 @@ type CloneOptions struct {
URL string
// Auth credentials, if required, to uses with the remote repository
Auth common.AuthMethod
+ // Remote branch to fetch
+ ReferenceName core.ReferenceName
+}
+
+func (o *CloneOptions) Default() {
+ if o.ReferenceName == "" {
+ o.ReferenceName = core.HEAD
+ }
}
// FetchOptions describe how a fetch should be perform
@@ -18,3 +26,9 @@ type FetchOptions struct {
// Remote branch to fetch
ReferenceName core.ReferenceName
}
+
+func (o *FetchOptions) Default() {
+ if o.ReferenceName == "" {
+ o.ReferenceName = core.HEAD
+ }
+}
diff --git a/remote.go b/remote.go
index 82604b7..a9e0409 100644
--- a/remote.go
+++ b/remote.go
@@ -24,17 +24,18 @@ func NewRemote(url string) (*Remote, error) {
// NewAuthenticatedRemote returns a new Remote using the given AuthMethod, using as
// client http.DefaultClient
func NewAuthenticatedRemote(url string, auth common.AuthMethod) (*Remote, error) {
- end, err := common.NewEndpoint(url)
+ endpoint, err := common.NewEndpoint(url)
if err != nil {
return nil, err
}
- upSrv, err := clients.NewGitUploadPackService(url)
+ upSrv, err := clients.NewGitUploadPackService(endpoint)
if err != nil {
return nil, err
}
+
return &Remote{
- Endpoint: end,
+ Endpoint: endpoint,
Auth: auth,
upSrv: upSrv,
}, nil
@@ -44,9 +45,9 @@ func NewAuthenticatedRemote(url string, auth common.AuthMethod) (*Remote, error)
func (r *Remote) Connect() error {
var err error
if r.Auth == nil {
- err = r.upSrv.Connect(r.Endpoint)
+ err = r.upSrv.Connect()
} else {
- err = r.upSrv.ConnectWithAuth(r.Endpoint, r.Auth)
+ err = r.upSrv.ConnectWithAuth(r.Auth)
}
if err != nil {
@@ -76,26 +77,27 @@ func (r *Remote) Capabilities() *common.Capabilities {
}
// Fetch returns a reader using the request
-func (r *Remote) Fetch(s core.ObjectStorage, o *FetchOptions) (h core.Hash, err error) {
+func (r *Remote) Fetch(s core.ObjectStorage, o *FetchOptions) (err error) {
+ o.Default()
+
ref, err := r.Ref(o.ReferenceName, true)
if err != nil {
- return core.ZeroHash, err
+ return err
}
- h = ref.Hash()
req := &common.GitUploadPackRequest{}
- req.Want(h)
+ req.Want(ref.Hash())
reader, err := r.upSrv.Fetch(req)
if err != nil {
- return core.ZeroHash, err
+ return err
}
defer checkClose(reader, &err)
stream := packfile.NewStream(reader)
d := packfile.NewDecoder(stream)
- return h, d.Decode(s)
+ return d.Decode(s)
}
// Head returns the Reference of the HEAD
diff --git a/remote_test.go b/remote_test.go
index df93b59..798d75d 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -3,6 +3,7 @@ package git
import (
"gopkg.in/src-d/go-git.v4/clients/http"
"gopkg.in/src-d/go-git.v4/core"
+ "gopkg.in/src-d/go-git.v4/storage/memory"
. "gopkg.in/check.v1"
)
@@ -13,10 +14,29 @@ type RemoteSuite struct {
var _ = Suite(&RemoteSuite{})
+func (s *RemoteSuite) TestNewRemote(c *C) {
+ r, err := NewRemote(RepositoryFixture)
+ c.Assert(err, IsNil)
+ c.Assert(r.Endpoint.String(), Equals, RepositoryFixture)
+}
+
+func (s *RemoteSuite) TestNewRemoteInvalidEndpoint(c *C) {
+ r, err := NewRemote("qux")
+ c.Assert(err, NotNil)
+ c.Assert(r, IsNil)
+}
+
+func (s *RemoteSuite) TestNewRemoteInvalidSchemaEndpoint(c *C) {
+ r, err := NewRemote("qux://foo")
+ c.Assert(err, NotNil)
+ c.Assert(r, IsNil)
+}
+
func (s *RemoteSuite) TestNewAuthenticatedRemote(c *C) {
a := &http.BasicAuth{}
r, err := NewAuthenticatedRemote(RepositoryFixture, a)
c.Assert(err, IsNil)
+ c.Assert(r.Endpoint.String(), Equals, RepositoryFixture)
c.Assert(r.Auth, Equals, a)
}
@@ -26,6 +46,15 @@ func (s *RemoteSuite) TestConnect(c *C) {
c.Assert(r.Connect(), IsNil)
}
+func (s *RemoteSuite) TestInfo(c *C) {
+ r, err := NewRemote(RepositoryFixture)
+ c.Assert(err, IsNil)
+ c.Assert(r.Info(), IsNil)
+ c.Assert(r.Connect(), IsNil)
+ c.Assert(r.Info(), NotNil)
+ c.Assert(r.Info().Capabilities.Get("ofs-delta"), NotNil)
+}
+
func (s *RemoteSuite) TestDefaultBranch(c *C) {
r, err := NewRemote(RepositoryFixture)
r.upSrv = &MockGitUploadPackService{}
@@ -44,7 +73,6 @@ func (s *RemoteSuite) TestCapabilities(c *C) {
c.Assert(r.Capabilities().Get("agent").Values, HasLen, 1)
}
-/*
func (s *RemoteSuite) TestFetch(c *C) {
r, err := NewRemote(RepositoryFixture)
r.upSrv = &MockGitUploadPackService{}
@@ -52,31 +80,63 @@ func (s *RemoteSuite) TestFetch(c *C) {
c.Assert(err, IsNil)
c.Assert(r.Connect(), IsNil)
- req := &common.GitUploadPackRequest{}
- req.Want(r.Head().Hash())
+ sto := memory.NewObjectStorage()
+ err = r.Fetch(sto, &FetchOptions{
+ ReferenceName: core.HEAD,
+ })
- reader, err := r.Fetch(req)
c.Assert(err, IsNil)
+ c.Assert(sto.Objects, HasLen, 28)
+}
- packfileReader := packfile.NewStream(reader)
- d := packfile.NewDecoder(packfileReader)
+func (s *RemoteSuite) TestFetchInvalidBranch(c *C) {
+ r, err := NewRemote(RepositoryFixture)
+ r.upSrv = &MockGitUploadPackService{}
- sto := memory.NewObjectStorage()
- err = d.Decode(sto)
c.Assert(err, IsNil)
- c.Assert(sto.Objects, HasLen, 28)
+ c.Assert(r.Connect(), IsNil)
+
+ sto := memory.NewObjectStorage()
+ err = r.Fetch(sto, &FetchOptions{
+ ReferenceName: core.ReferenceName("qux"),
+ })
+
+ c.Assert(err, NotNil)
}
-*/
func (s *RemoteSuite) TestHead(c *C) {
r, err := NewRemote(RepositoryFixture)
r.upSrv = &MockGitUploadPackService{}
+ c.Assert(err, IsNil)
+ err = r.Connect()
+ c.Assert(err, IsNil)
+ c.Assert(r.Head().Hash(), Equals, core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
+}
+
+func (s *RemoteSuite) TestRef(c *C) {
+ r, err := NewRemote(RepositoryFixture)
+ r.upSrv = &MockGitUploadPackService{}
c.Assert(err, IsNil)
err = r.Connect()
c.Assert(err, IsNil)
+ ref, err := r.Ref(core.HEAD, false)
c.Assert(err, IsNil)
- c.Assert(r.Head().Hash(), Equals, core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
+ c.Assert(ref.Name(), Equals, core.HEAD)
+
+ ref, err = r.Ref(core.HEAD, true)
+ c.Assert(err, IsNil)
+ c.Assert(ref.Name(), Equals, core.ReferenceName("refs/heads/master"))
+}
+
+func (s *RemoteSuite) TestRefs(c *C) {
+ r, err := NewRemote(RepositoryFixture)
+ r.upSrv = &MockGitUploadPackService{}
+ c.Assert(err, IsNil)
+
+ err = r.Connect()
+ c.Assert(err, IsNil)
+ c.Assert(r.Refs(), NotNil)
}
diff --git a/repository.go b/repository.go
index 2d57295..f286e03 100644
--- a/repository.go
+++ b/repository.go
@@ -53,6 +53,8 @@ func NewRepository(s core.Storage) (*Repository, error) {
// Clone clones a remote repository
func (r *Repository) Clone(o *CloneOptions) error {
+ o.Default()
+
remote, err := r.createDefaultRemote(o.URL, o.Auth)
if err != nil {
return err
@@ -62,15 +64,17 @@ func (r *Repository) Clone(o *CloneOptions) error {
return err
}
- h, err := remote.Fetch(r.os, &FetchOptions{
- ReferenceName: core.HEAD,
- })
+ err = remote.Fetch(r.os, &FetchOptions{ReferenceName: o.ReferenceName})
+ if err != nil {
+ return err
+ }
+ ref, err := remote.Ref(o.ReferenceName, true)
if err != nil {
return err
}
- return r.rs.Set(core.NewHashReference(core.HEAD, h))
+ return r.createDefaultBranch(ref)
}
func (r *Repository) createDefaultRemote(url string, auth common.AuthMethod) (*Remote, error) {
@@ -86,6 +90,19 @@ func (r *Repository) createDefaultRemote(url string, auth common.AuthMethod) (*R
return remote, nil
}
+func (r *Repository) createDefaultBranch(ref *core.Reference) error {
+ if !ref.IsBranch() {
+ // detached HEAD mode
+ return r.rs.Set(core.NewHashReference(core.HEAD, ref.Hash()))
+ }
+
+ if err := r.rs.Set(ref); err != nil {
+ return err
+ }
+
+ return r.rs.Set(core.NewSymbolicReference(core.HEAD, ref.Name()))
+}
+
// Commit return the commit with the given hash
func (r *Repository) Commit(h core.Hash) (*Commit, error) {
obj, err := r.os.Get(h)
@@ -191,12 +208,22 @@ func (r *Repository) Object(h core.Hash) (Object, error) {
}
}
-// Head returns the hash of the HEAD of the repository or the head of a
-// remote, if one is passed.
-func (r *Repository) Head(resolved bool) (*core.Reference, error) {
+// Head returns the reference where HEAD is pointing
+func (r *Repository) Head() (*core.Reference, error) {
+ return core.ResolveReference(r.rs, core.HEAD)
+}
+
+// Ref returns the Hash pointing the given refName
+func (r *Repository) Ref(name core.ReferenceName, resolved bool) (*core.Reference, error) {
if resolved {
- return core.ResolveReference(r.rs, core.HEAD)
+ return core.ResolveReference(r.rs, name)
}
- return r.rs.Get(core.HEAD)
+ return r.rs.Get(name)
+}
+
+// Refs returns a map with all the References
+func (r *Repository) Refs() core.ReferenceIter {
+ i, _ := r.rs.Iter()
+ return i
}
diff --git a/repository_test.go b/repository_test.go
index 3ca4d0d..80bd0d1 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -60,58 +60,68 @@ func (s *RepositorySuite) TearDownSuite(c *C) {
}
}
-/*
func (s *RepositorySuite) TestNewRepository(c *C) {
- r, err := NewRepository(RepositoryFixture, nil)
+ r, err := NewMemoryRepository()
c.Assert(err, IsNil)
- c.Assert(r.Remotes["origin"].Auth, IsNil)
+ c.Assert(r, NotNil)
}
-func (s *RepositorySuite) TestNewRepositoryWithAuth(c *C) {
- auth := &http.BasicAuth{}
- r, err := NewRepository(RepositoryFixture, auth)
+func (s *RepositorySuite) TestClone(c *C) {
+ r, err := NewMemoryRepository()
c.Assert(err, IsNil)
- c.Assert(r.Remotes["origin"].Auth, Equals, auth)
-}
+ c.Assert(r.Remotes, HasLen, 0)
-func (s *RepositorySuite) TestNewRepositoryFromFS(c *C) {
- for name, fix := range s.dirFixtures {
- fs := fs.NewOS()
- gitPath := fs.Join(fix.path, ".git/")
- com := Commentf("dir fixture %q → %q\n", name, gitPath)
- repo, err := NewRepositoryFromFS(fs, gitPath)
- c.Assert(err, IsNil, com)
+ head, err := r.Head()
+ c.Assert(err, Equals, core.ErrReferenceNotFound)
+ c.Assert(head, IsNil)
- err = repo.PullDefault()
- c.Assert(err, ErrorMatches, `unable to find remote "origin"`)
+ err = r.Clone(&CloneOptions{
+ URL: RepositoryFixture,
+ })
- c.Assert(repo.Storage, NotNil, com)
- c.Assert(repo.Storage, FitsTypeOf, &filesystem.ObjectStorage{}, com)
- }
-}
+ c.Assert(err, IsNil)
+ c.Assert(r.Remotes, HasLen, 1)
+ c.Assert(r.Remotes[DefaultRemoteName], NotNil)
+ head, err = r.Ref(core.HEAD, false)
+ c.Assert(err, IsNil)
+ c.Assert(head, NotNil)
+ c.Assert(head.Type(), Equals, core.SymbolicReference)
+ c.Assert(head.Target().String(), Equals, "refs/heads/master")
-func (s *RepositorySuite) TestClone(c *C) {
- r, err := NewRepository(RepositoryFixture, nil)
- r.Remotes["origin"].upSrv = &MockGitUploadPackService{}
+ branch, err := r.Ref(head.Target(), false)
+ c.Assert(err, IsNil)
+ c.Assert(branch, NotNil)
+ c.Assert(branch.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
+}
+func (s *RepositorySuite) TestCloneDetachedHEAD(c *C) {
+ r, err := NewMemoryRepository()
c.Assert(err, IsNil)
- c.Assert(r.Pull("origin", "refs/heads/master"), IsNil)
- mock, ok := (r.Remotes["origin"].upSrv).(*MockGitUploadPackService)
- c.Assert(ok, Equals, true)
- err = mock.RC.Close()
- c.Assert(err, Not(IsNil), Commentf("pull leaks an open fd from the fetch"))
-}
+ c.Assert(r.Remotes, HasLen, 0)
+ err = r.Clone(&CloneOptions{
+ URL: RepositoryFixture,
+ ReferenceName: core.ReferenceName("refs/tags/v1.0.0"),
+ })
+ head, err := r.Ref(core.HEAD, false)
+ c.Assert(err, IsNil)
+ c.Assert(head, NotNil)
+ c.Assert(head.Type(), Equals, core.HashReference)
+ c.Assert(head.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
+}
func (s *RepositorySuite) TestCommit(c *C) {
- r, err := NewRepository(RepositoryFixture, nil)
- r.Remotes["origin"].upSrv = &MockGitUploadPackService{}
+ r, err := NewMemoryRepository()
+ c.Assert(err, IsNil)
+
+ err = r.Clone(&CloneOptions{
+ URL: RepositoryFixture,
+ })
c.Assert(err, IsNil)
- c.Assert(r.Pull("origin", "refs/heads/master"), IsNil)
hash := core.NewHash("b8e471f58bcbca63b07bda20e428190409c2db47")
commit, err := r.Commit(hash)
@@ -124,7 +134,6 @@ func (s *RepositorySuite) TestCommit(c *C) {
c.Assert(commit.Tree().Hash.IsZero(), Equals, false)
c.Assert(commit.Author.Email, Equals, "daniel@lordran.local")
}
-*/
func (s *RepositorySuite) TestCommits(c *C) {
r, err := NewMemoryRepository()
@@ -192,67 +201,41 @@ func (s *RepositorySuite) TestObject(c *C) {
}
}
-/*
func (s *RepositorySuite) TestCommitIterClosePanic(c *C) {
- r, err := NewRepository(RepositoryFixture, nil)
- r.Remotes["origin"].upSrv = &MockGitUploadPackService{}
+ r, err := NewMemoryRepository()
+ c.Assert(err, IsNil)
+ err = r.Clone(&CloneOptions{URL: RepositoryFixture})
c.Assert(err, IsNil)
- c.Assert(r.Pull("origin", "refs/heads/master"), IsNil)
commits, err := r.Commits()
c.Assert(err, IsNil)
commits.Close()
}
-
-func (s *RepositorySuite) TestHeadFromFs(c *C) {
- for name, fix := range s.dirFixtures {
- fs := fs.NewOS()
- gitPath := fs.Join(fix.path, ".git/")
- com := Commentf("dir fixture %q → %q\n", name, gitPath)
- repo, err := NewRepositoryFromFS(fs, gitPath)
- c.Assert(err, IsNil, com)
-
- head, err := repo.Head("")
- c.Assert(err, IsNil)
-
- c.Assert(head, Equals, fix.head)
- }
-}
-
-func (s *RepositorySuite) TestHeadFromRemote(c *C) {
- r, err := NewRepository(RepositoryFixture, nil)
+func (s *RepositorySuite) TestRef(c *C) {
+ r, err := NewMemoryRepository()
c.Assert(err, IsNil)
- upSrv := &MockGitUploadPackService{}
- r.Remotes[DefaultRemoteName].upSrv = upSrv
- err = r.Remotes[DefaultRemoteName].Connect()
+ err = r.Clone(&CloneOptions{URL: RepositoryFixture})
c.Assert(err, IsNil)
- info, err := upSrv.Info()
+ ref, err := r.Ref(core.HEAD, false)
c.Assert(err, IsNil)
- expected := info.Head
+ c.Assert(ref.Name(), Equals, core.HEAD)
- obtained, err := r.Head(DefaultRemoteName)
+ ref, err = r.Ref(core.HEAD, true)
c.Assert(err, IsNil)
-
- c.Assert(obtained, Equals, expected)
+ c.Assert(ref.Name(), Equals, core.ReferenceName("refs/heads/master"))
}
-func (s *RepositorySuite) TestHeadErrors(c *C) {
- r, err := NewRepository(RepositoryFixture, nil)
+func (s *RepositorySuite) TestRefs(c *C) {
+ r, err := NewMemoryRepository()
c.Assert(err, IsNil)
- upSrv := &MockGitUploadPackService{}
- r.Remotes[DefaultRemoteName].upSrv = upSrv
-
- remote := "not found"
- _, err = r.Head(remote)
- c.Assert(err, ErrorMatches, fmt.Sprintf("unable to find remote %q", remote))
+ err = r.Clone(&CloneOptions{URL: RepositoryFixture})
+ c.Assert(err, IsNil)
- remote = ""
- _, err = r.Head(remote)
- c.Assert(err, ErrorMatches, "cannot retrieve local head: no local data found")
+ c.Assert(err, IsNil)
+ c.Assert(r.Refs(), NotNil)
}
-*/