3 files changed,
61 insertions(+),
53 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-02-17 23:13:44 +0200
Authored at:
2026-02-17 22:23:24 +0200
Change ID:
zuxttzlqluzpmlmqoyllqnqswuqmlxtt
Parent:
19c8a5c
M
internal/git/gitx/archive.go
路路路 4 4 "context" 5 5 "fmt" 6 6 "io" 7 - "os/exec" 8 7 "regexp" 9 8 "strings" 10 9 ) 路路路 15 14 return fmt.Errorf("invalid ref: %s", ref) 16 15 } 17 16 18 - cmd := exec.CommandContext(ctx, "git", "archive", "--format=tar.gz", ref) 19 - cmd.Dir = repoDir 20 - cmd.Env = gitEnv 21 - cmd.Stdout = out 22 - cmd.Stderr = io.Discard 23 - 24 - if err := cmd.Run(); err != nil { 17 + if err := gitCmd(ctx, cmdOpts{ 18 + Cmd: []string{"archive", "--format=tar.gz", ref}, 19 + RepoDir: repoDir, 20 + Stdout: out, 21 + }); err != nil { 25 22 return fmt.Errorf("git archive %s: %w", ref, err) 26 23 } 27 24 28 25 return nil 29 26 } 30 27 28 +var isValidRefRe = regexp.MustCompile(`^[a-zA-Z0-9._/-]+$`) 29 + 31 30 func isValidRef(ref string) bool { 32 31 if ref == "" || strings.Contains(ref, "..") { 33 32 return false 34 33 } 35 - matched, _ := regexp.MatchString(`^[a-zA-Z0-9._/-]+$`, ref) 36 - return matched 34 + return isValidRefRe.MatchString(ref) 37 35 }
M
internal/git/gitx/gitx.go
路路路 1 1 package gitx 2 2 3 +import ( 4 + "context" 5 + "io" 6 + "os/exec" 7 + "syscall" 8 +) 9 + 3 10 var gitEnv = []string{ 4 11 "GIT_CONFIG_GLOBAL=/dev/null", 5 12 "GIT_CONFIG_SYSTEM=/dev/null", 6 13 } 14 + 15 +type cmdOpts struct { 16 + Cmd []string 17 + RepoDir string 18 + Stdin io.Reader 19 + Stdout io.Writer 20 + Stderr io.Writer 21 +} 22 + 23 +func gitCmd(ctx context.Context, opts cmdOpts) error { 24 + opts.Cmd = append(opts.Cmd, ".") 25 + cmd := exec.CommandContext(ctx, "git", opts.Cmd...) 26 + cmd.Dir = opts.RepoDir 27 + cmd.Env = gitEnv 28 + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 29 + cmd.Stdin = opts.Stdin 30 + cmd.Stdout = opts.Stdout 31 + cmd.Stderr = opts.Stderr 32 + return cmd.Run() 33 +}
M
internal/git/gitx/pack.go
路路路 4 4 "context" 5 5 "fmt" 6 6 "io" 7 - "os/exec" 8 - "syscall" 9 7 ) 10 8 11 9 // InfoRefs executes git-upload-pack --advertise-refs for smart-HTTP discovery. 12 10 func InfoRefs(ctx context.Context, repoDir string, out io.Writer) error { 13 - cmd := exec.CommandContext(ctx, "git", []string{ 14 - "-c", "uploadpack.allowFilter=true", 15 - "upload-pack", 16 - "--stateless-rpc", 17 - "--advertise-refs", 18 - ".", 19 - }...) 20 - cmd.Dir = repoDir 21 - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 22 - cmd.Env = gitEnv 23 - 24 - cmd.Stdout = out 25 - cmd.Stderr = out // TODO: Check if this is correct. 26 - 27 11 if err := PackLine(out, "# service=git-upload-pack\n"); err != nil { 28 12 return fmt.Errorf("write pack line: %w", err) 29 13 } 14 + 30 15 if err := PackFlush(out); err != nil { 31 16 return fmt.Errorf("flush pack: %w", err) 32 17 } 33 18 34 - if err := cmd.Run(); err != nil { 19 + if err := gitCmd(ctx, cmdOpts{ 20 + RepoDir: repoDir, 21 + Cmd: []string{ 22 + "-c", "uploadpack.allowFilter=true", 23 + "upload-pack", "--stateless-rpc", "--advertise-refs", 24 + }, 25 + Stdout: out, 26 + Stderr: out, // TODO: Check if this is correct. 27 + }); err != nil { 35 28 return fmt.Errorf("git-upload-pack: %w", err) 36 29 } 37 - 38 30 return nil 39 31 } 40 32 41 33 // UploadPack executes git-upload-pack for smart-HTTP git fetch/clone. 42 34 // StatelessRPC should be true in case it's used over http, and false for ssh. 43 35 func UploadPack(ctx context.Context, repoDir string, statelessRPC bool, in io.Reader, out io.Writer) error { 44 - args := []string{"-c", "uploadpack.allowFilter=true", "upload-pack"} 36 + cmd := []string{"-c", "uploadpack.allowFilter=true", "upload-pack"} 45 37 if statelessRPC { 46 - args = append(args, "--stateless-rpc") 38 + cmd = append(cmd, "--stateless-rpc") 47 39 } 48 - args = append(args, ".") 49 40 50 - cmd := exec.CommandContext(ctx, "git", args...) 51 - cmd.Dir = repoDir 52 - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 53 - cmd.Env = gitEnv 54 - 55 - cmd.Stdin = in 56 - cmd.Stdout = out 57 - cmd.Stderr = out // TODO: Check if this is correct. 58 - 59 - if err := cmd.Run(); err != nil { 41 + if err := gitCmd(ctx, cmdOpts{ 42 + RepoDir: repoDir, 43 + Cmd: cmd, 44 + Stdin: in, 45 + Stdout: out, 46 + Stderr: out, // TODO: Check if this is correct. 47 + }); err != nil { 60 48 return fmt.Errorf("git-upload-pack: %w", err) 61 49 } 62 - 63 50 return nil 64 51 } 65 52 66 53 // ReceivePack executes git-receive-pack for git push. 67 54 func ReceivePack(ctx context.Context, repoDir string, in io.Reader, out, errout io.Writer) error { 68 - cmd := exec.CommandContext(ctx, "git", "receive-pack", ".") 69 - cmd.Dir = repoDir 70 - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 71 - cmd.Env = gitEnv 72 - 73 - cmd.Stdin = in 74 - cmd.Stdout = out 75 - cmd.Stderr = errout 76 - 77 - if err := cmd.Run(); err != nil { 55 + if err := gitCmd(ctx, cmdOpts{ 56 + RepoDir: repoDir, 57 + Cmd: []string{"receive-pack"}, 58 + Stdin: in, 59 + Stdout: out, 60 + Stderr: errout, 61 + }); err != nil { 78 62 return fmt.Errorf("git-receive-pack: %w", err) 79 63 } 80 - 81 64 return nil 82 65 }