Repository navigation
Limit repo size #21820
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
base: main
Are you sure you want to change the base?
Limit repo size #21820
Changes from 17 commits
bb96349
56b92a1
2f65545
7c31cfc
6a2e670
df60de2
136b631
20bfff3
75585de
036e55c
62d3c05
ee31efc
36b43fe
762799b
b391383
04de706
d9ab187
31359b4
4c0921e
1c7b3b6
a16f5fa
af2e3a3
4687f0c
d1368ec
4256bdc
cdc5a2c
e26bcfc
2763393
e7ab661
6060ae1
8383ec5
562bc27
d13d457
80fa68b
4a31279
fe168a4
f8b1413
ac99056
0666202
c20faef
3429b99
bcea146
7aeb909
dd0246e
64f5b94
9a36273
cc2521c
8adfb6d
b00f27e
37725e4
7b4e90b
9da8b9d
82dcd0c
ae06851
e3b4628
8494f19
0afa267
211c085
8293e7f
920fb58
f583b8f
8a84718
4b09713
3f8bdd1
ab5ffc0
83cc033
d98a62a
7f28229
4793882
3592ae7
1765ea3
a22b738
66c476e
d843a67
0231760
82f3e2d
2a1abe5
3d0004a
414c902
31600a0
703ba07
c55ccfd
9e5f2fd
80f8977
8ac833a
c31c510
8750728
c2fc283
4936e49
e9c29f8
57c94e6
656a3dc
ef760d7
51a7697
2cbdee0
88e74d6
7120c30
db5a8da
08c65ff
ab3097d
ed4865c
c96ec8d
fd73ace
256173f
6e99cf4
a32f797
7bc9554
22bb76c
a08c6fe
64f6dd6
20d4d4f
39ade30
0c3a46f
ccc564a
851c988
649da24
44df2b6
9c9f75f
cdf5946
eac9822
4b709c6
7240e3a
c203d2c
bc1cb65
9014d9f
79251d5
bc051a3
b521d36
9bf945f
efd3596
410d0cd
236681b
918325f
0e05c2e
e5a04cd
e9b8e6f
8097699
23a492d
f810b42
cfd013f
aec62fa
b709876
e1267d5
3612140
006f216
0fee4f4
ecdc2a7
807da90
4b6a77c
bf1870d
748dbd0
ef94e79
554c303
f4dff6a
758f4f3
206d688
e709a88
de1b2d8
56d388e
4bda9b8
17ef999
4ef0f99
624fe24
243c16d
4c5967c
521d277
b81fe08
7b10eb2
7942523
c16ad56
3641d45
374989a
ca9489a
baafa7b
fee277f
303cb6f
902829d
014c969
3622a71
d2beb1d
3dcfd23
fd57c84
5c80b8d
10edee8
a779d64
86d5918
15a12f0
00ba5be
4ba3f21
f8403ad
f53f2b9
0f2a872
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // Copyright 2022 The Gitea Authors. All rights reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package migrations | ||
|
|
||
| import "xorm.io/xorm" | ||
|
|
||
| func addSizeLimitOnRepo(x *xorm.Engine) error { | ||
| type Repository struct { | ||
| ID int64 `xorm:"pk autoincr"` | ||
| SizeLimit int64 `xorm:"NOT NULL DEFAULT 0"` | ||
| } | ||
|
|
||
| return x.Sync2(new(Repository)) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -256,6 +256,74 @@ func Push(ctx context.Context, repoPath string, opts PushOptions) error { | |
| return err | ||
| } | ||
|
|
||
| // CountObject represents repository count objects report | ||
| type CountObject struct { | ||
| Count int64 | ||
| Size int64 | ||
| InPack int64 | ||
| Packs int64 | ||
| SizePack int64 | ||
| PrunePack int64 | ||
| Garbage int64 | ||
| SizeGarbage int64 | ||
| } | ||
|
|
||
| const ( | ||
| statCount = "count: " | ||
| statSize = "size: " | ||
| statInpack = "in-pack: " | ||
| statPacks = "packs: " | ||
| statSizePack = "size-pack: " | ||
| statPrunePackage = "prune-package: " | ||
| statGarbage = "garbage: " | ||
| statSizeGarbage = "size-garbage: " | ||
| ) | ||
|
|
||
| // CountObjects returns the results of git count-objects on the repoPath | ||
| func CountObjects(ctx context.Context, repoPath string) (*CountObject, error) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's better to move all the functions to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok will work on this |
||
| return CountObjectsWithEnv(ctx, repoPath, nil) | ||
| } | ||
|
|
||
| // CountObjectsWithEnv returns the results of git count-objects on the repoPath with custom env setup | ||
| func CountObjectsWithEnv(ctx context.Context, repoPath string, env []string) (*CountObject, error) { | ||
|
DmitryFrolovTri marked this conversation as resolved.
Outdated
|
||
| cmd := NewCommand(ctx, "count-objects", "-v") | ||
| stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath, Env: env}) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| return parseSize(stdout), nil | ||
| } | ||
|
|
||
| // parseSize parses the output from count-objects and return a CountObject | ||
| func parseSize(objects string) *CountObject { | ||
| repoSize := new(CountObject) | ||
| for _, line := range strings.Split(objects, "\n") { | ||
| switch { | ||
| case strings.HasPrefix(line, statCount): | ||
| repoSize.Count, _ = strconv.ParseInt(line[7:], 10, 64) | ||
| case strings.HasPrefix(line, statSize): | ||
| number, _ := strconv.ParseInt(line[6:], 10, 64) | ||
| repoSize.Size = number * 1024 | ||
| case strings.HasPrefix(line, statInpack): | ||
| repoSize.InPack, _ = strconv.ParseInt(line[9:], 10, 64) | ||
| case strings.HasPrefix(line, statPacks): | ||
| repoSize.Packs, _ = strconv.ParseInt(line[7:], 10, 64) | ||
| case strings.HasPrefix(line, statSizePack): | ||
| number, _ := strconv.ParseInt(line[11:], 10, 64) | ||
| repoSize.SizePack = number * 1024 | ||
| case strings.HasPrefix(line, statPrunePackage): | ||
| repoSize.PrunePack, _ = strconv.ParseInt(line[16:], 10, 64) | ||
| case strings.HasPrefix(line, statGarbage): | ||
| repoSize.Garbage, _ = strconv.ParseInt(line[9:], 10, 64) | ||
| case strings.HasPrefix(line, statSizeGarbage): | ||
| number, _ := strconv.ParseInt(line[14:], 10, 64) | ||
| repoSize.SizeGarbage = number * 1024 | ||
| } | ||
| } | ||
| return repoSize | ||
| } | ||
|
Comment on lines
+251
to
+280
|
||
|
|
||
| // GetLatestCommitTime returns time for latest commit in repository (across all branches) | ||
| func GetLatestCommitTime(ctx context.Context, repoPath string) (time.Time, error) { | ||
| cmd := NewCommand(ctx, "for-each-ref", "--sort=-committerdate", BranchPrefix, "--count", "1", "--format=%(committerdate)") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -113,12 +113,35 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { | |
| opts: opts, | ||
| } | ||
|
|
||
| repo := ourCtx.Repo.Repository | ||
|
DmitryFrolovTri marked this conversation as resolved.
|
||
|
|
||
| pushSize, err := git.CountObjectsWithEnv(ctx, repo.RepoPath(), ourCtx.env) | ||
| if err != nil { | ||
| log.Error("Unable to get repository size with env %v: %s Error: %v", repo.RepoPath(), ourCtx.env, err) | ||
| ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ | ||
| "err": err.Error(), | ||
| }) | ||
| return | ||
| } | ||
| log.Trace("Push size %d", pushSize.Size) | ||
|
|
||
| // Iterate across the provided old commit IDs | ||
| for i := range opts.OldCommitIDs { | ||
| oldCommitID := opts.OldCommitIDs[i] | ||
| newCommitID := opts.NewCommitIDs[i] | ||
| refFullName := opts.RefFullNames[i] | ||
|
|
||
| // Check size | ||
| if newCommitID != git.EmptySHA && repo.RepoSizeIsOversized(pushSize.Size) { // Check next size if we are not deleting a reference | ||
| log.Warn("Forbidden: new repo size is over limitation: %d", repo.SizeLimit) | ||
| ctx.JSON(http.StatusForbidden, map[string]interface{}{ | ||
| "err": fmt.Sprintf("new repo size is over limitation: %d", repo.SizeLimit), | ||
| }) | ||
| } | ||
|
Comment on lines
+531
to
+764
|
||
| // TODO investigate why on force push some git objects are not cleaned on server side. | ||
| // TODO corner-case force push and branch creation -> git.EmptySHA == oldCommitID | ||
| // TODO calculate pushed LFS objects size | ||
|
|
||
| switch { | ||
| case strings.HasPrefix(refFullName, git.BranchPrefix): | ||
| preReceiveBranch(ourCtx, oldCommitID, newCommitID, refFullName) | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.