all repos

mugit @ b19bb18

馃惍 git server that your cow will love
3 files changed, 33 insertions(+), 0 deletions(-)
git: support git archive --remote
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-03-02 00:46:10 +0200
Authored at: 2026-03-02 00:34:23 +0200
Change ID: uopoopxxnnsztyppvwxwqovvsyrpzwxx
Parent: d985efd
M CHANGELOG.md
路路路
        4
        4
         

      
        5
        5
         ### Features:

      
        6
        6
         - Paginate log page (150 commits per page).

      
        
        7
        +- Support `git-upload-archive`.

      
        7
        8
         

      
        8
        9
         ### Bug fixes:

      
        9
        10
         - Allow downloading only valid and existing refs.

      
M internal/git/gitx/archive.go
路路路
        25
        25
         	return nil

      
        26
        26
         }

      
        27
        27
         

      
        
        28
        +func UploadArchive(ctx context.Context, repoDir string, in io.Reader, out io.Writer) error {

      
        
        29
        +	if err := gitCmd(ctx, cmdOpts{

      
        
        30
        +		RepoDir: repoDir,

      
        
        31
        +		Cmd:     []string{"upload-archive"},

      
        
        32
        +		Stdin:   in,

      
        
        33
        +		Stdout:  out,

      
        
        34
        +		Stderr:  out,

      
        
        35
        +	}); err != nil {

      
        
        36
        +		return fmt.Errorf("git-upload-archive: %w", err)

      
        
        37
        +	}

      
        
        38
        +	return nil

      
        
        39
        +}

      
        
        40
        +

      
        28
        41
         var isValidRefRe = regexp.MustCompile(`^[a-zA-Z0-9._/-]+$`)

      
        29
        42
         

      
        30
        43
         func isValidRef(ref string) bool {

      
M internal/ssh/ssh.go
路路路
        107
        107
         

      
        108
        108
         		sess.Exit(0)

      
        109
        109
         

      
        
        110
        +	case "git-upload-archive":

      
        
        111
        +		isPrivate, err := repo.IsPrivate()

      
        
        112
        +		if err != nil {

      
        
        113
        +			s.gitError(sess, badRequestErrMsg, nil)

      
        
        114
        +			return

      
        
        115
        +		}

      
        
        116
        +

      
        
        117
        +		if isPrivate && !authorized {

      
        
        118
        +			s.gitError(sess, badRequestErrMsg, nil)

      
        
        119
        +			return

      
        
        120
        +		}

      
        
        121
        +

      
        
        122
        +		if err := gitx.UploadArchive(ctx, repoPath, sess, sess); err != nil {

      
        
        123
        +			s.gitError(sess, internalServerErrMsg, err)

      
        
        124
        +			return

      
        
        125
        +		}

      
        
        126
        +

      
        
        127
        +		sess.Exit(0)

      
        
        128
        +

      
        110
        129
         	case "git-receive-pack":

      
        111
        130
         		if !authorized {

      
        112
        131
         			s.gitError(sess, unauthorizedErrMsg, nil)