Changes
21 changed files (+283/-190)
-
-
@@ -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) }
-
-
-
@@ -274,8 +274,8 @@ func prepareTestEnv(t testing.TB, skip ...int) func() {deferFn := PrintCurrentTest(t, ourSkip) assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, git.InitWithConfigSync(context.Background())) ownerDirs, err := os.ReadDir(setting.RepoRootPath) if err != nil { assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
-
@@ -576,6 +576,7 @@ func resetFixtures(t *testing.T) {assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, git.InitWithConfigSync(context.Background())) ownerDirs, err := os.ReadDir(setting.RepoRootPath) if err != nil { assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
-
-
-
@@ -62,6 +62,7 @@ func initMigrationTest(t *testing.T) func() {assert.True(t, len(setting.RepoRootPath) != 0) assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, git.InitWithConfigSync(context.Background())) ownerDirs, err := os.ReadDir(setting.RepoRootPath) if err != nil { assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
-
-
-
@@ -202,9 +202,8 @@ func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.EnourSkip += skip deferFn := PrintCurrentTest(t, ourSkip) assert.NoError(t, os.RemoveAll(setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath)) assert.NoError(t, git.InitWithConfigSync(context.Background())) ownerDirs, err := os.ReadDir(setting.RepoRootPath) if err != nil { assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
-
-
-
@@ -14,6 +14,7 @@ import ("code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util"
-
@@ -116,6 +117,9 @@ func MainTest(m *testing.M, testOpts *TestOptions) {if err = CopyDir(filepath.Join(testOpts.GiteaRootPath, "integrations", "gitea-repositories-meta"), setting.RepoRootPath); err != nil { fatalTestError("util.CopyDir: %v\n", err) } if err = git.InitWithConfigSync(context.Background()); err != nil { fatalTestError("git.Init: %v\n", err) } ownerDirs, err := os.ReadDir(setting.RepoRootPath) if err != nil {
-
@@ -198,6 +202,7 @@ func PrepareTestEnv(t testing.TB) {assert.NoError(t, util.RemoveAll(setting.RepoRootPath)) metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta") assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath)) assert.NoError(t, git.InitWithConfigSync(context.Background())) ownerDirs, err := os.ReadDir(setting.RepoRootPath) assert.NoError(t, err)
-
-
-
@@ -8,6 +8,7 @@ package gitimport ( "bytes" "context" "errors" "fmt" "io" "os"
-
@@ -104,6 +105,25 @@ type RunOpts struct {PipelineFunc func(context.Context, context.CancelFunc) error } // CommonGitCmdEnvs returns the common environment variables for a "git" command. func CommonGitCmdEnvs() []string { // at the moment, do not set "GIT_CONFIG_NOSYSTEM", users may have put some configs like "receive.certNonceSeed" in it return []string{ fmt.Sprintf("LC_ALL=%s", DefaultLocale), "GIT_TERMINAL_PROMPT=0", // avoid prompting for credentials interactively, supported since git v2.3 "GIT_NO_REPLACE_OBJECTS=1", // ignore replace references (https://git-scm.com/docs/git-replace) "HOME=" + HomeDir(), // make Gitea use internal git config only, to prevent conflicts with user's git config } } // CommonCmdServEnvs is like CommonGitCmdEnvs but it only returns minimal required environment variables for the "gitea serv" command func CommonCmdServEnvs() []string { return []string{ "GIT_NO_REPLACE_OBJECTS=1", // ignore replace references (https://git-scm.com/docs/git-replace) "HOME=" + HomeDir(), // make Gitea use internal git config only, to prevent conflicts with user's git config } } // Run runs the command with the RunOpts func (c *Command) Run(opts *RunOpts) error { if opts == nil {
-
@@ -148,16 +168,8 @@ func (c *Command) Run(opts *RunOpts) error {cmd.Env = opts.Env } cmd.Env = append( cmd.Env, fmt.Sprintf("LC_ALL=%s", DefaultLocale), // avoid prompting for credentials interactively, supported since git v2.3 "GIT_TERMINAL_PROMPT=0", // ignore replace references (https://git-scm.com/docs/git-replace) "GIT_NO_REPLACE_OBJECTS=1", ) process.SetSysProcAttribute(cmd) cmd.Env = append(cmd.Env, CommonGitCmdEnvs()...) cmd.Dir = opts.Dir cmd.Stdout = opts.Stdout cmd.Stderr = opts.Stderr
-
@@ -184,7 +196,9 @@ func (c *Command) Run(opts *RunOpts) error {type RunStdError interface { error Unwrap() error Stderr() string IsExitCode(code int) bool } type runStdError struct {
-
@@ -209,6 +223,14 @@ func (r *runStdError) Stderr() string {return r.stderr } func (r *runStdError) IsExitCode(code int) bool { var exitError *exec.ExitError if errors.As(r.err, &exitError) { return exitError.ExitCode() == code } return false } func bytesToString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) // that's what Golang's strings.Builder.String() does (go/src/strings/builder.go) }
-
-
-
@@ -398,11 +398,6 @@ func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {// GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only') func (c *Commit) GetBranchName() (string, error) { err := LoadGitVersion() if err != nil { return "", fmt.Errorf("Git version missing: %v", err) } args := []string{ "name-rev", }
-
-
-
@@ -10,11 +10,13 @@ import ("fmt" "os" "os/exec" "path/filepath" "runtime" "strings" "sync" "time" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "github.com/hashicorp/go-version"
-
@@ -32,38 +34,33 @@ var (GitExecutable = "git" // DefaultContext is the default context to run git commands in // will be overwritten by Init with HammerContext // will be overwritten by InitWithConfigSync with HammerContext DefaultContext = context.Background() gitVersion *version.Version // SupportProcReceive version >= 2.29.0 SupportProcReceive bool ) // LocalVersion returns current Git version from shell. func LocalVersion() (*version.Version, error) { if err := LoadGitVersion(); err != nil { return nil, err } return gitVersion, nil } // initMutex is used to avoid Golang's data race error. see the comments below. initMutex sync.Mutex gitVersion *version.Version ) // LoadGitVersion returns current Git version from shell. func LoadGitVersion() error { // loadGitVersion returns current Git version from shell. Internal usage only. func loadGitVersion() (*version.Version, error) { // doesn't need RWMutex because its exec by Init() if gitVersion != nil { return nil return gitVersion, nil } stdout, _, runErr := NewCommand(context.Background(), "version").RunStdString(nil) stdout, _, runErr := NewCommand(DefaultContext, "version").RunStdString(nil) if runErr != nil { return runErr return nil, runErr } fields := strings.Fields(stdout) if len(fields) < 3 { return fmt.Errorf("not enough output: %s", stdout) return nil, fmt.Errorf("invalid git version output: %s", stdout) } var versionString string
-
@@ -78,7 +75,7 @@ func LoadGitVersion() error {var err error gitVersion, err = version.NewVersion(versionString) return err return gitVersion, err } // SetExecutablePath changes the path of git executable and checks the file permission and version.
-
@@ -93,7 +90,7 @@ func SetExecutablePath(path string) error {} GitExecutable = absPath err = LoadGitVersion() _, err = loadGitVersion() if err != nil { return fmt.Errorf("unable to load git version: %w", err) }
-
@@ -120,7 +117,10 @@ func SetExecutablePath(path string) error {// VersionInfo returns git version information func VersionInfo() string { format := "Git Version: %s" if gitVersion == nil { return "(git not found)" } format := "%s" args := []interface{}{gitVersion.Original()} // Since git wire protocol has been released from git v2.18 if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
-
@@ -131,8 +131,33 @@ func VersionInfo() string {return fmt.Sprintf(format, args...) } // Init initializes git module func Init(ctx context.Context) error { // InitSimple initializes git module with a very simple step, no config changes, no global command arguments. // This method doesn't change anything to filesystem func InitSimple(ctx context.Context) error { initMutex.Lock() defer initMutex.Unlock() return initSimpleInternal(ctx) } // HomeDir is the home dir for git to store the global config file used by Gitea internally func HomeDir() string { if setting.RepoRootPath == "" { // TODO: now, some unit test code call the git module directly without initialization, which is incorrect. // at the moment, we just use a temp HomeDir to prevent from conflicting with user's git config // in the future, the git module should be initialized first before use. tmpHomeDir := filepath.Join(os.TempDir(), "gitea-temp-home") log.Error("Git's HomeDir is empty (RepoRootPath is empty), the git module is not initialized correctly, using a temp HomeDir (%s) temporarily", tmpHomeDir) return tmpHomeDir } return setting.RepoRootPath } func initSimpleInternal(ctx context.Context) error { // at the moment, when running integration tests, the git.InitXxx would be called twice. // one is called by the GlobalInitInstalled, one is called by TestMain. // so the init functions should be protected by a mutex to avoid Golang's data race error. DefaultContext = ctx if setting.Git.Timeout.Default > 0 {
-
@@ -146,6 +171,23 @@ func Init(ctx context.Context) error {// force cleanup args globalCommandArgs = []string{} return nil } // InitWithConfigSync initializes git module. This method may create directories or write files into filesystem func InitWithConfigSync(ctx context.Context) error { initMutex.Lock() defer initMutex.Unlock() err := initSimpleInternal(ctx) if err != nil { return err } if err = os.MkdirAll(setting.RepoRootPath, os.ModePerm); err != nil { return fmt.Errorf("unable to create directory %s, err: %w", setting.RepoRootPath, err) } if CheckGitVersionAtLeast("2.9") == nil { // Explicitly disable credential helper, otherwise Git credentials might leak globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
-
@@ -161,68 +203,71 @@ func Init(ctx context.Context) error {globalCommandArgs = append(globalCommandArgs, "-c", "uploadpack.allowfilter=true", "-c", "uploadpack.allowAnySHA1InWant=true") } // Save current git version on init to gitVersion otherwise it would require an RWMutex if err := LoadGitVersion(); err != nil { return err } // Git requires setting user.name and user.email in order to commit changes - if they're not set just add some defaults for configKey, defaultValue := range map[string]string{"user.name": "Gitea", "user.email": "gitea@fake.local"} { if err := checkAndSetConfig(configKey, defaultValue, false); err != nil { // Git requires setting user.name and user.email in order to commit changes - old comment: "if they're not set just add some defaults" // TODO: need to confirm whether users really need to change these values manually. It seems that these values are dummy only and not really used. // If these values are not really used, then they can be set (overwritten) directly without considering about existence. for configKey, defaultValue := range map[string]string{ "user.name": "Gitea", "user.email": "gitea@fake.local", } { if err := configSetNonExist(configKey, defaultValue); err != nil { return err } } // Set git some configurations - these must be set to these values for gitea to work correctly if err := checkAndSetConfig("core.quotePath", "false", true); err != nil { if err := configSet("core.quotePath", "false"); err != nil { return err } if CheckGitVersionAtLeast("2.10") == nil { if err := checkAndSetConfig("receive.advertisePushOptions", "true", true); err != nil { if err := configSet("receive.advertisePushOptions", "true"); err != nil { return err } } if CheckGitVersionAtLeast("2.18") == nil { if err := checkAndSetConfig("core.commitGraph", "true", true); err != nil { if err := configSet("core.commitGraph", "true"); err != nil { return err } if err := checkAndSetConfig("gc.writeCommitGraph", "true", true); err != nil { if err := configSet("gc.writeCommitGraph", "true"); err != nil { return err } } if CheckGitVersionAtLeast("2.29") == nil { // set support for AGit flow if err := checkAndAddConfig("receive.procReceiveRefs", "refs/for"); err != nil { if err := configAddNonExist("receive.procReceiveRefs", "refs/for"); err != nil { return err } SupportProcReceive = true } else { if err := checkAndRemoveConfig("receive.procReceiveRefs", "refs/for"); err != nil { if err := configUnsetAll("receive.procReceiveRefs", "refs/for"); err != nil { return err } SupportProcReceive = false } if runtime.GOOS == "windows" { if err := checkAndSetConfig("core.longpaths", "true", true); err != nil { if err := configSet("core.longpaths", "true"); err != nil { return err } } if setting.Git.DisableCoreProtectNTFS { if err := checkAndSetConfig("core.protectntfs", "false", true); err != nil { if setting.Git.DisableCoreProtectNTFS { err = configSet("core.protectNTFS", "false") } else { err = configUnsetAll("core.protectNTFS", "false") } if err != nil { return err } globalCommandArgs = append(globalCommandArgs, "-c", "core.protectntfs=false") } return nil } // CheckGitVersionAtLeast check git version is at least the constraint version func CheckGitVersionAtLeast(atLeast string) error { if err := LoadGitVersion(); err != nil { if _, err := loadGitVersion(); err != nil { return err } atLeastVersion, err := version.NewVersion(atLeast)
-
@@ -235,75 +280,75 @@ func CheckGitVersionAtLeast(atLeast string) error {return nil } func checkAndSetConfig(key, defaultValue string, forceToDefault bool) error { stdout, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", key) if err != nil { perr, ok := err.(*process.Error) if !ok { return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) } eerr, ok := perr.Err.(*exec.ExitError) if !ok || eerr.ExitCode() != 1 { return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) } func configSet(key, value string) error { stdout, _, err := NewCommand(DefaultContext, "config", "--get", key).RunStdString(nil) if err != nil && !err.IsExitCode(1) { return fmt.Errorf("failed to get git config %s, err: %w", key, err) } currValue := strings.TrimSpace(stdout) if currValue == defaultValue || (!forceToDefault && len(currValue) > 0) { if currValue == value { return nil } if _, stderr, err = process.GetManager().Exec(fmt.Sprintf("git.Init(set %s)", key), "git", "config", "--global", key, defaultValue); err != nil { return fmt.Errorf("Failed to set git %s(%s): %s", key, err, stderr) _, _, err = NewCommand(DefaultContext, "config", "--global", key, value).RunStdString(nil) if err != nil { return fmt.Errorf("failed to set git global config %s, err: %w", key, err) } return nil } func checkAndAddConfig(key, value string) error { _, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", key, value) if err != nil { perr, ok := err.(*process.Error) if !ok { return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) } eerr, ok := perr.Err.(*exec.ExitError) if !ok || eerr.ExitCode() != 1 { return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) } if eerr.ExitCode() == 1 { if _, stderr, err = process.GetManager().Exec(fmt.Sprintf("git.Init(set %s)", key), "git", "config", "--global", "--add", key, value); err != nil { return fmt.Errorf("Failed to set git %s(%s): %s", key, err, stderr) } return nil func configSetNonExist(key, value string) error { _, _, err := NewCommand(DefaultContext, "config", "--get", key).RunStdString(nil) if err == nil { // already exist return nil } if err.IsExitCode(1) { // not exist, set new config _, _, err = NewCommand(DefaultContext, "config", "--global", key, value).RunStdString(nil) if err != nil { return fmt.Errorf("failed to set git global config %s, err: %w", key, err) } return nil } return nil return fmt.Errorf("failed to get git config %s, err: %w", key, err) } func checkAndRemoveConfig(key, value string) error { _, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", key, value) if err != nil { perr, ok := err.(*process.Error) if !ok { return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) } eerr, ok := perr.Err.(*exec.ExitError) if !ok || eerr.ExitCode() != 1 { return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) } if eerr.ExitCode() == 1 { return nil func configAddNonExist(key, value string) error { _, _, err := NewCommand(DefaultContext, "config", "--fixed-value", "--get", key, value).RunStdString(nil) if err == nil { // already exist return nil } if err.IsExitCode(1) { // not exist, add new config _, _, err = NewCommand(DefaultContext, "config", "--global", "--add", key, value).RunStdString(nil) if err != nil { return fmt.Errorf("failed to add git global config %s, err: %w", key, err) } return nil } return fmt.Errorf("failed to get git config %s, err: %w", key, err) } if _, stderr, err = process.GetManager().Exec(fmt.Sprintf("git.Init(set %s)", key), "git", "config", "--global", "--unset-all", key, value); err != nil { return fmt.Errorf("Failed to set git %s(%s): %s", key, err, stderr) func configUnsetAll(key, value string) error { _, _, err := NewCommand(DefaultContext, "config", "--get", key).RunStdString(nil) if err == nil { // exist, need to remove _, _, err = NewCommand(DefaultContext, "config", "--global", "--fixed-value", "--unset-all", key, value).RunStdString(nil) if err != nil { return fmt.Errorf("failed to unset git global config %s, err: %w", key, err) } return nil } return nil if err.IsExitCode(1) { // not exist return nil } return fmt.Errorf("failed to get git config %s, err: %w", key, err) } // Fsck verifies the connectivity and validity of the objects in the database
-
-
-
@@ -8,23 +8,74 @@ import ("context" "fmt" "os" "strings" "testing" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" ) func fatalTestError(fmtStr string, args ...interface{}) { fmt.Fprintf(os.Stderr, fmtStr, args...) os.Exit(1) func testRun(m *testing.M) error { _ = log.NewLogger(1000, "console", "console", `{"level":"trace","stacktracelevel":"NONE","stderr":true}`) repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos") if err != nil { return fmt.Errorf("unable to create temp dir: %w", err) } defer util.RemoveAll(repoRootPath) setting.RepoRootPath = repoRootPath if err = InitWithConfigSync(context.Background()); err != nil { return fmt.Errorf("failed to call Init: %w", err) } exitCode := m.Run() if exitCode != 0 { return fmt.Errorf("run test failed, ExitCode=%d", exitCode) } return nil } func TestMain(m *testing.M) { _ = log.NewLogger(1000, "console", "console", `{"level":"trace","stacktracelevel":"NONE","stderr":true}`) if err := testRun(m); err != nil { _, _ = fmt.Fprintf(os.Stderr, "Test failed: %v", err) os.Exit(1) } } if err := Init(context.Background()); err != nil { fatalTestError("Init failed: %v", err) func TestGitConfig(t *testing.T) { gitConfigContains := func(sub string) bool { if b, err := os.ReadFile(HomeDir() + "/.gitconfig"); err == nil { return strings.Contains(string(b), sub) } return false } exitStatus := m.Run() os.Exit(exitStatus) assert.False(t, gitConfigContains("key-a")) assert.NoError(t, configSetNonExist("test.key-a", "val-a")) assert.True(t, gitConfigContains("key-a = val-a")) assert.NoError(t, configSetNonExist("test.key-a", "val-a-changed")) assert.False(t, gitConfigContains("key-a = val-a-changed")) assert.NoError(t, configSet("test.key-a", "val-a-changed")) assert.True(t, gitConfigContains("key-a = val-a-changed")) assert.NoError(t, configAddNonExist("test.key-b", "val-b")) assert.True(t, gitConfigContains("key-b = val-b")) assert.NoError(t, configAddNonExist("test.key-b", "val-2b")) assert.True(t, gitConfigContains("key-b = val-b")) assert.True(t, gitConfigContains("key-b = val-2b")) assert.NoError(t, configUnsetAll("test.key-b", "val-b")) assert.False(t, gitConfigContains("key-b = val-b")) assert.True(t, gitConfigContains("key-b = val-2b")) assert.NoError(t, configUnsetAll("test.key-b", "val-2b")) assert.False(t, gitConfigContains("key-b = val-2b")) }
-
-
-
@@ -18,12 +18,6 @@ func CheckLFSVersion() {if setting.LFS.StartServer { // Disable LFS client hooks if installed for the current OS user // Needs at least git v2.1.2 err := LoadGitVersion() if err != nil { logger.Fatal("Error retrieving git version: %v", err) } if CheckGitVersionAtLeast("2.1.2") != nil { setting.LFS.StartServer = false logger.Error("LFS server support needs at least Git v2.1.2")
-
-
-
@@ -11,10 +11,6 @@ import (// GetRemoteAddress returns the url of a specific remote of the repository. func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*url.URL, error) { err := LoadGitVersion() if err != nil { return nil, err } var cmd *Command if CheckGitVersionAtLeast("2.7") == nil { cmd = NewCommand(ctx, "remote", "get-url", remoteName)
-
-
-
@@ -28,11 +28,6 @@ type CheckAttributeOpts struct {// CheckAttribute return the Blame object of file func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[string]string, error) { err := LoadGitVersion() if err != nil { return nil, fmt.Errorf("git version missing: %v", err) } env := []string{} if len(opts.IndexFile) > 0 && CheckGitVersionAtLeast("1.7.8") == nil {
-
@@ -126,7 +121,7 @@ type CheckAttributeReader struct {cancel context.CancelFunc } // Init initializes the cmd // Init initializes the CheckAttributeReader func (c *CheckAttributeReader) Init(ctx context.Context) error { cmdArgs := []string{"check-attr", "--stdin", "-z"}
-
-
-
@@ -24,11 +24,6 @@ type CommitTreeOpts struct {// CommitTree creates a commit from a given tree id for the user with provided message func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opts CommitTreeOpts) (SHA1, error) { err := LoadGitVersion() if err != nil { return SHA1{}, err } commitTimeStr := time.Now().Format(time.RFC3339) // Because this may call hooks we should pass in the environment
-
@@ -60,14 +55,13 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, optstdout := new(bytes.Buffer) stderr := new(bytes.Buffer) err = cmd.Run(&RunOpts{ err := cmd.Run(&RunOpts{ Env: env, Dir: repo.Path, Stdin: messageBytes, Stdout: stdout, Stderr: stderr, }) if err != nil { return SHA1{}, ConcatenateError(err, stderr.String()) }
-
-
-
@@ -30,7 +30,7 @@ func TestMain(m *testing.M) {} func TestRepoStatsIndex(t *testing.T) { if err := git.Init(context.Background()); !assert.NoError(t, err) { if err := git.InitWithConfigSync(context.Background()); !assert.NoError(t, err) { return }
-
-
-
@@ -317,11 +317,6 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposireturn fmt.Errorf("git add --all: %v", err) } err = git.LoadGitVersion() if err != nil { return fmt.Errorf("Unable to get git version: %v", err) } args := []string{ "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email), "-m", "Initial commit",
-
-
-
@@ -182,6 +182,7 @@ func FileURLToPath(u *url.URL) (string, error) {// it returns error when the variable does not exist. func HomeDir() (home string, err error) { // TODO: some users run Gitea with mismatched uid and "HOME=xxx" (they set HOME=xxx by environment manually) // TODO: when running gitea as a sub command inside git, the HOME directory is not the user's home directory // so at the moment we can not use `user.Current().HomeDir` if isOSWindows() { home = os.Getenv("USERPROFILE")
-
-
-
@@ -102,8 +102,8 @@ func GlobalInitInstalled(ctx context.Context) {log.Fatal("Gitea is not installed") } mustInitCtx(ctx, git.Init) log.Info(git.VersionInfo()) mustInitCtx(ctx, git.InitWithConfigSync) log.Info("Git Version: %s (home: %s)", git.VersionInfo(), git.HomeDir()) git.CheckLFSVersion() log.Info("AppPath: %s", setting.AppPath)
-
-
-
@@ -247,9 +247,8 @@ func Config(ctx *context.Context) {ctx.Data["DisableRouterLog"] = setting.DisableRouterLog ctx.Data["RunUser"] = setting.RunUser ctx.Data["RunMode"] = util.ToTitleCase(setting.RunMode) if version, err := git.LocalVersion(); err == nil { ctx.Data["GitVersion"] = version.Original() } ctx.Data["GitVersion"] = git.VersionInfo() ctx.Data["RepoRootPath"] = setting.RepoRootPath ctx.Data["CustomRootPath"] = setting.CustomPath ctx.Data["StaticRootPath"] = setting.StaticRootPath
-
-
-
@@ -421,12 +421,9 @@ func LFSPointerFiles(ctx *context.Context) {return } ctx.Data["PageIsSettingsLFS"] = true err := git.LoadGitVersion() if err != nil { log.Fatal("Error retrieving git version: %v", err) } ctx.Data["LFSFilesLink"] = ctx.Repo.RepoLink + "/settings/lfs" var err error err = func() error { pointerChan := make(chan lfs.PointerBlob) errChan := make(chan error, 1)
-
-
-
@@ -223,12 +223,6 @@ func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, b// rawMerge perform the merge operation without changing any pull information in database func rawMerge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) (string, error) { err := git.LoadGitVersion() if err != nil { log.Error("git.LoadGitVersion: %v", err) return "", fmt.Errorf("Unable to get git version: %v", err) } // Clone base repo. tmpBasePath, err := createTemporaryRepo(ctx, pr) if err != nil {
-
-
-
@@ -229,11 +229,6 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(parent string, author, coauthorSig := author.NewGitSig() committerSig := committer.NewGitSig() err := git.LoadGitVersion() if err != nil { return "", fmt.Errorf("Unable to get git version: %v", err) } // Because this may call hooks we should pass in the environment env := append(os.Environ(), "GIT_AUTHOR_NAME="+authorSig.Name,
-