Skip to content

Commit 77730db

Browse files
authored
Move repoWorkPool outside rename/transfer repository (#9086)
* Move repoWorkPool outside rename/transfer repository * fix import * Fix test
1 parent 9ff5b75 commit 77730db

File tree

5 files changed

+40
-54
lines changed

5 files changed

+40
-54
lines changed

models/pull.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,8 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
609609
return nil
610610
}
611611

612-
repoWorkingPool.CheckIn(com.ToStr(pr.BaseRepoID))
613-
defer repoWorkingPool.CheckOut(com.ToStr(pr.BaseRepoID))
612+
RepoWorkingPool.CheckIn(com.ToStr(pr.BaseRepoID))
613+
defer RepoWorkingPool.CheckOut(com.ToStr(pr.BaseRepoID))
614614

615615
log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
616616

models/repo.go

+19-15
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ import (
4343
"xorm.io/builder"
4444
)
4545

46-
var repoWorkingPool = sync.NewExclusivePool()
46+
// RepoWorkingPool represents a working pool to order the parallel changes to the same repository
47+
var RepoWorkingPool = sync.NewExclusivePool()
4748

4849
var (
4950
// ErrMirrorNotExist mirror does not exist error
@@ -1655,7 +1656,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
16551656
return fmt.Errorf("sess.Begin: %v", err)
16561657
}
16571658

1658-
owner := repo.Owner
1659+
oldOwner := repo.Owner
16591660

16601661
// Note: we have to set value here to make sure recalculate accesses is based on
16611662
// new owner.
@@ -1691,8 +1692,8 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
16911692
}
16921693

16931694
// Remove old team-repository relations.
1694-
if owner.IsOrganization() {
1695-
if err = owner.removeOrgRepo(sess, repo.ID); err != nil {
1695+
if oldOwner.IsOrganization() {
1696+
if err = oldOwner.removeOrgRepo(sess, repo.ID); err != nil {
16961697
return fmt.Errorf("removeOrgRepo: %v", err)
16971698
}
16981699
}
@@ -1716,7 +1717,7 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
17161717
// Update repository count.
17171718
if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos+1 WHERE id=?", newOwner.ID); err != nil {
17181719
return fmt.Errorf("increase new owner repository count: %v", err)
1719-
} else if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", owner.ID); err != nil {
1720+
} else if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", oldOwner.ID); err != nil {
17201721
return fmt.Errorf("decrease old owner repository count: %v", err)
17211722
}
17221723

@@ -1725,8 +1726,8 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
17251726
}
17261727

