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