Skip to content

Commit 7a13e5a

Browse files
committed
fix
1 parent 6326db3 commit 7a13e5a

File tree

10 files changed

+101
-73
lines changed

10 files changed

+101
-73
lines changed

modules/structs/repo_file.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,17 @@ type ContentsExtResponse struct {
116116

117117
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
118118
type ContentsResponse struct {
119-
Name string `json:"name"`
120-
Path string `json:"path"`
121-
SHA string `json:"sha"`
122-
LastCommitSHA string `json:"last_commit_sha"`
119+
Name string `json:"name"`
120+
Path string `json:"path"`
121+
SHA string `json:"sha"`
122+
123+
LastCommitSHA *string `json:"last_commit_sha,omitempty"`
123124
// swagger:strfmt date-time
124-
LastCommitterDate time.Time `json:"last_committer_date"`
125+
LastCommitterDate *time.Time `json:"last_committer_date,omitempty"`
125126
// swagger:strfmt date-time
126-
LastAuthorDate time.Time `json:"last_author_date"`
127-
LastCommitMessage string `json:"last_commit_message"`
127+
LastAuthorDate *time.Time `json:"last_author_date,omitempty"`
128+
LastCommitMessage *string `json:"last_commit_message,omitempty"`
129+
128130
// `type` will be `file`, `dir`, `symlink`, or `submodule`
129131
Type string `json:"type"`
130132
Size int64 `json:"size"`
@@ -142,8 +144,8 @@ type ContentsResponse struct {
142144
SubmoduleGitURL *string `json:"submodule_git_url"`
143145
Links *FileLinksResponse `json:"_links"`
144146

145-
LfsOid *string `json:"lfs_oid"`
146-
LfsSize *int64 `json:"lfs_size"`
147+
LfsOid *string `json:"lfs_oid,omitempty"`
148+
LfsSize *int64 `json:"lfs_size,omitempty"`
147149
}
148150

149151
// FileCommitResponse contains information generated from a Git commit for a repo's file.

routers/api/v1/repo/file.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ func GetContentsExt(ctx *context.APIContext) {
814814
// in: path
815815
// description: path of the dir, file, symlink or submodule in the repo
816816
// type: string
817-
// required: true
817+
// required: false
818818
// - name: ref
819819
// in: query
820820
// description: the name of the commit/branch/tag, default to the repository’s default branch.
@@ -823,7 +823,8 @@ func GetContentsExt(ctx *context.APIContext) {
823823
// - name: includes
824824
// in: query
825825
// description: By default this API's response only contains file's metadata. Use comma-separated "includes" options to retrieve more fields.
826-
// Option "file_content" will try to retrieve the file content, option "lfs_metadata" will try to retrieve LFS metadata.
826+
// Option "file_content" will try to retrieve the file content, "lfs_metadata" will try to retrieve LFS metadata,
827+
// "commit_metadata" will try to retrieve commit metadata, and "commit_message" will try to retrieve commit message.
827828
// type: string
828829
// required: false
829830
// responses:
@@ -842,6 +843,10 @@ func GetContentsExt(ctx *context.APIContext) {
842843
opts.IncludeSingleFileContent = true
843844
case "lfs_metadata":
844845
opts.IncludeLfsMetadata = true
846+
case "commit_metadata":
847+
opts.IncludeCommitMetadata = true
848+
case "commit_message":
849+
opts.IncludeCommitMessage = true
845850
default:
846851
ctx.APIError(http.StatusBadRequest, fmt.Sprintf("unknown include option %q", includeOpt))
847852
return
@@ -883,7 +888,11 @@ func GetContents(ctx *context.APIContext) {
883888
// "$ref": "#/responses/ContentsResponse"
884889
// "404":
885890
// "$ref": "#/responses/notFound"
886-
ret := getRepoContents(ctx, files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*"), IncludeSingleFileContent: true})
891+
ret := getRepoContents(ctx, files_service.GetContentsOrListOptions{
892+
TreePath: ctx.PathParam("*"),
893+
IncludeSingleFileContent: true,
894+
IncludeCommitMetadata: true,
895+
})
887896
if ctx.Written() {
888897
return
889898
}

services/repository/files/content.go

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ type GetContentsOrListOptions struct {
3939
TreePath string
4040
IncludeSingleFileContent bool // include the file's content when the tree path is a file
4141
IncludeLfsMetadata bool
42+
IncludeCommitMetadata bool
43+
IncludeCommitMessage bool
4244
}
4345

4446
// GetContentsOrList gets the metadata of a file's contents (*ContentsResponse) if treePath not a tree
@@ -132,40 +134,46 @@ func getFileContentsByEntryInternal(_ context.Context, repo *repo_model.Reposito
132134
}
133135
selfURLString := selfURL.String()
134136

135-
err = gitRepo.AddLastCommitCache(repo.GetCommitsCountCacheKey(refCommit.InputRef, refType != git.RefTypeCommit), repo.FullName(), refCommit.CommitID)
136-
if err != nil {
137-
return nil, err
138-
}
139-
140-
lastCommit, err := refCommit.Commit.GetCommitByPath(opts.TreePath)
141-
if err != nil {
142-
return nil, err
143-
}
144-
145137
// All content types have these fields in populated
146138
contentsResponse := &api.ContentsResponse{
147-
Name: entry.Name(),
148-
Path: opts.TreePath,
149-
SHA: entry.ID.String(),
150-
LastCommitSHA: lastCommit.ID.String(),
151-
Size: entry.Size(),
152-
URL: &selfURLString,
139+
Name: entry.Name(),
140+
Path: opts.TreePath,
141+
SHA: entry.ID.String(),
142+
Size: entry.Size(),
143+
URL: &selfURLString,
153144
Links: &api.FileLinksResponse{
154145
Self: &selfURLString,
155146
},
156147
}
157148

158-
// GitHub doesn't have these fields in the response, but we could follow other similar APIs to name them
159-
// https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#list-commits
160-
if lastCommit.Committer != nil {
161-
contentsResponse.LastCommitterDate = lastCommit.Committer.When
162-
}
163-
if lastCommit.Author != nil {
164-
contentsResponse.LastAuthorDate = lastCommit.Author.When
149+
if opts.IncludeCommitMetadata || opts.IncludeCommitMessage {
150+
err = gitRepo.AddLastCommitCache(repo.GetCommitsCountCacheKey(refCommit.InputRef, refType != git.RefTypeCommit), repo.FullName(), refCommit.CommitID)
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
lastCommit, err := refCommit.Commit.GetCommitByPath(opts.TreePath)
156+
if err != nil {
157+
return nil, err
158+
}
159+
160+
if opts.IncludeCommitMetadata {
161+
contentsResponse.LastCommitSHA = util.ToPointer(lastCommit.ID.String())
162+
// GitHub doesn't have these fields in the response, but we could follow other similar APIs to name them
163+
// https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#list-commits
164+
if lastCommit.Committer != nil {
165+
contentsResponse.LastCommitterDate = util.ToPointer(lastCommit.Committer.When)
166+
}
167+
if lastCommit.Author != nil {
168+
contentsResponse.LastAuthorDate = util.ToPointer(lastCommit.Author.When)
169+
}
170+
}
171+
if opts.IncludeCommitMessage {
172+
contentsResponse.LastCommitMessage = util.ToPointer(lastCommit.Message())
173+
}
165174
}
166-
contentsResponse.LastCommitMessage = lastCommit.Message()
167175

168-
// Now populate the rest of the ContentsResponse based on entry type
176+
// Now populate the rest of the ContentsResponse based on the entry type
169177
if entry.IsRegular() || entry.IsExecutable() {
170178
contentsResponse.Type = string(ContentTypeRegular)
171179
// if it is listing the repo root dir, don't waste system resources on reading content

services/repository/files/content_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ func getExpectedReadmeContentsResponse() *api.ContentsResponse {
3636
Name: treePath,
3737
Path: treePath,
3838
SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
39-
LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
40-
LastCommitterDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)),
41-
LastAuthorDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)),
42-
LastCommitMessage: "Initial commit\n",
39+
LastCommitSHA: util.ToPointer("65f1bf27bc3bf70f64657658635e66094edbcb4d"),
40+
LastCommitterDate: util.ToPointer(time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400))),
41+
LastAuthorDate: util.ToPointer(time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400))),
42+
LastCommitMessage: util.ToPointer("Initial commit\n"),
4343
Type: "file",
4444
Size: 30,
4545
Encoding: &encoding,

templates/swagger/v1_json.tmpl

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/integration/api_repo_file_create_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"code.gitea.io/gitea/modules/gitrepo"
2020
"code.gitea.io/gitea/modules/setting"
2121
api "code.gitea.io/gitea/modules/structs"
22+
"code.gitea.io/gitea/modules/util"
2223
"code.gitea.io/gitea/services/context"
2324

2425
"github.com/stretchr/testify/assert"
@@ -52,8 +53,8 @@ func getCreateFileOptions() api.CreateFileOptions {
5253
func normalizeFileContentResponseCommitTime(c *api.ContentsResponse) {
5354
// decoded JSON response may contain different timezone from the one parsed by git commit
5455
// so we need to normalize the time to UTC to make "assert.Equal" pass
55-
c.LastCommitterDate = c.LastCommitterDate.UTC()
56-
c.LastAuthorDate = c.LastAuthorDate.UTC()
56+
c.LastCommitterDate = util.ToPointer(c.LastCommitterDate.UTC())
57+
c.LastAuthorDate = util.ToPointer(c.LastAuthorDate.UTC())
5758
}
5859

5960
type apiFileResponseInfo struct {
@@ -74,10 +75,10 @@ func getExpectedFileResponseForCreate(info apiFileResponseInfo) *api.FileRespons
7475
Name: path.Base(info.treePath),
7576
Path: info.treePath,
7677
SHA: sha,
77-
LastCommitSHA: info.lastCommitSHA,
78-
LastCommitterDate: info.lastCommitterWhen,
79-
LastAuthorDate: info.lastAuthorWhen,
80-
LastCommitMessage: info.lastCommitMessage,
78+
LastCommitSHA: util.ToPointer(info.lastCommitSHA),
79+
LastCommitterDate: util.ToPointer(info.lastCommitterWhen),
80+
LastAuthorDate: util.ToPointer(info.lastAuthorWhen),
81+
LastCommitMessage: util.ToPointer(info.lastCommitMessage),
8182
Size: 16,
8283
Type: "file",
8384
Encoding: &encoding,

tests/integration/api_repo_file_update_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"code.gitea.io/gitea/modules/gitrepo"
1919
"code.gitea.io/gitea/modules/setting"
2020
api "code.gitea.io/gitea/modules/structs"
21+
"code.gitea.io/gitea/modules/util"
2122
"code.gitea.io/gitea/services/context"
2223

2324
"github.com/stretchr/testify/assert"
@@ -60,9 +61,9 @@ func getExpectedFileResponseForUpdate(info apiFileResponseInfo) *api.FileRespons
6061
Name: path.Base(info.treePath),
6162
Path: info.treePath,
6263
SHA: sha,
63-
LastCommitSHA: info.lastCommitSHA,
64-
LastCommitterDate: info.lastCommitterWhen,
65-
LastAuthorDate: info.lastAuthorWhen,
64+
LastCommitSHA: util.ToPointer(info.lastCommitSHA),
65+
LastCommitterDate: util.ToPointer(info.lastCommitterWhen),
66+
LastAuthorDate: util.ToPointer(info.lastAuthorWhen),
6667
Type: "file",
6768
Size: 20,
6869
Encoding: &encoding,

tests/integration/api_repo_get_contents_list_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"code.gitea.io/gitea/modules/gitrepo"
1919
"code.gitea.io/gitea/modules/setting"
2020
api "code.gitea.io/gitea/modules/structs"
21+
"code.gitea.io/gitea/modules/util"
2122
repo_service "code.gitea.io/gitea/services/repository"
2223

2324
"github.com/stretchr/testify/assert"
@@ -35,10 +36,10 @@ func getExpectedContentsListResponseForContents(ref, refType, lastCommitSHA stri
3536
Name: path.Base(treePath),
3637
Path: treePath,
3738
SHA: sha,
38-
LastCommitSHA: lastCommitSHA,
39-
LastCommitterDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)),
40-
LastAuthorDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)),
41-
LastCommitMessage: "Initial commit",
39+
LastCommitSHA: util.ToPointer(lastCommitSHA),
40+
LastCommitterDate: util.ToPointer(time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400))),
41+
LastAuthorDate: util.ToPointer(time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400))),
42+
LastCommitMessage: util.ToPointer("Initial commit"),
4243
Type: "file",
4344
Size: 30,
4445
URL: &selfURL,

