diff options
-rw-r--r-- | clients/common/common.go | 42 | ||||
-rw-r--r-- | clients/common/common_test.go | 24 | ||||
-rw-r--r-- | common_test.go | 7 | ||||
-rw-r--r-- | core/object.go | 1 | ||||
-rw-r--r-- | examples/latest/latest.go | 8 | ||||
-rw-r--r-- | remote.go | 34 | ||||
-rw-r--r-- | remote_test.go | 13 | ||||
-rw-r--r-- | repository.go | 61 |
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) } @@ -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, |