mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08: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:
		@@ -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 ""
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user