Ver código fonte

#1021 Forked repo unavailable after deleting original repo

Unknwon 9 anos atrás
pai
commit
398569f6f8

+ 4 - 0
conf/locale/locale_en-US.ini

@@ -319,6 +319,7 @@ repo_name = Repository Name
 repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
 visibility = Visibility
 visiblity_helper = This repository is <span class="ui red text">Private</span>
+visiblity_fork_helper = (Change of this value will affect all forks)
 fork_repo = Fork Repository
 fork_from = Fork From
 fork_visiblity_helper = You cannot alter the visibility of a forked repository.
@@ -508,6 +509,9 @@ settings.transfer_notices_2 = - You will conserve access if new owner is an orga
 settings.transfer_form_title = Please enter following information to confirm your operation: 
 settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
 settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
+settings.delete_notices_fork_1 = - If this repository is public, all forks will be became independent after deletion.
+settings.delete_notices_fork_2 = - If this repository is private, all forks will be removed at the same time.
+settings.delete_notices_fork_3 = - If you want to keep all forks after deletion, please change visibility of this repository to public first.
 settings.update_settings_success = Repository options has been updated successfully.
 settings.transfer_owner = New Owner
 settings.make_transfer = Make Transfer

+ 24 - 23
models/action.go

@@ -158,6 +158,30 @@ func NewRepoAction(u *User, repo *Repository) (err error) {
 	return newRepoAction(x, u, repo)
 }
 
