aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clients/common/common.go42
-rw-r--r--clients/common/common_test.go24
-rw-r--r--common_test.go7
-rw-r--r--core/object.go1
-rw-r--r--examples/latest/latest.go8
-rw-r--r--remote.go34
-rw-r--r--remote_test.go13
-rw-r--r--repository.go61
8 files changed, 105 insertions, 85 deletions
diff --git a/clients/common/common.go b/clients/common/common.go
index 1c6e552..a09f2d8 100644
--- a/clients/common/common.go
+++ b/clients/common/common.go
@@ -180,8 +180,7 @@ func (c *Capabilities) String() string {
type GitUploadPackInfo struct {
Capabilities *Capabilities
- Head core.Hash
- Refs map[string]core.Hash
+ Refs map[core.ReferenceName]*core.Reference
}
func NewGitUploadPackInfo() *GitUploadPackInfo {
@@ -207,7 +206,7 @@ func (r *GitUploadPackInfo) read(d *pktline.Decoder) error {
}
isEmpty := true
- r.Refs = map[string]core.Hash{}
+ r.Refs = map[core.ReferenceName]*core.Reference{}
for _, line := range lines {
if !r.isValidLine(line) {
continue
@@ -230,9 +229,15 @@ func (r *GitUploadPackInfo) read(d *pktline.Decoder) error {
}
func (r *GitUploadPackInfo) decodeHeaderLine(line string) {
- parts := strings.SplitN(line, " HEAD", 2)
- r.Head = core.NewHash(parts[0])
r.Capabilities.Decode(line)
+
+ name := r.Capabilities.SymbolicReference("HEAD")
+ if len(name) == 0 {
+ return
+ }
+
+ refName := core.ReferenceName(name)
+ r.Refs[core.HEAD] = core.NewSymbolicReference(core.HEAD, refName)
}
func (r *GitUploadPackInfo) isValidLine(line string) bool {
@@ -245,7 +250,22 @@ func (r *GitUploadPackInfo) readLine(line string) {
return
}
- r.Refs[parts[1]] = core.NewHash(parts[0])
+ ref := core.NewReferenceFromStrings(parts[1], parts[0])
+ r.Refs[ref.Name()] = ref
+}
+
+func (r *GitUploadPackInfo) Head() *core.Reference {
+ h, ok := r.Refs[core.HEAD]
+ if !ok {
+ return nil
+ }
+
+ ref, ok := r.Refs[h.Target()]
+ if !ok {
+ return nil
+ }
+
+ return ref
}
func (r *GitUploadPackInfo) String() string {
@@ -256,10 +276,14 @@ func (r *GitUploadPackInfo) Bytes() []byte {
e := pktline.NewEncoder()
e.AddLine("# service=git-upload-pack")
e.AddFlush()
- e.AddLine(fmt.Sprintf("%s HEAD\x00%s", r.Head, r.Capabilities.String()))
+ e.AddLine(fmt.Sprintf("%s HEAD\x00%s", r.Head().Hash(), r.Capabilities.String()))
+
+ for _, ref := range r.Refs {
+ if ref.Type() != core.HashReference {
+ continue
+ }
- for name, id := range r.Refs {
- e.AddLine(fmt.Sprintf("%s %s", id, name))
+ e.AddLine(fmt.Sprintf("%s %s", ref.Hash(), ref.Name()))
}
e.AddFlush()
diff --git a/clients/common/common_test.go b/clients/common/common_test.go
index 791001e..5be6eba 100644
--- a/clients/common/common_test.go
+++ b/clients/common/common_test.go
@@ -50,10 +50,17 @@ func (s *SuiteCommon) TestGitUploadPackInfo(c *C) {
err := i.Decode(pktline.NewDecoder(bytes.NewBuffer(b)))
c.Assert(err, IsNil)
- ref := i.Capabilities.SymbolicReference("HEAD")
- c.Assert(ref, Equals, "refs/heads/master")
- c.Assert(i.Refs[ref].String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
- c.Assert(i.Head.String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
+ name := i.Capabilities.SymbolicReference("HEAD")
+ c.Assert(name, Equals, "refs/heads/master")
+ c.Assert(i.Refs, HasLen, 4)
+
+ ref := i.Refs[core.ReferenceName(name)]
+ c.Assert(ref, NotNil)
+ c.Assert(ref.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
+
+ ref = i.Refs[core.HEAD]
+ c.Assert(ref, NotNil)
+ c.Assert(ref.Target(), Equals, core.ReferenceName(name))
}
func (s *SuiteCommon) TestGitUploadPackInfoEmpty(c *C) {
@@ -101,11 +108,14 @@ func (s *SuiteCommon) TestGitUploadPackEncode(c *C) {
info := NewGitUploadPackInfo()
info.Capabilities.Add("symref", "HEAD:refs/heads/master")
- info.Head = core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
- info.Refs = map[string]core.Hash{
- "refs/heads/master": info.Head,
+ ref := core.ReferenceName("refs/heads/master")
+ hash := core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
+ info.Refs = map[core.ReferenceName]*core.Reference{
+ core.HEAD: core.NewSymbolicReference(core.HEAD, ref),
+ ref: core.NewHashReference(ref, hash),
}
+ c.Assert(info.Head(), NotNil)
c.Assert(info.String(), Equals,
"001e# service=git-upload-pack\n"+
"000000506ecf0ef2c2dffb796033e5a02219af86ec6584e5 HEAD\x00symref=HEAD:refs/heads/master\n"+
diff --git a/common_test.go b/common_test.go
index 0f2bcdf..4a8384f 100644
--- a/common_test.go
+++ b/common_test.go
@@ -36,10 +36,13 @@ func (s *MockGitUploadPackService) Info() (*common.GitUploadPackInfo, error) {
c := common.NewCapabilities()
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")
return &common.GitUploadPackInfo{
Capabilities: c,
- Head: h,
- Refs: map[string]core.Hash{"refs/heads/master": h},
+ Refs: map[core.ReferenceName]*core.Reference{
+ core.HEAD: core.NewSymbolicReference(core.HEAD, ref),
+ ref: core.NewHashReference(ref, h),
+ },
}, nil
}
diff --git a/core/object.go b/core/object.go
index 01dd660..e5f9a5e 100644
--- a/core/object.go
+++ b/core/object.go
@@ -51,6 +51,7 @@ type ObjectStorage interface {
type ObjectType int8
const (
+ InvalidObject ObjectType = 0
CommitObject ObjectType = 1
TreeObject ObjectType = 2
BlobObject ObjectType = 3
diff --git a/examples/latest/latest.go b/examples/latest/latest.go
index 9faf59f..2ccddf1 100644
--- a/examples/latest/latest.go
+++ b/examples/latest/latest.go
@@ -18,12 +18,8 @@ func main() {
panic(err)
}
- hash, err := r.Remotes[git.DefaultRemoteName].Head()
- if err != nil {
- panic(err)
- }
-
- commit, err := r.Commit(hash)
+ head := r.Remotes[git.DefaultRemoteName].Head()
+ commit, err := r.Commit(head.Hash())
if err != nil {
panic(err)
}
diff --git a/remote.go b/remote.go
index f450271..ecbcd54 100644
--- a/remote.go
+++ b/remote.go
@@ -77,45 +77,27 @@ func (r *Remote) Capabilities() *common.Capabilities {
return r.upInfo.Capabilities
}
-// DefaultBranch returns the name of the remote's default branch
-func (r *Remote) DefaultBranch() string {
- return r.upInfo.Capabilities.SymbolicReference("HEAD")
-}
-
-// Head returns the Hash of the HEAD
-func (r *Remote) Head() (core.Hash, error) {
- return r.Ref(r.DefaultBranch())
-}
-
// Fetch returns a reader using the request
func (r *Remote) Fetch(req *common.GitUploadPackRequest) (io.ReadCloser, error) {
return r.upSrv.Fetch(req)
}
-// FetchDefaultBranch returns a reader for the default branch
-func (r *Remote) FetchDefaultBranch() (io.ReadCloser, error) {
- ref, err := r.Ref(r.DefaultBranch())
- if err != nil {
- return nil, err
- }
-
- req := &common.GitUploadPackRequest{}
- req.Want(ref)
-
- return r.Fetch(req)
+// Head returns the Hash of the HEAD
+func (r *Remote) Head() *core.Reference {
+ return r.upInfo.Head()
}
// Ref returns the Hash pointing the given refName
-func (r *Remote) Ref(refName string) (core.Hash, error) {
- ref, ok := r.upInfo.Refs[refName]
+func (r *Remote) Ref(name core.ReferenceName) (*core.Reference, error) {
+ ref, ok := r.upInfo.Refs[name]
if !ok {
- return core.NewHash(""), fmt.Errorf("unable to find ref %q", refName)
+ return nil, fmt.Errorf("unable to find ref %q", name)
}
return ref, nil
}
-// Refs returns the Hash pointing the given refName
-func (r *Remote) Refs() map[string]core.Hash {
+// Refs returns a map with all the References
+func (r *Remote) Refs() map[core.ReferenceName]*core.Reference {
return r.upInfo.Refs
}
diff --git a/remote_test.go b/remote_test.go
index 9e3e678..9f476a2 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -1,6 +1,7 @@
package git
import (
+ "gopkg.in/src-d/go-git.v4/clients/common"
"gopkg.in/src-d/go-git.v4/clients/http"
"gopkg.in/src-d/go-git.v4/core"
"gopkg.in/src-d/go-git.v4/formats/packfile"
@@ -34,7 +35,7 @@ func (s *SuiteRemote) TestDefaultBranch(c *C) {
c.Assert(err, IsNil)
c.Assert(r.Connect(), IsNil)
- c.Assert(r.DefaultBranch(), Equals, "refs/heads/master")
+ c.Assert(r.Head().Name(), Equals, core.ReferenceName("refs/heads/master"))
}
func (s *SuiteRemote) TestCapabilities(c *C) {
@@ -46,14 +47,17 @@ func (s *SuiteRemote) TestCapabilities(c *C) {
c.Assert(r.Capabilities().Get("agent").Values, HasLen, 1)
}
-func (s *SuiteRemote) TestFetchDefaultBranch(c *C) {
+func (s *SuiteRemote) TestFetch(c *C) {
r, err := NewRemote(RepositoryFixture)
r.upSrv = &MockGitUploadPackService{}
c.Assert(err, IsNil)
c.Assert(r.Connect(), IsNil)
- reader, err := r.FetchDefaultBranch()
+ req := &common.GitUploadPackRequest{}
+ req.Want(r.Head().Hash())
+
+ reader, err := r.Fetch(req)
c.Assert(err, IsNil)
packfileReader := packfile.NewStream(reader)
@@ -74,7 +78,6 @@ func (s *SuiteRemote) TestHead(c *C) {
err = r.Connect()
c.Assert(err, IsNil)
- hash, err := r.Head()
c.Assert(err, IsNil)
- c.Assert(hash, Equals, core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
+ c.Assert(r.Head().Hash(), Equals, core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
}
diff --git a/repository.go b/repository.go
index cab0ada..9669435 100644
--- a/repository.go
+++ b/repository.go
@@ -69,30 +69,50 @@ func NewPlainRepository() *Repository {
}
}
+func (r *Repository) Clone(url string, auth common.AuthMethod) error {
+ remote, err := r.createDefaultRemote(url, auth)
+ if err != nil {
+ return err
+ }
+
+ if err = remote.Connect(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (r *Repository) createDefaultRemote(url string, auth common.AuthMethod) (*Remote, error) {
+ remote, err := NewAuthenticatedRemote(url, auth)
+ if err != nil {
+ return nil, err
+ }
+
+ r.Remotes[DefaultRemoteName] = remote
+
+ return remote, nil
+}
+
// Pull connect and fetch the given branch from the given remote, the branch
// should be provided with the full path not only the abbreviation, eg.:
// "refs/heads/master"
-func (r *Repository) Pull(remoteName, branch string) (err error) {
+func (r *Repository) Pull(remoteName, branch string) error {
remote, ok := r.Remotes[remoteName]
if !ok {
return fmt.Errorf("unable to find remote %q", remoteName)
}
- if err = remote.Connect(); err != nil {
+ if err := remote.Connect(); err != nil {
return err
}
- if branch == "" {
- branch = remote.DefaultBranch()
- }
-
- ref, err := remote.Ref(branch)
- if err != nil {
- return err
+ head := remote.Head()
+ if head.Hash().IsZero() {
+ return errors.New("HEAD is missing")
}
req := &common.GitUploadPackRequest{}
- req.Want(ref)
+ req.Want(head.Hash())
// TODO: Provide "haves" for what's already in the repository's storage
@@ -104,9 +124,7 @@ func (r *Repository) Pull(remoteName, branch string) (err error) {
stream := packfile.NewStream(reader)
d := packfile.NewDecoder(stream)
- err = d.Decode(r.Storage)
-
- return err
+ return d.Decode(r.Storage)
}
// PullDefault like Pull but retrieve the default branch from the default remote
@@ -222,23 +240,6 @@ 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(remote string) (core.Hash, error) {
- if remote == "" {
- return r.localHead()
- }
-
- return r.remoteHead(remote)
-}
-
-func (r *Repository) remoteHead(remote string) (core.Hash, error) {
- rem, ok := r.Remotes[remote]
- if !ok {
- return core.ZeroHash, fmt.Errorf("unable to find remote %q", remote)
- }
-
- return rem.Head()
-}
-
-func (r *Repository) localHead() (core.Hash, error) {
storage, ok := r.Storage.(*filesystem.ObjectStorage)
if !ok {
return core.ZeroHash,