Skip to content
Draft
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
42 changes: 42 additions & 0 deletions modules/gitrepo/cleanup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gitrepo

import (
"context"
"os"
"path/filepath"
"time"
)

var lockFiles = []string{
"config.lock",
"objects/info/commit-graphs/commit-graph-chain.lock",
}

// CleanupRepo cleans up the repository by removing unnecessary lock files.
func CleanupRepo(ctx context.Context, repo Repository) error {
return CleanFixedFileLocks(ctx, repo, time.Now().Add(-24*time.Hour))
}

// CleanFixedFileLocks removes lock files that haven't been modified since the last update.
func CleanFixedFileLocks(ctx context.Context, repo Repository, lastUpdated time.Time) error {
for _, lockFile := range lockFiles {
p := filepath.Join(repoPath(repo), lockFile)
fInfo, err := os.Stat(p)
if err != nil {
if os.IsNotExist(err) {
continue
}
return err
}

if fInfo.ModTime().Before(lastUpdated) {
if err := os.Remove(p); err != nil {
return err
}
}
}
return nil
}
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3080,6 +3080,7 @@ dashboard.sync_branch.started = Branches Sync started
dashboard.sync_tag.started = Tags Sync started
dashboard.rebuild_issue_indexer = Rebuild issue indexer
dashboard.sync_repo_licenses = Sync repo licenses
dashboard.cleanup_repo_lock_files = Clean up repository lock files

users.user_manage_panel = User Account Management
users.new_account = Create User Account
Expand Down
11 changes: 11 additions & 0 deletions services/cron/tasks_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@ func registerRebuildIssueIndexer() {
})
}

func registerCleanupRepoLockFiles() {
RegisterTaskFatal("cleanup_repo_lock_files", &BaseConfig{
Enabled: false,
RunAtStart: false,
Schedule: "@every 24h",
}, func(ctx context.Context, _ *user_model.User, config Config) error {
return repo_service.CleanupRepo(ctx)
})
}

func initExtendedTasks() {
registerDeleteInactiveUsers()
registerDeleteRepositoryArchives()
Expand All @@ -239,4 +249,5 @@ func initExtendedTasks() {
registerDeleteOldSystemNotices()
registerGCLFS()
registerRebuildIssueIndexer()
registerCleanupRepoLockFiles()
}
38 changes: 38 additions & 0 deletions services/repository/cleanup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package repository

import (
"context"

"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"

"xorm.io/builder"
)

func CleanupRepo(ctx context.Context) error {
log.Trace("Doing: CleanupRepo")

if err := db.Iterate(
ctx,
builder.Eq{"is_empty": false},
func(ctx context.Context, repo *repo_model.Repository) error {
select {
case <-ctx.Done():
return db.ErrCancelledf("before cleanup repo lock files for %s", repo.FullName())
default:
}
return gitrepo.CleanupRepo(ctx, repo)
},
); err != nil {
log.Trace("Error: CleanupRepo: %v", err)
return err
}

log.Trace("Finished: CleanupRepo")
return nil
}
4 changes: 2 additions & 2 deletions tests/integration/api_admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,11 +304,11 @@ func TestAPICron(t *testing.T) {
AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)

assert.Equal(t, "29", resp.Header().Get("X-Total-Count"))
assert.Equal(t, "30", resp.Header().Get("X-Total-Count"))

var crons []api.Cron
DecodeJSON(t, resp, &crons)
assert.Len(t, crons, 29)
assert.Len(t, crons, 30)
})

t.Run("Execute", func(t *testing.T) {
Expand Down