Skip to content

Commit 7a7f560

Browse files
Adopt repositories (#12920)
* Don't automatically delete repository files if they are present Prior to this PR Gitea would delete any repository files if they are present during creation or migration. This can in certain circumstances lead to data-loss and is slightly unpleasant. This PR provides a mechanism for Gitea to adopt repositories on creation and otherwise requires an explicit flag for deletion. PushCreate is slightly different - the create will cause adoption if that is allowed otherwise it will delete the data if that is allowed. Signed-off-by: Andrew Thornton <[email protected]> * Update swagger Signed-off-by: Andrew Thornton <[email protected]> * Fix tests and migrate overwrite Signed-off-by: Andrew Thornton <[email protected]> * as per @lunny Only offer to adopt or overwrite if the user can do that. Allow the site administrator to adopt or overwrite in all circumstances Signed-off-by: Andrew Thornton <[email protected]> * Use setting.Repository.DefaultBranch for the default branch Signed-off-by: Andrew Thornton <[email protected]> * Always set setting.Repository.DefaultBranch Signed-off-by: Andrew Thornton <[email protected]> * update swagger Signed-off-by: Andrew Thornton <[email protected]> * update templates Signed-off-by: Andrew Thornton <[email protected]> * ensure repo closed Signed-off-by: Andrew Thornton <[email protected]> * Rewrite of adoption as per @6543 and @lunny Signed-off-by: Andrew Thornton <[email protected]> * Apply suggestions from code review * update swagger Signed-off-by: Andrew Thornton <[email protected]> * missing not Signed-off-by: Andrew Thornton <[email protected]> * add modals and flash reporting Signed-off-by: Andrew Thornton <[email protected]> * Make the unadopted page searchable Signed-off-by: Andrew Thornton <[email protected]> * Add API Signed-off-by: Andrew Thornton <[email protected]> * Fix swagger Signed-off-by: Andrew Thornton <[email protected]> * fix swagger Signed-off-by: Andrew Thornton <[email protected]> * Handle empty and non-master branched repositories Signed-off-by: Andrew Thornton <[email protected]> * placate lint Signed-off-by: Andrew Thornton <[email protected]> * remove commented out code Signed-off-by: Andrew Thornton <[email protected]> Co-authored-by: techknowlogick <[email protected]>
1 parent 6fa19a8 commit 7a7f560

File tree

31 files changed

+1335
-95
lines changed

31 files changed

+1335
-95
lines changed

custom/conf/app.example.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ PREFIX_ARCHIVE_FILES = true
6464
DISABLE_MIRRORS = false
6565
; The default branch name of new repositories
6666
DEFAULT_BRANCH=master
67+
; Allow adoption of unadopted repositories
68+
ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES=false
69+
; Allow deletion of unadopted repositories
70+
ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES=false
6771

6872
[repository.editor]
6973
; List of file extensions for which lines should be wrapped in the Monaco editor

models/error.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,22 @@ func (err ErrRepoAlreadyExist) Error() string {
743743
return fmt.Sprintf("repository already exists [uname: %s, name: %s]", err.Uname, err.Name)
744744
}
745745

746+
// ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error.
747+
type ErrRepoFilesAlreadyExist struct {
748+
Uname string
749+
Name string
750+
}
751+
752+
// IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist.
753+
func IsErrRepoFilesAlreadyExist(err error) bool {
754+
_, ok := err.(ErrRepoFilesAlreadyExist)
755+
return ok
756+
}
757+
758+
func (err ErrRepoFilesAlreadyExist) Error() string {
759+
return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name)
760+
}
761+
746762
// ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error.
747763
type ErrForkAlreadyExist struct {
748764
Uname string

models/repo.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ func (repo *Repository) IsBeingCreated() bool {
278278
func (repo *Repository) AfterLoad() {
279279
// FIXME: use models migration to solve all at once.
280280
if len(repo.DefaultBranch) == 0 {
281-
repo.DefaultBranch = "master"
281+
repo.DefaultBranch = setting.Repository.DefaultBranch
282282
}
283283

284284
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
@@ -1048,7 +1048,7 @@ func (repo *Repository) CloneLink() (cl *CloneLink) {
10481048
}
10491049

10501050
// CheckCreateRepository check if could created a repository
1051-
func CheckCreateRepository(doer, u *User, name string) error {
1051+
func CheckCreateRepository(doer, u *User, name string, overwriteOrAdopt bool) error {
10521052
if !doer.CanCreateRepo() {
10531053
return ErrReachLimitOfRepo{u.MaxRepoCreation}
10541054
}
@@ -1063,6 +1063,10 @@ func CheckCreateRepository(doer, u *User, name string) error {
10631063
} else if has {
10641064
return ErrRepoAlreadyExist{u.Name, name}
10651065
}
1066+
1067+
if !overwriteOrAdopt && com.IsExist(RepoPath(u.Name, name)) {
1068+
return ErrRepoFilesAlreadyExist{u.Name, name}
1069+
}
10661070
return nil
10671071
}
10681072

@@ -1116,11 +1120,15 @@ var (
11161120

11171121
// IsUsableRepoName returns true when repository is usable
11181122
func IsUsableRepoName(name string) error {
1123+
if alphaDashDotPattern.MatchString(name) {
1124+
// Note: usually this error is normally caught up earlier in the UI
1125+
return ErrNameCharsNotAllowed{Name: name}
1126+
}
11191127
return isUsableName(reservedRepoNames, reservedRepoPatterns, name)
11201128
}
11211129

11221130
// CreateRepository creates a repository for the user/organization.
1123-
func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error) {
1131+
func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, overwriteOrAdopt bool) (err error) {
11241132
if err = IsUsableRepoName(repo.Name); err != nil {
11251133
return err
11261134
}
@@ -1132,6 +1140,15 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error
11321140
return ErrRepoAlreadyExist{u.Name, repo.Name}
11331141
}
11341142

1143+
repoPath := RepoPath(u.Name, repo.Name)
1144+
if !overwriteOrAdopt && com.IsExist(repoPath) {
1145+
log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath)
1146+
return ErrRepoFilesAlreadyExist{
1147+
Uname: u.Name,
1148+
Name: repo.Name,
1149+
}
1150+
}
1151+
11351152
if _, err = ctx.e.Insert(repo); err != nil {
11361153
return err
11371154
}
@@ -1856,6 +1873,10 @@ func GetUserRepositories(opts *SearchRepoOptions) ([]*Repository, int64, error)
18561873
cond = cond.And(builder.Eq{"is_private": false})
18571874
}
18581875

1876+
if opts.LowerNames != nil && len(opts.LowerNames) > 0 {
1877+
cond = cond.And(builder.In("lower_name", opts.LowerNames))
1878+
}
1879+
18591880
sess := x.NewSession()
18601881
defer sess.Close()
18611882

models/repo_list.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ type SearchRepoOptions struct {
175175
// True -> include just has milestones
176176
// False -> include just has no milestone
177177
HasMilestones util.OptionalBool
178+
// LowerNames represents valid lower names to restrict to
179+
LowerNames []string
178180
}
179181

180182
//SearchOrderBy is used to sort the result

models/user.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,8 @@ func (u *User) GetOrganizationCount() (int64, error) {
646646
}
647647

648648
// GetRepositories returns repositories that user owns, including private repositories.
649-
func (u *User) GetRepositories(listOpts ListOptions) (err error) {
650-
u.Repos, _, err = GetUserRepositories(&SearchRepoOptions{Actor: u, Private: true, ListOptions: listOpts})
649+
func (u *User) GetRepositories(listOpts ListOptions, names ...string) (err error) {
650+
u.Repos, _, err = GetUserRepositories(&SearchRepoOptions{Actor: u, Private: true, ListOptions: listOpts, LowerNames: names})
651651
return err
652652
}
653653

modules/git/repo_branch.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ func (repo *Repository) SetDefaultBranch(name string) error {
7474
return err
7575
}
7676

77+
// GetDefaultBranch gets default branch of repository.
78+
func (repo *Repository) GetDefaultBranch() (string, error) {
79+
return NewCommand("symbolic-ref", "HEAD").RunInDir(repo.Path)
80+
}
81+
7782
// GetBranches returns all branches of the repository.
7883
func (repo *Repository) GetBranches() ([]string, error) {
7984
var branchNames []string

0 commit comments

Comments
 (0)