6
6
package repo
7
7
8
8
import (
9
+ "math"
10
+ "strconv"
9
11
"time"
10
12
11
13
"code.gitea.io/gitea/models"
@@ -55,25 +57,186 @@ func GetSingleCommit(ctx *context.APIContext) {
55
57
return
56
58
}
57
59
58
- // Retrieve author and committer information
59
- var apiAuthor , apiCommitter * api.User
60
- author , err := models .GetUserByEmail (commit .Author .Email )
61
- if err != nil && ! models .IsErrUserNotExist (err ) {
62
- ctx .ServerError ("Get user by author email" , err )
60
+ json , err := toCommit (ctx , ctx .Repo .Repository , commit , nil )
61
+ if err != nil {
62
+ ctx .ServerError ("toCommit" , err )
63
+ return
64
+ }
65
+
66
+ ctx .JSON (200 , json )
67
+ }
68
+
69
+ // GetAllCommits get all commits via
70
+ func GetAllCommits (ctx * context.APIContext ) {
71
+ // swagger:operation GET /repos/{owner}/{repo}/commits repository repoGetAllCommits
72
+ // ---
73
+ // summary: Get a list of all commits from a repository
74
+ // produces:
75
+ // - application/json
76
+ // parameters:
77
+ // - name: owner
78
+ // in: path
79
+ // description: owner of the repo
80
+ // type: string
81
+ // required: true
82
+ // - name: repo
83
+ // in: path
84
+ // description: name of the repo
85
+ // type: string
86
+ // required: true
87
+ // - name: sha
88
+ // in: query
89
+ // description: SHA or branch to start listing commits from (usually 'master')
90
+ // type: string
91
+ // - name: page
92
+ // in: query
93
+ // description: page number of requested commits
94
+ // type: integer
95
+ // responses:
96
+ // "200":
97
+ // "$ref": "#/responses/CommitList"
98
+ // "404":
99
+ // "$ref": "#/responses/notFound"
100
+ // "409":
101
+ // "$ref": "#/responses/EmptyRepository"
102
+
103
+ if ctx .Repo .Repository .IsEmpty {
104
+ ctx .JSON (409 , api.APIError {
105
+ Message : "Git Repository is empty." ,
106
+ URL : setting .API .SwaggerURL ,
107
+ })
108
+ return
109
+ }
110
+
111
+ gitRepo , err := git .OpenRepository (ctx .Repo .Repository .RepoPath ())
112
+ if err != nil {
113
+ ctx .ServerError ("OpenRepository" , err )
114
+ return
115
+ }
116
+
117
+ page := ctx .QueryInt ("page" )
118
+ if page <= 0 {
119
+ page = 1
120
+ }
121
+
122
+ sha := ctx .Query ("sha" )
123
+
124
+ var baseCommit * git.Commit
125
+ if len (sha ) == 0 {
126
+ // no sha supplied - use default branch
127
+ head , err := gitRepo .GetHEADBranch ()
128
+ if err != nil {
129
+ ctx .ServerError ("GetHEADBranch" , err )
130
+ return
131
+ }
132
+
133
+ baseCommit , err = gitRepo .GetBranchCommit (head .Name )
134
+ if err != nil {
135
+ ctx .ServerError ("GetCommit" , err )
136
+ return
137
+ }
138
+ } else {
139
+ // get commit specified by sha
140
+ baseCommit , err = gitRepo .GetCommit (sha )
141
+ if err != nil {
142
+ ctx .ServerError ("GetCommit" , err )
143
+ return
144
+ }
145
+ }
146
+
147
+ // Total commit count
148
+ commitsCountTotal , err := baseCommit .CommitsCount ()
149
+ if err != nil {
150
+ ctx .ServerError ("GetCommitsCount" , err )
151
+ return
152
+ }
153
+
154
+ pageCount := int (math .Ceil (float64 (commitsCountTotal ) / float64 (git .CommitsRangeSize )))
155
+
156
+ // Query commits
157
+ commits , err := baseCommit .CommitsByRange (page )
158
+ if err != nil {
159
+ ctx .ServerError ("CommitsByRange" , err )
63
160
return
64
- } else if err == nil {
65
- apiAuthor = author .APIFormat ()
66
161
}
67
- // Save one query if the author is also the committer
68
- if commit .Committer .Email == commit .Author .Email {
69
- apiCommitter = apiAuthor
162
+
163
+ userCache := make (map [string ]* models.User )
164
+
165
+ apiCommits := make ([]* api.Commit , commits .Len ())
166
+
167
+ i := 0
168
+ for commitPointer := commits .Front (); commitPointer != nil ; commitPointer = commitPointer .Next () {
169
+ commit := commitPointer .Value .(* git.Commit )
170
+
171
+ // Create json struct
172
+ apiCommits [i ], err = toCommit (ctx , ctx .Repo .Repository , commit , userCache )
173
+ if err != nil {
174
+ ctx .ServerError ("toCommit" , err )
175
+ return
176
+ }
177
+
178
+ i ++
179
+ }
180
+
181
+ ctx .SetLinkHeader (int (commitsCountTotal ), git .CommitsRangeSize )
182
+
183
+ ctx .Header ().Set ("X-Page" , strconv .Itoa (page ))
184
+ ctx .Header ().Set ("X-PerPage" , strconv .Itoa (git .CommitsRangeSize ))
185
+ ctx .Header ().Set ("X-Total" , strconv .FormatInt (commitsCountTotal , 10 ))
186
+ ctx .Header ().Set ("X-PageCount" , strconv .Itoa (pageCount ))
187
+ ctx .Header ().Set ("X-HasMore" , strconv .FormatBool (page < pageCount ))
188
+
189
+ ctx .JSON (200 , & apiCommits )
190
+ }
191
+
192
+ func toCommit (ctx * context.APIContext , repo * models.Repository , commit * git.Commit , userCache map [string ]* models.User ) (* api.Commit , error ) {
193
+
194
+ var apiAuthor , apiCommitter * api.User
195
+
196
+ // Retrieve author and committer information
197
+
198
+ var cacheAuthor * models.User
199
+ var ok bool
200
+ if userCache == nil {
201
+ cacheAuthor = ((* models .User )(nil ))
202
+ ok = false
203
+ } else {
204
+ cacheAuthor , ok = userCache [commit .Author .Email ]
205
+ }
206
+
207
+ if ok {
208
+ apiAuthor = cacheAuthor .APIFormat ()
209
+ } else {
210
+ author , err := models .GetUserByEmail (commit .Author .Email )
211
+ if err != nil && ! models .IsErrUserNotExist (err ) {
212
+ return nil , err
213
+ } else if err == nil {
214
+ apiAuthor = author .APIFormat ()
215
+ if userCache != nil {
216
+ userCache [commit .Author .Email ] = author
217
+ }
218
+ }
219
+ }
220
+
221
+ var cacheCommitter * models.User
222
+ if userCache == nil {
223
+ cacheCommitter = ((* models .User )(nil ))
224
+ ok = false
225
+ } else {
226
+ cacheCommitter , ok = userCache [commit .Committer .Email ]
227
+ }
228
+
229
+ if ok {
230
+ apiCommitter = cacheCommitter .APIFormat ()
70
231
} else {
71
232
committer , err := models .GetUserByEmail (commit .Committer .Email )
72
233
if err != nil && ! models .IsErrUserNotExist (err ) {
73
- ctx .ServerError ("Get user by committer email" , err )
74
- return
234
+ return nil , err
75
235
} else if err == nil {
76
236
apiCommitter = committer .APIFormat ()
237
+ if userCache != nil {
238
+ userCache [commit .Committer .Email ] = committer
239
+ }
77
240
}
78
241
}
79
242
@@ -82,23 +245,23 @@ func GetSingleCommit(ctx *context.APIContext) {
82
245
for i := 0 ; i < commit .ParentCount (); i ++ {
83
246
sha , _ := commit .ParentID (i )
84
247
apiParents [i ] = & api.CommitMeta {
85
- URL : ctx . Repo . Repository .APIURL () + "/git/commits/" + sha .String (),
248
+ URL : repo .APIURL () + "/git/commits/" + sha .String (),
86
249
SHA : sha .String (),
87
250
}
88
251
}
89
252
90
- ctx . JSON ( 200 , & api.Commit {
253
+ return & api.Commit {
91
254
CommitMeta : & api.CommitMeta {
92
- URL : setting . AppURL + ctx . Link [ 1 :] ,
255
+ URL : repo . APIURL () + "/git/commits/" + commit . ID . String () ,
93
256
SHA : commit .ID .String (),
94
257
},
95
- HTMLURL : ctx . Repo . Repository .HTMLURL () + "/commit/" + commit .ID .String (),
258
+ HTMLURL : repo .HTMLURL () + "/commit/" + commit .ID .String (),
96
259
RepoCommit : & api.RepoCommit {
97
- URL : setting . AppURL + ctx . Link [ 1 :] ,
260
+ URL : repo . APIURL () + "/git/commits/" + commit . ID . String () ,
98
261
Author : & api.CommitUser {
99
262
Identity : api.Identity {
100
- Name : commit .Author .Name ,
101
- Email : commit .Author .Email ,
263
+ Name : commit .Committer .Name ,
264
+ Email : commit .Committer .Email ,
102
265
},
103
266
Date : commit .Author .When .Format (time .RFC3339 ),
104
267
},
@@ -109,14 +272,14 @@ func GetSingleCommit(ctx *context.APIContext) {
109
272
},
110
273
Date : commit .Committer .When .Format (time .RFC3339 ),
111
274
},
112
- Message : commit .Message (),
275
+ Message : commit .Summary (),
113
276
Tree : & api.CommitMeta {
114
- URL : ctx . Repo . Repository .APIURL () + "/git/trees/" + commit .ID .String (),
277
+ URL : repo .APIURL () + "/git/trees/" + commit .ID .String (),
115
278
SHA : commit .ID .String (),
116
279
},
117
280
},
118
281
Author : apiAuthor ,
119
282
Committer : apiCommitter ,
120
283
Parents : apiParents ,
121
- })
284
+ }, nil
122
285
}
0 commit comments