ref: 3a4b9149b94b9b43243fd0b1580625514f7670ee
parent: 273963c6ee47469032f2e74803daf0b40f396ce6
author: Runxi Yu <me@runxiyu.org>
date: Sat Mar 7 20:36:31 EST 2026
protocol/v0v1/server/receivepack: Fix report-status
--- /dev/null
+++ b/protocol/v0v1/server/receivepack/report_status.go
@@ -1,0 +1,183 @@
+package receivepack
+
+import (
+ "fmt"
+
+ "codeberg.org/lindenii/furgit/format/pktline"
+)
+
+// WriteReportStatus writes one classic report-status response.
+func (session *Session) WriteReportStatus(result ReportStatusResult) error {+ unpackResult := "ok"
+ if result.UnpackError != "" {+ unpackResult = result.UnpackError
+ }
+
+ if !session.negotiated.SideBand64K {+ err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult))
+ if err != nil {+ return err
+ }
+
+ for _, command := range result.Commands {+ line := fmt.Sprintf("ok %s\n", command.Name)+ if command.Error != "" {+ line = fmt.Sprintf("ng %s %s\n", command.Name, command.Error)+ }
+
+ err = session.base.WriteData([]byte(line))
+ if err != nil {+ return err
+ }
+ }
+
+ return session.base.WriteFlush()
+ }
+
+ buf, err := pktline.AppendData(nil, fmt.Appendf(nil, "unpack %s\n", unpackResult))
+ if err != nil {+ return err
+ }
+
+ for _, command := range result.Commands {+ line := fmt.Sprintf("ok %s\n", command.Name)+ if command.Error != "" {+ line = fmt.Sprintf("ng %s %s\n", command.Name, command.Error)+ }
+
+ buf, err = pktline.AppendData(buf, []byte(line))
+ if err != nil {+ return err
+ }
+ }
+
+ buf = pktline.AppendFlushPkt(buf)
+
+ w := session.base.PrimaryDataWriter()
+ _, err = w.Write(buf)
+ if err != nil {+ return err
+ }
+
+ return session.base.WriteFlush()
+}
+
+// WriteReportStatusV2 writes one report-status-v2 response.
+func (session *Session) WriteReportStatusV2(result ReportStatusResult) error {+ unpackResult := "ok"
+ if result.UnpackError != "" {+ unpackResult = result.UnpackError
+ }
+
+ if !session.negotiated.SideBand64K {+ err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult))
+ if err != nil {+ return err
+ }
+
+ for _, command := range result.Commands {+ if command.Error != "" {+ err = session.base.WriteData(fmt.Appendf(nil, "ng %s %s\n", command.Name, command.Error))
+ if err != nil {+ return err
+ }
+
+ continue
+ }
+
+ err = session.base.WriteData(fmt.Appendf(nil, "ok %s\n", command.Name))
+ if err != nil {+ return err
+ }
+
+ if command.RefName != "" {+ err = session.base.WriteData(fmt.Appendf(nil, "option refname %s\n", command.RefName))
+ if err != nil {+ return err
+ }
+ }
+
+ if command.OldID != nil {+ err = session.base.WriteData(fmt.Appendf(nil, "option old-oid %s\n", *command.OldID))
+ if err != nil {+ return err
+ }
+ }
+
+ if command.NewID != nil {+ err = session.base.WriteData(fmt.Appendf(nil, "option new-oid %s\n", *command.NewID))
+ if err != nil {+ return err
+ }
+ }
+
+ if command.ForcedUpdate {+ err = session.base.WriteData([]byte("option forced-update\n"))+ if err != nil {+ return err
+ }
+ }
+ }
+
+ return session.base.WriteFlush()
+ }
+
+ buf, err := pktline.AppendData(nil, fmt.Appendf(nil, "unpack %s\n", unpackResult))
+ if err != nil {+ return err
+ }
+
+ for _, command := range result.Commands {+ if command.Error != "" {+ buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "ng %s %s\n", command.Name, command.Error))
+ if err != nil {+ return err
+ }
+
+ continue
+ }
+
+ buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "ok %s\n", command.Name))
+ if err != nil {+ return err
+ }
+
+ if command.RefName != "" {+ buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "option refname %s\n", command.RefName))
+ if err != nil {+ return err
+ }
+ }
+
+ if command.OldID != nil {+ buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "option old-oid %s\n", *command.OldID))
+ if err != nil {+ return err
+ }
+ }
+
+ if command.NewID != nil {+ buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "option new-oid %s\n", *command.NewID))
+ if err != nil {+ return err
+ }
+ }
+
+ if command.ForcedUpdate {+ buf, err = pktline.AppendData(buf, []byte("option forced-update\n"))+ if err != nil {+ return err
+ }
+ }
+ }
+
+ buf = pktline.AppendFlushPkt(buf)
+
+ w := session.base.PrimaryDataWriter()
+ _, err = w.Write(buf)
+ if err != nil {+ return err
+ }
+
+ return session.base.WriteFlush()
+}
--- a/protocol/v0v1/server/receivepack/report_status_test.go
+++ b/protocol/v0v1/server/receivepack/report_status_test.go
@@ -101,26 +101,46 @@
t.Fatalf("ReadFrame(unpack): %v", err)}
- if frame.Type != sideband64k.FrameData || string(frame.Payload) != "unpack ok\n" {+ if frame.Type != sideband64k.FrameData { t.Fatalf("first frame = %#v", frame)}
- frame, err = dec.ReadFrame()
+ statusDec := pktline.NewDecoder(strings.NewReader(string(frame.Payload)), pktline.ReadOptions{})+
+ statusFrame, err := statusDec.ReadFrame()
if err != nil {- t.Fatalf("ReadFrame(ok): %v", err)+ t.Fatalf("ReadFrame(unpack status): %v", err)}
- if frame.Type != sideband64k.FrameData || string(frame.Payload) != "ok refs/heads/main\n" {- t.Fatalf("second frame = %#v", frame)+ if statusFrame.Type != pktline.PacketData || string(statusFrame.Payload) != "unpack ok\n" {+ t.Fatalf("first status frame = %#v", statusFrame)}
+ statusFrame, err = statusDec.ReadFrame()
+ if err != nil {+ t.Fatalf("ReadFrame(ok status): %v", err)+ }
+
+ if statusFrame.Type != pktline.PacketData || string(statusFrame.Payload) != "ok refs/heads/main\n" {+ t.Fatalf("second status frame = %#v", statusFrame)+ }
+
+ statusFrame, err = statusDec.ReadFrame()
+ if err != nil {+ t.Fatalf("ReadFrame(status flush): %v", err)+ }
+
+ if statusFrame.Type != pktline.PacketFlush {+ t.Fatalf("status flush frame.Type = %v, want FrameFlush", statusFrame.Type)+ }
+
frame, err = dec.ReadFrame()
if err != nil {- t.Fatalf("ReadFrame(flush): %v", err)+ t.Fatalf("ReadFrame(outer flush): %v", err)}
if frame.Type != sideband64k.FrameFlush {- t.Fatalf("flush frame.Type = %v, want FrameFlush", frame.Type)+ t.Fatalf("outer flush frame.Type = %v, want FrameFlush", frame.Type)}
})
}
--- a/protocol/v0v1/server/receivepack/session.go
+++ b/protocol/v0v1/server/receivepack/session.go
@@ -159,92 +159,6 @@
return req, nil
}
-// WriteReportStatus writes one classic report-status response.
-func (session *Session) WriteReportStatus(result ReportStatusResult) error {- unpackResult := "ok"
- if result.UnpackError != "" {- unpackResult = result.UnpackError
- }
-
- err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult))
- if err != nil {- return err
- }
-
- for _, command := range result.Commands {- line := fmt.Sprintf("ok %s\n", command.Name)- if command.Error != "" {- line = fmt.Sprintf("ng %s %s\n", command.Name, command.Error)- }
-
- err = session.base.WriteData([]byte(line))
- if err != nil {- return err
- }
- }
-
- return session.base.WriteFlush()
-}
-
-// WriteReportStatusV2 writes one report-status-v2 response.
-func (session *Session) WriteReportStatusV2(result ReportStatusResult) error {- unpackResult := "ok"
- if result.UnpackError != "" {- unpackResult = result.UnpackError
- }
-
- err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult))
- if err != nil {- return err
- }
-
- for _, command := range result.Commands {- if command.Error != "" {- err = session.base.WriteData(fmt.Appendf(nil, "ng %s %s\n", command.Name, command.Error))
- if err != nil {- return err
- }
-
- continue
- }
-
- err = session.base.WriteData(fmt.Appendf(nil, "ok %s\n", command.Name))
- if err != nil {- return err
- }
-
- if command.RefName != "" {- err = session.base.WriteData(fmt.Appendf(nil, "option refname %s\n", command.RefName))
- if err != nil {- return err
- }
- }
-
- if command.OldID != nil {- err = session.base.WriteData(fmt.Appendf(nil, "option old-oid %s\n", *command.OldID))
- if err != nil {- return err
- }
- }
-
- if command.NewID != nil {- err = session.base.WriteData(fmt.Appendf(nil, "option new-oid %s\n", *command.NewID))
- if err != nil {- return err
- }
- }
-
- if command.ForcedUpdate {- err = session.base.WriteData([]byte("option forced-update\n"))- if err != nil {- return err
- }
- }
- }
-
- return session.base.WriteFlush()
-}
-
// WriteProgress writes one progress packet.
func (session *Session) WriteProgress(p []byte) error {return session.base.WriteProgress(p)
--
⑨