1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Add agit flow support in gitea (#14295)

* feature: add agit flow support

ref: https://git-repo.info/en/2020/03/agit-flow-and-git-repo/

example:

```Bash
git checkout -b test
echo "test" >> README.md
git commit -m "test"
git push origin HEAD:refs/for/master -o topic=test
```

Signed-off-by: a1012112796 <1012112796@qq.com>

* fix lint

* simplify code add fix some nits

* update merge help message

* Apply suggestions from code review. Thanks @jiangxin

* add forced-update message

* fix lint

* splite writePktLine

* add refs/for/<target-branch>/<topic-branch> support also

* Add test code add fix api

* fix lint

* fix test

* skip test if git version < 2.29

* try test with git 2.30.1

* fix permission check bug

* fix some nit

* logic implify and test code update

* fix bug

* apply suggestions from code review

* prepare for merge

Signed-off-by: Andrew Thornton <art27@cantab.net>

* fix permission check bug

- test code update
- apply suggestions from code review @zeripath

Signed-off-by: a1012112796 <1012112796@qq.com>

* fix bug when target branch isn't exist

* prevent some special push and fix some nits

* fix lint

* try splite

* Apply suggestions from code review

- fix permission check
- handle user rename

* fix version negotiation

* remane

* fix template

* handle empty repo

* ui: fix  branch link under the title

* fix nits

Co-authored-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
a1012112796
2021-07-28 17:42:56 +08:00
committed by GitHub
parent 5b2e2d29ca
commit 3705168837
30 changed files with 1334 additions and 32 deletions

View File

@@ -329,6 +329,8 @@ var migrations = []Migration{
NewMigration("Add key is verified to gpg key", addKeyIsVerified),
// v189 -> v190
NewMigration("Unwrap ldap.Sources", unwrapLDAPSourceCfg),
// v190 -> v191
NewMigration("Add agit flow pull request support", addAgitFlowPullRequest),
}
// GetCurrentDBVersion returns the current db version

24
models/migrations/v190.go Normal file
View File

@@ -0,0 +1,24 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package migrations
import (
"fmt"
"xorm.io/xorm"
)
func addAgitFlowPullRequest(x *xorm.Engine) error {
type PullRequestFlow int
type PullRequest struct {
Flow PullRequestFlow `xorm:"NOT NULL DEFAULT 0"`
}
if err := x.Sync2(new(PullRequest)); err != nil {
return fmt.Errorf("sync2: %v", err)
}
return nil
}

View File

@@ -38,6 +38,16 @@ const (
PullRequestStatusEmpty
)
// PullRequestFlow the flow of pull request
type PullRequestFlow int
const (
// PullRequestFlowGithub github flow from head branch to base branch
PullRequestFlowGithub PullRequestFlow = iota
// PullRequestFlowAGit Agit flow pull request, head branch is not exist
PullRequestFlowAGit
)
// PullRequest represents relation between pull request and repositories.
type PullRequest struct {
ID int64 `xorm:"pk autoincr"`
@@ -58,6 +68,7 @@ type PullRequest struct {
BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *Repository `xorm:"-"`
HeadBranch string
HeadCommitID string `xorm:"-"`
BaseBranch string
ProtectedBranch *ProtectedBranch `xorm:"-"`
MergeBase string `xorm:"VARCHAR(40)"`
@@ -69,6 +80,8 @@ type PullRequest struct {
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
isHeadRepoLoaded bool `xorm:"-"`
Flow PullRequestFlow `xorm:"NOT NULL DEFAULT 0"`
}
// MustHeadUserName returns the HeadRepo's username if failed return blank
@@ -470,11 +483,11 @@ func NewPullRequest(repo *Repository, issue *Issue, labelIDs []int64, uuids []st
// GetUnmergedPullRequest returns a pull request that is open and has not been merged
// by given head/base and repo/branch.
func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) {
func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string, flow PullRequestFlow) (*PullRequest, error) {
pr := new(PullRequest)
has, err := x.
Where("head_repo_id=? AND head_branch=? AND base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
headRepoID, headBranch, baseRepoID, baseBranch, false, false).
Where("head_repo_id=? AND head_branch=? AND base_repo_id=? AND base_branch=? AND has_merged=? AND flow = ? AND issue.is_closed=?",
headRepoID, headBranch, baseRepoID, baseBranch, false, flow, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").
Get(pr)
if err != nil {
@@ -491,7 +504,7 @@ func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch
func GetLatestPullRequestByHeadInfo(repoID int64, branch string) (*PullRequest, error) {
pr := new(PullRequest)
has, err := x.
Where("head_repo_id = ? AND head_branch = ?", repoID, branch).
Where("head_repo_id = ? AND head_branch = ? AND flow = ?", repoID, branch, PullRequestFlowGithub).
OrderBy("id DESC").
Get(pr)
if !has {
@@ -566,6 +579,20 @@ func getPullRequestByIssueID(e Engine, issueID int64) (*PullRequest, error) {
return pr, pr.loadAttributes(e)
}
// GetAllUnmergedAgitPullRequestByPoster get all unmerged agit flow pull request
// By poster id.
func GetAllUnmergedAgitPullRequestByPoster(uid int64) ([]*PullRequest, error) {
pulls := make([]*PullRequest, 0, 10)
err := x.
Where("has_merged=? AND flow = ? AND issue.is_closed=? AND issue.poster_id=?",
false, PullRequestFlowAGit, false, uid).
Join("INNER", "issue", "issue.id=pull_request.issue_id").
Find(&pulls)
return pulls, err
}
// GetPullRequestByIssueID returns pull request by given issue ID.
func GetPullRequestByIssueID(issueID int64) (*PullRequest, error) {
return getPullRequestByIssueID(x, issueID)
@@ -663,6 +690,10 @@ func (pr *PullRequest) GetBaseBranchHTMLURL() string {
// GetHeadBranchHTMLURL returns the HTML URL of the head branch
func (pr *PullRequest) GetHeadBranchHTMLURL() string {
if pr.Flow == PullRequestFlowAGit {
return ""
}
if err := pr.LoadHeadRepo(); err != nil {
log.Error("LoadHeadRepo: %v", err)
return ""

View File

@@ -51,8 +51,8 @@ func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) (*xor
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2)
return prs, x.
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ? AND flow = ?",
repoID, branch, false, false, PullRequestFlowGithub).
Join("INNER", "issue", "issue.id = pull_request.issue_id").
Find(&prs)
}

View File

@@ -92,11 +92,11 @@ func TestPullRequestsOldest(t *testing.T) {
func TestGetUnmergedPullRequest(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
pr, err := GetUnmergedPullRequest(1, 1, "branch2", "master")
pr, err := GetUnmergedPullRequest(1, 1, "branch2", "master", PullRequestFlowGithub)
assert.NoError(t, err)
assert.Equal(t, int64(2), pr.ID)
_, err = GetUnmergedPullRequest(1, 9223372036854775807, "branch1", "master")
_, err = GetUnmergedPullRequest(1, 9223372036854775807, "branch1", "master", PullRequestFlowGithub)
assert.Error(t, err)
assert.True(t, IsErrPullRequestNotExist(err))
}