Skip to content

Commit 6285579

Browse files
update repository storage layout as per #1872 (comment)
1 parent 394b9cc commit 6285579

File tree

17 files changed

+292
-148
lines changed

17 files changed

+292
-148
lines changed

models/repo/repo.go

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,21 @@ func init() {
228228
db.RegisterModel(new(Repository))
229229
}
230230

231-
func RelativePath(ownerName, repoName string) string {
232-
return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".git"
231+
func RelativePathBaseName(ownerName, repoName string, groupID int64) string {
232+
var groupSegment string
233+
if groupID > 0 {
234+
groupSegment = strconv.FormatInt(groupID, 10) + "/"
235+
}
236+
return strings.ToLower(ownerName) + "/" + groupSegment + strings.ToLower(repoName)
237+
}
238+
239+
func RelativePath(ownerName, repoName string, groupID int64) string {
240+
return RelativePathBaseName(ownerName, repoName, groupID) + ".git"
233241
}
234242

235243
// RelativePath should be an unix style path like username/reponame.git
236244
func (repo *Repository) RelativePath() string {
237-
return RelativePath(repo.OwnerName, repo.Name)
245+
return RelativePath(repo.OwnerName, repo.Name, repo.GroupID)
238246
}
239247

240248
type StorageRepo string
@@ -245,7 +253,7 @@ func (sr StorageRepo) RelativePath() string {
245253
}
246254

247255
func (repo *Repository) WikiStorageRepo() StorageRepo {
248-
return StorageRepo(strings.ToLower(repo.OwnerName) + "/" + strings.ToLower(repo.Name) + ".wiki.git")
256+
return StorageRepo(RelativePathBaseName(repo.Name, repo.OwnerName, repo.GroupID) + ".wiki.git")
249257
}
250258

251259
// SanitizedOriginalURL returns a sanitized OriginalURL
@@ -603,13 +611,19 @@ func (repo *Repository) IsGenerated() bool {
603611
}
604612

605613
// RepoPath returns repository path by given user and repository name.
606-
func RepoPath(userName, repoName string) string { //revive:disable-line:exported
607-
return filepath.Join(user_model.UserPath(userName), strings.ToLower(repoName)+".git")
614+
func RepoPath(userName, repoName string, groupID int64) string { //revive:disable-line:exported
615+
var joinArgs []string
616+
joinArgs = append(joinArgs, user_model.UserPath(userName))
617+
if groupID > 0 {
618+
joinArgs = append(joinArgs, strconv.FormatInt(groupID, 10))
619+
}
620+
joinArgs = append(joinArgs, strings.ToLower(repoName)+".git")
621+
return filepath.Join(joinArgs...)
608622
}
609623

610624
// RepoPath returns the repository path
611625
func (repo *Repository) RepoPath() string {
612-
return RepoPath(repo.OwnerName, repo.Name)
626+
return RepoPath(repo.OwnerName, repo.Name, repo.GroupID)
613627
}
614628

615629
// Link returns the repository relative url
@@ -682,13 +696,25 @@ type CloneLink struct {
682696
Tea string
683697
}
684698

699+
func getGroupSegment(gid int64) string {
700+
var groupSegment string
701+
if gid > 0 {
702+
groupSegment = fmt.Sprintf("%d", gid)
703+
}
704+
return groupSegment
705+
}
706+
707+
func groupSegmentWithTrailingSlash(gid int64) string {
708+
return getGroupSegment(gid) + "/"
709+
}
710+
685711
// ComposeHTTPSCloneURL returns HTTPS clone URL based on the given owner and repository name.
686-
func ComposeHTTPSCloneURL(ctx context.Context, owner, repo string) string {
687-
return fmt.Sprintf("%s%s/%s.git", httplib.GuessCurrentAppURL(ctx), url.PathEscape(owner), url.PathEscape(repo))
712+
func ComposeHTTPSCloneURL(ctx context.Context, owner, repo string, groupID int64) string {
713+
return fmt.Sprintf("%s%s/%s%s.git", httplib.GuessCurrentAppURL(ctx), url.PathEscape(owner), groupSegmentWithTrailingSlash(groupID), url.PathEscape(repo))
688714
}
689715

690716
// ComposeSSHCloneURL returns SSH clone URL based on the given owner and repository name.
691-
func ComposeSSHCloneURL(doer *user_model.User, ownerName, repoName string) string {
717+
func ComposeSSHCloneURL(doer *user_model.User, ownerName, repoName string, groupID int64) string {
692718
sshUser := setting.SSH.User
693719
sshDomain := setting.SSH.Domain
694720

@@ -707,7 +733,7 @@ func ComposeSSHCloneURL(doer *user_model.User, ownerName, repoName string) strin
707733
// non-standard port, it must use full URI
708734
if setting.SSH.Port != 22 {
709735
sshHost := net.JoinHostPort(sshDomain, strconv.Itoa(setting.SSH.Port))
710-
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName))
736+
return fmt.Sprintf("ssh://%s@%s/%s%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), groupSegmentWithTrailingSlash(groupID), url.PathEscape(repoName))
711737
}
712738

713739
// for standard port, it can use a shorter URI (without the port)
@@ -722,25 +748,25 @@ func ComposeSSHCloneURL(doer *user_model.User, ownerName, repoName string) strin
722748
}
723749

724750
// ComposeTeaCloneCommand returns Tea CLI clone command based on the given owner and repository name.
725-
func ComposeTeaCloneCommand(ctx context.Context, owner, repo string) string {
726-
return fmt.Sprintf("tea clone %s/%s", url.PathEscape(owner), url.PathEscape(repo))
751+
func ComposeTeaCloneCommand(ctx context.Context, owner, repo string, groupID int64) string {
752+
return fmt.Sprintf("tea clone %s/%s%s", url.PathEscape(owner), url.PathEscape(repo), groupSegmentWithTrailingSlash(groupID))
727753
}
728754

729-
func (repo *Repository) cloneLink(ctx context.Context, doer *user_model.User, repoPathName string) *CloneLink {
755+
func (repo *Repository) cloneLink(ctx context.Context, doer *user_model.User, repoPathName string, groupID int64) *CloneLink {
730756
return &CloneLink{
731-
SSH: ComposeSSHCloneURL(doer, repo.OwnerName, repoPathName),
732-
HTTPS: ComposeHTTPSCloneURL(ctx, repo.OwnerName, repoPathName),
733-
Tea: ComposeTeaCloneCommand(ctx, repo.OwnerName, repoPathName),
757+
SSH: ComposeSSHCloneURL(doer, repo.OwnerName, repoPathName, groupID),
758+
HTTPS: ComposeHTTPSCloneURL(ctx, repo.OwnerName, repoPathName, groupID),
759+
Tea: ComposeTeaCloneCommand(ctx, repo.OwnerName, repoPathName, groupID),
734760
}
735761
}
736762

737763
// CloneLink returns clone URLs of repository.
738764
func (repo *Repository) CloneLink(ctx context.Context, doer *user_model.User) (cl *CloneLink) {
739-
return repo.cloneLink(ctx, doer, repo.Name)
765+
return repo.cloneLink(ctx, doer, repo.Name, repo.GroupID)
740766
}
741767

742768
func (repo *Repository) CloneLinkGeneral(ctx context.Context) (cl *CloneLink) {
743-
return repo.cloneLink(ctx, nil /* no doer, use a general git user */, repo.Name)
769+
return repo.cloneLink(ctx, nil /* no doer, use a general git user */, repo.Name, repo.GroupID)
744770
}
745771

746772
// GetOriginalURLHostname returns the hostname of a URL or the URL
@@ -879,19 +905,20 @@ func GetRepositoriesMapByIDs(ctx context.Context, ids []int64) (map[int64]*Repos
879905
}
880906

881907
// IsRepositoryModelOrDirExist returns true if the repository with given name under user has already existed.
882-
func IsRepositoryModelOrDirExist(ctx context.Context, u *user_model.User, repoName string) (bool, error) {
883-
has, err := IsRepositoryModelExist(ctx, u, repoName)
908+
func IsRepositoryModelOrDirExist(ctx context.Context, u *user_model.User, repoName string, groupID int64) (bool, error) {
909+
has, err := IsRepositoryModelExist(ctx, u, repoName, groupID)
884910
if err != nil {
885911
return false, err
886912
}
887-
isDir, err := util.IsDir(RepoPath(u.Name, repoName))
913+
isDir, err := util.IsDir(RepoPath(u.Name, repoName, groupID))
888914
return has || isDir, err
889915
}
890916

891-
func IsRepositoryModelExist(ctx context.Context, u *user_model.User, repoName string) (bool, error) {
917+
func IsRepositoryModelExist(ctx context.Context, u *user_model.User, repoName string, groupID int64) (bool, error) {
892918
return db.GetEngine(ctx).Get(&Repository{
893919
OwnerID: u.ID,
894920
LowerName: strings.ToLower(repoName),
921+
GroupID: groupID,
895922
})
896923
}
897924

models/repo/transfer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_m
254254
}
255255

256256
// Check if new owner has repository with same name.
257-
if has, err := IsRepositoryModelExist(ctx, newOwner, repo.Name); err != nil {
257+
if has, err := IsRepositoryModelExist(ctx, newOwner, repo.Name, repo.GroupID); err != nil {
258258
return fmt.Errorf("IsRepositoryExist: %w", err)
259259
} else if has {
260260
return ErrRepoAlreadyExist{

models/repo/update.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ func CheckCreateRepository(ctx context.Context, doer, owner *user_model.User, na
116116
return err
117117
}
118118

119-
has, err := IsRepositoryModelOrDirExist(ctx, owner, name)
119+
has, err := IsRepositoryModelOrDirExist(ctx, owner, name, 0)
120120
if err != nil {
121121
return fmt.Errorf("IsRepositoryExist: %w", err)
122122
} else if has {
123123
return ErrRepoAlreadyExist{owner.Name, name}
124124
}
125125

126-
repoPath := RepoPath(owner.Name, name)
126+
repoPath := RepoPath(owner.Name, name, 0)
127127
isExist, err := util.IsExist(repoPath)
128128
if err != nil {
129129
log.Error("Unable to check if %s exists. Error: %v", repoPath, err)

models/repo/wiki.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@
55
package repo
66

77
import (
8-
"context"
9-
"fmt"
10-
"path/filepath"
11-
"strings"
12-
138
user_model "code.gitea.io/gitea/models/user"
149
"code.gitea.io/gitea/modules/log"
1510
"code.gitea.io/gitea/modules/util"
11+
"context"
12+
"fmt"
1613
)
1714

1815
// ErrWikiAlreadyExist represents a "WikiAlreadyExist" kind of error.
@@ -74,17 +71,17 @@ func (err ErrWikiInvalidFileName) Unwrap() error {
7471

7572
// WikiCloneLink returns clone URLs of repository wiki.
7673
func (repo *Repository) WikiCloneLink(ctx context.Context, doer *user_model.User) *CloneLink {
77-
return repo.cloneLink(ctx, doer, repo.Name+".wiki")
74+
return repo.cloneLink(ctx, doer, repo.Name+".wiki", repo.GroupID)
7875
}
7976

8077
// WikiPath returns wiki data path by given user and repository name.
81-
func WikiPath(userName, repoName string) string {
82-
return filepath.Join(user_model.UserPath(userName), strings.ToLower(repoName)+".wiki.git")
78+
func WikiPath(userName, repoName string, groupID int64) string {
79+
return RepoPath(userName, repoName+".wiki", groupID)
8380
}
8481

8582
// WikiPath returns wiki data path for given repository.
8683
func (repo *Repository) WikiPath() string {
87-
return WikiPath(repo.OwnerName, repo.Name)
84+
return WikiPath(repo.OwnerName, repo.Name, repo.GroupID)
8885
}
8986

9087
// HasWiki returns true if repository has wiki.

0 commit comments

Comments
 (0)