tests/integration/api_repo_get_contents_test.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ func getExpectedContentsResponseForContents(ref, refType, lastCommitSHA string)
3535
Name: treePath,
3636
Path: treePath,
3737
SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
38-
LastCommitSHA: lastCommitSHA,
39-
LastCommitterDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)),
40-
LastAuthorDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)),
41-
LastCommitMessage: "Initial commit",
38+
LastCommitSHA: util.ToPointer(lastCommitSHA),
39+
LastCommitterDate: util.ToPointer(time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400))),
40+
LastAuthorDate: util.ToPointer(time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400))),
4241
Type: "file",
4342
Size: 30,
4443
Encoding: util.ToPointer("base64"),
@@ -215,6 +214,8 @@ func testAPIGetContentsExt(t *testing.T) {
215214
assert.Equal(t, "README.md", contentsResponse.DirContents[0].Name)
216215
assert.Nil(t, contentsResponse.DirContents[0].Encoding)
217216
assert.Nil(t, contentsResponse.DirContents[0].Content)
217+
assert.Nil(t, contentsResponse.DirContents[0].LastCommitSHA)
218+
assert.Nil(t, contentsResponse.DirContents[0].LastCommitMessage)
218219

219220
// "includes=file_content" shouldn't affect directory listing
220221
req = NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/contents-ext/docs?ref=sub-home-md-img-check&includes=file_content")
@@ -250,16 +251,20 @@ func testAPIGetContentsExt(t *testing.T) {
250251
assert.Equal(t, "README.md", contentsResponse.FileContents.Name)
251252
assert.Nil(t, contentsResponse.FileContents.Encoding)
252253
assert.Nil(t, contentsResponse.FileContents.Content)
254+
assert.Nil(t, contentsResponse.FileContents.LastCommitSHA)
255+
assert.Nil(t, contentsResponse.FileContents.LastCommitMessage)
253256

254257
// file content is only returned when `includes=file_content`
255-
req = NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/contents-ext/docs/README.md?ref=sub-home-md-img-check&includes=file_content")
258+
req = NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/contents-ext/docs/README.md?ref=sub-home-md-img-check&includes=file_content,commit_metadata,commit_message")
256259
resp = MakeRequest(t, req, http.StatusOK)
257260
contentsResponse = api.ContentsExtResponse{}
258261
DecodeJSON(t, resp, &contentsResponse)
259262
assert.Nil(t, contentsResponse.DirContents)
260263
assert.Equal(t, "README.md", contentsResponse.FileContents.Name)
261264
assert.NotNil(t, contentsResponse.FileContents.Encoding)
262265
assert.NotNil(t, contentsResponse.FileContents.Content)
266+
assert.NotNil(t, contentsResponse.FileContents.LastCommitSHA)
267+
assert.NotNil(t, contentsResponse.FileContents.LastCommitMessage)
263268

264269
req = NewRequestf(t, "GET", "/api/v1/repos/user2/lfs/contents-ext/jpeg.jpg?includes=file_content").AddTokenAuth(token2)
265270
resp = session.MakeRequest(t, req, http.StatusOK)
@@ -271,6 +276,8 @@ func testAPIGetContentsExt(t *testing.T) {
271276
assert.Equal(t, "jpeg.jpg", respFile.Name)
272277
assert.NotNil(t, respFile.Encoding)
273278
assert.NotNil(t, respFile.Content)
279+
assert.Nil(t, contentsResponse.FileContents.LastCommitSHA)
280+
assert.Nil(t, contentsResponse.FileContents.LastCommitMessage)
274281
assert.Equal(t, util.ToPointer(int64(107)), respFile.LfsSize)
275282
assert.Equal(t, util.ToPointer("0b8d8b5f15046343fd32f451df93acc2bdd9e6373be478b968e4cad6b6647351"), respFile.LfsOid)
276283
})

tests/integration/repofiles_change_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,10 @@ func getExpectedFileResponseForRepoFilesCreate(commitID string, lastCommit *git.
155155
Name: path.Base(treePath),
156156
Path: treePath,
157157
SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885",
158-
LastCommitSHA: lastCommit.ID.String(),
159-
LastCommitterDate: lastCommit.Committer.When,
160-
LastAuthorDate: lastCommit.Author.When,
161-
LastCommitMessage: "Creates new/file.txt\n",
158+
LastCommitSHA: util.ToPointer(lastCommit.ID.String()),
159+
LastCommitterDate: util.ToPointer(lastCommit.Committer.When),
160+
LastAuthorDate: util.ToPointer(lastCommit.Author.When),
161+
LastCommitMessage: util.ToPointer("Creates new/file.txt\n"),
162162
Type: "file",
163163
Size: 18,
164164
Encoding: &encoding,
@@ -226,10 +226,10 @@ func getExpectedFileResponseForRepoFilesUpdate(commitID, filename, lastCommitSHA
226226
Name: filename,
227227
Path: filename,
228228
SHA: "dbf8d00e022e05b7e5cf7e535de857de57925647",
229-
LastCommitSHA: lastCommitSHA,
230-
LastCommitterDate: lastCommitterWhen,
231-
LastAuthorDate: lastAuthorWhen,
232-
LastCommitMessage: "Updates README.md\n",
229+
LastCommitSHA: util.ToPointer(lastCommitSHA),
230+
LastCommitterDate: util.ToPointer(lastCommitterWhen),
231+
LastAuthorDate: util.ToPointer(lastAuthorWhen),
232+
LastCommitMessage: util.ToPointer("Updates README.md\n"),
233233
Type: "file",
234234
Size: 43,
235235
Encoding: &encoding,
@@ -333,8 +333,8 @@ func getExpectedFileResponseForRepoFilesUpdateRename(commitID, lastCommitSHA str
333333
Name: detail.filename,
334334
Path: detail.filename,
335335
SHA: detail.sha,
336-
LastCommitSHA: lastCommitSHA,
337-
LastCommitMessage: "Rename files\n",
336+
LastCommitSHA: util.ToPointer(lastCommitSHA),
337+
LastCommitMessage: util.ToPointer("Rename files\n"),
338338
Type: "file",
339339
Size: detail.size,
340340
Encoding: util.ToPointer("base64"),
@@ -540,7 +540,7 @@ func TestChangeRepoFilesForUpdateWithFileRename(t *testing.T) {
540540
lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath)
541541
expectedFileResponse := getExpectedFileResponseForRepoFilesUpdateRename(commit.ID.String(), lastCommit.ID.String())
542542
for _, file := range filesResponse.Files {
543-
file.LastCommitterDate, file.LastAuthorDate = time.Time{}, time.Time{} // there might be different time in one operation, so we ignore them
543+
file.LastCommitterDate, file.LastAuthorDate = nil, nil // there might be different time in one operation, so we ignore them
544544
}
545545
assert.Len(t, filesResponse.Files, 4)
546546
assert.Equal(t, expectedFileResponse.Files, filesResponse.Files)

0 commit comments

Comments
 (0)