aboutsummaryrefslogtreecommitdiff
path: root/modules/git/git.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/git/git.go')
-rw-r--r--modules/git/git.go73
1 files changed, 48 insertions, 25 deletions
diff --git a/modules/git/git.go b/modules/git/git.go
index 43901b3c1..3a3663995 100644
--- a/modules/git/git.go
+++ b/modules/git/git.go
@@ -7,35 +7,31 @@ package git
import (
"context"
+ "errors"
"fmt"
"os"
"os/exec"
- "path/filepath"
"runtime"
"strings"
"sync"
"time"
- //"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/hashicorp/go-version"
)
-var (
- // GitVersionRequired is the minimum Git version required
- // At the moment, all code for git 1.x are not changed, if some users want to test with old git client
- // or bypass the check, they still have a chance to edit this variable manually.
- // If everything works fine, the code for git 1.x could be removed in a separate PR before 1.17 frozen.
- GitVersionRequired = "2.0.0"
+// GitVersionRequired is the minimum Git version required
+const GitVersionRequired = "2.0.0"
+var (
// GitExecutable is the command name of git
// Could be updated to an absolute path while initialization
GitExecutable = "git"
- // DefaultContext is the default context to run git commands in
- // will be overwritten by InitXxx with HammerContext
- DefaultContext = context.Background()
+ // DefaultContext is the default context to run git commands in, must be initialized by git.InitXxx
+ DefaultContext context.Context
// SupportProcReceive version >= 2.29.0
SupportProcReceive bool
@@ -128,36 +124,43 @@ func VersionInfo() string {
return fmt.Sprintf(format, args...)
}
+func checkInit() error {
+ if setting.RepoRootPath == "" {
+ return errors.New("can not init Git's HomeDir (RepoRootPath is empty), the setting and git modules are not initialized correctly")
+ }
+ if DefaultContext != nil {
+ log.Warn("git module has been initialized already, duplicate init should be fixed")
+ }
+ return nil
+}
+
// 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
+ // strict check, make sure the git module is initialized correctly.
+ // attention: when the git module is called in gitea sub-command (serv/hook), the log module is not able to show messages to users.
+ // for example: if there is gitea git hook code calling git.NewCommand before git.InitXxx, the integration test won't show the real failure reasons.
+ log.Fatal("can not get Git's HomeDir (RepoRootPath is empty), the setting and git modules are not initialized correctly")
+ return ""
}
return setting.RepoRootPath
}
// InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
// This method doesn't change anything to filesystem. At the moment, it is only used by "git serv" sub-command, no data-race
+// However, in integration test, the sub-command function may be called in the current process, so the InitSimple would be called multiple times, too
func InitSimple(ctx context.Context) error {
+ if err := checkInit(); err != nil {
+ return err
+ }
+
DefaultContext = ctx
if setting.Git.Timeout.Default > 0 {
defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second
}
- if err := SetExecutablePath(setting.Git.Path); err != nil {
- return err
- }
-
- // force cleanup args
- globalCommandArgs = []string{}
-
- return nil
+ return SetExecutablePath(setting.Git.Path)
}
var initOnce sync.Once
@@ -166,6 +169,10 @@ var initOnce sync.Once
// This method will update the global variables ONLY ONCE (just like git.CheckLFSVersion -- which is not ideal too),
// otherwise there will be data-race problem at the moment.
func InitOnceWithSync(ctx context.Context) (err error) {
+ if err = checkInit(); err != nil {
+ return err
+ }
+
initOnce.Do(func() {
err = InitSimple(ctx)
if err != nil {
@@ -231,6 +238,9 @@ func syncGitConfig() (err error) {
if err := configSet("gc.writeCommitGraph", "true"); err != nil {
return err
}
+ if err := configSet("fetch.writeCommitGraph", "true"); err != nil {
+ return err
+ }
}
if SupportProcReceive {
@@ -244,6 +254,19 @@ func syncGitConfig() (err error) {
}
}
+ // Due to CVE-2022-24765, git now denies access to git directories which are not owned by current user
+ // however, some docker users and samba users find it difficult to configure their systems so that Gitea's git repositories are owned by the Gitea user. (Possibly Windows Service users - but ownership in this case should really be set correctly on the filesystem.)
+ // see issue: https://github.com/go-gitea/gitea/issues/19455
+ // Fundamentally the problem lies with the uid-gid-mapping mechanism for filesystems in docker on windows (and to a lesser extent samba).
+ // Docker's configuration mechanism for local filesystems provides no way of setting this mapping and although there is a mechanism for setting this uid through using cifs mounting it is complicated and essentially undocumented
+ // Thus the owner uid/gid for files on these filesystems will be marked as root.
+ // As Gitea now always use its internal git config file, and access to the git repositories is managed through Gitea,
+ // it is now safe to set "safe.directory=*" for internal usage only.
+ // Please note: the wildcard "*" is only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later
+ // Although only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later - this setting is tolerated by earlier versions
+ if err := configAddNonExist("safe.directory", "*"); err != nil {
+ return err
+ }
if runtime.GOOS == "windows" {
if err := configSet("core.longpaths", "true"); err != nil {
return err