aboutsummaryrefslogtreecommitdiff
path: root/pkg/git
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/git')
-rw-r--r--pkg/git/git.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/pkg/git/git.go b/pkg/git/git.go
index 64c721a..95355f3 100644
--- a/pkg/git/git.go
+++ b/pkg/git/git.go
@@ -3,12 +3,17 @@ package git
import (
"archive/tar"
"bytes"
+ "context"
"errors"
"fmt"
"io"
"io/fs"
+ "log"
+ "log/slog"
+ "os/exec"
"path"
"sort"
+ "syscall"
"time"
"github.com/go-git/go-git/v5"
@@ -432,6 +437,66 @@ func (g *GitRepository) FileContent(path string) ([]byte, error) {
return buf.Bytes(), nil
}
+func (g *GitRepository) WriteInfoRefs(ctx context.Context, w io.Writer) error {
+ cmd := exec.CommandContext(
+ ctx,
+ "git-upload-pack",
+ "--stateless-rpc",
+ "--advertise-refs",
+ ".",
+ )
+
+ cmd.Dir = g.path
+ cmd.Stdout = w
+
+ var buff bytes.Buffer
+ cmd.Stderr = &buff
+
+ err := packLine(w, "# service=git-upload-pack\n")
+ if err != nil {
+ return err
+ }
+
+ err = packFlush(w)
+ if err != nil {
+ return err
+ }
+
+ err = cmd.Run()
+ if err != nil {
+ slog.Error("Error upload pack refs", "message", buff.String())
+ return err
+ }
+ return nil
+}
+
+func (g *GitRepository) WriteUploadPack(ctx context.Context, r io.Reader, w io.Writer) error {
+ cmd := exec.CommandContext(
+ ctx,
+ "git-upload-pack",
+ "--stateless-rpc",
+ ".",
+ )
+ cmd.Dir = g.Path()
+ cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+ var buff bytes.Buffer
+ cmd.Stderr = &buff
+ cmd.Stdin = r
+ cmd.Stdout = w
+
+ if err := cmd.Start(); err != nil {
+ log.Printf("git: failed to start git-upload-pack: %s", err)
+ return err
+ }
+
+ if err := cmd.Wait(); err != nil {
+ log.Printf("git: failed to wait for git-upload-pack: %s", buff.String())
+ return err
+ }
+
+ return nil
+}
+
func (g *GitRepository) WriteTar(w io.Writer, prefix string) error {
tw := tar.NewWriter(w)
defer tw.Close()
@@ -613,3 +678,31 @@ func (self *tagList) Less(i, j int) bool {
return dateI.After(dateJ)
}
+
+func packLine(w io.Writer, s string) error {
+ _, err := fmt.Fprintf(w, "%04x%s", len(s)+4, s)
+ return err
+}
+
+func packFlush(w io.Writer) error {
+ _, err := fmt.Fprint(w, "0000")
+ return err
+}
+
+type debugReader struct {
+ r io.Reader
+}
+
+func (d *debugReader) Read(p []byte) (n int, err error) {
+ fmt.Printf("READ: %x\n", p)
+ return d.r.Read(p)
+}
+
+type debugWriter struct {
+ w io.Writer
+}
+
+func (d *debugWriter) Write(p []byte) (n int, err error) {
+ fmt.Printf("WRITE: %x\n", p)
+ return d.w.Write(p)
+}