+func renameRepoAction(e Engine, actUser *User, oldRepoName string, repo *Repository) (err error) {
+	if err = notifyWatchers(e, &Action{
+		ActUserID:    actUser.Id,
+		ActUserName:  actUser.Name,
+		ActEmail:     actUser.Email,
+		OpType:       RENAME_REPO,
+		RepoID:       repo.ID,
+		RepoUserName: repo.Owner.Name,
+		RepoName:     repo.Name,
+		IsPrivate:    repo.IsPrivate,
+		Content:      oldRepoName,
+	}); err != nil {
+		return fmt.Errorf("notify watchers: %v", err)
+	}
+
+	log.Trace("action.renameRepoAction: %s/%s", actUser.Name, repo.Name)
+	return nil
+}
+
+// RenameRepoAction adds new action for renaming a repository.
+func RenameRepoAction(actUser *User, oldRepoName string, repo *Repository) error {
+	return renameRepoAction(x, actUser, oldRepoName, repo)
+}
+
 // updateIssuesCommit checks if issues are manipulated by commit message.
 func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string, commits []*base.PushCommit) error {
 	for _, c := range commits {
@@ -502,29 +526,6 @@ func TransferRepoAction(actUser, oldOwner, newOwner *User, repo *Repository) err
 	return transferRepoAction(x, actUser, oldOwner, newOwner, repo)
 }
 
-func renameRepoAction(e Engine, actUser *User, oldRepoName string, repo *Repository) (err error) {
-	if err = notifyWatchers(e, &Action{
-		ActUserID:    actUser.Id,
-		ActUserName:  actUser.Name,
-		ActEmail:     actUser.Email,
-		OpType:       RENAME_REPO,
-		RepoUserName: repo.Owner.Name,
-		RepoName:     repo.Name,
-		IsPrivate:    repo.IsPrivate,
-		Content:      oldRepoName,
-	}); err != nil {
-		return fmt.Errorf("notify watchers: %v", err)
-	}
-
-	log.Trace("action.renameRepoAction: %s/%s", actUser.Name, repo.Name)
-	return nil
-}
-
-// RenameRepoAction adds new action for renaming a repository.
-func RenameRepoAction(actUser *User, oldRepoName string, repo *Repository) error {
-	return renameRepoAction(x, actUser, oldRepoName, repo)
-}
-
 // GetFeeds returns action list of given user in given context.
 func GetFeeds(uid, offset int64, isProfile bool) ([]*Action, error) {
 	actions := make([]*Action, 0, 20)

+ 1 - 1
models/models.go

@@ -78,7 +78,7 @@ func init() {
 	tables = append(tables,
 		new(User), new(PublicKey), new(Oauth2), new(AccessToken),
 		new(Repository), new(DeployKey), new(Collaboration), new(Access),
-		new(Watch), new(Star), new(Follow), new(Action),
+		new(Watch), new(Star), new(ForkInfo), new(Follow), new(Action),
 		new(Issue), new(Comment), new(Attachment), new(IssueUser),
 		new(Label), new(IssueLabel), new(Milestone),
 		new(Mirror), new(Release), new(LoginSource), new(Webhook),

+ 165 - 70
models/repo.go

@@ -160,6 +160,7 @@ type Repository struct {
 	IsFork   bool `xorm:"NOT NULL DEFAULT false"`
 	ForkID   int64
 	BaseRepo *Repository `xorm:"-"`
+	ForkInfo *ForkInfo   `xorm:"-"`
 
 	Created time.Time `xorm:"CREATED"`
 	Updated time.Time `xorm:"UPDATED"`
@@ -167,6 +168,15 @@ type Repository struct {
 
 func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
 	switch colName {
+	case "is_fork":
+		forkInfo := new(ForkInfo)
+		has, err := x.Where("repo_id=?", repo.ID).Get(forkInfo)
+		if err != nil {
+			log.Error(3, "get fork in[%d]: %v", repo.ID, err)
+			return
+		} else if has {
+			repo.ForkInfo = forkInfo
+		}
 	case "updated":
 		repo.Updated = regulateTimeZone(repo.Updated)
 	}
@@ -883,6 +893,16 @@ func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error)
 	return os.Rename(RepoPath(u.LowerName, oldRepoName), RepoPath(u.LowerName, newRepoName))
 }
 
+func getRepositoriesByForkID(e Engine, forkID int64) ([]*Repository, error) {
+	repos := make([]*Repository, 0, 10)
+	return repos, e.Where("fork_id=?", forkID).Find(&repos)
+}
+
+// GetRepositoriesByForkID returns all repositories with given fork ID.
+func GetRepositoriesByForkID(forkID int64) ([]*Repository, error) {
+	return getRepositoriesByForkID(x, forkID)
+}
+
 func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) {
 	repo.LowerName = strings.ToLower(repo.Name)
 
@@ -909,6 +929,17 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e
 		if err = repo.recalculateTeamAccesses(e, 0); err != nil {
 			return fmt.Errorf("recalculateTeamAccesses: %v", err)
 		}
+
+		forkRepos, err := getRepositoriesByForkID(e, repo.ID)
+		if err != nil {
+			return fmt.Errorf("getRepositoriesByForkID: %v", err)
+		}
+		for i := range forkRepos {
+			forkRepos[i].IsPrivate = repo.IsPrivate
+			if err = updateRepository(e, forkRepos[i], true); err != nil {
+				return fmt.Errorf("updateRepository[%d]: %v", forkRepos[i].ID, err)
+			}
+		}
 	}
 
 	return nil
@@ -929,7 +960,7 @@ func UpdateRepository(repo *Repository, visibilityChanged bool) (err error) {
 }
 
 // DeleteRepository deletes a repository for a user or organization.
-func DeleteRepository(uid, repoID int64, userName string) error {
+func DeleteRepository(uid, repoID int64) error {
 	repo := &Repository{ID: repoID, OwnerID: uid}
 	has, err := x.Get(repo)
 	if err != nil {
@@ -1015,7 +1046,9 @@ func DeleteRepository(uid, repoID int64, userName string) error {
 
 	if repo.IsFork {
 		if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repo.ForkID); err != nil {
-			return err
+			return fmt.Errorf("decrease fork count: %v", err)
+		} else if _, err = sess.Delete(&ForkInfo{RepoID: repo.ID}); err != nil {
+			return fmt.Errorf("delete fork info: %v", err)
 		}
 	}
 
@@ -1024,8 +1057,12 @@ func DeleteRepository(uid, repoID int64, userName string) error {
 	}
 
 	// Remove repository files.
-	if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil {
-		desc := fmt.Sprintf("delete repository files(%s/%s): %v", userName, repo.Name, err)
+	repoPath, err := repo.RepoPath()
+	if err != nil {
+		return fmt.Errorf("RepoPath: %v", err)
+	}
+	if err = os.RemoveAll(repoPath); err != nil {
+		desc := fmt.Sprintf("delete repository files[%s]: %v", repoPath, err)
 		log.Warn(desc)
 		if err = CreateRepositoryNotice(desc); err != nil {
 			log.Error(4, "add notice: %v", err)
@@ -1039,7 +1076,32 @@ func DeleteRepository(uid, repoID int64, userName string) error {
 		}
 	}
 
-	return sess.Commit()
+	if err = sess.Commit(); err != nil {
+		return fmt.Errorf("Commit: %v", err)
+	}
+
+	if repo.NumForks > 0 {
+		if repo.IsPrivate {
+			forkRepos, err := GetRepositoriesByForkID(repo.ID)
+			if err != nil {
+				return fmt.Errorf("getRepositoriesByForkID: %v", err)
+			}
+			for i := range forkRepos {
+				if err = DeleteRepository(forkRepos[i].OwnerID, forkRepos[i].ID); err != nil {
+					log.Error(4, "updateRepository[%d]: %v", forkRepos[i].ID, err)
+				}
+			}
+		} else {
+			if _, err = x.Exec("UPDATE `repository` SET fork_id=0,is_fork=? WHERE fork_id=?", false, repo.ID); err != nil {
+				log.Error(4, "reset 'fork_id' and 'is_fork': %v", err)
+			}
+			if _, err = x.Delete(&ForkInfo{ForkID: repo.ID}); err != nil {
+				log.Error(4, "clear fork infos: %v", err)
+			}
+		}
+	}
+
+	return nil
 }
 
 // GetRepositoryByRef returns a Repository specified by a GFM reference.
@@ -1275,78 +1337,96 @@ func GitGcRepos() error {
 		})
 }
 
-func CheckRepoStats() {
-	if isCheckingRepos {
-		return
-	}
-	isCheckingRepos = true
-	defer func() { isCheckingRepos = false }()
-
-	log.Trace("Doing: CheckRepoStats")
+type repoChecker struct {
+	querySQL, correctSQL string
+	desc                 string
+}
 
-	// ***** START: Repository.NumWatches *****
-	results, err := x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_watches!=(SELECT COUNT(*) FROM `watch` WHERE repo_id=repo.id)")
+func repoStatsCheck(checker *repoChecker) {
+	results, err := x.Query(checker.querySQL)
 	if err != nil {
-		log.Error(4, "Select repository check 'watch': %v", err)
+		log.Error(4, "Select %s: %v", checker.desc, err)
 		return
 	}
-	for _, watch := range results {
-		repoID := com.StrTo(watch["id"]).MustInt64()
-		log.Trace("Updating repository count 'watch': %d", repoID)
-		_, err = x.Exec("UPDATE `repository` SET num_watches=(SELECT COUNT(*) FROM `watch` WHERE repo_id=?) WHERE id=?", repoID, repoID)
+	for _, result := range results {
+		id := com.StrTo(result["id"]).MustInt64()
+		log.Trace("Updating %s: %d", checker.desc, id)
+		_, err = x.Exec(checker.correctSQL, id, id)
 		if err != nil {
-			log.Error(4, "Update repository check 'watch'[%d]: %v", repoID, err)
+			log.Error(4, "Update %s[%d]: %v", checker.desc, id, err)
 		}
 	}
-	// ***** END: Repository.NumWatches *****
+}
 
-	// ***** START: Repository.NumStars *****
-	results, err = x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_stars!=(SELECT COUNT(*) FROM `star` WHERE repo_id=repo.id)")
-	if err != nil {
-		log.Error(4, "Select repository check 'star': %v", err)
+func CheckRepoStats() {
+	if isCheckingRepos {
 		return
 	}
-	for _, star := range results {
-		repoID := com.StrTo(star["id"]).MustInt64()
-		log.Trace("Updating repository count 'star': %d", repoID)
-		_, err = x.Exec("UPDATE `repository` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE repo_id=?) WHERE id=?", repoID, repoID)
-		if err != nil {
-			log.Error(4, "Update repository check 'star'[%d]: %v", repoID, err)
-		}
-	}
-	// ***** END: Repository.NumStars *****
+	isCheckingRepos = true
+	defer func() { isCheckingRepos = false }()
 
-	// ***** START: Label.NumIssues *****
-	results, err = x.Query("SELECT label.id FROM `label` WHERE label.num_issues!=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=label.id)")
-	if err != nil {
-		log.Error(4, "Select label check 'num_issues': %v", err)
-		return
-	}
-	for _, label := range results {
-		labelID := com.StrTo(label["id"]).MustInt64()
-		log.Trace("Updating label count 'num_issues': %d", labelID)
-		_, err = x.Exec("UPDATE `label` SET num_issues=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=?) WHERE id=?", labelID, labelID)
-		if err != nil {
-			log.Error(4, "Update label check 'num_issues'[%d]: %v", labelID, err)
-		}
-	}
-	// ***** END: Label.NumIssues *****
+	log.Trace("Doing: CheckRepoStats")
 
-	// ***** START: User.NumRepos *****
-	results, err = x.Query("SELECT `user`.id FROM `user` WHERE `user`.num_repos!=(SELECT COUNT(*) FROM `repository` WHERE owner_id=`user`.id)")
+	checkers := []*repoChecker{
+		// Repository.NumWatches
+		{
+			"SELECT repo.id FROM `repository` repo WHERE repo.num_watches!=(SELECT COUNT(*) FROM `watch` WHERE repo_id=repo.id)",
+			"UPDATE `repository` SET num_watches=(SELECT COUNT(*) FROM `watch` WHERE repo_id=?) WHERE id=?",
+			"repository count 'num_watches'",
+		},
+		// Repository.NumStars
+		{
+			"SELECT repo.id FROM `repository` repo WHERE repo.num_stars!=(SELECT COUNT(*) FROM `star` WHERE repo_id=repo.id)",
+			"UPDATE `repository` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE repo_id=?) WHERE id=?",
+			"repository count 'num_stars'",
+		},
+		// Label.NumIssues
+		{
+			"SELECT label.id FROM `label` WHERE label.num_issues!=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=label.id)",
+			"UPDATE `label` SET num_issues=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=?) WHERE id=?",
+			"label count 'num_issues'",
+		},
+		// User.NumRepos
+		{
+			"SELECT `user`.id FROM `user` WHERE `user`.num_repos!=(SELECT COUNT(*) FROM `repository` WHERE owner_id=`user`.id)",
+			"UPDATE `user` SET num_repos=(SELECT COUNT(*) FROM `repository` WHERE owner_id=?) WHERE id=?",
+			"user count 'num_repos'",
+		},
+	}
+	for i := range checkers {
+		repoStatsCheck(checkers[i])
+	}
+
+	// FIXME: use checker when v0.8, stop supporting old fork repo format.
+	// ***** START: Repository.NumForks *****
+	results, err := x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_forks!=(SELECT COUNT(*) FROM `repository` WHERE fork_id=repo.id)")
 	if err != nil {
-		log.Error(4, "Select user check 'num_repos': %v", err)
-		return
-	}
-	for _, user := range results {
-		userID := com.StrTo(user["id"]).MustInt64()
-		log.Trace("Updating user count 'num_repos': %d", userID)
-		_, err = x.Exec("UPDATE `user` SET num_repos=(SELECT COUNT(*) FROM `repository` WHERE owner_id=?) WHERE id=?", userID, userID)
-		if err != nil {
-			log.Error(4, "Update user check 'num_repos'[%d]: %v", userID, err)
+		log.Error(4, "Select repository count 'num_forks': %v", err)
+	} else {
+		for _, result := range results {
+			id := com.StrTo(result["id"]).MustInt64()
+			log.Trace("Updating repository count 'num_forks': %d", id)
+
+			repo, err := GetRepositoryByID(id)
+			if err != nil {
+				log.Error(4, "GetRepositoryByID[%d]: %v", id, err)
+				continue
+			}
+
+			rawResult, err := x.Query("SELECT COUNT(*) FROM `repository` WHERE fork_id=?", repo.ID)
+			if err != nil {
+				log.Error(4, "Select count of forks[%d]: %v", repo.ID, err)
+				continue
+			}
+			repo.NumForks = int(parseCountResult(rawResult))
+
+			if err = UpdateRepository(repo, false); err != nil {
+				log.Error(4, "UpdateRepository[%d]: %v", id, err)
+				continue
+			}
 		}
 	}
-	// ***** END: User.NumRepos *****
+	// ***** END: Repository.NumForks *****
 }
 
 // _________        .__  .__        ___.                        __  .__
@@ -1589,6 +1669,13 @@ func IsStaring(uid, repoId int64) bool {
 //  \___  / \____/|__|  |__|_ \
 //      \/                   \/
 
+type ForkInfo struct {
+	ID            int64 `xorm:"pk autoincr"`
+	ForkID        int64
+	RepoID        int64  `xorm:"UNIQUE"`
+	StartCommitID string `xorm:"VARCHAR(40)"`
+}
+
 // HasForkedRepo checks if given user has already forked a repository with given ID.
 func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
 	repo := new(Repository)
@@ -1598,14 +1685,15 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
 
 func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
 	repo := &Repository{
-		OwnerID:     u.Id,
-		Owner:       u,
-		Name:        name,
-		LowerName:   strings.ToLower(name),
-		Description: desc,
-		IsPrivate:   oldRepo.IsPrivate,
-		IsFork:      true,
-		ForkID:      oldRepo.ID,
+		OwnerID:       u.Id,
+		Owner:         u,
+		Name:          name,
+		LowerName:     strings.ToLower(name),
+		Description:   desc,
+		DefaultBranch: oldRepo.DefaultBranch,
+		IsPrivate:     oldRepo.IsPrivate,
+		IsFork:        true,
+		ForkID:        oldRepo.ID,
 	}
 
 	sess := x.NewSession()
@@ -1621,6 +1709,13 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
 	if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.ID); err != nil {
 		return nil, err
 	}
+	// else if _, err = sess.Insert(&ForkInfo{
+	// 	ForkID:        oldRepo.ID,
+	// 	RepoID:        repo.ID,
+	// 	StartCommitID: "",
+	// }); err != nil {
+	// 	return nil, fmt.Errorf("insert fork info: %v", err)
+	// }
 
 	oldRepoPath, err := oldRepo.RepoPath()
 	if err != nil {

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
modules/bindata/bindata.go


+ 37 - 25
modules/middleware/repo.go

@@ -190,6 +190,41 @@ func RepoRef() macaron.Handler {
 	}
 }
 
+func RetrieveBaseRepo(ctx *Context, repo *models.Repository) {
+	// Non-fork repository will not return error in this method.
+	if err := repo.GetBaseRepo(); err != nil {
+		if models.IsErrRepoNotExist(err) {
+			repo.IsFork = false
+			repo.ForkID = 0
+			return
+		}
+		ctx.Handle(500, "GetBaseRepo", err)
+		return
+	} else if err = repo.BaseRepo.GetOwner(); err != nil {
+		ctx.Handle(500, "BaseRepo.GetOwner", err)
+		return
+	}
+
+	bsaeRepo := repo.BaseRepo
+	baseGitRepo, err := git.OpenRepository(models.RepoPath(bsaeRepo.Owner.Name, bsaeRepo.Name))
+	if err != nil {
+		ctx.Handle(500, "OpenRepository", err)
+		return
+	}
+	if len(bsaeRepo.DefaultBranch) > 0 && baseGitRepo.IsBranchExist(bsaeRepo.DefaultBranch) {
+		ctx.Data["BaseDefaultBranch"] = bsaeRepo.DefaultBranch
+	} else {
+		baseBranches, err := baseGitRepo.GetBranches()
+		if err != nil {
+			ctx.Handle(500, "GetBranches", err)
+			return
+		}
+		if len(baseBranches) > 0 {
+			ctx.Data["BaseDefaultBranch"] = baseBranches[0]
+		}
+	}
+}
+
 func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 	return func(ctx *Context) {
 		var (
@@ -292,32 +327,9 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 		ctx.Repo.Repository.NumTags = len(tags)
 
 		if repo.IsFork {
-			// Non-fork repository will not return error in this method.
-			if err = repo.GetBaseRepo(); err != nil {
-				ctx.Handle(500, "GetBaseRepo", err)
+			RetrieveBaseRepo(ctx, repo)
+			if ctx.Written() {
 				return
-			} else if repo.BaseRepo.GetOwner(); err != nil {
-				ctx.Handle(500, "BaseRepo.GetOwner", err)
-				return
-			}
-
-			bsaeRepo := repo.BaseRepo
-			baseGitRepo, err := git.OpenRepository(models.RepoPath(bsaeRepo.Owner.Name, bsaeRepo.Name))
-			if err != nil {
-				ctx.Handle(500, "OpenRepository", err)
-				return
-			}
-			if len(bsaeRepo.DefaultBranch) > 0 && baseGitRepo.IsBranchExist(bsaeRepo.DefaultBranch) {
-				ctx.Data["BaseDefaultBranch"] = bsaeRepo.DefaultBranch
-			} else {
-				baseBranches, err := baseGitRepo.GetBranches()
-				if err != nil {
-					ctx.Handle(500, "GetBranches", err)
-					return
-				}
-				if len(baseBranches) > 0 {
-					ctx.Data["BaseDefaultBranch"] = baseBranches[0]
-				}
 			}
 		}
 

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
public/css/gogs.min.css


+ 7 - 5
public/less/_form.less

@@ -61,11 +61,13 @@
 	}
 
 	&.new.repo {
-		.selection.dropdown {
-			width: 50%!important;
-		}
-		#auto-init {
-			margin-left: @input-padding+15px;
+		.ui.form {
+			.selection.dropdown:not(.owner) {
+				width: 50%!important;
+			}
+			#auto-init {
+				margin-left: @input-padding+15px;
+			}
 		}
 	}
 }

+ 2 - 2
routers/api/v1/repo.go

@@ -151,7 +151,7 @@ func createRepo(ctx *middleware.Context, owner *models.User, opt api.CreateRepoO
 		} else {
 			log.Error(4, "CreateRepository: %v", err)
 			if repo != nil {
-				if err = models.DeleteRepository(ctx.User.Id, repo.ID, ctx.User.Name); err != nil {
+				if err = models.DeleteRepository(ctx.User.Id, repo.ID); err != nil {
 					log.Error(4, "DeleteRepository: %v", err)
 				}
 			}
@@ -256,7 +256,7 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
 	repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr)
 	if err != nil {
 		if repo != nil {
-			if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID, ctxUser.Name); errDelete != nil {
+			if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID); errDelete != nil {
 				log.Error(4, "DeleteRepository: %v", errDelete)
 			}
 		}

+ 2 - 2
routers/repo/repo.go

@@ -126,7 +126,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 	}
 
 	if repo != nil {
-		if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID, ctxUser.Name); errDelete != nil {
+		if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID); errDelete != nil {
 			log.Error(4, "DeleteRepository: %v", errDelete)
 		}
 	}
@@ -192,7 +192,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 	}
 
 	if repo != nil {
-		if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID, ctxUser.Name); errDelete != nil {
+		if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID); errDelete != nil {
 			log.Error(4, "DeleteRepository: %v", errDelete)
 		}
 	}

+ 10 - 4
routers/repo/setting.go

@@ -53,10 +53,12 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 			return
 		}
 
+		isNameChanged := false
 		oldRepoName := repo.Name
 		newRepoName := form.RepoName
 		// Check if repository name has been changed.
 		if repo.LowerName != strings.ToLower(newRepoName) {
+			isNameChanged = true
 			if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil {
 				ctx.Data["Err_RepoName"] = true
 				switch {
@@ -71,6 +73,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 				}
 				return
 			}
+
 			log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName)
 		}
 		// In case it's just a case change.
@@ -87,12 +90,15 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 		if err := models.UpdateRepository(repo, visibilityChanged); err != nil {
 			ctx.Handle(500, "UpdateRepository", err)
 			return
-		} else if err = models.RenameRepoAction(ctx.User, oldRepoName, repo); err != nil {
-			ctx.Handle(500, "RenameRepoAction", err)
-			return
 		}
 		log.Trace("Repository updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 
+		if isNameChanged {
+			if err := models.RenameRepoAction(ctx.User, oldRepoName, repo); err != nil {
+				log.Error(4, "RenameRepoAction: %v", err)
+			}
+		}
+
 		if repo.IsMirror {
 			if form.Interval > 0 {
 				ctx.Repo.Mirror.Interval = form.Interval
@@ -152,7 +158,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 			}
 		}
 
-		if err := models.DeleteRepository(ctx.Repo.Owner.Id, repo.ID, ctx.Repo.Owner.Name); err != nil {
+		if err := models.DeleteRepository(ctx.Repo.Owner.Id, repo.ID); err != nil {
 			ctx.Handle(500, "DeleteRepository", err)
 			return
 		}

+ 1 - 1
templates/repo/create.tmpl

@@ -11,7 +11,7 @@
           {{template "base/alert" .}}
           <div class="inline required field {{if .Err_Owner}}error{{end}}">
             <label>{{.i18n.Tr "repo.owner"}}</label>
-            <div class="ui selection dropdown">
+            <div class="ui selection owner dropdown">
               <input type="hidden" id="uid" name="uid" value="{{.ContextUser.Id}}" required>
               <span class="text">
                 <img class="ui mini image" src="{{.ContextUser.AvatarLink}}">

+ 1 - 1
templates/repo/pulls/fork.tmpl

@@ -45,7 +45,7 @@
 			  	</div>
 			  	<div class="inline field">
 			  		<label>{{.i18n.Tr "repo.visibility"}}</label>
-			  		<div class="ui read-only toggle checkbox">
+			  		<div class="ui read-only checkbox">
 		  		    <input type="checkbox" {{if .IsPrivate}}checked{{end}}>
 		  		    <label>{{.i18n.Tr "repo.visiblity_helper" | Safe}}</label>
 		  		  </div>

+ 6 - 1
templates/repo/settings/options.tmpl

@@ -47,7 +47,7 @@
 	            <label>{{.i18n.Tr "repo.visibility"}}</label>
 	            <div class="ui checkbox">
 	              <input name="private" type="checkbox" {{if .Repository.IsPrivate}}checked{{end}}>
-	              <label>{{.i18n.Tr "repo.visiblity_helper" | Safe}}</label>
+	              <label>{{.i18n.Tr "repo.visiblity_helper" | Safe}} {{if .Repository.NumForks}}<span class="text red">{{.i18n.Tr "repo.visiblity_fork_helper"}}</span>{{end}}</label>
 	            </div>
 	          </div>
 	          {{end}}
@@ -138,6 +138,11 @@
 		<div class="ui warning message text left">
 			{{.i18n.Tr "repo.settings.delete_notices_1" | Safe}} <br>
 			{{.i18n.Tr "repo.settings.delete_notices_2" | Safe}}
+			{{if .Repository.NumForks}}<br>
+			{{.i18n.Tr "repo.settings.delete_notices_fork_1" | Safe}} <br>
+			{{.i18n.Tr "repo.settings.delete_notices_fork_2" | Safe}} <br>
+			{{.i18n.Tr "repo.settings.delete_notices_fork_3" | Safe}}
+			{{end}}
 		</div>
   	<form class="ui form" action="{{.Link}}" method="post">
       {{.CsrfTokenHtml}}

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff