diff --git a/docs/content/doc/administration/repo-size-limit.en-us.md b/docs/content/doc/administration/repo-size-limit.en-us.md index 09c378d335..7e35531294 100644 --- a/docs/content/doc/administration/repo-size-limit.en-us.md +++ b/docs/content/doc/administration/repo-size-limit.en-us.md @@ -28,16 +28,14 @@ ENABLE_SIZE_LIMIT = true ;; If repository has it's own limit set in UI it will override the global setting ;; Standard units of measurements for size can be used like B, KB, KiB, ... , EB, EiB, ... REPO_SIZE_LIMIT = 500 MB -``` -This setting is persistent. +This setting is persistent. The size limitation is triggered when repository `disk size` + `new commit size` > `defined repository size limit` If size limitation is triggered the feature would prevent commits that increase repository size on disk of gitea server and allow those that decrease it - # Gitea per repository size limit setup in UI 1. For Gitea admin it is possible during runtime to enable/disable limit size feature, change the global size limit on the fly. diff --git a/tests/integration/git_test.go b/tests/integration/git_test.go index cdff57f21f..7369f2694b 100644 --- a/tests/integration/git_test.go +++ b/tests/integration/git_test.go @@ -102,6 +102,14 @@ func testGit(t *testing.T, u *url.URL) { }) t.Run("Deletion", func(t *testing.T) { defer tests.PrintCurrentTest(t)() + doCommitAndPush(t, littleSize, dstPath, "data-file-") + + bigFileName := doCommitAndPush(t, bigSize, dstPath, "data-file-") + oldRepoSize := doCalculateRepoSize(t, dstPath) + doDeleteAndCliean(t, dstPath, bigFileName) + newRepoSize := doCalculateRepoSize(t, dstPath) + assert.Less(t, newRepoSize, oldRepoSize) + setting.SaveGlobalRepositorySetting(false, 0) // TODO doDeleteCommitAndPush(t, littleSize, dstPath, "data-file-") }) // TODO delete branch @@ -325,6 +333,42 @@ func lockFileTest(t *testing.T, filename, repoPath string) { assert.NoError(t, err) } +const notRegularFileMode = os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | os.ModeDevice | os.ModeCharDevice | os.ModeIrregular + +func doCalculateRepoSize(t *testing.T, path string) int64 { + var size int64 + err := filepath.WalkDir(path, func(_ string, info os.DirEntry, err error) error { + if err != nil { + if os.IsNotExist(err) { // ignore the error because the file maybe deleted during traversing. + return nil + } + return err + } + if info.IsDir() { + return nil + } + f, err := info.Info() + if err != nil { + return err + } + if (f.Mode() & notRegularFileMode) == 0 { + size += f.Size() + } + return err + }) + assert.NoError(t, err) + return size +} + +func doDeleteAndCliean(t *testing.T, repoPath, filename string) { + _, _, err := git.NewCommand(git.DefaultContext, "rm").AddDashesAndList(filename).RunStdString(&git.RunOpts{Dir: repoPath}) // Delete + assert.NoError(t, err) + _, _, err = git.NewCommand(git.DefaultContext, "reflog", "expire", "--expire-unreachable=all", "--all").RunStdString(&git.RunOpts{Dir: repoPath}) // reflog + assert.NoError(t, err) + _, _, err = git.NewCommand(git.DefaultContext, "gc", "--prune=now").RunStdString(&git.RunOpts{Dir: repoPath}) // reflog + assert.NoError(t, err) +} + func doCommitAndPush(t *testing.T, size int, repoPath, prefix string) string { name, err := generateCommitWithNewData(size, repoPath, "user2@example.com", "User Two", prefix) assert.NoError(t, err)