all repos

mugit @ 72ef851

🐮 git server that your cow will love

mugit/internal/git/external.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
git: get last commit from git cli, improves performance..., 2 months ago
1
package git
2
3
import (
4
	"context"
5
	"fmt"
6
	"io"
7
	"os/exec"
8
	"syscall"
9
)
10
11
var gitEnv = []string{
12
	"GIT_CONFIG_GLOBAL=/dev/null",
13
	"GIT_CONFIG_SYSTEM=/dev/null",
14
}
15
16
type cmdOpts struct {
17
	Cmd         []string
18
	GitProtocol string
19
	RepoDir     string
20
	Stdin       io.Reader
21
	Stdout      io.Writer
22
	Stderr      io.Writer
23
}
24
25
func gitCmd(ctx context.Context, opts cmdOpts) error {
26
	opts.Cmd = append(opts.Cmd, ".")
27
	cmd := exec.CommandContext(ctx, "git", opts.Cmd...)
28
	cmd.Dir = opts.RepoDir
29
	cmd.Env = append(gitEnv, fmt.Sprintf("GIT_PROTOCOL=%s", opts.GitProtocol))
30
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
31
	cmd.Stdin = opts.Stdin
32
	cmd.Stdout = opts.Stdout
33
	cmd.Stderr = opts.Stderr
34
	return cmd.Run()
35
}
36
37
func (g *Repo) streamingGitLog(ctx context.Context, extraArgs ...string) (io.ReadCloser, error) {
38
	args := []string{"log", g.h.String()}
39
	args = append(args, extraArgs...)
40
41
	cmd := exec.CommandContext(ctx, "git", args...)
42
	cmd.Dir = g.path
43
44
	stdout, err := cmd.StdoutPipe()
45
	if err != nil {
46
		return nil, err
47
	}
48
49
	if err := cmd.Start(); err != nil {
50
		return nil, err
51
	}
52
53
	return &processReader{
54
		Reader: stdout,
55
		cmd:    cmd,
56
		stdout: stdout,
57
	}, nil
58
}
59
60
// processReader wraps a reader and ensures the associated process is cleaned up
61
type processReader struct {
62
	io.Reader
63
	cmd    *exec.Cmd
64
	stdout io.ReadCloser
65
}
66
67
func (pr *processReader) Close() error {
68
	if err := pr.stdout.Close(); err != nil {
69
		return err
70
	}
71
	return pr.cmd.Wait()
72
}