all repos

mugit @ da15464

馃惍 git server that your cow will love
4 files changed, 52 insertions(+), 13 deletions(-)
ssh: dont write slog to output
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-04-23 21:54:34 +0300
Authored at: 2026-04-23 21:20:21 +0300
Change ID: soxrtypuworrmyxkxtyxzvlzvyvrluvy
Parent: 46e2219
M internal/cli/ssh_shell.go
路路路
        17
        17
         	}

      
        18
        18
         

      
        19
        19
         	sshCommand := os.Getenv("SSH_ORIGINAL_COMMAND")

      
        20
        
        -	return c.ssh.HandleCommand(ctx, sshCommand, os.Stdin, os.Stdout, os.Stderr)

      
        
        20
        +	if err := c.ssh.HandleCommand(ctx, sshCommand, os.Stdin, os.Stdout, os.Stderr); err != nil {

      
        
        21
        +		os.Exit(1)

      
        
        22
        +		return nil

      
        
        23
        +	}

      
        
        24
        +	return nil

      
        21
        25
         }

      
        22
        26
         

      
        23
        27
         func (c *Cli) sshAuthorizedKeysAction(ctx context.Context, cmd *cli.Command) error {

      
M internal/ssh/ssh.go
路路路
        2
        2
         

      
        3
        3
         import (

      
        4
        4
         	"context"

      
        
        5
        +	"errors"

      
        5
        6
         	"fmt"

      
        6
        7
         	"io"

      
        7
        
        -	"log/slog"

      
        8
        8
         	"strings"

      
        9
        9
         

      
        10
        10
         	"olexsmir.xyz/mugit/internal/config"

      路路路
        44
        44
         func (s *Shell) HandleCommand(ctx context.Context, cmd string, stdin io.Reader, stdout, stderr io.Writer) error {

      
        45
        45
         	gitCmd, repoName, err := s.parseCommand(cmd)

      
        46
        46
         	if err != nil {

      
        47
        
        -		slog.Error("ssh invalid command", "error", err, "raw_cmd", cmd)

      
        48
        
        -		return err

      
        
        47
        +		return s.replyWithGitError(stderr, "access denied: invalid command", err)

      
        49
        48
         	}

      
        50
        49
         

      
        51
        50
         	if !validCommands[gitCmd] {

      
        52
        
        -		slog.Error("access denied: invalid git command")

      
        53
        
        -		return fmt.Errorf("access denied: invalid git command")

      
        
        51
        +		msg := "access denied: invalid git command"

      
        
        52
        +		return s.replyWithGitError(stderr, msg, errors.New(msg))

      
        54
        53
         	}

      
        55
        54
         

      
        56
        55
         	repoPath, err := git.ResolvePath(s.cfg.Repo.Dir, git.ResolveName(repoName))

      
        57
        56
         	if err != nil {

      
        58
        
        -		slog.Error("ssh access denied", "cmd", gitCmd, "repo", repoName, "error", err)

      
        59
        
        -		return err

      
        
        57
        +		return s.replyWithGitError(stderr, "access denied", err)

      
        60
        58
         	}

      
        61
        59
         

      
        62
        60
         	repo, err := git.Open(repoPath, "")

      
        63
        61
         	if err != nil {

      
        64
        
        -		slog.Error("ssh access denied", "cmd", gitCmd, "repo", repoName, "error", err)

      
        65
        
        -		return err

      
        
        62
        +		return s.replyWithGitError(stderr, "repository not found", err)

      
        66
        63
         	}

      
        67
        64
         

      
        68
        65
         	switch gitCmd {

      路路路
        73
        70
         	case "git-receive-pack":

      
        74
        71
         		err = repo.ReceivePack(ctx, stdin, stdout, stderr)

      
        75
        72
         	default:

      
        76
        
        -		err = fmt.Errorf("access denied: invalid git command %q", gitCmd)

      
        
        73
        +		msg := "access denied: invalid git command"

      
        
        74
        +		return s.replyWithGitError(stderr, msg, errors.New(msg))

      
        77
        75
         	}

      
        78
        76
         

      
        79
        77
         	if err != nil {

      
        80
        
        -		slog.Error("ssh operation failed", "cmd", gitCmd, "repo", repoName, "error", err)

      
        
        78
        +		return err

      
        81
        79
         	}

      
        82
        80
         

      
        83
        
        -	return err

      
        
        81
        +	return nil

      
        84
        82
         }

      
        85
        83
         

      
        86
        84
         func (s *Shell) AuthorizedKeys(executablePath string) string {

      路路路
        106
        104
         

      
        107
        105
         	return gitCmd, repoName, nil

      
        108
        106
         }

      
        
        107
        +

      
        
        108
        +func (s *Shell) replyWithGitError(stderr io.Writer, msg string, cause error) error {

      
        
        109
        +	if _, err := fmt.Fprintf(stderr, "fatal: %s\n", msg); err != nil {

      
        
        110
        +		return err

      
        
        111
        +	}

      
        
        112
        +

      
        
        113
        +	return cause

      
        
        114
        +}

      
M testscript/http-clone.txtar
路路路
        18
        18
         stdout 'hello world'

      
        19
        19
         

      
        20
        20
         

      
        
        21
        +# non existent repo

      
        
        22
        +! git clone $MURL/nonexistent-http-repo

      
        
        23
        +stderr 'remote: repository not found'

      
        
        24
        +

      
        
        25
        +

      
        21
        26
         -- readme.txt --

      
        22
        27
         hello world

      
        23
        28
         

      
A testscript/ssh-clone-nonexistent.txtar
路路路
        
        1
        +git init local

      
        
        2
        +cp readme.txt local/readme.txt

      
        
        3
        +git -C local add .

      
        
        4
        +git -C local commit -m 'init'

      
        
        5
        +

      
        
        6
        +mugit repo new ssh-clone.git

      
        
        7
        +git -C local push file://$REPOS/ssh-clone.git master

      
        
        8
        +

      
        
        9
        +

      
        
        10
        +exec env GIT_SSH_COMMAND=$SSH_WRAPPER git clone git@localhost:ssh-clone.git clone

      
        
        11
        +exists clone/readme.txt

      
        
        12
        +

      
        
        13
        +exec cat clone/readme.txt

      
        
        14
        +stdout 'hello world'

      
        
        15
        +

      
        
        16
        +

      
        
        17
        +# clone non existent repo

      
        
        18
        +! exec env GIT_SSH_COMMAND=$SSH_WRAPPER git clone git@localhost:nonexistent.git wont-clone

      
        
        19
        +stderr 'fatal: repository not found'

      
        
        20
        +! stderr 'ERROR mugit'

      
        
        21
        +

      
        
        22
        +

      
        
        23
        +-- readme.txt --

      
        
        24
        +hello world