Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).

knotserver: git: add support for git protocol v2

v1-style requests are unaffected and v0 (dumb-protocol) requests remain
unsupported.

authored by tjh.dev and committed by

Tangled d67e7d07 31a506aa

+30 -19
+7 -5
knotserver/git.go
··· 31 31 } 32 32 33 33 cmd := service.ServiceCommand{ 34 - Dir: repoPath, 35 - Stdout: w, 34 + GitProtocol: r.Header.Get("Git-Protocol"), 35 + Dir: repoPath, 36 + Stdout: w, 36 37 } 37 38 38 39 serviceName := r.URL.Query().Get("service") ··· 82 81 d.l.Info("git: executing git-upload-pack", "handler", "UploadPack", "repo", repo) 83 82 84 83 cmd := service.ServiceCommand{ 85 - Dir: repo, 86 - Stdout: w, 87 - Stdin: bodyReader, 84 + GitProtocol: r.Header.Get("Git-Protocol"), 85 + Dir: repo, 86 + Stdout: w, 87 + Stdin: bodyReader, 88 88 } 89 89 90 90 w.WriteHeader(http.StatusOK)
+23 -14
knotserver/git/service/service.go
··· 15 15 // Mostly from charmbracelet/soft-serve and sosedoff/gitkit. 16 16 17 17 type ServiceCommand struct { 18 - Dir string 19 - Stdin io.Reader 20 - Stdout http.ResponseWriter 18 + GitProtocol string 19 + Dir string 20 + Stdin io.Reader 21 + Stdout http.ResponseWriter 21 22 } 22 23 23 24 func (c *ServiceCommand) InfoRefs() error { 24 25 cmd := exec.Command("git", []string{ 25 26 "upload-pack", 26 27 "--stateless-rpc", 27 - "--advertise-refs", 28 + "--http-backend-info-refs", 28 29 ".", 29 30 }...) 30 - 31 + cmd.Env = append(cmd.Env, fmt.Sprintf("GIT_PROTOCOL=%s", c.GitProtocol)) 31 32 cmd.Dir = c.Dir 32 33 cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 33 34 stdoutPipe, _ := cmd.StdoutPipe() ··· 39 38 return err 40 39 } 41 40 42 - if err := packLine(c.Stdout, "# service=git-upload-pack\n"); err != nil { 43 - log.Printf("git: failed to write pack line: %s", err) 44 - return err 45 - } 41 + if !strings.Contains(c.GitProtocol, "version=2") { 42 + if err := packLine(c.Stdout, "# service=git-upload-pack\n"); err != nil { 43 + log.Printf("git: failed to write pack line: %s", err) 44 + return err 45 + } 46 46 47 - if err := packFlush(c.Stdout); err != nil { 48 - log.Printf("git: failed to flush pack: %s", err) 49 - return err 47 + if err := packFlush(c.Stdout); err != nil { 48 + log.Printf("git: failed to flush pack: %s", err) 49 + return err 50 + } 50 51 } 51 52 52 53 buf := bytes.Buffer{} ··· 74 71 func (c *ServiceCommand) UploadPack() error { 75 72 var stderr bytes.Buffer 76 73 77 - cmd := exec.Command("git", "-c", "uploadpack.allowFilter=true", 78 - "upload-pack", "--stateless-rpc", ".") 74 + cmd := exec.Command("git", []string{ 75 + "-c", "uploadpack.allowFilter=true", 76 + "upload-pack", 77 + "--stateless-rpc", 78 + ".", 79 + }...) 80 + 79 81 cmd.Dir = c.Dir 80 82 cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 83 + cmd.Env = append(cmd.Env, fmt.Sprintf("GIT_PROTOCOL=%s", c.GitProtocol)) 81 84 82 85 stdoutPipe, err := cmd.StdoutPipe() 83 86 if err != nil {