Skip to content

Use [git.config] for reflog cleaning up #24958

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -693,17 +693,13 @@ LEVEL = Info
;PULL = 300
;GC = 60

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Git Reflog timeout in days
;[git.reflog]
;ENABLED = true
;EXPIRATION = 90

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Git config options
;; This section only does "set" config, a removed config key from this section won't be removed from git config automatically. The format is `some.configKey = value`.
;[git.config]
;diff.algorithm = histogram
;core.logAllRefUpdates = true
;gc.reflogExpire = 90

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
7 changes: 2 additions & 5 deletions docs/content/doc/administration/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -1065,17 +1065,14 @@ Default templates for project boards:
- `PULL`: **300**: Git pull from internal repositories timeout seconds.
- `GC`: **60**: Git repository GC timeout seconds.

### Git - Reflog settings (`git.reflog`)

- `ENABLED`: **true** Set to true to enable Git to write changes to reflogs in each repo.
- `EXPIRATION`: **90** Reflog entry lifetime, in days. Entries are removed opportunistically by Git.

### Git - Config options (`git.config`)

The key/value pairs in this section will be used as git config.
This section only does "set" config, a removed config key from this section won't be removed from git config automatically. The format is `some.configKey = value`.

- `diff.algorithm`: **histogram**
- `core.logAllRefUpdates`: **true**
- `gc.reflogExpire`: **90**

## Metrics (`metrics`)

Expand Down
27 changes: 0 additions & 27 deletions modules/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,23 +201,6 @@ func InitFull(ctx context.Context) (err error) {
return syncGitConfig()
}

func enableReflogs() error {
if err := configSet("core.logAllRefUpdates", "true"); err != nil {
return err
}
err := configSet("gc.reflogExpire", fmt.Sprintf("%d", setting.Git.Reflog.Expiration))
return err
}

func disableReflogs() error {
if err := configUnsetAll("core.logAllRefUpdates", "true"); err != nil {
return err
} else if err := configUnsetAll("gc.reflogExpire", ""); err != nil {
return err
}
return nil
}

// syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem)
func syncGitConfig() (err error) {
if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil {
Expand Down Expand Up @@ -249,16 +232,6 @@ func syncGitConfig() (err error) {
return err
}

if setting.Git.Reflog.Enabled {
if err := enableReflogs(); err != nil {
return err
}
} else {
if err := disableReflogs(); err != nil {
return err
}
}

if CheckGitVersionAtLeast("2.10") == nil {
if err := configSet("receive.advertisePushOptions", "true"); err != nil {
return err
Expand Down
48 changes: 29 additions & 19 deletions modules/setting/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ var Git = struct {
Path string
HomePath string
DisableDiffHighlight bool
Reflog struct {
Enabled bool
Expiration int
} `ini:"git.reflog"`

MaxGitDiffLines int
MaxGitDiffLineCharacters int
MaxGitDiffFiles int
Expand All @@ -42,13 +39,6 @@ var Git = struct {
GC int `ini:"GC"`
} `ini:"git.timeout"`
}{
Reflog: struct {
Enabled bool
Expiration int
}{
Enabled: true,
Expiration: 90,
},
DisableDiffHighlight: false,
MaxGitDiffLines: 1000,
MaxGitDiffLineCharacters: 5000,
Expand Down Expand Up @@ -79,9 +69,19 @@ var Git = struct {
},
}

var GitConfig = struct {
Options map[string]string
}{
type GitConfigType struct {
Options map[string]string // git config key is case-insensitive, always use lower-case
}

func (c *GitConfigType) SetOption(key, val string) {
c.Options[strings.ToLower(key)] = val
}

func (c *GitConfigType) GetOption(key string) string {
return c.Options[strings.ToLower(key)]
}

var GitConfig = GitConfigType{
Options: make(map[string]string),
}

Expand All @@ -93,12 +93,22 @@ func loadGitFrom(rootCfg ConfigProvider) {

secGitConfig := rootCfg.Section("git.config")
GitConfig.Options = make(map[string]string)
for _, key := range secGitConfig.Keys() {
// git config key is case-insensitive, so always use lower-case
GitConfig.Options[strings.ToLower(key.Name())] = key.String()
GitConfig.SetOption("diff.algorithm", "histogram")
GitConfig.SetOption("core.logAllRefUpdates", "true")
GitConfig.SetOption("gc.reflogExpire", "90")

secGitReflog := rootCfg.Section("git.reflog")
if secGitReflog.HasKey("ENABLED") {
deprecatedSetting(rootCfg, "git.reflog", "ENABLED", "git.config", "core.logAllRefUpdates", "1.21")
GitConfig.SetOption("core.logAllRefUpdates", secGitReflog.Key("ENABLED").In("true", []string{"true", "false"}))
}
if _, ok := GitConfig.Options["diff.algorithm"]; !ok {
GitConfig.Options["diff.algorithm"] = "histogram"
if secGitReflog.HasKey("EXPIRATION") {
deprecatedSetting(rootCfg, "git.reflog", "EXPIRATION", "git.config", "core.reflogExpire", "1.21")
GitConfig.SetOption("gc.reflogExpire", secGitReflog.Key("EXPIRATION").String())
}

for _, key := range secGitConfig.Keys() {
GitConfig.SetOption(key.Name(), key.String())
}

Git.HomePath = sec.Key("HOME_PATH").MustString("home")
Expand Down
33 changes: 29 additions & 4 deletions modules/setting/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ a.b = 1
`)
assert.NoError(t, err)
loadGitFrom(cfg)

assert.Len(t, GitConfig.Options, 2)
assert.EqualValues(t, "1", GitConfig.Options["a.b"])
assert.EqualValues(t, "histogram", GitConfig.Options["diff.algorithm"])

Expand All @@ -34,7 +32,34 @@ diff.algorithm = other
`)
assert.NoError(t, err)
loadGitFrom(cfg)

assert.Len(t, GitConfig.Options, 1)
assert.EqualValues(t, "other", GitConfig.Options["diff.algorithm"])
}

func TestGitReflog(t *testing.T) {
oldGit := Git
oldGitConfig := GitConfig
defer func() {
Git = oldGit
GitConfig = oldGitConfig
}()

// default reflog config without legacy options
cfg, err := NewConfigProviderFromData(``)
assert.NoError(t, err)
loadGitFrom(cfg)

assert.EqualValues(t, "true", GitConfig.GetOption("core.logAllRefUpdates"))
assert.EqualValues(t, "90", GitConfig.GetOption("gc.reflogExpire"))

// custom reflog config by legacy options
cfg, err = NewConfigProviderFromData(`
[git.reflog]
ENABLED = false
EXPIRATION = 123
`)
assert.NoError(t, err)
loadGitFrom(cfg)

assert.EqualValues(t, "false", GitConfig.GetOption("core.logAllRefUpdates"))
assert.EqualValues(t, "123", GitConfig.GetOption("gc.reflogExpire"))
}