4
4
package repository
5
5
6
6
import (
7
- "context "
7
+ "errors "
8
8
"fmt"
9
9
10
10
issue_model "code.gitea.io/gitea/models/issues"
@@ -18,16 +18,24 @@ import (
18
18
)
19
19
20
20
// MergeUpstream merges the base repository's default branch into the fork repository's current branch.
21
- func MergeUpstream (ctx context. Context , doer * user_model.User , repo * repo_model.Repository , branch string ) (mergeStyle string , err error ) {
21
+ func MergeUpstream (ctx reqctx. RequestContext , doer * user_model.User , repo * repo_model.Repository , branch string ) (mergeStyle string , err error ) {
22
22
if err = repo .MustNotBeArchived (); err != nil {
23
23
return "" , err
24
24
}
25
25
if err = repo .GetBaseRepo (ctx ); err != nil {
26
26
return "" , err
27
27
}
28
+ divergingInfo , err := GetUpstreamDivergingInfo (ctx , repo , branch )
29
+ if err != nil {
30
+ return "" , err
31
+ }
32
+ if ! divergingInfo .BaseBranchHasNewCommits {
33
+ return "up-to-date" , nil
34
+ }
35
+
28
36
err = git .Push (ctx , repo .BaseRepo .RepoPath (), git.PushOptions {
29
37
Remote : repo .RepoPath (),
30
- Branch : fmt .Sprintf ("%s:%s" , repo . BaseRepo . DefaultBranch , branch ),
38
+ Branch : fmt .Sprintf ("%s:%s" , divergingInfo . BaseBranchName , branch ),
31
39
Env : repo_module .PushingEnvironment (doer , repo ),
32
40
})
33
41
if err == nil {
@@ -59,7 +67,7 @@ func MergeUpstream(ctx context.Context, doer *user_model.User, repo *repo_model.
59
67
BaseRepoID : repo .BaseRepo .ID ,
60
68
BaseRepo : repo .BaseRepo ,
61
69
HeadBranch : branch , // maybe HeadCommitID is not needed
62
- BaseBranch : repo . BaseRepo . DefaultBranch ,
70
+ BaseBranch : divergingInfo . BaseBranchName ,
63
71
}
64
72
fakeIssue .PullRequest = fakePR
65
73
err = pull .Update (ctx , fakePR , doer , "merge upstream" , false )
@@ -69,8 +77,15 @@ func MergeUpstream(ctx context.Context, doer *user_model.User, repo *repo_model.
69
77
return "merge" , nil
70
78
}
71
79
80
+ // UpstreamDivergingInfo is also used in templates, so it needs to search for all references before changing it.
81
+ type UpstreamDivergingInfo struct {
82
+ BaseBranchName string
83
+ BaseBranchHasNewCommits bool
84
+ HeadBranchCommitsBehind int
85
+ }
86
+
72
87
// GetUpstreamDivergingInfo returns the information about the divergence between the fork repository's branch and the base repository's default branch.
73
- func GetUpstreamDivergingInfo (ctx reqctx.RequestContext , forkRepo * repo_model.Repository , forkBranch string ) (* BranchDivergingInfo , error ) {
88
+ func GetUpstreamDivergingInfo (ctx reqctx.RequestContext , forkRepo * repo_model.Repository , forkBranch string ) (* UpstreamDivergingInfo , error ) {
74
89
if ! forkRepo .IsFork {
75
90
return nil , util .NewInvalidArgumentErrorf ("repo is not a fork" )
76
91
}
@@ -83,5 +98,26 @@ func GetUpstreamDivergingInfo(ctx reqctx.RequestContext, forkRepo *repo_model.Re
83
98
return nil , err
84
99
}
85
100
86
- return GetBranchDivergingInfo (ctx , forkRepo .BaseRepo , forkRepo .BaseRepo .DefaultBranch , forkRepo , forkBranch )
101
+ // Do the best to follow the GitHub's behavior, suppose there is a `branch-a` in fork repo:
102
+ // * if `branch-a` exists in base repo: try to sync `base:branch-a` to `fork:branch-a`
103
+ // * if `branch-a` doesn't exist in base repo: try to sync `base:main` to `fork:branch-a`
104
+ info , err := GetBranchDivergingInfo (ctx , forkRepo .BaseRepo , forkBranch , forkRepo , forkBranch )
105
+ if err == nil {
106
+ return & UpstreamDivergingInfo {
107
+ BaseBranchName : forkBranch ,
108
+ BaseBranchHasNewCommits : info .BaseHasNewCommits ,
109
+ HeadBranchCommitsBehind : info .HeadCommitsBehind ,
110
+ }, nil
111
+ }
112
+ if errors .Is (err , util .ErrNotExist ) {
113
+ info , err = GetBranchDivergingInfo (ctx , forkRepo .BaseRepo , forkRepo .BaseRepo .DefaultBranch , forkRepo , forkBranch )
114
+ if err == nil {
115
+ return & UpstreamDivergingInfo {
116
+ BaseBranchName : forkRepo .BaseRepo .DefaultBranch ,
117
+ BaseBranchHasNewCommits : info .BaseHasNewCommits ,
118
+ HeadBranchCommitsBehind : info .HeadCommitsBehind ,
119
+ }, nil
120
+ }
121
+ }
122
+ return nil , err
87
123
}
0 commit comments