Skip to content

Commit 22cea96

Browse files
lunnyzeripath
authored andcommitted
Fix bug on pull requests when transfer head repository (#8564) (#8569)
* fix bug on pull requests when transfer head repository * add migration and fix lint * fix tests and add a cache check on LoadBaseRepo
1 parent 7565ac0 commit 22cea96

File tree

10 files changed

+87
-73
lines changed

10 files changed

+87
-73
lines changed

models/fixtures/pull_request.yml

-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
index: 2
77
head_repo_id: 1
88
base_repo_id: 1
9-
head_user_name: user1
109
head_branch: branch1
1110
base_branch: master
1211
merge_base: 1234567890abcdef
@@ -21,7 +20,6 @@
2120
index: 3
2221
head_repo_id: 1
2322
base_repo_id: 1
24-
head_user_name: user1
2523
head_branch: branch2
2624
base_branch: master
2725
merge_base: fedcba9876543210
@@ -35,7 +33,6 @@
3533
index: 1
3634
head_repo_id: 11
3735
base_repo_id: 10
38-
head_user_name: user13
3936
head_branch: branch2
4037
base_branch: master
4138
merge_base: 0abcb056019adb83

models/migrations/migrations.go

+2
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ var migrations = []Migration{
258258
NewMigration("update migration repositories' service type", updateMigrationServiceTypes),
259259
// v101 -> v102
260260
NewMigration("change length of some external login users columns", changeSomeColumnsLengthOfExternalLoginUser),
261+
// v102 -> v103
262+
NewMigration("update migration repositories' service type", dropColumnHeadUserNameOnPullRequest),
261263
}
262264

263265
// Migrate database to current version

models/migrations/v102.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"github.com/go-xorm/xorm"
9+
)
10+
11+
func dropColumnHeadUserNameOnPullRequest(x *xorm.Engine) error {
12+
sess := x.NewSession()
13+
defer sess.Close()
14+
return dropTableColumns(sess, "pull_request", "head_user_name")
15+
}

models/pull.go

