shithub: furgit

Download patch

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)
--