mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Refactor legacy git init (#20376)
* merge `CheckLFSVersion` into `InitFull` (renamed from `InitWithSyncOnce`) * remove the `Once` during git init, no data-race now * for doctor sub-commands, `InitFull` should only be called in initialization stage Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
		@@ -14,6 +14,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	"code.gitea.io/gitea/models/migrations"
 | 
						"code.gitea.io/gitea/models/migrations"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/doctor"
 | 
						"code.gitea.io/gitea/modules/doctor"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/git"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -124,13 +125,18 @@ func runRecreateTable(ctx *cli.Context) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func runDoctor(ctx *cli.Context) error {
 | 
					func runDoctor(ctx *cli.Context) error {
 | 
				
			||||||
 | 
						stdCtx, cancel := installSignals()
 | 
				
			||||||
 | 
						defer cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// some doctor sub-commands need to use git command
 | 
				
			||||||
 | 
						if err := git.InitFull(stdCtx); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Silence the default loggers
 | 
						// Silence the default loggers
 | 
				
			||||||
	log.DelNamedLogger("console")
 | 
						log.DelNamedLogger("console")
 | 
				
			||||||
	log.DelNamedLogger(log.DEFAULT)
 | 
						log.DelNamedLogger(log.DEFAULT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stdCtx, cancel := installSignals()
 | 
					 | 
				
			||||||
	defer cancel()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Now setup our own
 | 
						// Now setup our own
 | 
				
			||||||
	logFile := ctx.String("log-file")
 | 
						logFile := ctx.String("log-file")
 | 
				
			||||||
	if !ctx.IsSet("log-file") {
 | 
						if !ctx.IsSet("log-file") {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,6 @@ func runPR() {
 | 
				
			|||||||
	setting.RunUser = curUser.Username
 | 
						setting.RunUser = curUser.Username
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Printf("[PR] Loading fixtures data ...\n")
 | 
						log.Printf("[PR] Loading fixtures data ...\n")
 | 
				
			||||||
	gitea_git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	//models.LoadConfigs()
 | 
						//models.LoadConfigs()
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
		setting.Database.Type = "sqlite3"
 | 
							setting.Database.Type = "sqlite3"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -156,11 +156,6 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
 | 
				
			|||||||
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
 | 
					func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
 | 
				
			||||||
	t.Run("LFS", func(t *testing.T) {
 | 
						t.Run("LFS", func(t *testing.T) {
 | 
				
			||||||
		defer PrintCurrentTest(t)()
 | 
							defer PrintCurrentTest(t)()
 | 
				
			||||||
		git.CheckLFSVersion()
 | 
					 | 
				
			||||||
		if !setting.LFS.StartServer {
 | 
					 | 
				
			||||||
			t.Skip()
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		prefix := "lfs-data-file-"
 | 
							prefix := "lfs-data-file-"
 | 
				
			||||||
		err := git.NewCommand(git.DefaultContext, "lfs").AddArguments("install").Run(&git.RunOpts{Dir: dstPath})
 | 
							err := git.NewCommand(git.DefaultContext, "lfs").AddArguments("install").Run(&git.RunOpts{Dir: dstPath})
 | 
				
			||||||
		assert.NoError(t, err)
 | 
							assert.NoError(t, err)
 | 
				
			||||||
@@ -226,7 +221,6 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
 | 
				
			|||||||
		resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
 | 
							resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
 | 
				
			||||||
		assert.Equal(t, littleSize, resp.Length)
 | 
							assert.Equal(t, littleSize, resp.Length)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		git.CheckLFSVersion()
 | 
					 | 
				
			||||||
		if setting.LFS.StartServer {
 | 
							if setting.LFS.StartServer {
 | 
				
			||||||
			req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
 | 
								req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
 | 
				
			||||||
			resp := session.MakeRequest(t, req, http.StatusOK)
 | 
								resp := session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
@@ -268,12 +262,9 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
 | 
				
			|||||||
		resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
 | 
							resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
 | 
				
			||||||
		assert.Equal(t, littleSize, resp.Length)
 | 
							assert.Equal(t, littleSize, resp.Length)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		git.CheckLFSVersion()
 | 
							req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
 | 
				
			||||||
		if setting.LFS.StartServer {
 | 
							resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
 | 
				
			||||||
			req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
 | 
							assert.Equal(t, littleSize, resp.Length)
 | 
				
			||||||
			resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
 | 
					 | 
				
			||||||
			assert.Equal(t, littleSize, resp.Length)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !testing.Short() {
 | 
							if !testing.Short() {
 | 
				
			||||||
			req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
 | 
								req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -175,10 +175,9 @@ func initIntegrationTest() {
 | 
				
			|||||||
	setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
 | 
						setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
 | 
				
			||||||
	_ = util.RemoveAll(repo_module.LocalCopyPath())
 | 
						_ = util.RemoveAll(repo_module.LocalCopyPath())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := git.InitOnceWithSync(context.Background()); err != nil {
 | 
						if err := git.InitFull(context.Background()); err != nil {
 | 
				
			||||||
		log.Fatal("git.InitOnceWithSync: %v", err)
 | 
							log.Fatal("git.InitOnceWithSync: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setting.InitDBConfig()
 | 
						setting.InitDBConfig()
 | 
				
			||||||
	if err := storage.Init(); err != nil {
 | 
						if err := storage.Init(); err != nil {
 | 
				
			||||||
@@ -285,7 +284,6 @@ func prepareTestEnv(t testing.TB, skip ...int) func() {
 | 
				
			|||||||
	assert.NoError(t, unittest.LoadFixtures())
 | 
						assert.NoError(t, unittest.LoadFixtures())
 | 
				
			||||||
	assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
 | 
						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, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
 | 
				
			||||||
	assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
 | 
					 | 
				
			||||||
	ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
						ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
 | 
							assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
 | 
				
			||||||
@@ -586,7 +584,6 @@ func resetFixtures(t *testing.T) {
 | 
				
			|||||||
	assert.NoError(t, unittest.LoadFixtures())
 | 
						assert.NoError(t, unittest.LoadFixtures())
 | 
				
			||||||
	assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
 | 
						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, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
 | 
				
			||||||
	assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
 | 
					 | 
				
			||||||
	ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
						ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
 | 
							assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	git_model "code.gitea.io/gitea/models/git"
 | 
						git_model "code.gitea.io/gitea/models/git"
 | 
				
			||||||
	repo_model "code.gitea.io/gitea/models/repo"
 | 
						repo_model "code.gitea.io/gitea/models/repo"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/git"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/modules/json"
 | 
						"code.gitea.io/gitea/modules/json"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/lfs"
 | 
						"code.gitea.io/gitea/modules/lfs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
@@ -83,11 +82,6 @@ func checkResponseTestContentEncoding(t *testing.T, content *[]byte, resp *httpt
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetLFSSmall(t *testing.T) {
 | 
					func TestGetLFSSmall(t *testing.T) {
 | 
				
			||||||
	defer prepareTestEnv(t)()
 | 
						defer prepareTestEnv(t)()
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	if !setting.LFS.StartServer {
 | 
					 | 
				
			||||||
		t.Skip()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	content := []byte("A very small file\n")
 | 
						content := []byte("A very small file\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
 | 
						resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
 | 
				
			||||||
@@ -96,11 +90,6 @@ func TestGetLFSSmall(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetLFSLarge(t *testing.T) {
 | 
					func TestGetLFSLarge(t *testing.T) {
 | 
				
			||||||
	defer prepareTestEnv(t)()
 | 
						defer prepareTestEnv(t)()
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	if !setting.LFS.StartServer {
 | 
					 | 
				
			||||||
		t.Skip()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	content := make([]byte, web.GzipMinSize*10)
 | 
						content := make([]byte, web.GzipMinSize*10)
 | 
				
			||||||
	for i := range content {
 | 
						for i := range content {
 | 
				
			||||||
		content[i] = byte(i % 256)
 | 
							content[i] = byte(i % 256)
 | 
				
			||||||
@@ -112,11 +101,6 @@ func TestGetLFSLarge(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetLFSGzip(t *testing.T) {
 | 
					func TestGetLFSGzip(t *testing.T) {
 | 
				
			||||||
	defer prepareTestEnv(t)()
 | 
						defer prepareTestEnv(t)()
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	if !setting.LFS.StartServer {
 | 
					 | 
				
			||||||
		t.Skip()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	b := make([]byte, web.GzipMinSize*10)
 | 
						b := make([]byte, web.GzipMinSize*10)
 | 
				
			||||||
	for i := range b {
 | 
						for i := range b {
 | 
				
			||||||
		b[i] = byte(i % 256)
 | 
							b[i] = byte(i % 256)
 | 
				
			||||||
@@ -133,11 +117,6 @@ func TestGetLFSGzip(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetLFSZip(t *testing.T) {
 | 
					func TestGetLFSZip(t *testing.T) {
 | 
				
			||||||
	defer prepareTestEnv(t)()
 | 
						defer prepareTestEnv(t)()
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	if !setting.LFS.StartServer {
 | 
					 | 
				
			||||||
		t.Skip()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	b := make([]byte, web.GzipMinSize*10)
 | 
						b := make([]byte, web.GzipMinSize*10)
 | 
				
			||||||
	for i := range b {
 | 
						for i := range b {
 | 
				
			||||||
		b[i] = byte(i % 256)
 | 
							b[i] = byte(i % 256)
 | 
				
			||||||
@@ -156,11 +135,6 @@ func TestGetLFSZip(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetLFSRangeNo(t *testing.T) {
 | 
					func TestGetLFSRangeNo(t *testing.T) {
 | 
				
			||||||
	defer prepareTestEnv(t)()
 | 
						defer prepareTestEnv(t)()
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	if !setting.LFS.StartServer {
 | 
					 | 
				
			||||||
		t.Skip()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	content := []byte("123456789\n")
 | 
						content := []byte("123456789\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
 | 
						resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
 | 
				
			||||||
@@ -169,11 +143,6 @@ func TestGetLFSRangeNo(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestGetLFSRange(t *testing.T) {
 | 
					func TestGetLFSRange(t *testing.T) {
 | 
				
			||||||
	defer prepareTestEnv(t)()
 | 
						defer prepareTestEnv(t)()
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	if !setting.LFS.StartServer {
 | 
					 | 
				
			||||||
		t.Skip()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	content := []byte("123456789\n")
 | 
						content := []byte("123456789\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,8 +82,7 @@ func initMigrationTest(t *testing.T) func() {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.NoError(t, git.InitOnceWithSync(context.Background()))
 | 
						assert.NoError(t, git.InitFull(context.Background()))
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	setting.InitDBConfig()
 | 
						setting.InitDBConfig()
 | 
				
			||||||
	setting.NewLogServices(true)
 | 
						setting.NewLogServices(true)
 | 
				
			||||||
	return deferFn
 | 
						return deferFn
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,11 +66,10 @@ func TestMain(m *testing.M) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	setting.SetCustomPathAndConf("", "", "")
 | 
						setting.SetCustomPathAndConf("", "", "")
 | 
				
			||||||
	setting.LoadForTest()
 | 
						setting.LoadForTest()
 | 
				
			||||||
	if err = git.InitOnceWithSync(context.Background()); err != nil {
 | 
						if err = git.InitFull(context.Background()); err != nil {
 | 
				
			||||||
		fmt.Printf("Unable to InitOnceWithSync: %v\n", err)
 | 
							fmt.Printf("Unable to InitFull: %v\n", err)
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	setting.InitDBConfig()
 | 
						setting.InitDBConfig()
 | 
				
			||||||
	setting.NewLogServices(true)
 | 
						setting.NewLogServices(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -207,7 +206,6 @@ func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En
 | 
				
			|||||||
	deferFn := PrintCurrentTest(t, ourSkip)
 | 
						deferFn := PrintCurrentTest(t, ourSkip)
 | 
				
			||||||
	assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
 | 
						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.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
 | 
					 | 
				
			||||||
	ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
						ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
 | 
							assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -120,11 +120,9 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
 | 
				
			|||||||
		fatalTestError("util.CopyDir: %v\n", err)
 | 
							fatalTestError("util.CopyDir: %v\n", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = git.InitOnceWithSync(context.Background()); err != nil {
 | 
						if err = git.InitFull(context.Background()); err != nil {
 | 
				
			||||||
		fatalTestError("git.Init: %v\n", err)
 | 
							fatalTestError("git.Init: %v\n", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
						ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fatalTestError("unable to read the new repo root: %v\n", err)
 | 
							fatalTestError("unable to read the new repo root: %v\n", err)
 | 
				
			||||||
@@ -206,8 +204,6 @@ func PrepareTestEnv(t testing.TB) {
 | 
				
			|||||||
	assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
 | 
						assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
 | 
				
			||||||
	metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta")
 | 
						metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta")
 | 
				
			||||||
	assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
 | 
						assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
 | 
				
			||||||
	assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
						ownerDirs, err := os.ReadDir(setting.RepoRootPath)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	for _, ownerDir := range ownerDirs {
 | 
						for _, ownerDir := range ownerDirs {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,9 +30,6 @@ func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*rep
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) error {
 | 
					func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) error {
 | 
				
			||||||
	if err := git.InitOnceWithSync(ctx); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	numRepos := 0
 | 
						numRepos := 0
 | 
				
			||||||
	numPRs := 0
 | 
						numPRs := 0
 | 
				
			||||||
	numPRsUpdated := 0
 | 
						numPRsUpdated := 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -190,10 +190,6 @@ func checkDaemonExport(ctx context.Context, logger log.Logger, autofix bool) err
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) error {
 | 
					func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) error {
 | 
				
			||||||
	if err := git.InitOnceWithSync(ctx); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	numRepos := 0
 | 
						numRepos := 0
 | 
				
			||||||
	numNeedUpdate := 0
 | 
						numNeedUpdate := 0
 | 
				
			||||||
	numWritten := 0
 | 
						numWritten := 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 users.
 | 
							// attention: when the git module is called in gitea sub-command (serv/hook), the log module might not obviously show messages to users/developers.
 | 
				
			||||||
		// 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,46 +164,46 @@ 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
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// when git works with gnupg (commit signing), there should be a stable home for gnupg commands
 | 
					 | 
				
			||||||
		if _, ok := os.LookupEnv("GNUPGHOME"); !ok {
 | 
					 | 
				
			||||||
			_ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg"))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Since git wire protocol has been released from git v2.18
 | 
					 | 
				
			||||||
		if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
 | 
					 | 
				
			||||||
			globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// By default partial clones are disabled, enable them from git v2.22
 | 
					 | 
				
			||||||
		if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
 | 
					 | 
				
			||||||
			globalCommandArgs = append(globalCommandArgs, "-c", "uploadpack.allowfilter=true", "-c", "uploadpack.allowAnySHA1InWant=true")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Explicitly disable credential helper, otherwise Git credentials might leak
 | 
					 | 
				
			||||||
		if CheckGitVersionAtLeast("2.9") == nil {
 | 
					 | 
				
			||||||
			globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// when git works with gnupg (commit signing), there should be a stable home for gnupg commands
 | 
				
			||||||
 | 
						if _, ok := os.LookupEnv("GNUPGHOME"); !ok {
 | 
				
			||||||
 | 
							_ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Since git wire protocol has been released from git v2.18
 | 
				
			||||||
 | 
						if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
 | 
				
			||||||
 | 
							globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// By default partial clones are disabled, enable them from git v2.22
 | 
				
			||||||
 | 
						if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
 | 
				
			||||||
 | 
							globalCommandArgs = append(globalCommandArgs, "-c", "uploadpack.allowfilter=true", "-c", "uploadpack.allowAnySHA1InWant=true")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Explicitly disable credential helper, otherwise Git credentials might leak
 | 
				
			||||||
 | 
						if CheckGitVersionAtLeast("2.9") == nil {
 | 
				
			||||||
 | 
							globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if setting.LFS.StartServer {
 | 
				
			||||||
 | 
							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()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@ func testRun(m *testing.M) error {
 | 
				
			|||||||
	defer util.RemoveAll(gitHomePath)
 | 
						defer util.RemoveAll(gitHomePath)
 | 
				
			||||||
	setting.Git.HomePath = gitHomePath
 | 
						setting.Git.HomePath = gitHomePath
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = InitOnceWithSync(context.Background()); err != nil {
 | 
						if err = InitFull(context.Background()); err != nil {
 | 
				
			||||||
		return fmt.Errorf("failed to call Init: %w", err)
 | 
							return fmt.Errorf("failed to call Init: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
// Copyright 2021 The Gitea Authors. All rights reserved.
 | 
					 | 
				
			||||||
// Use of this source code is governed by a MIT-style
 | 
					 | 
				
			||||||
// license that can be found in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package git
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	logger "code.gitea.io/gitea/modules/log"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var once sync.Once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CheckLFSVersion will check lfs version, if not satisfied, then disable it.
 | 
					 | 
				
			||||||
func CheckLFSVersion() {
 | 
					 | 
				
			||||||
	if setting.LFS.StartServer {
 | 
					 | 
				
			||||||
		// Disable LFS client hooks if installed for the current OS user
 | 
					 | 
				
			||||||
		// Needs at least git v2.1.2
 | 
					 | 
				
			||||||
		if CheckGitVersionAtLeast("2.1.2") != nil {
 | 
					 | 
				
			||||||
			setting.LFS.StartServer = false
 | 
					 | 
				
			||||||
			logger.Error("LFS server support needs at least Git v2.1.2")
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			once.Do(func() {
 | 
					 | 
				
			||||||
				globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=",
 | 
					 | 
				
			||||||
					"-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -100,10 +100,8 @@ func GlobalInitInstalled(ctx context.Context) {
 | 
				
			|||||||
		log.Fatal("Gitea is not installed")
 | 
							log.Fatal("Gitea is not installed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mustInitCtx(ctx, git.InitOnceWithSync)
 | 
						mustInitCtx(ctx, git.InitFull)
 | 
				
			||||||
	log.Info("Git Version: %s (home: %s)", git.VersionInfo(), git.HomeDir())
 | 
						log.Info("Git Version: %s (home: %s)", git.VersionInfo(), git.HomeDir())
 | 
				
			||||||
 | 
					 | 
				
			||||||
	git.CheckLFSVersion()
 | 
					 | 
				
			||||||
	log.Info("AppPath: %s", setting.AppPath)
 | 
						log.Info("AppPath: %s", setting.AppPath)
 | 
				
			||||||
	log.Info("AppWorkPath: %s", setting.AppWorkPath)
 | 
						log.Info("AppWorkPath: %s", setting.AppWorkPath)
 | 
				
			||||||
	log.Info("Custom path: %s", setting.CustomPath)
 | 
						log.Info("Custom path: %s", setting.CustomPath)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user