Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ type PushOptions struct {
RefSpecs []config.RefSpec
// Auth credentials, if required, to use with the remote repository.
Auth transport.AuthMethod
// Progress is where the human readable information sent by the server is
// stored, if nil nothing is stored.
Progress sideband.Progress
}

// Validate validates the fields and sets the default values.
Expand Down
4 changes: 4 additions & 0 deletions plumbing/protocol/packp/updreq.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability"
"gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/sideband"
)

var (
Expand All @@ -21,6 +22,9 @@ type ReferenceUpdateRequest struct {
Shallow *plumbing.Hash
// Packfile contains an optional packfile reader.
Packfile io.ReadCloser

// Progress receives sideband progress messages from the server
Progress sideband.Progress
}

// New returns a pointer to a new ReferenceUpdateRequest value.
Expand Down
13 changes: 13 additions & 0 deletions plumbing/transport/http/receive_pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (

"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/protocol/packp/capability"
"gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/sideband"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/utils/ioutil"
)
Expand Down Expand Up @@ -52,6 +54,17 @@ func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateR
return nil, err
}

var d *sideband.Demuxer
if req.Capabilities.Supports(capability.Sideband64k) {
d = sideband.NewDemuxer(sideband.Sideband64k, r)
} else if req.Capabilities.Supports(capability.Sideband) {
d = sideband.NewDemuxer(sideband.Sideband, r)
}
if d != nil {
d.Progress = req.Progress
r = d
}

rc := ioutil.NewReadCloser(r, res.Body)

report := packp.NewReportStatus()
Expand Down
18 changes: 16 additions & 2 deletions plumbing/transport/internal/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/format/pktline"
"gopkg.in/src-d/go-git.v4/plumbing/protocol/packp"
"gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability"
"gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/sideband"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/utils/ioutil"
)
Expand Down Expand Up @@ -298,13 +299,26 @@ func (s *session) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateReq
}

if !req.Capabilities.Supports(capability.ReportStatus) {
// If we have neither report-status or sideband, we can only
// If we don't have report-status, we can only
// check return value error.
return nil, s.Command.Close()
}

r := s.StdoutContext(ctx)

var d *sideband.Demuxer
if req.Capabilities.Supports(capability.Sideband64k) {
d = sideband.NewDemuxer(sideband.Sideband64k, r)
} else if req.Capabilities.Supports(capability.Sideband) {
d = sideband.NewDemuxer(sideband.Sideband, r)
}
if d != nil {
d.Progress = req.Progress
r = d
}

report := packp.NewReportStatus()
if err := report.Decode(s.StdoutContext(ctx)); err != nil {
if err := report.Decode(r); err != nil {
return nil, err
}

Expand Down
25 changes: 21 additions & 4 deletions remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ func (r *Remote) Push(o *PushOptions) error {
// operation is complete, an error is returned. The context only affects to the
// transport operations.
func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error {
// TODO: Sideband support
if err := o.Validate(); err != nil {
return err
}
Expand Down Expand Up @@ -108,9 +107,8 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error {
return ErrDeleteRefNotSupported
}

req := packp.NewReferenceUpdateRequestFromCapabilities(ar.Capabilities)
if err := r.addReferencesToUpdate(o.RefSpecs, remoteRefs, req); err != nil {

req, err := r.newReferenceUpdateRequest(o, remoteRefs, ar)
if err != nil {
return err
}

Expand Down Expand Up @@ -158,6 +156,25 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error {
return r.updateRemoteReferenceStorage(req, rs)
}

func (r *Remote) newReferenceUpdateRequest(o *PushOptions, remoteRefs storer.ReferenceStorer, ar *packp.AdvRefs) (*packp.ReferenceUpdateRequest, error) {
req := packp.NewReferenceUpdateRequestFromCapabilities(ar.Capabilities)

if o.Progress != nil {
req.Progress = o.Progress
if ar.Capabilities.Supports(capability.Sideband64k) {
req.Capabilities.Set(capability.Sideband64k)
} else if ar.Capabilities.Supports(capability.Sideband) {
req.Capabilities.Set(capability.Sideband)
}
}

if err := r.addReferencesToUpdate(o.RefSpecs, remoteRefs, req); err != nil {
return nil, err
}

return req, nil
}

func (r *Remote) updateRemoteReferenceStorage(
req *packp.ReferenceUpdateRequest,
result *packp.ReportStatus,
Expand Down
41 changes: 41 additions & 0 deletions repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,47 @@ func (s *RepositorySuite) TestPushContext(c *C) {
c.Assert(err, NotNil)
}

// installPreReceiveHook installs a pre-receive hook in the .git
// directory at path which prints message m before exiting
// successfully.
func installPreReceiveHook(c *C, path, m string) {
hooks := filepath.Join(path, "hooks")
err := os.MkdirAll(hooks, 0777)
c.Assert(err, IsNil)

err = ioutil.WriteFile(filepath.Join(hooks, "pre-receive"), preReceiveHook(m), 0777)
c.Assert(err, IsNil)
}

func (s *RepositorySuite) TestPushWithProgress(c *C) {
url := c.MkDir()
server, err := PlainInit(url, true)
c.Assert(err, IsNil)

m := "Receiving..."
installPreReceiveHook(c, url, m)

_, err = s.Repository.CreateRemote(&config.RemoteConfig{
Name: "bar",
URLs: []string{url},
})
c.Assert(err, IsNil)

var p bytes.Buffer
err = s.Repository.Push(&PushOptions{
RemoteName: "bar",
Progress: &p,
})
c.Assert(err, IsNil)

AssertReferences(c, server, map[string]string{
"refs/heads/master": "6ecf0ef2c2dffb796033e5a02219af86ec6584e5",
"refs/heads/branch": "e8d3ffab552895c19b9fcf7aa264d277cde33881",
})

c.Assert((&p).Bytes(), DeepEquals, []byte(m))
}

func (s *RepositorySuite) TestPushDepth(c *C) {
url := c.MkDir()
server, err := PlainClone(url, true, &CloneOptions{
Expand Down
11 changes: 11 additions & 0 deletions repository_unix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// +build !plan9,!windows

package git

import "fmt"

// preReceiveHook returns the bytes of a pre-receive hook script
// that prints m before exiting successfully
func preReceiveHook(m string) []byte {
return []byte(fmt.Sprintf("#!/bin/sh\nprintf '%s'\n", m))
}
9 changes: 9 additions & 0 deletions repository_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package git

import "fmt"

// preReceiveHook returns the bytes of a pre-receive hook script
// that prints m before exiting successfully
func preReceiveHook(m string) []byte {
return []byte(fmt.Sprintf("#!C:/Program\\ Files/Git/usr/bin/sh.exe\nprintf '%s'\n", m))
}