@ 797c7a407b8fa943b19b8241e470451b21fde72d | history
package core
import (
"io"
"log"
"net/http"
"os/exec"
"syscall"
)
func UploadPack(repoLocation string, r io.Reader, w http.ResponseWriter) error {
cmd := exec.Command(
"git",
"-c", "uploadpack.allowFilter=true",
"upload-pack",
"--stateless-rpc",
".",
)
cmd.Dir = repoLocation
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
stdoutPipe, _ := cmd.StdoutPipe()
cmd.Stderr = cmd.Stdout
defer stdoutPipe.Close()
stdinPipe, err := cmd.StdinPipe()
if err != nil {
return err
}
defer stdinPipe.Close()
if err := cmd.Start(); err != nil {
log.Printf("git: failed to start git-upload-pack: %s", err)
return err
}
if _, err := io.Copy(stdinPipe, r); err != nil {
log.Printf("git: failed to copy stdin: %s", err)
return err
}
stdinPipe.Close()
if _, err := io.Copy(flushWriter{w}, stdoutPipe); err != nil {
log.Printf("git: failed to copy stdout: %s", err)
return err
}
if err := cmd.Wait(); err != nil {
log.Printf("git: failed to wait for git-upload-pack: %s", err)
return err
}
return nil
}
type flushWriter struct {
http.ResponseWriter
}
func (w flushWriter) Write(p []byte) (n int, err error) {
if f, ok := w.ResponseWriter.(http.Flusher); ok {
defer f.Flush()
}
return w.ResponseWriter.Write(p)
}