aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing
diff options
context:
space:
mode:
Diffstat (limited to 'plumbing')
-rw-r--r--plumbing/protocol/packp/report_status.go29
-rw-r--r--plumbing/protocol/packp/report_status_test.go19
-rw-r--r--plumbing/transport/internal/common/common.go4
-rw-r--r--plumbing/transport/test/send_pack.go53
4 files changed, 80 insertions, 25 deletions
diff --git a/plumbing/protocol/packp/report_status.go b/plumbing/protocol/packp/report_status.go
index ead4bb6..29c1a4c 100644
--- a/plumbing/protocol/packp/report_status.go
+++ b/plumbing/protocol/packp/report_status.go
@@ -26,9 +26,19 @@ func NewReportStatus() *ReportStatus {
return &ReportStatus{}
}
-// Ok returns true if the report status reported no error.
-func (s *ReportStatus) Ok() bool {
- return s.UnpackStatus == ok
+// Error returns the first error if any.
+func (s *ReportStatus) Error() error {
+ if s.UnpackStatus != ok {
+ return fmt.Errorf("unpack error: %s", s.UnpackStatus)
+ }
+
+ for _, s := range s.CommandStatuses {
+ if err := s.Error(); err != nil {
+ return err
+ }
+ }
+
+ return nil
}
// Encode writes the report status to a writer.
@@ -135,14 +145,19 @@ type CommandStatus struct {
Status string
}
-// Ok returns true if the command status reported no error.
-func (s *CommandStatus) Ok() bool {
- return s.Status == ok
+// Error returns the error, if any.
+func (s *CommandStatus) Error() error {
+ if s.Status == ok {
+ return nil
+ }
+
+ return fmt.Errorf("command error on %s: %s",
+ s.ReferenceName.String(), s.Status)
}
func (s *CommandStatus) encode(w io.Writer) error {
e := pktline.NewEncoder(w)
- if s.Ok() {
+ if s.Error() == nil {
return e.Encodef("ok %s\n", s.ReferenceName.String())
}
diff --git a/plumbing/protocol/packp/report_status_test.go b/plumbing/protocol/packp/report_status_test.go
index 168d25b..1c3fa81 100644
--- a/plumbing/protocol/packp/report_status_test.go
+++ b/plumbing/protocol/packp/report_status_test.go
@@ -13,22 +13,25 @@ type ReportStatusSuite struct{}
var _ = Suite(&ReportStatusSuite{})
-func (s *ReportStatusSuite) TestOk(c *C) {
+func (s *ReportStatusSuite) TestError(c *C) {
rs := NewReportStatus()
rs.UnpackStatus = "ok"
- c.Assert(rs.Ok(), Equals, true)
+ c.Assert(rs.Error(), IsNil)
rs.UnpackStatus = "OK"
- c.Assert(rs.Ok(), Equals, false)
+ c.Assert(rs.Error(), ErrorMatches, "unpack error: OK")
rs.UnpackStatus = ""
- c.Assert(rs.Ok(), Equals, false)
+ c.Assert(rs.Error(), ErrorMatches, "unpack error: ")
+
+ cs := &CommandStatus{ReferenceName: plumbing.ReferenceName("ref")}
+ rs.UnpackStatus = "ok"
+ rs.CommandStatuses = append(rs.CommandStatuses, cs)
- cs := &CommandStatus{}
cs.Status = "ok"
- c.Assert(cs.Ok(), Equals, true)
+ c.Assert(rs.Error(), IsNil)
cs.Status = "OK"
- c.Assert(cs.Ok(), Equals, false)
+ c.Assert(rs.Error(), ErrorMatches, "command error on ref: OK")
cs.Status = ""
- c.Assert(cs.Ok(), Equals, false)
+ c.Assert(rs.Error(), ErrorMatches, "command error on ref: ")
}
func (s *ReportStatusSuite) testEncodeDecodeOk(c *C, rs *ReportStatus, lines ...string) {
diff --git a/plumbing/transport/internal/common/common.go b/plumbing/transport/internal/common/common.go
index f6d1249..17c473e 100644
--- a/plumbing/transport/internal/common/common.go
+++ b/plumbing/transport/internal/common/common.go
@@ -281,8 +281,8 @@ func (s *session) SendPack(req *packp.ReferenceUpdateRequest) (*packp.ReportStat
return nil, err
}
- if !report.Ok() {
- return report, fmt.Errorf("report status: %s", report.UnpackStatus)
+ if err := report.Error(); err != nil {
+ return report, err
}
return report, s.Command.Wait()
diff --git a/plumbing/transport/test/send_pack.go b/plumbing/transport/test/send_pack.go
index 8cb549d..f880588 100644
--- a/plumbing/transport/test/send_pack.go
+++ b/plumbing/transport/test/send_pack.go
@@ -131,7 +131,7 @@ func (s *SendPackSuite) TestFullSendPackOnNonEmpty(c *C) {
fixture := fixtures.Basic().ByTag("packfile").One()
req := packp.NewReferenceUpdateRequest()
req.Commands = []*packp.Command{
- {"refs/heads/master", plumbing.ZeroHash, fixture.Head},
+ {"refs/heads/master", fixture.Head, fixture.Head},
}
s.sendPack(c, endpoint, req, fixture, full)
s.checkRemoteHead(c, endpoint, fixture.Head)
@@ -143,7 +143,7 @@ func (s *SendPackSuite) TestSendPackOnNonEmpty(c *C) {
fixture := fixtures.Basic().ByTag("packfile").One()
req := packp.NewReferenceUpdateRequest()
req.Commands = []*packp.Command{
- {"refs/heads/master", plumbing.ZeroHash, fixture.Head},
+ {"refs/heads/master", fixture.Head, fixture.Head},
}
s.sendPack(c, endpoint, req, fixture, full)
s.checkRemoteHead(c, endpoint, fixture.Head)
@@ -155,7 +155,7 @@ func (s *SendPackSuite) TestSendPackOnNonEmptyWithReportStatus(c *C) {
fixture := fixtures.Basic().ByTag("packfile").One()
req := packp.NewReferenceUpdateRequest()
req.Commands = []*packp.Command{
- {"refs/heads/master", plumbing.ZeroHash, fixture.Head},
+ {"refs/heads/master", fixture.Head, fixture.Head},
}
req.Capabilities.Set(capability.ReportStatus)
@@ -163,10 +163,30 @@ func (s *SendPackSuite) TestSendPackOnNonEmptyWithReportStatus(c *C) {
s.checkRemoteHead(c, endpoint, fixture.Head)
}
-func (s *SendPackSuite) sendPack(c *C, ep transport.Endpoint,
- req *packp.ReferenceUpdateRequest, fixture *fixtures.Fixture,
- callAdvertisedReferences bool) {
+func (s *SendPackSuite) TestSendPackOnNonEmptyWithReportStatusWithError(c *C) {
+ endpoint := s.Endpoint
+ full := false
+ fixture := fixtures.Basic().ByTag("packfile").One()
+ req := packp.NewReferenceUpdateRequest()
+ req.Commands = []*packp.Command{
+ {"refs/heads/master", plumbing.ZeroHash, fixture.Head},
+ }
+ req.Capabilities.Set(capability.ReportStatus)
+
+ report, err := s.sendPackNoCheck(c, endpoint, req, fixture, full)
+ //XXX: Recent git versions return "failed to update ref", while older
+ // (>=1.9) return "failed to lock".
+ c.Assert(err, ErrorMatches, ".*(failed to update ref|failed to lock).*")
+ c.Assert(report.UnpackStatus, Equals, "ok")
+ c.Assert(len(report.CommandStatuses), Equals, 1)
+ c.Assert(report.CommandStatuses[0].ReferenceName, Equals, plumbing.ReferenceName("refs/heads/master"))
+ c.Assert(report.CommandStatuses[0].Status, Matches, "(failed to update ref|failed to lock)")
+ s.checkRemoteHead(c, endpoint, fixture.Head)
+}
+func (s *SendPackSuite) sendPackNoCheck(c *C, ep transport.Endpoint,
+ req *packp.ReferenceUpdateRequest, fixture *fixtures.Fixture,
+ callAdvertisedReferences bool) (*packp.ReportStatus, error) {
url := ""
if fixture != nil {
url = fixture.URL
@@ -193,11 +213,28 @@ func (s *SendPackSuite) sendPack(c *C, ep transport.Endpoint,
req.Packfile = s.emptyPackfile()
}
- report, err := r.SendPack(req)
+ return r.SendPack(req)
+}
+
+func (s *SendPackSuite) sendPack(c *C, ep transport.Endpoint,
+ req *packp.ReferenceUpdateRequest, fixture *fixtures.Fixture,
+ callAdvertisedReferences bool) {
+
+ url := ""
+ if fixture != nil {
+ url = fixture.URL
+ }
+
+ comment := Commentf(
+ "failed with ep=%s fixture=%s callAdvertisedReferences=%s",
+ ep.String(), url, callAdvertisedReferences,
+ )
+ report, err := s.sendPackNoCheck(c, ep, req, fixture, callAdvertisedReferences)
+
c.Assert(err, IsNil, comment)
if req.Capabilities.Supports(capability.ReportStatus) {
c.Assert(report, NotNil, comment)
- c.Assert(report.Ok(), Equals, true, comment)
+ c.Assert(report.Error(), IsNil, comment)
} else {
c.Assert(report, IsNil, comment)
}