@ -15,7 +15,6 @@ import (
"regexp"
"regexp"
"runtime"
"runtime"
"strings"
"strings"
"sync"
"time"
"time"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/log"
@ -24,8 +23,8 @@ import (
"github.com/hashicorp/go-version"
"github.com/hashicorp/go-version"
)
)
// GitVersionRequired is the minimum Git version required
// RequiredVersion is the minimum Git version required
const GitVersionRequired = "2.0.0"
const RequiredVersion = "2.0.0"
var (
var (
// GitExecutable is the command name of git
// GitExecutable is the command name of git
@ -43,7 +42,7 @@ var (
// loadGitVersion returns current Git version from shell. Internal usage only.
// loadGitVersion returns current Git version from shell. Internal usage only.
func loadGitVersion ( ) ( * version . Version , error ) {
func loadGitVersion ( ) ( * version . Version , error ) {
// doesn't need RWMutex because its exec by Init()
// doesn't need RWMutex because it' s executed by Init()
if gitVersion != nil {
if gitVersion != nil {
return gitVersion , nil
return gitVersion , nil
}
}
@ -90,7 +89,7 @@ func SetExecutablePath(path string) error {
return fmt . Errorf ( "unable to load git version: %w" , err )
return fmt . Errorf ( "unable to load git version: %w" , err )
}
}
versionRequired , err := version . NewVersion ( GitVersionRequired )
versionRequired , err := version . NewVersion ( RequiredVersion )
if err != nil {
if err != nil {
return err
return err
}
}
@ -104,7 +103,7 @@ func SetExecutablePath(path string) error {
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
}
}
}
}
return fmt . Errorf ( "installed git version %q is not supported, Gitea requires git version >= %q, %s" , gitVersion . Original ( ) , GitVersionRequired , moreHint )
return fmt . Errorf ( "installed git version %q is not supported, Gitea requires git version >= %q, %s" , gitVersion . Original ( ) , RequiredVersion , moreHint )
}
}
return nil
return nil
@ -131,7 +130,7 @@ func checkInit() error {
return errors . New ( "unable to init Git's HomeDir, incorrect initialization of the setting and git modules" )
return errors . New ( "unable to init Git's HomeDir, incorrect initialization of the setting and git modules" )
}
}
if DefaultContext != nil {
if DefaultContext != nil {
log . Warn ( "git module has been initialized already, duplicate init should be fixed " )
log . Warn ( "git module has been initialized already, duplicate init may work but it's better to fix it " )
}
}
return nil
return nil
}
}
@ -140,7 +139,7 @@ func checkInit() error {
func HomeDir ( ) string {
func HomeDir ( ) string {
if setting . Git . HomePath == "" {
if setting . Git . HomePath == "" {
// strict check, make sure the git module is initialized correctly.
// 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 us ers.
// attention: when the git module is called in gitea sub-command (serv/hook), the log module might not obviously show messages to users/develop ers.
// 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.
// 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 ( "Unable to init Git's HomeDir, incorrect initialization of the setting and git modules" )
log . Fatal ( "Unable to init Git's HomeDir, incorrect initialization of the setting and git modules" )
return ""
return ""
@ -149,14 +148,14 @@ func HomeDir() string {
}
}
// InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
// 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
// This method doesn't change anything to filesystem. At the moment, it is only used by some Gitea sub-commands.
// 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 {
func InitSimple ( ctx context . Context ) error {
if err := checkInit ( ) ; err != nil {
if err := checkInit ( ) ; err != nil {
return err
return err
}
}
DefaultContext = ctx
DefaultContext = ctx
globalCommandArgs = nil
if setting . Git . Timeout . Default > 0 {
if setting . Git . Timeout . Default > 0 {
defaultCommandExecutionTimeout = time . Duration ( setting . Git . Timeout . Default ) * time . Second
defaultCommandExecutionTimeout = time . Duration ( setting . Git . Timeout . Default ) * time . Second
@ -165,17 +164,13 @@ func InitSimple(ctx context.Context) error {
return SetExecutablePath ( setting . Git . Path )
return SetExecutablePath ( setting . Git . Path )
}
}
var initOnce sync . Once
// InitFull initializes git module with version check and change global variables, sync gitconfig.
// It should only be called once at the beginning of the program initialization (TestMain/GlobalInitInstalled) as this code makes unsynchronized changes to variables.
// InitOnceWithSync initializes git module with version check and change global variables, sync gitconfig.
func InitFull ( ctx context . Context ) ( err error ) {
// 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 {
if err = checkInit ( ) ; err != nil {
return err
return err
}
}
initOnce . Do ( func ( ) {
if err = InitSimple ( ctx ) ; err != nil {
if err = InitSimple ( ctx ) ; err != nil {
return
return
}
}
@ -201,10 +196,14 @@ func InitOnceWithSync(ctx context.Context) (err error) {
}
}
SupportProcReceive = CheckGitVersionAtLeast ( "2.29" ) == nil
SupportProcReceive = CheckGitVersionAtLeast ( "2.29" ) == nil
} )
if err != nil {
if setting . LFS . StartServer {
return err
if CheckGitVersionAtLeast ( "2.1.2" ) != nil {
return errors . New ( "LFS server support requires Git >= 2.1.2" )
}
globalCommandArgs = append ( globalCommandArgs , "-c" , "filter.lfs.required=" , "-c" , "filter.lfs.smudge=" , "-c" , "filter.lfs.clean=" )
}
}
return syncGitConfig ( )
return syncGitConfig ( )
}
}