17271728
// Remove watch for organization.
1728-
if owner.IsOrganization() {
1729-
if err = watchRepo(sess, owner.ID, repo.ID, false); err != nil {
1729+
if oldOwner.IsOrganization() {
1730+
if err = watchRepo(sess, oldOwner.ID, repo.ID, false); err != nil {
17301731
return fmt.Errorf("watchRepo [false]: %v", err)
17311732
}
17321733
}
@@ -1738,12 +1739,12 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
17381739
return fmt.Errorf("Failed to create dir %s: %v", dir, err)
17391740
}
17401741

1741-
if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
1742+
if err = os.Rename(RepoPath(oldOwner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
17421743
return fmt.Errorf("rename repository directory: %v", err)
17431744
}
17441745

17451746
// Rename remote wiki repository to new path and delete local copy.
1746-
wikiPath := WikiPath(owner.Name, repo.Name)
1747+
wikiPath := WikiPath(oldOwner.Name, repo.Name)
17471748
if com.IsExist(wikiPath) {
17481749
if err = os.Rename(wikiPath, WikiPath(newOwner.Name, repo.Name)); err != nil {
17491750
return fmt.Errorf("rename repository wiki: %v", err)
@@ -1755,11 +1756,16 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
17551756
return fmt.Errorf("delete repo redirect: %v", err)
17561757
}
17571758

1759+
if err := NewRepoRedirect(DBContext{sess}, oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil {
1760+
return fmt.Errorf("NewRepoRedirect: %v", err)
1761+
}
1762+
17581763
return sess.Commit()
17591764
}
17601765

17611766
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
17621767
func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err error) {
1768+
oldRepoName := repo.Name
17631769
newRepoName = strings.ToLower(newRepoName)
17641770
if err = IsUsableRepoName(newRepoName); err != nil {
17651771
return err
@@ -1776,12 +1782,6 @@ func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err
17761782
return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName}
17771783
}
17781784

1779-
// Change repository directory name. We must lock the local copy of the
1780-
// repo so that we can atomically rename the repo path and updates the
1781-
// local copy's origin accordingly.
1782-
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
1783-
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
1784-
17851785
newRepoPath := RepoPath(repo.Owner.Name, newRepoName)
17861786
if err = os.Rename(repo.RepoPath(), newRepoPath); err != nil {
17871787
return fmt.Errorf("rename repository directory: %v", err)
@@ -1805,6 +1805,10 @@ func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err
18051805
return fmt.Errorf("delete repo redirect: %v", err)
18061806
}
18071807

1808+
if err := NewRepoRedirect(DBContext{sess}, repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
1809+
return err
1810+
}
1811+
18081812
return sess.Commit()
18091813
}
18101814

models/repo_redirect.go

+4-20
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ package models
66

77
import (
88
"strings"
9-
10-
"code.gitea.io/gitea/modules/log"
119
)
1210

1311
// RepoRedirect represents that a repo name should be redirected to another
@@ -31,36 +29,22 @@ func LookupRepoRedirect(ownerID int64, repoName string) (int64, error) {
3129
}
3230

3331
// NewRepoRedirect create a new repo redirect
34-
func NewRepoRedirect(ownerID, repoID int64, oldRepoName, newRepoName string) error {
32+
func NewRepoRedirect(ctx DBContext, ownerID, repoID int64, oldRepoName, newRepoName string) error {
3533
oldRepoName = strings.ToLower(oldRepoName)
3634
newRepoName = strings.ToLower(newRepoName)
37-
sess := x.NewSession()
38-
defer sess.Close()
39-
40-
if err := sess.Begin(); err != nil {
41-
return err
42-
}
4335

44-
if err := deleteRepoRedirect(sess, ownerID, newRepoName); err != nil {
45-
errRollback := sess.Rollback()
46-
if errRollback != nil {
47-
log.Error("NewRepoRedirect sess.Rollback: %v", errRollback)
48-
}
36+
if err := deleteRepoRedirect(ctx.e, ownerID, newRepoName); err != nil {
4937
return err
5038
}
5139

52-
if _, err := sess.Insert(&RepoRedirect{
40+
if _, err := ctx.e.Insert(&RepoRedirect{
5341
OwnerID: ownerID,
5442
LowerName: oldRepoName,
5543
RedirectRepoID: repoID,
5644
}); err != nil {
57-
errRollback := sess.Rollback()
58-
if errRollback != nil {
59-
log.Error("NewRepoRedirect sess.Rollback: %v", errRollback)
60-
}
6145
return err
6246
}
63-
return sess.Commit()
47+
return nil
6448
}
6549

6650
// deleteRepoRedirect delete any redirect from the specified repo name to

models/repo_redirect_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestNewRepoRedirect(t *testing.T) {
2626
assert.NoError(t, PrepareTestDatabase())
2727

2828
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
29-
assert.NoError(t, NewRepoRedirect(repo.OwnerID, repo.ID, repo.Name, "newreponame"))
29+
assert.NoError(t, NewRepoRedirect(DefaultDBContext(), repo.OwnerID, repo.ID, repo.Name, "newreponame"))
3030

3131
AssertExistsAndLoadBean(t, &RepoRedirect{
3232
OwnerID: repo.OwnerID,
@@ -45,7 +45,7 @@ func TestNewRepoRedirect2(t *testing.T) {
4545
assert.NoError(t, PrepareTestDatabase())
4646

4747
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
48-
assert.NoError(t, NewRepoRedirect(repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
48+
assert.NoError(t, NewRepoRedirect(DefaultDBContext(), repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
4949

5050
AssertExistsAndLoadBean(t, &RepoRedirect{
5151
OwnerID: repo.OwnerID,
@@ -64,7 +64,7 @@ func TestNewRepoRedirect3(t *testing.T) {
6464
assert.NoError(t, PrepareTestDatabase())
6565

6666
repo := AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
67-
assert.NoError(t, NewRepoRedirect(repo.OwnerID, repo.ID, repo.Name, "newreponame"))
67+
assert.NoError(t, NewRepoRedirect(DefaultDBContext(), repo.OwnerID, repo.ID, repo.Name, "newreponame"))
6868

6969
AssertExistsAndLoadBean(t, &RepoRedirect{
7070
OwnerID: repo.OwnerID,

services/repository/transfer.go

+12-14
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
package repository
66

77
import (
8-
"fmt"
9-
108
"code.gitea.io/gitea/models"
119
"code.gitea.io/gitea/modules/notification"
10+
11+
"github.com/unknwon/com"
1212
)
1313

1414
// 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
1919

2020
oldOwner := repo.Owner
2121

22+
models.RepoWorkingPool.CheckIn(com.ToStr(repo.ID))
2223
if err := models.TransferOwnership(doer, newOwnerName, repo); err != nil {
24+
models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
2325
return err
2426
}
25-
26-
if err := models.NewRepoRedirect(oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil {
27-
return fmt.Errorf("NewRepoRedirect: %v", err)
28-
}
27+
models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
2928

3029
notification.NotifyTransferRepository(doer, repo, oldOwner.Name)
3130

@@ -36,17 +35,16 @@ func TransferOwnership(doer *models.User, newOwnerName string, repo *models.Repo
3635
func ChangeRepositoryName(doer *models.User, repo *models.Repository, newRepoName string) error {
3736
oldRepoName := repo.Name
3837

39-
if err := models.ChangeRepositoryName(doer, repo, newRepoName); err != nil {
40-
return err
41-
}
42-
43-
if err := repo.GetOwner(); err != nil {
44-
return err
45-
}
38+
// Change repository directory name. We must lock the local copy of the
39+
// repo so that we can atomically rename the repo path and updates the
40+
// local copy's origin accordingly.
4641

47-
if err := models.NewRepoRedirect(repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
42+
models.RepoWorkingPool.CheckIn(com.ToStr(repo.ID))
43+
if err := models.ChangeRepositoryName(doer, repo, newRepoName); err != nil {
44+
models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
4845
return err
4946
}
47+
models.RepoWorkingPool.CheckOut(com.ToStr(repo.ID))
5048

5149
notification.NotifyRenameRepository(doer, repo, oldRepoName)
5250

0 commit comments

Comments
 (0)