diff options
author | Santiago M. Mola <santi@mola.io> | 2016-12-09 14:44:03 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-09 14:44:03 +0100 |
commit | 0e1a52757a3938e97cf7d31e0dff3c9949001763 (patch) | |
tree | 8b998fdc3eaaf6b2d6c69a125759a778664207a5 /plumbing/transport/internal/common/common.go | |
parent | 4f16cc925238aae81586e917d26b8ff6b6a340bd (diff) | |
download | go-git-0e1a52757a3938e97cf7d31e0dff3c9949001763.tar.gz |
transport: add git-send-pack support to local/ssh. (#163)
* protocol/packp: add Packfile field to ReferenceUpdateRequest.
* protocol/packp: add NewReferenceUpdateRequestFromCapabilities.
* NewReferenceUpdateRequestFromCapabilities can be used to create
a ReferenceUpdateRequest with initial capabilities compatible with
the server.
* protocol/packp: fix new line handling on report status.
* transport/file: test error on unexisting command.
Diffstat (limited to 'plumbing/transport/internal/common/common.go')
-rw-r--r-- | plumbing/transport/internal/common/common.go | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/plumbing/transport/internal/common/common.go b/plumbing/transport/internal/common/common.go index 12f4995..f0e1691 100644 --- a/plumbing/transport/internal/common/common.go +++ b/plumbing/transport/internal/common/common.go @@ -15,6 +15,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/transport" "gopkg.in/src-d/go-git.v4/utils/ioutil" ) @@ -91,7 +92,7 @@ func (c *client) NewFetchPackSession(ep transport.Endpoint) ( func (c *client) NewSendPackSession(ep transport.Endpoint) ( transport.SendPackSession, error) { - return nil, errors.New("git send-pack not supported") + return c.newSession(transport.ReceivePackServiceName, ep) } type session struct { @@ -99,10 +100,11 @@ type session struct { Stdout io.Reader Command Command - advRefs *packp.AdvRefs - packRun bool - finished bool - errLines chan string + isReceivePack bool + advRefs *packp.AdvRefs + packRun bool + finished bool + errLines chan string } func (c *client) newSession(s string, ep transport.Endpoint) (*session, error) { @@ -140,10 +142,11 @@ func (c *client) newSession(s string, ep transport.Endpoint) (*session, error) { }() return &session{ - Stdin: stdin, - Stdout: stdout, - Command: cmd, - errLines: errLines, + Stdin: stdin, + Stdout: stdout, + Command: cmd, + errLines: errLines, + isReceivePack: s == transport.ReceivePackServiceName, }, nil } @@ -174,6 +177,11 @@ func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) { // advertised-references message. But valid. That is, it // includes at least a flush. if err == packp.ErrEmptyAdvRefs { + // Empty repositories are valid for git-receive-pack. + if s.isReceivePack { + return ar, nil + } + if err := s.finish(); err != nil { return nil, err } @@ -229,6 +237,35 @@ func (s *session) FetchPack(req *packp.UploadPackRequest) (*packp.UploadPackResp return DecodeUploadPackResponse(rc, req) } +func (s *session) SendPack(req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) { + if _, err := s.AdvertisedReferences(); err != nil { + return nil, err + } + + s.packRun = true + + if err := req.Encode(s.Stdin); err != nil { + return nil, err + } + + if !req.Capabilities.Supports(capability.ReportStatus) { + // If we have neither report-status or sideband, we can only + // check return value error. + return nil, s.Command.Wait() + } + + report := packp.NewReportStatus() + if err := report.Decode(s.Stdout); err != nil { + return nil, err + } + + if !report.Ok() { + return report, fmt.Errorf("report status: %s", report.UnpackStatus) + } + + return report, s.Command.Wait() +} + func (s *session) finish() error { if s.finished { return nil |