pass env GNUPGHOME to git command, move the existing .gitconfig to new home, make the fix for 1.17rc more clear.

This commit is contained in:
wxiaoguang 2022-07-04 12:49:19 +08:00
parent f345b4c9df
commit 1a386b7f66
2 changed files with 69 additions and 30 deletions

View File

@ -105,23 +105,36 @@ type RunOpts struct {
PipelineFunc func(context.Context, context.CancelFunc) error PipelineFunc func(context.Context, context.CancelFunc) error
} }
func commonBaseEnvs() []string {
// at the moment, do not set "GIT_CONFIG_NOSYSTEM", users may have put some configs like "receive.certNonceSeed" in it
envs := []string{
"HOME=" + HomeDir(), // make Gitea use internal git config only, to prevent conflicts with user's git config
"GIT_NO_REPLACE_OBJECTS=1", // ignore replace references (https://git-scm.com/docs/git-replace)
}
// some environment variables should be passed to git command
passThroughEnvKeys := []string{
"GNUPGHOME", // git may call gnupg to do commit signing
}
for _, key := range passThroughEnvKeys {
if val, ok := os.LookupEnv(key); ok {
envs = append(envs, key+"="+val)
}
}
return envs
}
// CommonGitCmdEnvs returns the common environment variables for a "git" command. // CommonGitCmdEnvs returns the common environment variables for a "git" command.
func CommonGitCmdEnvs() []string { func CommonGitCmdEnvs() []string {
// at the moment, do not set "GIT_CONFIG_NOSYSTEM", users may have put some configs like "receive.certNonceSeed" in it return append(commonBaseEnvs(), []string{
return []string{ "LC_ALL=" + DefaultLocale,
fmt.Sprintf("LC_ALL=%s", DefaultLocale), "GIT_TERMINAL_PROMPT=0", // avoid prompting for credentials interactively, supported since git v2.3
"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 // CommonCmdServEnvs is like CommonGitCmdEnvs but it only returns minimal required environment variables for the "gitea serv" command
func CommonCmdServEnvs() []string { func CommonCmdServEnvs() []string {
return []string{ return commonBaseEnvs()
"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 // Run runs the command with the RunOpts

View File

@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"github.com/hashicorp/go-version" "github.com/hashicorp/go-version"
) )
@ -167,6 +168,47 @@ func InitSimple(ctx context.Context) error {
var initOnce sync.Once var initOnce sync.Once
func initFixGitHome117rc() error {
// Gitea 1.17-rc uses "setting.RepoRootPath" for Git HOME, which is incorrect.
// Do this check to make sure there is no legacy file in the RepoRootPath. This check might be able to be removed with 1.19 release.
// remove the auto generated git config file (it will be moved to new home)
gitConfigNewPath := filepath.Join(HomeDir(), ".gitconfig")
gitConfigLegacyPath := filepath.Join(setting.RepoRootPath, ".gitconfig")
if ok, err := util.IsExist(gitConfigLegacyPath); ok && err == nil {
if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil {
return err
}
if ok, err = util.IsExist(gitConfigNewPath); !ok && err == nil {
err = util.CopyFile(gitConfigLegacyPath, gitConfigNewPath)
} else {
err = util.CopyFile(gitConfigLegacyPath, gitConfigNewPath+".bak")
}
if err != nil {
return err
}
_ = os.Remove(gitConfigLegacyPath)
}
// remove the empty directories, if some directories are non-empty, warn users and exit
var hasCheckErr bool
for _, wellDirName := range []string{".ssh", ".gnupg"} {
checkLegacyDir := filepath.Join(setting.RepoRootPath, wellDirName)
_ = os.Remove(checkLegacyDir) // try to remove the empty dummy directory first
_, checkErr := os.Stat(checkLegacyDir) // if the directory is not empty, then it won't be removed, it should be handled manually
if checkErr == nil || !errors.Is(checkErr, os.ErrNotExist) {
log.Error(`Git HOME has been moved to [git].HOME_PATH, but there are legacy file in old place. Please backup and remove the legacy files %q`, checkLegacyDir)
hasCheckErr = true
}
}
if hasCheckErr {
log.Fatal("Please fix errors above, remove legacy files.")
}
return nil
}
// InitOnceWithSync initializes git module with version check and change global variables, sync gitconfig. // InitOnceWithSync initializes git module with version check and change global variables, sync gitconfig.
// This method will update the global variables ONLY ONCE (just like git.CheckLFSVersion -- which is not ideal too), // 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. // otherwise there will be data-race problem at the moment.
@ -176,28 +218,12 @@ func InitOnceWithSync(ctx context.Context) (err error) {
} }
initOnce.Do(func() { initOnce.Do(func() {
err = InitSimple(ctx) if err = InitSimple(ctx); err != nil {
if err != nil {
return return
} }
if err = initFixGitHome117rc(); err != nil {
// Gitea 1.17-rc uses "setting.RepoRootPath" for Git HOME, which is incorrect. return
// Do this check to make sure there is no legacy file in the RepoRootPath. This check might be able to be removed with 1.19 release.
var hasCheckErr bool
_ = os.Remove(filepath.Join(setting.RepoRootPath, ".gitconfig")) // remove the auto generated git config file
_ = os.Remove(filepath.Join(setting.RepoRootPath, ".ssh")) // remove the empty dummy ".ssh" directory
for _, wellKnownName := range []string{".ssh", ".gnupg"} {
checkLegacyFile := filepath.Join(setting.RepoRootPath, wellKnownName)
_, checkErr := os.Stat(checkLegacyFile)
if checkErr == nil || !errors.Is(checkErr, os.ErrNotExist) {
log.Error(`Git HOME has been moved to [git].HOME_PATH, but there are legacy file in old place. Please backup and remove the legacy files %q`, checkLegacyFile)
hasCheckErr = true
}
} }
if hasCheckErr {
log.Fatal("Please fix errors above, remove legacy files")
}
// end of legacy Gitea 1.17-rc check
// Since git wire protocol has been released from git v2.18 // Since git wire protocol has been released from git v2.18
if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil { if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {