Skip to content

Commit 6410c34

Browse files
lunnywxiaoguang
andauthored
Refactor ref type (#33242)
Major changes: 1. do not sync ".keep" file during tests 2. fix incorrect route handler and empty repo handling (backported as #33253 with tests) 3. do not use `RepoRef`: most of the calls are abuses. 4. Use `git.RefType` instead of a new type definition `RepoRefType` on `context`. --------- Co-authored-by: wxiaoguang <[email protected]>
1 parent 3a749fc commit 6410c34

File tree

7 files changed

+120
-143
lines changed

7 files changed

+120
-143
lines changed

models/unittest/fscopy.go

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,13 @@ import (
1111
"code.gitea.io/gitea/modules/util"
1212
)
1313

14-
// Copy copies file from source to target path.
15-
func Copy(src, dest string) error {
16-
// Gather file information to set back later.
17-
si, err := os.Lstat(src)
18-
if err != nil {
19-
return err
20-
}
21-
22-
// Handle symbolic link.
23-
if si.Mode()&os.ModeSymlink != 0 {
24-
target, err := os.Readlink(src)
25-
if err != nil {
26-
return err
27-
}
28-
// NOTE: os.Chmod and os.Chtimes don't recognize symbolic link,
29-
// which will lead "no such file or directory" error.
30-
return os.Symlink(target, dest)
31-
}
32-
33-
return util.CopyFile(src, dest)
34-
}
35-
36-
// Sync synchronizes the two files. This is skipped if both files
14+
// SyncFile synchronizes the two files. This is skipped if both files
3715
// exist and the size, modtime, and mode match.
38-
func Sync(srcPath, destPath string) error {
16+
func SyncFile(srcPath, destPath string) error {
3917
dest, err := os.Stat(destPath)
4018
if err != nil {
4119
if os.IsNotExist(err) {
42-
return Copy(srcPath, destPath)
20+
return util.CopyFile(srcPath, destPath)
4321
}
4422
return err
4523
}
@@ -55,7 +33,7 @@ func Sync(srcPath, destPath string) error {
5533
return nil
5634
}
5735

58-
return Copy(srcPath, destPath)
36+
return util.CopyFile(srcPath, destPath)
5937
}
6038

6139
// SyncDirs synchronizes files recursively from source to target directory.
@@ -66,23 +44,31 @@ func SyncDirs(srcPath, destPath string) error {
6644
return err
6745
}
6846

47+
// the keep file is used to keep the directory in a git repository, it doesn't need to be synced
48+
// and go-git doesn't work with the ".keep" file (it would report errors like "ref is empty")
49+
const keepFile = ".keep"
50+
6951
// find and delete all untracked files
7052
destFiles, err := util.ListDirRecursively(destPath, &util.ListDirOptions{IncludeDir: true})
7153
if err != nil {
7254
return err
7355
}
7456
for _, destFile := range destFiles {
7557
destFilePath := filepath.Join(destPath, destFile)
58+
shouldRemove := filepath.Base(destFilePath) == keepFile
7659
if _, err = os.Stat(filepath.Join(srcPath, destFile)); err != nil {
7760
if os.IsNotExist(err) {
78-
// if src file does not exist, remove dest file
79-
if err = os.RemoveAll(destFilePath); err != nil {
80-
return err
81-
}
61+
shouldRemove = true
8262
} else {
8363
return err
8464
}
8565
}
66+
// if src file does not exist, remove dest file
67+
if shouldRemove {
68+
if err = os.RemoveAll(destFilePath); err != nil {
69+
return err
70+
}
71+
}
8672
}
8773

8874
// sync src files to dest
@@ -95,8 +81,8 @@ func SyncDirs(srcPath, destPath string) error {
9581
// util.ListDirRecursively appends a slash to the directory name
9682
if strings.HasSuffix(srcFile, "/") {
9783
err = os.MkdirAll(destFilePath, os.ModePerm)
98-
} else {
99-
err = Sync(filepath.Join(srcPath, srcFile), destFilePath)
84+
} else if filepath.Base(destFilePath) != keepFile {
85+
err = SyncFile(filepath.Join(srcPath, srcFile), destFilePath)
10086
}
10187
if err != nil {
10288
return err

routers/web/repo/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func MustBeNotEmpty(ctx *context.Context) {
5151

5252
// MustBeEditable check that repo can be edited
5353
func MustBeEditable(ctx *context.Context) {
54-
if !ctx.Repo.Repository.CanEnableEditor() || ctx.Repo.IsViewCommit {
54+
if !ctx.Repo.Repository.CanEnableEditor() {
5555
ctx.NotFound("", nil)
5656
return
5757
}

routers/web/repo/view_home.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ func handleRepoEmptyOrBroken(ctx *context.Context) {
249249
} else if reallyEmpty {
250250
showEmpty = true // the repo is really empty
251251
updateContextRepoEmptyAndStatus(ctx, true, repo_model.RepositoryReady)
252-
} else if ctx.Repo.Commit == nil {
252+
} else if branches, _, _ := ctx.Repo.GitRepo.GetBranches(0, 1); len(branches) == 0 {
253253
showEmpty = true // it is not really empty, but there is no branch
254254
// at the moment, other repo units like "actions" are not able to handle such case,
255255
// so we just mark the repo as empty to prevent from displaying these units.

routers/web/web.go

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"code.gitea.io/gitea/models/db"
1212
"code.gitea.io/gitea/models/perm"
1313
"code.gitea.io/gitea/models/unit"
14+
"code.gitea.io/gitea/modules/git"
1415
"code.gitea.io/gitea/modules/log"
1516
"code.gitea.io/gitea/modules/metrics"
1617
"code.gitea.io/gitea/modules/public"
@@ -817,7 +818,6 @@ func registerRoutes(m *web.Router) {
817818

818819
reqRepoAdmin := context.RequireRepoAdmin()
819820
reqRepoCodeWriter := context.RequireUnitWriter(unit.TypeCode)
820-
canEnableEditor := context.CanEnableEditor()
821821
reqRepoReleaseWriter := context.RequireUnitWriter(unit.TypeReleases)
822822
reqRepoReleaseReader := context.RequireUnitReader(unit.TypeReleases)
823823
reqRepoIssuesOrPullsWriter := context.RequireUnitWriter(unit.TypeIssues, unit.TypePullRequests)
@@ -1152,16 +1152,16 @@ func registerRoutes(m *web.Router) {
11521152
// end "/{username}/{reponame}/settings"
11531153

11541154
// user/org home, including rss feeds
1155-
m.Get("/{username}/{reponame}", optSignIn, context.RepoAssignment, context.RepoRef(), repo.SetEditorconfigIfExists, repo.Home)
1155+
m.Get("/{username}/{reponame}", optSignIn, context.RepoAssignment, context.RepoRefByType(git.RefTypeBranch), repo.SetEditorconfigIfExists, repo.Home)
11561156

11571157
m.Post("/{username}/{reponame}/markup", optSignIn, context.RepoAssignment, reqUnitsWithMarkdown, web.Bind(structs.MarkupOption{}), misc.Markup)
11581158

11591159
m.Group("/{username}/{reponame}", func() {
11601160
m.Get("/find/*", repo.FindFiles)
11611161
m.Group("/tree-list", func() {
1162-
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.TreeList)
1163-
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.TreeList)
1164-
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.TreeList)
1162+
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.TreeList)
1163+
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.TreeList)
1164+
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.TreeList)
11651165
})
11661166
m.Get("/compare", repo.MustBeNotEmpty, repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff)
11671167
m.Combo("/compare/*", repo.MustBeNotEmpty, repo.SetEditorconfigIfExists).
@@ -1306,18 +1306,18 @@ func registerRoutes(m *web.Router) {
13061306
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost)
13071307
m.Combo("/_cherrypick/{sha:([a-f0-9]{7,64})}/*").Get(repo.CherryPick).
13081308
Post(web.Bind(forms.CherryPickForm{}), repo.CherryPickPost)
1309-
}, repo.MustBeEditable)
1309+
}, context.RepoRefByType(git.RefTypeBranch), context.CanWriteToBranch())
13101310
m.Group("", func() {
13111311
m.Post("/upload-file", repo.UploadFileToServer)
13121312
m.Post("/upload-remove", web.Bind(forms.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
1313-
}, repo.MustBeEditable, repo.MustBeAbleToUpload)
1314-
}, context.RepoRef(), canEnableEditor, context.RepoMustNotBeArchived())
1313+
}, repo.MustBeAbleToUpload, reqRepoCodeWriter)
1314+
}, repo.MustBeEditable, context.RepoMustNotBeArchived())
13151315

13161316
m.Group("/branches", func() {
13171317
m.Group("/_new", func() {
1318-
m.Post("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.CreateBranch)
1319-
m.Post("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.CreateBranch)
1320-
m.Post("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.CreateBranch)
1318+
m.Post("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.CreateBranch)
1319+
m.Post("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.CreateBranch)
1320+
m.Post("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.CreateBranch)
13211321
}, web.Bind(forms.NewBranchForm{}))
13221322
m.Post("/delete", repo.DeleteBranchPost)
13231323
m.Post("/restore", repo.RestoreBranchPost)
@@ -1332,39 +1332,36 @@ func registerRoutes(m *web.Router) {
13321332
m.Group("/{username}/{reponame}", func() { // repo tags
13331333
m.Group("/tags", func() {
13341334
m.Get("", repo.TagsList)
1335-
m.Get("/list", repo.GetTagList)
13361335
m.Get(".rss", feedEnabled, repo.TagsListFeedRSS)
13371336
m.Get(".atom", feedEnabled, repo.TagsListFeedAtom)
1338-
}, ctxDataSet("EnableFeed", setting.Other.EnableFeed),
1339-
repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefTag, context.RepoRefByTypeOptions{IgnoreNotExistErr: true}))
1340-
m.Post("/tags/delete", repo.DeleteTag, reqSignIn,
1341-
repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoCodeWriter, context.RepoRef())
1342-
}, optSignIn, context.RepoAssignment, reqUnitCodeReader)
1337+
m.Get("/list", repo.GetTagList)
1338+
}, ctxDataSet("EnableFeed", setting.Other.EnableFeed))
1339+
m.Post("/tags/delete", reqSignIn, reqRepoCodeWriter, context.RepoMustNotBeArchived(), repo.DeleteTag)
1340+
}, optSignIn, context.RepoAssignment, repo.MustBeNotEmpty, reqUnitCodeReader)
13431341
// end "/{username}/{reponame}": repo tags
13441342

13451343
m.Group("/{username}/{reponame}", func() { // repo releases
13461344
m.Group("/releases", func() {
13471345
m.Get("", repo.Releases)
1348-
m.Get("/tag/*", repo.SingleRelease)
1349-
m.Get("/latest", repo.LatestRelease)
13501346
m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS)
13511347
m.Get(".atom", feedEnabled, repo.ReleasesFeedAtom)
1352-
}, ctxDataSet("EnableFeed", setting.Other.EnableFeed),
1353-
repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefTag, context.RepoRefByTypeOptions{IgnoreNotExistErr: true}))
1354-
m.Get("/releases/attachments/{uuid}", repo.MustBeNotEmpty, repo.GetAttachment)
1355-
m.Get("/releases/download/{vTag}/{fileName}", repo.MustBeNotEmpty, repo.RedirectDownload)
1348+
m.Get("/tag/*", repo.SingleRelease)
1349+
m.Get("/latest", repo.LatestRelease)
1350+
}, ctxDataSet("EnableFeed", setting.Other.EnableFeed))
1351+
m.Get("/releases/attachments/{uuid}", repo.GetAttachment)
1352+
m.Get("/releases/download/{vTag}/{fileName}", repo.RedirectDownload)
13561353
m.Group("/releases", func() {
13571354
m.Get("/new", repo.NewRelease)
13581355
m.Post("/new", web.Bind(forms.NewReleaseForm{}), repo.NewReleasePost)
13591356
m.Post("/delete", repo.DeleteRelease)
13601357
m.Post("/attachments", repo.UploadReleaseAttachment)
13611358
m.Post("/attachments/remove", repo.DeleteAttachment)
1362-
}, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef())
1359+
}, reqSignIn, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef())
13631360
m.Group("/releases", func() {
13641361
m.Get("/edit/*", repo.EditRelease)
13651362
m.Post("/edit/*", web.Bind(forms.EditReleaseForm{}), repo.EditReleasePost)
1366-
}, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, repo.CommitInfoCache)
1367-
}, optSignIn, context.RepoAssignment, reqRepoReleaseReader)
1363+
}, reqSignIn, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, repo.CommitInfoCache)
1364+
}, optSignIn, context.RepoAssignment, repo.MustBeNotEmpty, reqRepoReleaseReader)
13681365
// end "/{username}/{reponame}": repo releases
13691366

13701367
m.Group("/{username}/{reponame}", func() { // to maintain compatibility with old attachments
@@ -1528,42 +1525,39 @@ func registerRoutes(m *web.Router) {
15281525
}, repo.MustBeNotEmpty, context.RepoRef())
15291526

15301527
m.Group("/media", func() {
1531-
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.SingleDownloadOrLFS)
1532-
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.SingleDownloadOrLFS)
1533-
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.SingleDownloadOrLFS)
15341528
m.Get("/blob/{sha}", repo.DownloadByIDOrLFS)
1535-
// "/*" route is deprecated, and kept for backward compatibility
1536-
m.Get("/*", context.RepoRefByType(context.RepoRefUnknown), repo.SingleDownloadOrLFS)
1529+
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.SingleDownloadOrLFS)
1530+
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.SingleDownloadOrLFS)
1531+
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.SingleDownloadOrLFS)
1532+
m.Get("/*", context.RepoRefByType(""), repo.SingleDownloadOrLFS) // "/*" route is deprecated, and kept for backward compatibility
15371533
}, repo.MustBeNotEmpty)
15381534

15391535
m.Group("/raw", func() {
1540-
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.SingleDownload)
1541-
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.SingleDownload)
1542-
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.SingleDownload)
15431536
m.Get("/blob/{sha}", repo.DownloadByID)
1544-
// "/*" route is deprecated, and kept for backward compatibility
1545-
m.Get("/*", context.RepoRefByType(context.RepoRefUnknown), repo.SingleDownload)
1537+
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.SingleDownload)
1538+
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.SingleDownload)
1539+
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.SingleDownload)
1540+
m.Get("/*", context.RepoRefByType(""), repo.SingleDownload) // "/*" route is deprecated, and kept for backward compatibility
15461541
}, repo.MustBeNotEmpty)
15471542

15481543
m.Group("/render", func() {
1549-
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RenderFile)
1550-
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.RenderFile)
1551-
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RenderFile)
1544+
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.RenderFile)
1545+
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.RenderFile)
1546+
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.RenderFile)
15521547
m.Get("/blob/{sha}", repo.RenderFile)
15531548
}, repo.MustBeNotEmpty)
15541549

15551550
m.Group("/commits", func() {
1556-
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RefCommits)
1557-
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.RefCommits)
1558-
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RefCommits)
1559-
// "/*" route is deprecated, and kept for backward compatibility
1560-
m.Get("/*", context.RepoRefByType(context.RepoRefUnknown), repo.RefCommits)
1551+
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.RefCommits)
1552+
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.RefCommits)
1553+
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.RefCommits)
1554+
m.Get("/*", context.RepoRefByType(""), repo.RefCommits) // "/*" route is deprecated, and kept for backward compatibility
15611555
}, repo.MustBeNotEmpty)
15621556

15631557
m.Group("/blame", func() {
1564-
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RefBlame)
1565-
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.RefBlame)
1566-
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RefBlame)
1558+
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.RefBlame)
1559+
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.RefBlame)
1560+
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.RefBlame)
15671561
}, repo.MustBeNotEmpty)
15681562

15691563
m.Get("/blob_excerpt/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob)
@@ -1575,20 +1569,20 @@ func registerRoutes(m *web.Router) {
15751569
m.Get("/cherry-pick/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, repo.CherryPick)
15761570
}, repo.MustBeNotEmpty, context.RepoRef())
15771571

1578-
m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
1579-
m.Get("/atom/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
1572+
m.Get("/rss/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed)
1573+
m.Get("/atom/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed)
15801574

15811575
m.Group("/src", func() {
15821576
m.Get("", func(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink) }) // there is no "{owner}/{repo}/src" page, so redirect to "{owner}/{repo}" to avoid 404
1583-
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home)
1584-
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.Home)
1585-
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.Home)
1586-
m.Get("/*", context.RepoRefByType(context.RepoRefUnknown), repo.Home) // "/*" route is deprecated, and kept for backward compatibility
1577+
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.Home)
1578+
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.Home)
1579+
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.Home)
1580+
m.Get("/*", context.RepoRefByType(""), repo.Home) // "/*" route is deprecated, and kept for backward compatibility
15871581
}, repo.SetEditorconfigIfExists)
15881582

15891583
m.Get("/forks", context.RepoRef(), repo.Forks)
15901584
m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff)
1591-
m.Post("/lastcommit/*", context.RepoRefByType(context.RepoRefCommit), repo.LastCommit)
1585+
m.Post("/lastcommit/*", context.RepoRefByType(git.RefTypeCommit), repo.LastCommit)
15921586
}, optSignIn, context.RepoAssignment, reqUnitCodeReader)
15931587
// end "/{username}/{reponame}": repo code
15941588

services/context/permission.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ func RequireRepoAdmin() func(ctx *Context) {
2121
}
2222
}
2323

24-
// CanEnableEditor checks if the user is allowed to write to the branch of the repo
25-
func CanEnableEditor() func(ctx *Context) {
24+
// CanWriteToBranch checks if the user is allowed to write to the branch of the repo
25+
func CanWriteToBranch() func(ctx *Context) {
2626
return func(ctx *Context) {
2727
if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
2828
ctx.NotFound("CanWriteToBranch denies permission", nil)

0 commit comments

Comments
 (0)