fork of go-git with some jj specific features

Add sideband support for push

Changed files
+118 -6
plumbing
protocol
packp
transport
http
internal
common
+3
options.go
··· 160 160 RefSpecs []config.RefSpec 161 161 // Auth credentials, if required, to use with the remote repository. 162 162 Auth transport.AuthMethod 163 + // Progress is where the human readable information sent by the server is 164 + // stored, if nil nothing is stored. 165 + Progress sideband.Progress 163 166 } 164 167 165 168 // Validate validates the fields and sets the default values.
+4
plumbing/protocol/packp/updreq.go
··· 6 6 7 7 "gopkg.in/src-d/go-git.v4/plumbing" 8 8 "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability" 9 + "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/sideband" 9 10 ) 10 11 11 12 var ( ··· 21 22 Shallow *plumbing.Hash 22 23 // Packfile contains an optional packfile reader. 23 24 Packfile io.ReadCloser 25 + 26 + // Progress receives sideband progress messages from the server 27 + Progress sideband.Progress 24 28 } 25 29 26 30 // New returns a pointer to a new ReferenceUpdateRequest value.
+13
plumbing/transport/http/receive_pack.go
··· 9 9 10 10 "gopkg.in/src-d/go-git.v4/plumbing" 11 11 "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp" 12 + "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability" 13 + "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/sideband" 12 14 "gopkg.in/src-d/go-git.v4/plumbing/transport" 13 15 "gopkg.in/src-d/go-git.v4/utils/ioutil" 14 16 ) ··· 50 52 51 53 if err != nil { 52 54 return nil, err 55 + } 56 + 57 + var d *sideband.Demuxer 58 + if req.Capabilities.Supports(capability.Sideband64k) { 59 + d = sideband.NewDemuxer(sideband.Sideband64k, r) 60 + } else if req.Capabilities.Supports(capability.Sideband) { 61 + d = sideband.NewDemuxer(sideband.Sideband, r) 62 + } 63 + if d != nil { 64 + d.Progress = req.Progress 65 + r = d 53 66 } 54 67 55 68 rc := ioutil.NewReadCloser(r, res.Body)
+16 -2
plumbing/transport/internal/common/common.go
··· 18 18 "gopkg.in/src-d/go-git.v4/plumbing/format/pktline" 19 19 "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp" 20 20 "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability" 21 + "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/sideband" 21 22 "gopkg.in/src-d/go-git.v4/plumbing/transport" 22 23 "gopkg.in/src-d/go-git.v4/utils/ioutil" 23 24 ) ··· 298 299 } 299 300 300 301 if !req.Capabilities.Supports(capability.ReportStatus) { 301 - // If we have neither report-status or sideband, we can only 302 + // If we don't have report-status, we can only 302 303 // check return value error. 303 304 return nil, s.Command.Close() 304 305 } 305 306 307 + r := s.StdoutContext(ctx) 308 + 309 + var d *sideband.Demuxer 310 + if req.Capabilities.Supports(capability.Sideband64k) { 311 + d = sideband.NewDemuxer(sideband.Sideband64k, r) 312 + } else if req.Capabilities.Supports(capability.Sideband) { 313 + d = sideband.NewDemuxer(sideband.Sideband, r) 314 + } 315 + if d != nil { 316 + d.Progress = req.Progress 317 + r = d 318 + } 319 + 306 320 report := packp.NewReportStatus() 307 - if err := report.Decode(s.StdoutContext(ctx)); err != nil { 321 + if err := report.Decode(r); err != nil { 308 322 return nil, err 309 323 } 310 324
+21 -4
remote.go
··· 65 65 // operation is complete, an error is returned. The context only affects to the 66 66 // transport operations. 67 67 func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error { 68 - // TODO: Sideband support 69 68 if err := o.Validate(); err != nil { 70 69 return err 71 70 } ··· 108 107 return ErrDeleteRefNotSupported 109 108 } 110 109 111 - req := packp.NewReferenceUpdateRequestFromCapabilities(ar.Capabilities) 112 - if err := r.addReferencesToUpdate(o.RefSpecs, remoteRefs, req); err != nil { 113 - 110 + req, err := r.newReferenceUpdateRequest(o, remoteRefs, ar) 111 + if err != nil { 114 112 return err 115 113 } 116 114 ··· 156 154 } 157 155 158 156 return r.updateRemoteReferenceStorage(req, rs) 157 + } 158 + 159 + func (r *Remote) newReferenceUpdateRequest(o *PushOptions, remoteRefs storer.ReferenceStorer, ar *packp.AdvRefs) (*packp.ReferenceUpdateRequest, error) { 160 + req := packp.NewReferenceUpdateRequestFromCapabilities(ar.Capabilities) 161 + 162 + if o.Progress != nil { 163 + req.Progress = o.Progress 164 + if ar.Capabilities.Supports(capability.Sideband64k) { 165 + req.Capabilities.Set(capability.Sideband64k) 166 + } else if ar.Capabilities.Supports(capability.Sideband) { 167 + req.Capabilities.Set(capability.Sideband) 168 + } 169 + } 170 + 171 + if err := r.addReferencesToUpdate(o.RefSpecs, remoteRefs, req); err != nil { 172 + return nil, err 173 + } 174 + 175 + return req, nil 159 176 } 160 177 161 178 func (r *Remote) updateRemoteReferenceStorage(
+41
repository_test.go
··· 719 719 c.Assert(err, NotNil) 720 720 } 721 721 722 + // installPreReceiveHook installs a pre-receive hook in the .git 723 + // directory at path which prints message m before exiting 724 + // successfully. 725 + func installPreReceiveHook(c *C, path, m string) { 726 + hooks := filepath.Join(path, "hooks") 727 + err := os.MkdirAll(hooks, 0777) 728 + c.Assert(err, IsNil) 729 + 730 + err = ioutil.WriteFile(filepath.Join(hooks, "pre-receive"), preReceiveHook(m), 0777) 731 + c.Assert(err, IsNil) 732 + } 733 + 734 + func (s *RepositorySuite) TestPushWithProgress(c *C) { 735 + url := c.MkDir() 736 + server, err := PlainInit(url, true) 737 + c.Assert(err, IsNil) 738 + 739 + m := "Receiving..." 740 + installPreReceiveHook(c, url, m) 741 + 742 + _, err = s.Repository.CreateRemote(&config.RemoteConfig{ 743 + Name: "bar", 744 + URLs: []string{url}, 745 + }) 746 + c.Assert(err, IsNil) 747 + 748 + var p bytes.Buffer 749 + err = s.Repository.Push(&PushOptions{ 750 + RemoteName: "bar", 751 + Progress: &p, 752 + }) 753 + c.Assert(err, IsNil) 754 + 755 + AssertReferences(c, server, map[string]string{ 756 + "refs/heads/master": "6ecf0ef2c2dffb796033e5a02219af86ec6584e5", 757 + "refs/heads/branch": "e8d3ffab552895c19b9fcf7aa264d277cde33881", 758 + }) 759 + 760 + c.Assert((&p).Bytes(), DeepEquals, []byte(m)) 761 + } 762 + 722 763 func (s *RepositorySuite) TestPushDepth(c *C) { 723 764 url := c.MkDir() 724 765 server, err := PlainClone(url, true, &CloneOptions{
+11
repository_unix_test.go
··· 1 + // +build !plan9,!windows 2 + 3 + package git 4 + 5 + import "fmt" 6 + 7 + // preReceiveHook returns the bytes of a pre-receive hook script 8 + // that prints m before exiting successfully 9 + func preReceiveHook(m string) []byte { 10 + return []byte(fmt.Sprintf("#!/bin/sh\nprintf '%s'\n", m)) 11 + }
+9
repository_windows_test.go
··· 1 + package git 2 + 3 + import "fmt" 4 + 5 + // preReceiveHook returns the bytes of a pre-receive hook script 6 + // that prints m before exiting successfully 7 + func preReceiveHook(m string) []byte { 8 + return []byte(fmt.Sprintf("#!C:/Program\\ Files/Git/usr/bin/sh.exe\nprintf '%s'\n", m)) 9 + }