@@ -12,17 +12,20 @@ import (
12
12
repo_model "code.gitea.io/gitea/models/repo"
13
13
user_model "code.gitea.io/gitea/models/user"
14
14
"code.gitea.io/gitea/modules/git"
15
+ "code.gitea.io/gitea/modules/gitrepo"
15
16
repo_module "code.gitea.io/gitea/modules/repository"
17
+ "code.gitea.io/gitea/modules/reqctx"
16
18
"code.gitea.io/gitea/modules/util"
17
19
"code.gitea.io/gitea/services/pull"
18
20
)
19
21
20
22
type UpstreamDivergingInfo struct {
21
- BaseIsNewer bool
22
- CommitsBehind int
23
- CommitsAhead int
23
+ BaseHasNewCommits bool
24
+ CommitsBehind int
25
+ CommitsAhead int
24
26
}
25
27
28
+ // MergeUpstream merges the base repository's default branch into the fork repository's current branch.
26
29
func MergeUpstream (ctx context.Context , doer * user_model.User , repo * repo_model.Repository , branch string ) (mergeStyle string , err error ) {
27
30
if err = repo .MustNotBeArchived (); err != nil {
28
31
return "" , err
@@ -32,7 +35,7 @@ func MergeUpstream(ctx context.Context, doer *user_model.User, repo *repo_model.
32
35
}
33
36
err = git .Push (ctx , repo .BaseRepo .RepoPath (), git.PushOptions {
34
37
Remote : repo .RepoPath (),
35
- Branch : fmt .Sprintf ("%s:%s" , branch , branch ),
38
+ Branch : fmt .Sprintf ("%s:%s" , repo . BaseRepo . DefaultBranch , branch ),
36
39
Env : repo_module .PushingEnvironment (doer , repo ),
37
40
})
38
41
if err == nil {
@@ -64,7 +67,7 @@ func MergeUpstream(ctx context.Context, doer *user_model.User, repo *repo_model.
64
67
BaseRepoID : repo .BaseRepo .ID ,
65
68
BaseRepo : repo .BaseRepo ,
66
69
HeadBranch : branch , // maybe HeadCommitID is not needed
67
- BaseBranch : branch ,
70
+ BaseBranch : repo . BaseRepo . DefaultBranch ,
68
71
}
69
72
fakeIssue .PullRequest = fakePR
70
73
err = pull .Update (ctx , fakePR , doer , "merge upstream" , false )
@@ -74,7 +77,8 @@ func MergeUpstream(ctx context.Context, doer *user_model.User, repo *repo_model.
74
77
return "merge" , nil
75
78
}
76
79
77
- func GetUpstreamDivergingInfo (ctx context.Context , repo * repo_model.Repository , branch string ) (* UpstreamDivergingInfo , error ) {
80
+ // GetUpstreamDivergingInfo returns the information about the divergence between the fork repository's branch and the base repository's default branch.
81
+ func GetUpstreamDivergingInfo (ctx reqctx.RequestContext , repo * repo_model.Repository , branch string ) (* UpstreamDivergingInfo , error ) {
78
82
if ! repo .IsFork {
79
83
return nil , util .NewInvalidArgumentErrorf ("repo is not a fork" )
80
84
}
@@ -92,7 +96,7 @@ func GetUpstreamDivergingInfo(ctx context.Context, repo *repo_model.Repository,
92
96
return nil , err
93
97
}
94
98
95
- baseBranch , err := git_model .GetBranch (ctx , repo .BaseRepo .ID , branch )
99
+ baseBranch , err := git_model .GetBranch (ctx , repo .BaseRepo .ID , repo . BaseRepo . DefaultBranch )
96
100
if err != nil {
97
101
return nil , err
98
102
}
@@ -102,14 +106,39 @@ func GetUpstreamDivergingInfo(ctx context.Context, repo *repo_model.Repository,
102
106
return info , nil
103
107
}
104
108
105
- // TODO: if the fork repo has new commits, this call will fail:
109
+ // if the fork repo has new commits, this call will fail because they are not in the base repo
106
110
// exit status 128 - fatal: Invalid symmetric difference expression aaaaaaaaaaaa...bbbbbbbbbbbb
107
- // so at the moment, we are not able to handle this case, should be improved in the future
111
+ // so at the moment, we first check the update time, then check whether the fork branch has base's head
108
112
diff , err := git .GetDivergingCommits (ctx , repo .BaseRepo .RepoPath (), baseBranch .CommitID , forkBranch .CommitID )
109
113
if err != nil {
110
- info .BaseIsNewer = baseBranch .UpdatedUnix > forkBranch .UpdatedUnix
114
+ info .BaseHasNewCommits = baseBranch .UpdatedUnix > forkBranch .UpdatedUnix
115
+ if info .BaseHasNewCommits {
116
+ return info , nil
117
+ }
118
+
119
+ // if the base's update time is before the fork, check whether the base's head is in the fork
120
+ baseGitRepo , err := gitrepo .RepositoryFromRequestContextOrOpen (ctx , repo .BaseRepo )
121
+ if err != nil {
122
+ return nil , err
123
+ }
124
+ headGitRepo , err := gitrepo .RepositoryFromRequestContextOrOpen (ctx , repo )
125
+ if err != nil {
126
+ return nil , err
127
+ }
128
+
129
+ baseCommitID , err := baseGitRepo .ConvertToGitID (baseBranch .CommitID )
130
+ if err != nil {
131
+ return nil , err
132
+ }
133
+ headCommit , err := headGitRepo .GetCommit (forkBranch .CommitID )
134
+ if err != nil {
135
+ return nil , err
136
+ }
137
+ hasPreviousCommit , _ := headCommit .HasPreviousCommit (baseCommitID )
138
+ info .BaseHasNewCommits = ! hasPreviousCommit
111
139
return info , nil
112
140
}
141
+
113
142
info .CommitsBehind , info .CommitsAhead = diff .Behind , diff .Ahead
114
143
return info , nil
115
144
}
0 commit comments