@@ -34,15 +34,12 @@ var (
3434 GitExecutable = "git"
3535
3636 // DefaultContext is the default context to run git commands in
37- // will be overwritten by InitWithConfigSync with HammerContext
37+ // will be overwritten by InitXxx with HammerContext
3838 DefaultContext = context .Background ()
3939
4040 // SupportProcReceive version >= 2.29.0
4141 SupportProcReceive bool
4242
43- // initMutex is used to avoid Golang's data race error. see the comments below.
44- initMutex sync.Mutex
45-
4643 gitVersion * version.Version
4744)
4845
@@ -131,15 +128,6 @@ func VersionInfo() string {
131128 return fmt .Sprintf (format , args ... )
132129}
133130
134- // InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
135- // This method doesn't change anything to filesystem
136- func InitSimple (ctx context.Context ) error {
137- initMutex .Lock ()
138- defer initMutex .Unlock ()
139-
140- return initSimpleInternal (ctx )
141- }
142-
143131// HomeDir is the home dir for git to store the global config file used by Gitea internally
144132func HomeDir () string {
145133 if setting .RepoRootPath == "" {
@@ -153,11 +141,9 @@ func HomeDir() string {
153141 return setting .RepoRootPath
154142}
155143
156- func initSimpleInternal (ctx context.Context ) error {
157- // at the moment, when running integration tests, the git.InitXxx would be called twice.
158- // one is called by the GlobalInitInstalled, one is called by TestMain.
159- // so the init functions should be protected by a mutex to avoid Golang's data race error.
160-
144+ // InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
145+ // This method doesn't change anything to filesystem. At the moment, it is only used by "git serv" sub-command, no data-race
146+ func InitSimple (ctx context.Context ) error {
161147 DefaultContext = ctx
162148
163149 if setting .Git .Timeout .Default > 0 {
@@ -174,33 +160,45 @@ func initSimpleInternal(ctx context.Context) error {
174160 return nil
175161}
176162
177- // InitWithConfigSync initializes git module. This method may create directories or write files into filesystem
178- func InitWithConfigSync (ctx context.Context ) error {
179- initMutex .Lock ()
180- defer initMutex .Unlock ()
163+ var initOnce sync.Once
181164
182- err := initSimpleInternal (ctx )
183- if err != nil {
184- return err
185- }
165+ // InitOnceWithSync initializes git module with version check and change global variables, sync gitconfig.
166+ // This method will update the global variables ONLY ONCE (just like git.CheckLFSVersion -- which is not ideal too),
167+ // otherwise there will be data-race problem at the moment.
168+ func InitOnceWithSync (ctx context.Context ) (err error ) {
169+ initOnce .Do (func () {
170+ err = InitSimple (ctx )
171+ if err != nil {
172+ return
173+ }
186174
187- if err = os .MkdirAll (setting .RepoRootPath , os .ModePerm ); err != nil {
188- return fmt .Errorf ("unable to create directory %s, err: %w" , setting .RepoRootPath , err )
189- }
175+ // Since git wire protocol has been released from git v2.18
176+ if setting .Git .EnableAutoGitWireProtocol && CheckGitVersionAtLeast ("2.18" ) == nil {
177+ globalCommandArgs = append (globalCommandArgs , "-c" , "protocol.version=2" )
178+ }
179+
180+ // By default partial clones are disabled, enable them from git v2.22
181+ if ! setting .Git .DisablePartialClone && CheckGitVersionAtLeast ("2.22" ) == nil {
182+ globalCommandArgs = append (globalCommandArgs , "-c" , "uploadpack.allowfilter=true" , "-c" , "uploadpack.allowAnySHA1InWant=true" )
183+ }
190184
191- if CheckGitVersionAtLeast ("2.9" ) == nil {
192185 // Explicitly disable credential helper, otherwise Git credentials might leak
193- globalCommandArgs = append (globalCommandArgs , "-c" , "credential.helper=" )
194- }
186+ if CheckGitVersionAtLeast ("2.9" ) == nil {
187+ globalCommandArgs = append (globalCommandArgs , "-c" , "credential.helper=" )
188+ }
195189
196- // Since git wire protocol has been released from git v2.18
197- if setting .Git .EnableAutoGitWireProtocol && CheckGitVersionAtLeast ("2.18" ) == nil {
198- globalCommandArgs = append (globalCommandArgs , "-c" , "protocol.version=2" )
190+ SupportProcReceive = CheckGitVersionAtLeast ("2.29" ) == nil
191+ })
192+ if err != nil {
193+ return err
199194 }
195+ return syncGitConfig ()
196+ }
200197
201- // By default partial clones are disabled, enable them from git v2.22
202- if ! setting .Git .DisablePartialClone && CheckGitVersionAtLeast ("2.22" ) == nil {
203- globalCommandArgs = append (globalCommandArgs , "-c" , "uploadpack.allowfilter=true" , "-c" , "uploadpack.allowAnySHA1InWant=true" )
198+ // syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem)
199+ func syncGitConfig () (err error ) {
200+ if err = os .MkdirAll (HomeDir (), os .ModePerm ); err != nil {
201+ return fmt .Errorf ("unable to create directory %s, err: %w" , setting .RepoRootPath , err )
204202 }
205203
206204 // Git requires setting user.name and user.email in order to commit changes - old comment: "if they're not set just add some defaults"
@@ -235,17 +233,15 @@ func InitWithConfigSync(ctx context.Context) error {
235233 }
236234 }
237235
238- if CheckGitVersionAtLeast ( "2.29" ) == nil {
236+ if SupportProcReceive {
239237 // set support for AGit flow
240238 if err := configAddNonExist ("receive.procReceiveRefs" , "refs/for" ); err != nil {
241239 return err
242240 }
243- SupportProcReceive = true
244241 } else {
245242 if err := configUnsetAll ("receive.procReceiveRefs" , "refs/for" ); err != nil {
246243 return err
247244 }
248- SupportProcReceive = false
249245 }
250246
251247 if runtime .GOOS == "windows" {
0 commit comments