+32-14
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ type PullRequest struct {
6666
HeadRepo *Repository `xorm:"-"`
6767
BaseRepoID int64 `xorm:"INDEX"`
6868
BaseRepo *Repository `xorm:"-"`
69-
HeadUserName string
7069
HeadBranch string
7170
BaseBranch string
7271
ProtectedBranch *ProtectedBranch `xorm:"-"`
@@ -79,6 +78,15 @@ type PullRequest struct {
7978
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
8079
}
8180

81+
// MustHeadUserName returns the HeadRepo's username if failed return blank
82+
func (pr *PullRequest) MustHeadUserName() string {
83+
if err := pr.LoadHeadRepo(); err != nil {
84+
log.Error("LoadHeadRepo: %v", err)
85+
return ""
86+
}
87+
return pr.HeadRepo.MustOwnerName()
88+
}
89+
8290
// Note: don't try to get Issue because will end up recursive querying.
8391
func (pr *PullRequest) loadAttributes(e Engine) (err error) {
8492
if pr.HasMerged && pr.Merger == nil {
@@ -102,6 +110,10 @@ func (pr *PullRequest) LoadAttributes() error {
102110
// LoadBaseRepo loads pull request base repository from database
103111
func (pr *PullRequest) LoadBaseRepo() error {
104112
if pr.BaseRepo == nil {
113+
if pr.HeadRepoID == pr.BaseRepoID && pr.HeadRepo != nil {
114+
pr.BaseRepo = pr.HeadRepo
115+
return nil
116+
}
105117
var repo Repository
106118
if has, err := x.ID(pr.BaseRepoID).Get(&repo); err != nil {
107119
return err
@@ -113,6 +125,24 @@ func (pr *PullRequest) LoadBaseRepo() error {
113125
return nil
114126
}
115127

128+
// LoadHeadRepo loads pull request head repository from database
129+
func (pr *PullRequest) LoadHeadRepo() error {
130+
if pr.HeadRepo == nil {
131+
if pr.HeadRepoID == pr.BaseRepoID && pr.BaseRepo != nil {
132+
pr.HeadRepo = pr.BaseRepo
133+
return nil
134+
}
135+
var repo Repository
136+
if has, err := x.ID(pr.HeadRepoID).Get(&repo); err != nil {
137+
return err
138+
} else if !has {
139+
return ErrRepoNotExist{ID: pr.BaseRepoID}
140+
}
141+
pr.HeadRepo = &repo
142+
}
143+
return nil
144+
}
145+
116146
// LoadIssue loads issue information from database
117147
func (pr *PullRequest) LoadIssue() (err error) {
118148
return pr.loadIssue(x)
@@ -152,7 +182,7 @@ func (pr *PullRequest) GetDefaultMergeMessage() string {
152182
return ""
153183
}
154184
}
155-
return fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.HeadUserName, pr.HeadRepo.Name, pr.BaseBranch)
185+
return fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.MustHeadUserName(), pr.HeadRepo.Name, pr.BaseBranch)
156186
}
157187

158188
// GetDefaultSquashMessage returns default message used when squash and merging pull request
@@ -1159,18 +1189,6 @@ func checkForInvalidation(requests PullRequestList, repoID int64, doer *User, br
11591189
return nil
11601190
}
11611191

1162-
// ChangeUsernameInPullRequests changes the name of head_user_name
1163-
func ChangeUsernameInPullRequests(oldUserName, newUserName string) error {
1164-
pr := PullRequest{
1165-
HeadUserName: strings.ToLower(newUserName),
1166-
}
1167-
_, err := x.
1168-
Cols("head_user_name").
1169-
Where("head_user_name = ?", strings.ToLower(oldUserName)).
1170-
Update(pr)
1171-
return err
1172-
}
1173-
11741192
// checkAndUpdateStatus checks if pull request is possible to leaving checking status,
11751193
// and set to be either conflict or mergeable.
11761194
func (pr *PullRequest) checkAndUpdateStatus() {

models/pull_test.go

-14
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,6 @@ func TestPullRequestList_LoadAttributes(t *testing.T) {
232232

233233
// TODO TestAddTestPullRequestTask
234234

235-
func TestChangeUsernameInPullRequests(t *testing.T) {
236-
assert.NoError(t, PrepareTestDatabase())
237-
const newUsername = "newusername"
238-
assert.NoError(t, ChangeUsernameInPullRequests("user1", newUsername))
239-
240-
prs := make([]*PullRequest, 0, 10)
241-
assert.NoError(t, x.Where("head_user_name = ?", newUsername).Find(&prs))
242-
assert.Len(t, prs, 2)
243-
for _, pr := range prs {
244-
assert.Equal(t, newUsername, pr.HeadUserName)
245-
}
246-
CheckConsistencyFor(t, &PullRequest{})
247-
}
248-
249235
func TestPullRequest_IsWorkInProgress(t *testing.T) {
250236
assert.NoError(t, PrepareTestDatabase())
251237

models/user.go

-4
Original file line numberDiff line numberDiff line change
@@ -994,10 +994,6 @@ func ChangeUserName(u *User, newUserName string) (err error) {
994994
return ErrUserAlreadyExist{newUserName}
995995
}
996996

997-
if err = ChangeUsernameInPullRequests(u.Name, newUserName); err != nil {
998-
return fmt.Errorf("ChangeUsernameInPullRequests: %v", err)
999-
}
1000-
1001997
// Do not fail if directory does not exist
1002998
if err = os.Rename(UserPath(u.Name), UserPath(newUserName)); err != nil && !os.IsNotExist(err) {
1003999
return fmt.Errorf("Rename user directory: %v", err)

modules/migrations/gitea.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -579,14 +579,13 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
579579
}
580580

581581
var pullRequest = models.PullRequest{
582-
HeadRepoID: g.repo.ID,
583-
HeadBranch: head,
584-
HeadUserName: g.repoOwner,
585-
BaseRepoID: g.repo.ID,
586-
BaseBranch: pr.Base.Ref,
587-
MergeBase: pr.Base.SHA,
588-
Index: pr.Number,
589-
HasMerged: pr.Merged,
582+
HeadRepoID: g.repo.ID,
583+
HeadBranch: head,
584+
BaseRepoID: g.repo.ID,
585+
BaseBranch: pr.Base.Ref,
586+
MergeBase: pr.Base.SHA,
587+
Index: pr.Number,
588+
HasMerged: pr.Merged,
590589

591590
Issue: &issue,
592591
}

routers/api/v1/repo/pull.go

+9-10
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
190190
)
191191

192192
// Get repo/branch information
193-
headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch := parseCompareInfo(ctx, form)
193+
_, headRepo, headGitRepo, compareInfo, baseBranch, headBranch := parseCompareInfo(ctx, form)
194194
if ctx.Written() {
195195
return
196196
}
@@ -265,15 +265,14 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
265265
DeadlineUnix: deadlineUnix,
266266
}
267267
pr := &models.PullRequest{
268-
HeadRepoID: headRepo.ID,
269-
BaseRepoID: repo.ID,
270-
HeadUserName: headUser.Name,
271-
HeadBranch: headBranch,
272-
BaseBranch: baseBranch,
273-
HeadRepo: headRepo,
274-
BaseRepo: repo,
275-
MergeBase: compareInfo.MergeBase,
276-
Type: models.PullRequestGitea,
268+
HeadRepoID: headRepo.ID,
269+
BaseRepoID: repo.ID,
270+
HeadBranch: headBranch,
271+
BaseBranch: baseBranch,
272+
HeadRepo: headRepo,
273+
BaseRepo: repo,
274+
MergeBase: compareInfo.MergeBase,
275+
Type: models.PullRequestGitea,
277276
}
278277

279278
// Get all assignee IDs

routers/repo/pull.go

+15-16
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,12 @@ func checkPullInfo(ctx *context.Context) *models.Issue {
272272
}
273273

274274
func setMergeTarget(ctx *context.Context, pull *models.PullRequest) {
275-
if ctx.Repo.Owner.Name == pull.HeadUserName {
275+
if ctx.Repo.Owner.Name == pull.MustHeadUserName() {
276276
ctx.Data["HeadTarget"] = pull.HeadBranch
277277
} else if pull.HeadRepo == nil {
278-
ctx.Data["HeadTarget"] = pull.HeadUserName + ":" + pull.HeadBranch
278+
ctx.Data["HeadTarget"] = pull.MustHeadUserName() + ":" + pull.HeadBranch
279279
} else {
280-
ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch
280+
ctx.Data["HeadTarget"] = pull.MustHeadUserName() + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch
281281
}
282282
ctx.Data["BaseTarget"] = pull.BaseBranch
283283
}
@@ -440,7 +440,7 @@ func ViewPullCommits(ctx *context.Context) {
440440
ctx.NotFound("ViewPullCommits", nil)
441441
return
442442
}
443-
ctx.Data["Username"] = pull.HeadUserName
443+
ctx.Data["Username"] = pull.MustHeadUserName()
444444
ctx.Data["Reponame"] = pull.HeadRepo.Name
445445
commits = prInfo.Commits
446446
}
@@ -512,7 +512,7 @@ func ViewPullFiles(ctx *context.Context) {
512512
return
513513
}
514514

515-
headRepoPath := models.RepoPath(pull.HeadUserName, pull.HeadRepo.Name)
515+
headRepoPath := pull.HeadRepo.RepoPath()
516516

517517
headGitRepo, err := git.OpenRepository(headRepoPath)
518518
if err != nil {
@@ -531,8 +531,8 @@ func ViewPullFiles(ctx *context.Context) {
531531
endCommitID = headCommitID
532532
gitRepo = headGitRepo
533533

534-
headTarget = path.Join(pull.HeadUserName, pull.HeadRepo.Name)
535-
ctx.Data["Username"] = pull.HeadUserName
534+
headTarget = path.Join(pull.MustHeadUserName(), pull.HeadRepo.Name)
535+
ctx.Data["Username"] = pull.MustHeadUserName()
536536
ctx.Data["Reponame"] = pull.HeadRepo.Name
537537
}
538538

@@ -754,15 +754,14 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
754754
Content: form.Content,
755755
}
756756
pullRequest := &models.PullRequest{
757-
HeadRepoID: headRepo.ID,
758-
BaseRepoID: repo.ID,
759-
HeadUserName: headUser.Name,
760-
HeadBranch: headBranch,
761-
BaseBranch: baseBranch,
762-
HeadRepo: headRepo,
763-
BaseRepo: repo,
764-
MergeBase: prInfo.MergeBase,
765-
Type: models.PullRequestGitea,
757+
HeadRepoID: headRepo.ID,
758+
BaseRepoID: repo.ID,
759+
HeadBranch: headBranch,
760+
BaseBranch: baseBranch,
761+
HeadRepo: headRepo,
762+
BaseRepo: repo,
763+
MergeBase: prInfo.MergeBase,
764+
Type: models.PullRequestGitea,
766765
}
767766
// FIXME: check error in the case two people send pull request at almost same time, give nice error prompt
768767
// instead of 500.

services/pull/merge.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
6565
}
6666
}()
6767

68-
headRepoPath := models.RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
68+
headRepoPath := pr.HeadRepo.RepoPath()
6969

7070
if err := git.InitRepository(tmpBasePath, false); err != nil {
7171
return fmt.Errorf("git init: %v", err)
@@ -260,14 +260,17 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
260260
}
261261
}
262262

263-
headUser, err := models.GetUserByName(pr.HeadUserName)
263+
var headUser *models.User
264+
err = pr.HeadRepo.GetOwner()
264265
if err != nil {
265266
if !models.IsErrUserNotExist(err) {
266-
log.Error("Can't find user: %s for head repository - %v", pr.HeadUserName, err)
267+
log.Error("Can't find user: %d for head repository - %v", pr.HeadRepo.OwnerID, err)
267268
return err
268269
}
269-
log.Error("Can't find user: %s for head repository - defaulting to doer: %s - %v", pr.HeadUserName, doer.Name, err)
270+
log.Error("Can't find user: %d for head repository - defaulting to doer: %s - %v", pr.HeadRepo.OwnerID, doer.Name, err)
270271
headUser = doer
272+
} else {
273+
headUser = pr.HeadRepo.Owner
271274
}
272275

273276
env := models.FullPushingEnvironment(

0 commit comments

Comments
 (0)