mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Move repoWorkPool outside rename/transfer repository (#9086)
* Move repoWorkPool outside rename/transfer repository * fix import * Fix test
This commit is contained in:
		@@ -609,8 +609,8 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repoWorkingPool.CheckIn(com.ToStr(pr.BaseRepoID))
 | 
						RepoWorkingPool.CheckIn(com.ToStr(pr.BaseRepoID))
 | 
				
			||||||
	defer repoWorkingPool.CheckOut(com.ToStr(pr.BaseRepoID))
 | 
						defer RepoWorkingPool.CheckOut(com.ToStr(pr.BaseRepoID))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
 | 
						log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,8 @@ import (
 | 
				
			|||||||
	"xorm.io/builder"
 | 
						"xorm.io/builder"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var repoWorkingPool = sync.NewExclusivePool()
 | 
					// RepoWorkingPool represents a working pool to order the parallel changes to the same repository
 | 
				
			||||||
 | 
					var RepoWorkingPool = sync.NewExclusivePool()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// ErrMirrorNotExist mirror does not exist error
 | 
						// ErrMirrorNotExist mirror does not exist error
 | 
				
			||||||
@@ -1655,7 +1656,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
 | 
				
			|||||||
		return fmt.Errorf("sess.Begin: %v", err)
 | 
							return fmt.Errorf("sess.Begin: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	owner := repo.Owner
 | 
						oldOwner := repo.Owner
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Note: we have to set value here to make sure recalculate accesses is based on
 | 
						// Note: we have to set value here to make sure recalculate accesses is based on
 | 
				
			||||||
	// new owner.
 | 
						// new owner.
 | 
				
			||||||
@@ -1691,8 +1692,8 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Remove old team-repository relations.
 | 
						// Remove old team-repository relations.
 | 
				
			||||||
	if owner.IsOrganization() {
 | 
						if oldOwner.IsOrganization() {
 | 
				
			||||||
		if err = owner.removeOrgRepo(sess, repo.ID); err != nil {
 | 
							if err = oldOwner.removeOrgRepo(sess, repo.ID); err != nil {
 | 
				
			||||||
			return fmt.Errorf("removeOrgRepo: %v", err)
 | 
								return fmt.Errorf("removeOrgRepo: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1716,7 +1717,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
 | 
				
			|||||||
	// Update repository count.
 | 
						// Update repository count.
 | 
				
			||||||
	if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos+1 WHERE id=?", newOwner.ID); err != nil {
 | 
						if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos+1 WHERE id=?", newOwner.ID); err != nil {
 | 
				
			||||||
		return fmt.Errorf("increase new owner repository count: %v", err)
 | 
							return fmt.Errorf("increase new owner repository count: %v", err)
 | 
				
			||||||
	} else if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", owner.ID); err != nil {
 | 
						} else if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", oldOwner.ID); err != nil {
 | 
				
			||||||
		return fmt.Errorf("decrease old owner repository count: %v", err)
 | 
							return fmt.Errorf("decrease old owner repository count: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1725,8 +1726,8 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Remove watch for organization.
 | 
						// Remove watch for organization.
 | 
				
			||||||
	if owner.IsOrganization() {
 | 
						if oldOwner.IsOrganization() {
 | 
				
			||||||
		if err = watchRepo(sess, owner.ID, repo.ID, false); err != nil {
 | 
							if err = watchRepo(sess, oldOwner.ID, repo.ID, false); err != nil {
 | 
				
			||||||
			return fmt.Errorf("watchRepo [false]: %v", err)
 | 
								return fmt.Errorf("watchRepo [false]: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1738,12 +1739,12 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
 | 
				
			|||||||
		return fmt.Errorf("Failed to create dir %s: %v", dir, err)
 | 
							return fmt.Errorf("Failed to create dir %s: %v", dir, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
 | 
						if err = os.Rename(RepoPath(oldOwner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
 | 
				
			||||||
		return fmt.Errorf("rename repository directory: %v", err)
 | 
							return fmt.Errorf("rename repository directory: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Rename remote wiki repository to new path and delete local copy.
 | 
						// Rename remote wiki repository to new path and delete local copy.
 | 
				
			||||||
	wikiPath := WikiPath(owner.Name, repo.Name)
 | 
						wikiPath := WikiPath(oldOwner.Name, repo.Name)
 | 
				
			||||||
	if com.IsExist(wikiPath) {
 | 
						if com.IsExist(wikiPath) {
 | 
				
			||||||
		if err = os.Rename(wikiPath, WikiPath(newOwner.Name, repo.Name)); err != nil {
 | 
							if err = os.Rename(wikiPath, WikiPath(newOwner.Name, repo.Name)); err != nil {
 | 
				
			||||||
			return fmt.Errorf("rename repository wiki: %v", err)
 | 
								return fmt.Errorf("rename repository wiki: %v", err)
 | 
				
			||||||
@@ -1755,11 +1756,16 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
 | 
				
			|||||||
		return fmt.Errorf("delete repo redirect: %v", err)
 | 
							return fmt.Errorf("delete repo redirect: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := NewRepoRedirect(DBContext{sess}, oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("NewRepoRedirect: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
 | 
					// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
 | 
				
			||||||
func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err error) {
 | 
					func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err error) {
 | 
				
			||||||
 | 
						oldRepoName := repo.Name
 | 
				
			||||||
	newRepoName = strings.ToLower(newRepoName)
 | 
						newRepoName = strings.ToLower(newRepoName)
 | 
				
			||||||
	if err = IsUsableRepoName(newRepoName); err != nil {
 | 
						if err = IsUsableRepoName(newRepoName); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -1776,12 +1782,6 @@ func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err
 | 
				
			|||||||
		return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName}
 | 
							return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Change repository directory name. We must lock the local copy of the
 | 
					 | 
				
			||||||
	// repo so that we can atomically rename the repo path and updates the
 | 
					 | 
				
			||||||
	// local copy's origin accordingly.
 | 
					 | 
				
			||||||
	repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
					 | 
				
			||||||
	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	newRepoPath := RepoPath(repo.Owner.Name, newRepoName)
 | 
						newRepoPath := RepoPath(repo.Owner.Name, newRepoName)
 | 
				
			||||||
	if err = os.Rename(repo.RepoPath(), newRepoPath); err != nil {
 | 
						if err = os.Rename(repo.RepoPath(), newRepoPath); err != nil {
 | 
				
			||||||
		return fmt.Errorf("rename repository directory: %v", err)
 | 
							return fmt.Errorf("rename repository directory: %v", err)
 | 
				
			||||||
@@ -1805,6 +1805,10 @@ func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err
 | 
				
			|||||||
		return fmt.Errorf("delete repo redirect: %v", err)
 | 
							return fmt.Errorf("delete repo redirect: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := NewRepoRedirect(DBContext{sess}, repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,6 @@ package models
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RepoRedirect represents that a repo name should be redirected to another
 | 
					// RepoRedirect represents that a repo name should be redirected to another
 | 
				
			||||||
@@ -31,36 +29,22 @@ func LookupRepoRedirect(ownerID int64, repoName string) (int64, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewRepoRedirect create a new repo redirect
 | 
					// NewRepoRedirect create a new repo redirect
 | 
				
			||||||
func NewRepoRedirect(ownerID, repoID int64, oldRepoName, newRepoName string) error {
 | 
					func NewRepoRedirect(ctx DBContext, ownerID, repoID int64, oldRepoName, newRepoName string) error {
 | 
				
			||||||
	oldRepoName = strings.ToLower(oldRepoName)
 | 
						oldRepoName = strings.ToLower(oldRepoName)
 | 
				
			||||||
	newRepoName = strings.ToLower(newRepoName)
 | 
						newRepoName = strings.ToLower(newRepoName)
 | 
				
			||||||
	sess := x.NewSession()
 | 
					 | 
				
			||||||
	defer sess.Close()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := sess.Begin(); err != nil {
 | 
						if err := deleteRepoRedirect(ctx.e, ownerID, newRepoName); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := deleteRepoRedirect(sess, ownerID, newRepoName); err != nil {
 | 
						if _, err := ctx.e.Insert(&RepoRedirect{
 | 
				
			||||||
		errRollback := sess.Rollback()
 | 
					 | 
				
			||||||
		if errRollback != nil {
 | 
					 | 
				
			||||||
			log.Error("NewRepoRedirect sess.Rollback: %v", errRollback)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if _, err := sess.Insert(&RepoRedirect{
 | 
					 | 
				
			||||||
		OwnerID:        ownerID,
 | 
							OwnerID:        ownerID,
 | 
				
			||||||
		LowerName:      oldRepoName,
 | 
							LowerName:      oldRepoName,
 | 
				
			||||||
		RedirectRepoID: repoID,
 | 
							RedirectRepoID: repoID,
 | 
				
			||||||
	}); err != nil {
 | 
						}); err != nil {
 | 
				
			||||||
		errRollback := sess.Rollback()
 | 
					 | 
				
			||||||
		if errRollback != nil {
 | 
					 | 
				
			||||||
			log.Error("NewRepoRedirect sess.Rollback: %v", errRollback)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return sess.Commit()
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// deleteRepoRedirect delete any redirect from the specified repo name to
 | 
					// deleteRepoRedirect delete any redirect from the specified repo name to
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ func TestNewRepoRedirect(t *testing.T) {
 | 
				
			|||||||
	assert.NoError(t, PrepareTestDatabase())
 | 
						assert.NoError(t, PrepareTestDatabase())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
 | 
						repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
 | 
				
			||||||
	assert.NoError(t, NewRepoRedirect(repo.OwnerID, repo.ID, repo.Name, "newreponame"))
 | 
						assert.NoError(t, NewRepoRedirect(DefaultDBContext(), repo.OwnerID, repo.ID, repo.Name, "newreponame"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AssertExistsAndLoadBean(t, &RepoRedirect{
 | 
						AssertExistsAndLoadBean(t, &RepoRedirect{
 | 
				
			||||||
		OwnerID:        repo.OwnerID,
 | 
							OwnerID:        repo.OwnerID,
 | 
				
			||||||
@@ -45,7 +45,7 @@ func TestNewRepoRedirect2(t *testing.T) {
 | 
				
			|||||||
	assert.NoError(t, PrepareTestDatabase())
 | 
						assert.NoError(t, PrepareTestDatabase())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
 | 
						repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
 | 
				
			||||||
	assert.NoError(t, NewRepoRedirect(repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
 | 
						assert.NoError(t, NewRepoRedirect(DefaultDBContext(), repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AssertExistsAndLoadBean(t, &RepoRedirect{
 | 
						AssertExistsAndLoadBean(t, &RepoRedirect{
 | 
				
			||||||
		OwnerID:        repo.OwnerID,
 | 
							OwnerID:        repo.OwnerID,
 | 
				
			||||||
@@ -64,7 +64,7 @@ func TestNewRepoRedirect3(t *testing.T) {
 | 
				
			|||||||
	assert.NoError(t, PrepareTestDatabase())
 | 
						assert.NoError(t, PrepareTestDatabase())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo := AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
 | 
						repo := AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
 | 
				
			||||||
	assert.NoError(t, NewRepoRedirect(repo.OwnerID, repo.ID, repo.Name, "newreponame"))
 | 
						assert.NoError(t, NewRepoRedirect(DefaultDBContext(), repo.OwnerID, repo.ID, repo.Name, "newreponame"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AssertExistsAndLoadBean(t, &RepoRedirect{
 | 
						AssertExistsAndLoadBean(t, &RepoRedirect{
 | 
				
			||||||
		OwnerID:        repo.OwnerID,
 | 
							OwnerID:        repo.OwnerID,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,10 +5,10 @@
 | 
				
			|||||||
package repository
 | 
					package repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/notification"
 | 
						"code.gitea.io/gitea/modules/notification"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/unknwon/com"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TransferOwnership transfers all corresponding setting from old user to new one.
 | 
					// TransferOwnership transfers all corresponding setting from old user to new one.
 | 
				
			||||||
@@ -19,13 +19,12 @@ func TransferOwnership(doer *models.User, newOwnerName string, repo *models.Repo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	oldOwner := repo.Owner
 | 
						oldOwner := repo.Owner
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						models.RepoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
				
			||||||
	if err := models.TransferOwnership(doer, newOwnerName, repo); err != nil {
 | 
						if err := models.TransferOwnership(doer, newOwnerName, repo); err != nil {
 | 
				
			||||||
 | 
							models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
 | 
				
			||||||
	if err := models.NewRepoRedirect(oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("NewRepoRedirect: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	notification.NotifyTransferRepository(doer, repo, oldOwner.Name)
 | 
						notification.NotifyTransferRepository(doer, repo, oldOwner.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,17 +35,16 @@ func TransferOwnership(doer *models.User, newOwnerName string, repo *models.Repo
 | 
				
			|||||||
func ChangeRepositoryName(doer *models.User, repo *models.Repository, newRepoName string) error {
 | 
					func ChangeRepositoryName(doer *models.User, repo *models.Repository, newRepoName string) error {
 | 
				
			||||||
	oldRepoName := repo.Name
 | 
						oldRepoName := repo.Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Change repository directory name. We must lock the local copy of the
 | 
				
			||||||
 | 
						// repo so that we can atomically rename the repo path and updates the
 | 
				
			||||||
 | 
						// local copy's origin accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						models.RepoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
				
			||||||
	if err := models.ChangeRepositoryName(doer, repo, newRepoName); err != nil {
 | 
						if err := models.ChangeRepositoryName(doer, repo, newRepoName); err != nil {
 | 
				
			||||||
 | 
							models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
 | 
				
			||||||
	if err := repo.GetOwner(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := models.NewRepoRedirect(repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	notification.NotifyRenameRepository(doer, repo, oldRepoName)
 | 
						notification.NotifyRenameRepository(doer, repo, oldRepoName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user