mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 00:20:25 +08:00 
			
		
		
		
	Refactor git module, make Gitea use internal git config (#19732)
* Refactor git module, make Gitea use internal git config, add safe.directory config * introduce git.InitSimple and git.InitWithConfigSync, make serv cmd use gitconfig * use HOME instead of GIT_CONFIG_GLOBAL, because git always needs a correct HOME * fix cmd env in cmd/serv.go * fine tune error message * Fix a incorrect test case * fix configAddNonExist * fix configAddNonExist logic, add `--fixed-value` flag, add tests * add configSetNonExist function in case it's needed. * use configSetNonExist for `user.name` and `user.email` * add some comments * Update cmd/serv.go Co-authored-by: zeripath <art27@cantab.net> * Update cmd/serv.go Co-authored-by: zeripath <art27@cantab.net> * Update modules/git/git.go Co-authored-by: zeripath <art27@cantab.net> * Update modules/setting/setting.go Co-authored-by: zeripath <art27@cantab.net> * Update modules/git/repo_attribute.go Co-authored-by: zeripath <art27@cantab.net> * fix spaces in messages * use `configSet("core.protectNTFS", ...)` instead of `globalCommandArgs` * remove GIT_CONFIG_NOSYSTEM, continue to use system's git config * Update cmd/serv.go Co-authored-by: zeripath <art27@cantab.net> * fix merge * remove code for safe.directory * separate git.CommonEnvs to CommonGitCmdEnvs and CommonCmdServEnvs * avoid Golang's data race error Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
		
							
								
								
									
										60
									
								
								cmd/serv.go
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								cmd/serv.go
									
									
									
									
									
								
							@@ -6,6 +6,7 @@
 | 
			
		||||
package cmd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
@@ -65,6 +66,21 @@ func setup(logPath string, debug bool) {
 | 
			
		||||
	if debug {
 | 
			
		||||
		setting.RunMode = "dev"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check if setting.RepoRootPath exists. It could be the case that it doesn't exist, this can happen when
 | 
			
		||||
	// `[repository]` `ROOT` is a relative path and $GITEA_WORK_DIR isn't passed to the SSH connection.
 | 
			
		||||
	if _, err := os.Stat(setting.RepoRootPath); err != nil {
 | 
			
		||||
		if os.IsNotExist(err) {
 | 
			
		||||
			_ = fail("Incorrect configuration, no repository directory.", "Directory `[repository].ROOT` %q was not found, please check if $GITEA_WORK_DIR is passed to the SSH connection or make `[repository].ROOT` an absolute value.", setting.RepoRootPath)
 | 
			
		||||
		} else {
 | 
			
		||||
			_ = fail("Incorrect configuration, repository directory is inaccessible", "Directory `[repository].ROOT` %q is inaccessible. err: %v", setting.RepoRootPath, err)
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := git.InitSimple(context.Background()); err != nil {
 | 
			
		||||
		_ = fail("Failed to init git", "Failed to init git, err: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
@@ -80,12 +96,12 @@ var (
 | 
			
		||||
func fail(userMessage, logMessage string, args ...interface{}) error {
 | 
			
		||||
	// There appears to be a chance to cause a zombie process and failure to read the Exit status
 | 
			
		||||
	// if nothing is outputted on stdout.
 | 
			
		||||
	fmt.Fprintln(os.Stdout, "")
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
 | 
			
		||||
	_, _ = fmt.Fprintln(os.Stdout, "")
 | 
			
		||||
	_, _ = fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
 | 
			
		||||
 | 
			
		||||
	if len(logMessage) > 0 {
 | 
			
		||||
		if !setting.IsProd {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
 | 
			
		||||
			_, _ = fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ctx, cancel := installSignals()
 | 
			
		||||
@@ -237,17 +253,6 @@ func runServ(c *cli.Context) error {
 | 
			
		||||
		}
 | 
			
		||||
		return fail("Internal Server Error", "%s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	os.Setenv(repo_module.EnvRepoIsWiki, strconv.FormatBool(results.IsWiki))
 | 
			
		||||
	os.Setenv(repo_module.EnvRepoName, results.RepoName)
 | 
			
		||||
	os.Setenv(repo_module.EnvRepoUsername, results.OwnerName)
 | 
			
		||||
	os.Setenv(repo_module.EnvPusherName, results.UserName)
 | 
			
		||||
	os.Setenv(repo_module.EnvPusherEmail, results.UserEmail)
 | 
			
		||||
	os.Setenv(repo_module.EnvPusherID, strconv.FormatInt(results.UserID, 10))
 | 
			
		||||
	os.Setenv(repo_module.EnvRepoID, strconv.FormatInt(results.RepoID, 10))
 | 
			
		||||
	os.Setenv(repo_module.EnvPRID, fmt.Sprintf("%d", 0))
 | 
			
		||||
	os.Setenv(repo_module.EnvDeployKeyID, fmt.Sprintf("%d", results.DeployKeyID))
 | 
			
		||||
	os.Setenv(repo_module.EnvKeyID, fmt.Sprintf("%d", results.KeyID))
 | 
			
		||||
	os.Setenv(repo_module.EnvAppURL, setting.AppURL)
 | 
			
		||||
 | 
			
		||||
	// LFS token authentication
 | 
			
		||||
	if verb == lfsAuthenticateVerb {
 | 
			
		||||
@@ -298,20 +303,29 @@ func runServ(c *cli.Context) error {
 | 
			
		||||
		gitcmd = exec.CommandContext(ctx, verb, repoPath)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check if setting.RepoRootPath exists. It could be the case that it doesn't exist, this can happen when
 | 
			
		||||
	// `[repository]` `ROOT` is a relative path and $GITEA_WORK_DIR isn't passed to the SSH connection.
 | 
			
		||||
	if _, err := os.Stat(setting.RepoRootPath); err != nil {
 | 
			
		||||
		if os.IsNotExist(err) {
 | 
			
		||||
			return fail("Incorrect configuration.",
 | 
			
		||||
				"Directory `[repository]` `ROOT` %s was not found, please check if $GITEA_WORK_DIR is passed to the SSH connection or make `[repository]` `ROOT` an absolute value.", setting.RepoRootPath)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	process.SetSysProcAttribute(gitcmd)
 | 
			
		||||
	gitcmd.Dir = setting.RepoRootPath
 | 
			
		||||
	gitcmd.Stdout = os.Stdout
 | 
			
		||||
	gitcmd.Stdin = os.Stdin
 | 
			
		||||
	gitcmd.Stderr = os.Stderr
 | 
			
		||||
	gitcmd.Env = append(gitcmd.Env, os.Environ()...)
 | 
			
		||||
	gitcmd.Env = append(gitcmd.Env,
 | 
			
		||||
		repo_module.EnvRepoIsWiki+"="+strconv.FormatBool(results.IsWiki),
 | 
			
		||||
		repo_module.EnvRepoName+"="+results.RepoName,
 | 
			
		||||
		repo_module.EnvRepoUsername+"="+results.OwnerName,
 | 
			
		||||
		repo_module.EnvPusherName+"="+results.UserName,
 | 
			
		||||
		repo_module.EnvPusherEmail+"="+results.UserEmail,
 | 
			
		||||
		repo_module.EnvPusherID+"="+strconv.FormatInt(results.UserID, 10),
 | 
			
		||||
		repo_module.EnvRepoID+"="+strconv.FormatInt(results.RepoID, 10),
 | 
			
		||||
		repo_module.EnvPRID+"="+fmt.Sprintf("%d", 0),
 | 
			
		||||
		repo_module.EnvDeployKeyID+"="+fmt.Sprintf("%d", results.DeployKeyID),
 | 
			
		||||
		repo_module.EnvKeyID+"="+fmt.Sprintf("%d", results.KeyID),
 | 
			
		||||
		repo_module.EnvAppURL+"="+setting.AppURL,
 | 
			
		||||
	)
 | 
			
		||||
	// to avoid breaking, here only use the minimal environment variables for the "gitea serv" command.
 | 
			
		||||
	// it could be re-considered whether to use the same git.CommonGitCmdEnvs() as "git" command later.
 | 
			
		||||
	gitcmd.Env = append(gitcmd.Env, git.CommonCmdServEnvs()...)
 | 
			
		||||
 | 
			
		||||
	if err = gitcmd.Run(); err != nil {
 | 
			
		||||
		return fail("Internal error", "Failed to execute git command: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user