Skip to content

Commit 99a4cff

Browse files
wxiaoguangzeripath6543justusbunsilunny
authored and
Sysoev, Vladimir
committed
Use git.HOME_PATH for Git HOME directory (go-gitea#20114)
* Add git.HOME_PATH * add legacy file check * Apply suggestions from code review Co-authored-by: zeripath <[email protected]> * pass env GNUPGHOME to git command, move the existing .gitconfig to new home, make the fix for 1.17rc more clear. * set git.HOME_PATH for docker images to default HOME * Revert "set git.HOME_PATH for docker images to default HOME" This reverts commit f120101. * force Gitea to use a stable GNUPGHOME directory * extra check to ensure only process dir or symlink for legacy files * refactor variable name * The legacy dir check (for 1.17-rc1) could be removed with 1.18 release, since users should have upgraded from 1.17-rc to 1.17-stable * Update modules/git/git.go Co-authored-by: Steven Kriegler <[email protected]> * remove initFixGitHome117rc * Update git.go * Update docs/content/doc/advanced/config-cheat-sheet.en-us.md Co-authored-by: zeripath <[email protected]> Co-authored-by: 6543 <[email protected]> Co-authored-by: Steven Kriegler <[email protected]> Co-authored-by: Lunny Xiao <[email protected]>
1 parent 3a35259 commit 99a4cff

File tree

8 files changed

+63
-27
lines changed

8 files changed

+63
-27
lines changed

custom/conf/app.example.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,10 @@ ROUTER = console
603603
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
604604
;;
605605
;; The path of git executable. If empty, Gitea searches through the PATH environment.
606-
PATH =
606+
;PATH =
607+
;;
608+
;; The HOME directory for Git
609+
;HOME_PATH = %(APP_DATA_PATH)/home
607610
;;
608611
;; Disables highlight of added and removed changes
609612
;DISABLE_DIFF_HIGHLIGHT = false

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,8 @@ Default templates for project boards:
948948
## Git (`git`)
949949

950950
- `PATH`: **""**: The path of Git executable. If empty, Gitea searches through the PATH environment.
951+
- `HOME_PATH`: **%(APP_DATA_PATH)/home**: The HOME directory for Git.
952+
This directory will be used to contain the `.gitconfig` and possible `.gnupg` directories that Gitea's git calls will use. If you can confirm Gitea is the only application running in this environment, you can set it to the normal home directory for Gitea user.
951953
- `DISABLE_DIFF_HIGHLIGHT`: **false**: Disables highlight of added and removed changes.
952954
- `MAX_GIT_DIFF_LINES`: **1000**: Max number of lines allowed of a single file in diff view.
953955
- `MAX_GIT_DIFF_LINE_CHARACTERS`: **5000**: Max character count per line highlighted in diff view.

docs/content/doc/advanced/signing.en-us.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,11 @@ repositories, `SIGNING_KEY=default` could be used to provide different
9797
signing keys on a per-repository basis. However, this is clearly not an
9898
ideal UI and therefore subject to change.
9999

100-
**Since 1.17**, Gitea runs git in its own home directory `[repository].ROOT` and uses its own config `{[repository].ROOT}/.gitconfig`.
100+
**Since 1.17**, Gitea runs git in its own home directory `[git].HOME_PATH` (default to `%(APP_DATA_PATH)/home`)
101+
and uses its own config `{[git].HOME_PATH}/.gitconfig`.
101102
If you have your own customized git config for Gitea, you should set these configs in system git config (aka `/etc/gitconfig`)
102-
or the Gitea internal git config `{[repository].ROOT}/.gitconfig`.
103-
Related home files for git command (like `.gnupg`) should also be put in Gitea's git home directory `[repository].ROOT`.
103+
or the Gitea internal git config `{[git].HOME_PATH}/.gitconfig`.
104+
Related home files for git command (like `.gnupg`) should also be put in Gitea's git home directory `[git].HOME_PATH`.
104105

105106

106107
### `INITIAL_COMMIT`

models/unittest/testdb.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
107107

108108
setting.Packages.Storage.Path = filepath.Join(setting.AppDataPath, "packages")
109109

110+
setting.Git.HomePath = filepath.Join(setting.AppDataPath, "home")
111+
110112
if err = storage.Init(); err != nil {
111113
fatalTestError("storage.Init: %v\n", err)
112114
}

modules/git/command.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,23 +105,36 @@ type RunOpts struct {
105105
PipelineFunc func(context.Context, context.CancelFunc) error
106106
}
107107

108-
// CommonGitCmdEnvs returns the common environment variables for a "git" command.
109-
func CommonGitCmdEnvs() []string {
108+
func commonBaseEnvs() []string {
110109
// at the moment, do not set "GIT_CONFIG_NOSYSTEM", users may have put some configs like "receive.certNonceSeed" in it
111-
return []string{
112-
fmt.Sprintf("LC_ALL=%s", DefaultLocale),
113-
"GIT_TERMINAL_PROMPT=0", // avoid prompting for credentials interactively, supported since git v2.3
114-
"GIT_NO_REPLACE_OBJECTS=1", // ignore replace references (https://git-scm.com/docs/git-replace)
110+
envs := []string{
115111
"HOME=" + HomeDir(), // make Gitea use internal git config only, to prevent conflicts with user's git config
112+
"GIT_NO_REPLACE_OBJECTS=1", // ignore replace references (https://git-scm.com/docs/git-replace)
113+
}
114+
115+
// some environment variables should be passed to git command
116+
passThroughEnvKeys := []string{
117+
"GNUPGHOME", // git may call gnupg to do commit signing
118+
}
119+
for _, key := range passThroughEnvKeys {
120+
if val, ok := os.LookupEnv(key); ok {
121+
envs = append(envs, key+"="+val)
122+
}
116123
}
124+
return envs
125+
}
126+
127+
// CommonGitCmdEnvs returns the common environment variables for a "git" command.
128+
func CommonGitCmdEnvs() []string {
129+
return append(commonBaseEnvs(), []string{
130+
"LC_ALL=" + DefaultLocale,
131+
"GIT_TERMINAL_PROMPT=0", // avoid prompting for credentials interactively, supported since git v2.3
132+
}...)
117133
}
118134

119135
// CommonCmdServEnvs is like CommonGitCmdEnvs but it only returns minimal required environment variables for the "gitea serv" command
120136
func CommonCmdServEnvs() []string {
121-
return []string{
122-
"GIT_NO_REPLACE_OBJECTS=1", // ignore replace references (https://git-scm.com/docs/git-replace)
123-
"HOME=" + HomeDir(), // make Gitea use internal git config only, to prevent conflicts with user's git config
124-
}
137+
return commonBaseEnvs()
125138
}
126139

127140
// Run runs the command with the RunOpts

modules/git/git.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"os"
1313
"os/exec"
14+
"path/filepath"
1415
"regexp"
1516
"runtime"
1617
"strings"
@@ -19,7 +20,6 @@ import (
1920

2021
"code.gitea.io/gitea/modules/log"
2122
"code.gitea.io/gitea/modules/setting"
22-
2323
"github.com/hashicorp/go-version"
2424
)
2525

@@ -126,8 +126,8 @@ func VersionInfo() string {
126126
}
127127

128128
func checkInit() error {
129-
if setting.RepoRootPath == "" {
130-
return errors.New("can not init Git's HomeDir (RepoRootPath is empty), the setting and git modules are not initialized correctly")
129+
if setting.Git.HomePath == "" {
130+
return errors.New("unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
131131
}
132132
if DefaultContext != nil {
133133
log.Warn("git module has been initialized already, duplicate init should be fixed")
@@ -137,14 +137,14 @@ func checkInit() error {
137137

138138
// HomeDir is the home dir for git to store the global config file used by Gitea internally
139139
func HomeDir() string {
140-
if setting.RepoRootPath == "" {
140+
if setting.Git.HomePath == "" {
141141
// strict check, make sure the git module is initialized correctly.
142142
// attention: when the git module is called in gitea sub-command (serv/hook), the log module is not able to show messages to users.
143143
// 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.
144-
log.Fatal("can not get Git's HomeDir (RepoRootPath is empty), the setting and git modules are not initialized correctly")
144+
log.Fatal("Unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
145145
return ""
146146
}
147-
return setting.RepoRootPath
147+
return setting.Git.HomePath
148148
}
149149

150150
// InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
@@ -175,11 +175,15 @@ func InitOnceWithSync(ctx context.Context) (err error) {
175175
}
176176

177177
initOnce.Do(func() {
178-
err = InitSimple(ctx)
179-
if err != nil {
178+
if err = InitSimple(ctx); err != nil {
180179
return
181180
}
182181

182+
// when git works with gnupg (commit signing), there should be a stable home for gnupg commands
183+
if _, ok := os.LookupEnv("GNUPGHOME"); !ok {
184+
_ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg"))
185+
}
186+
183187
// Since git wire protocol has been released from git v2.18
184188
if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
185189
globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
@@ -206,7 +210,7 @@ func InitOnceWithSync(ctx context.Context) (err error) {
206210
// syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem)
207211
func syncGitConfig() (err error) {
208212
if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil {
209-
return fmt.Errorf("unable to create directory %s, err: %w", setting.RepoRootPath, err)
213+
return fmt.Errorf("unable to prepare git home directory %s, err: %w", HomeDir(), err)
210214
}
211215

212216
// Git requires setting user.name and user.email in order to commit changes - old comment: "if they're not set just add some defaults"

modules/git/git_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ import (
2121
func testRun(m *testing.M) error {
2222
_ = log.NewLogger(1000, "console", "console", `{"level":"trace","stacktracelevel":"NONE","stderr":true}`)
2323

24-
repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos")
24+
gitHomePath, err := os.MkdirTemp(os.TempDir(), "git-home")
2525
if err != nil {
2626
return fmt.Errorf("unable to create temp dir: %w", err)
2727
}
28-
defer util.RemoveAll(repoRootPath)
29-
setting.RepoRootPath = repoRootPath
28+
defer util.RemoveAll(gitHomePath)
29+
setting.Git.HomePath = gitHomePath
3030

3131
if err = InitOnceWithSync(context.Background()); err != nil {
3232
return fmt.Errorf("failed to call Init: %w", err)

modules/setting/git.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package setting
66

77
import (
8+
"path/filepath"
89
"time"
910

1011
"code.gitea.io/gitea/modules/log"
@@ -13,6 +14,7 @@ import (
1314
// Git settings
1415
var Git = struct {
1516
Path string
17+
HomePath string
1618
DisableDiffHighlight bool
1719
MaxGitDiffLines int
1820
MaxGitDiffLineCharacters int
@@ -67,7 +69,16 @@ var Git = struct {
6769
}
6870

6971
func newGit() {
70-
if err := Cfg.Section("git").MapTo(&Git); err != nil {
72+
sec := Cfg.Section("git")
73+
74+
if err := sec.MapTo(&Git); err != nil {
7175
log.Fatal("Failed to map Git settings: %v", err)
7276
}
77+
78+
Git.HomePath = sec.Key("HOME_PATH").MustString("home")
79+
if !filepath.IsAbs(Git.HomePath) {
80+
Git.HomePath = filepath.Join(AppDataPath, Git.HomePath)
81+
} else {
82+
Git.HomePath = filepath.Clean(Git.HomePath)
83+
}
7384
}

0 commit comments

Comments
 (0)