2024-12-07 05:10:35 +08:00
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repository
import (
"context"
"fmt"
issue_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
repo_module "code.gitea.io/gitea/modules/repository"
2025-01-10 13:29:55 +08:00
"code.gitea.io/gitea/modules/reqctx"
2024-12-07 05:10:35 +08:00
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/pull"
)
2025-01-10 13:29:55 +08:00
// MergeUpstream merges the base repository's default branch into the fork repository's current branch.
2024-12-07 05:10:35 +08:00
func MergeUpstream ( ctx context . Context , doer * user_model . User , repo * repo_model . Repository , branch string ) ( mergeStyle string , err error ) {
if err = repo . MustNotBeArchived ( ) ; err != nil {
return "" , err
}
if err = repo . GetBaseRepo ( ctx ) ; err != nil {
return "" , err
}
err = git . Push ( ctx , repo . BaseRepo . RepoPath ( ) , git . PushOptions {
Remote : repo . RepoPath ( ) ,
2025-01-10 13:29:55 +08:00
Branch : fmt . Sprintf ( "%s:%s" , repo . BaseRepo . DefaultBranch , branch ) ,
2024-12-07 05:10:35 +08:00
Env : repo_module . PushingEnvironment ( doer , repo ) ,
} )
if err == nil {
return "fast-forward" , nil
}
if ! git . IsErrPushOutOfDate ( err ) && ! git . IsErrPushRejected ( err ) {
return "" , err
}
// TODO: FakePR: it is somewhat hacky, but it is the only way to "merge" at the moment
// ideally in the future the "merge" functions should be refactored to decouple from the PullRequest
fakeIssue := & issue_model . Issue {
ID : - 1 ,
RepoID : repo . ID ,
Repo : repo ,
Index : - 1 ,
PosterID : doer . ID ,
Poster : doer ,
IsPull : true ,
}
fakePR := & issue_model . PullRequest {
ID : - 1 ,
Status : issue_model . PullRequestStatusMergeable ,
IssueID : - 1 ,
Issue : fakeIssue ,
Index : - 1 ,
HeadRepoID : repo . ID ,
HeadRepo : repo ,
BaseRepoID : repo . BaseRepo . ID ,
BaseRepo : repo . BaseRepo ,
HeadBranch : branch , // maybe HeadCommitID is not needed
2025-01-10 13:29:55 +08:00
BaseBranch : repo . BaseRepo . DefaultBranch ,
2024-12-07 05:10:35 +08:00
}
fakeIssue . PullRequest = fakePR
err = pull . Update ( ctx , fakePR , doer , "merge upstream" , false )
if err != nil {
return "" , err
}
return "merge" , nil
}
2025-01-10 13:29:55 +08:00
// GetUpstreamDivergingInfo returns the information about the divergence between the fork repository's branch and the base repository's default branch.
2025-01-18 03:37:17 +08:00
func GetUpstreamDivergingInfo ( ctx reqctx . RequestContext , forkRepo * repo_model . Repository , forkBranch string ) ( * BranchDivergingInfo , error ) {
if ! forkRepo . IsFork {
2024-12-07 05:10:35 +08:00
return nil , util . NewInvalidArgumentErrorf ( "repo is not a fork" )
}
2025-01-18 03:37:17 +08:00
if forkRepo . IsArchived {
2024-12-07 05:10:35 +08:00
return nil , util . NewInvalidArgumentErrorf ( "repo is archived" )
}
2025-01-18 03:37:17 +08:00
if err := forkRepo . GetBaseRepo ( ctx ) ; err != nil {
2024-12-07 05:10:35 +08:00
return nil , err
}
2025-01-18 03:37:17 +08:00
return GetBranchDivergingInfo ( ctx , forkRepo . BaseRepo , forkRepo . BaseRepo . DefaultBranch , forkRepo , forkBranch )
2024-12-07 05:10:35 +08:00
}