Skip to content

Commit 84c566b

Browse files
authored
Merge branch 'main' into lunny/pending_comment_not_trigger_webhook
2 parents 681ffa6 + 6455c82 commit 84c566b

File tree

15 files changed

+154
-153
lines changed

15 files changed

+154
-153
lines changed

modules/structs/repo_file.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +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+
LastAuthorDate *time.Time `json:"last_author_date,omitempty"`
128+
LastCommitMessage *string `json:"last_commit_message,omitempty"`
129+
127130
// `type` will be `file`, `dir`, `symlink`, or `submodule`
128131
Type string `json:"type"`
129132
Size int64 `json:"size"`
@@ -141,8 +144,8 @@ type ContentsResponse struct {
141144
SubmoduleGitURL *string `json:"submodule_git_url"`
142145
Links *FileLinksResponse `json:"_links"`
143146

144-
LfsOid *string `json:"lfs_oid"`
145-
LfsSize *int64 `json:"lfs_size"`
147+
LfsOid *string `json:"lfs_oid,omitempty"`
148+
LfsSize *int64 `json:"lfs_size,omitempty"`
146149
}
147150

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

options/locale/locale_fr-FR.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,7 @@ pulls.cmd_instruction_checkout_title=Basculer
19691969
pulls.cmd_instruction_checkout_desc=Depuis votre dépôt, basculer sur une nouvelle branche et tester des modifications.
19701970
pulls.cmd_instruction_merge_title=Fusionner
19711971
pulls.cmd_instruction_merge_desc=Fusionner les modifications et mettre à jour sur Gitea.
1972+
pulls.cmd_instruction_merge_warning=Attention : cette opération ne peut pas fusionner la demande d’ajout car la « détection automatique de fusion manuelle » n’a pas été activée
19721973
pulls.clear_merge_message=Effacer le message de fusion
19731974
pulls.clear_merge_message_hint=Effacer le message de fusion ne supprimera que le message de la révision, mais pas les pieds de révision générés tels que "Co-Authored-By:".
19741975

@@ -2768,6 +2769,8 @@ branch.new_branch_from=`Créer une nouvelle branche à partir de "%s"`
27682769
branch.renamed=La branche %s à été renommée en %s.
27692770
branch.rename_default_or_protected_branch_error=Seuls les administrateurs peuvent renommer les branches par défaut ou protégées.
27702771
branch.rename_protected_branch_failed=Cette branche est protégée par des règles de protection basées sur des globs.
2772+
branch.commits_divergence_from=Divergence de révisions : %[1]d en retard et %[2]d en avance sur %[3]s
2773+
branch.commits_no_divergence=Identique à la branche %[1]s
27712774

27722775
tag.create_tag=Créer l'étiquette %s
27732776
tag.create_tag_operation=Créer une étiquette

options/locale/locale_ga-IE.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,8 @@ branch.new_branch_from=`Cruthaigh brainse nua ó "%s"`
27692769
branch.renamed=Ainmníodh brainse %s go %s.
27702770
branch.rename_default_or_protected_branch_error=Ní féidir ach le riarthóirí brainsí réamhshocraithe nó cosanta a athainmniú.
27712771
branch.rename_protected_branch_failed=Tá an brainse seo faoi chosaint ag rialacha cosanta domhanda.
2772+
branch.commits_divergence_from=Déanann sé dialltacht a thiomnú: %[1]d taobh thiar agus %[2]d chun tosaigh ar %[3]s
2773+
branch.commits_no_divergence=Mar an gcéanna le brainse %[1]s
27722774
27732775
tag.create_tag=Cruthaigh clib %s
27742776
tag.create_tag_operation=Cruthaigh clib
@@ -2782,6 +2784,7 @@ topic.done=Déanta
27822784
topic.count_prompt=Ní féidir leat níos mó ná 25 topaicí a roghnú
27832785
topic.format_prompt=Ní mór do thopaicí tosú le litir nó uimhir, is féidir daiseanna ('-') agus poncanna ('.') a áireamh, a bheith suas le 35 carachtar ar fad. Ní mór litreacha a bheith i litreacha beaga.
27842786
2787+
find_file.follow_symlink=Lean an nasc siombalach seo go dtí an áit a bhfuil sé ag pointeáil air
27852788
find_file.go_to_file=Téigh go dtí an comhad
27862789
find_file.no_matching=Níl aon chomhad meaitseála le fáil
27872790

options/locale/locale_pt-PT.ini

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,8 +1562,8 @@ issues.filter_project=Planeamento
15621562
issues.filter_project_all=Todos os planeamentos
15631563
issues.filter_project_none=Nenhum planeamento
15641564
issues.filter_assignee=Encarregado
1565-
issues.filter_assignee_no_assignee=Não atribuído
1566-
issues.filter_assignee_any_assignee=Atribuído a qualquer pessoa
1565+
issues.filter_assignee_no_assignee=Não atribuída
1566+
issues.filter_assignee_any_assignee=Atribuída a alguém
15671567
issues.filter_poster=Autor(a)
15681568
issues.filter_user_placeholder=Procurar utilizadores
15691569
issues.filter_user_no_select=Todos os utilizadores
@@ -1969,6 +1969,7 @@ pulls.cmd_instruction_checkout_title=Checkout
19691969
pulls.cmd_instruction_checkout_desc=A partir do seu repositório, crie um novo ramo e teste nele as modificações.
19701970
pulls.cmd_instruction_merge_title=Integrar
19711971
pulls.cmd_instruction_merge_desc=Integrar as modificações e enviar para o Gitea.
1972+
pulls.cmd_instruction_merge_warning=Aviso: Esta operação não pode executar pedidos de integração porque a opção "auto-identificar integração manual" não está habilitada.
19721973
pulls.clear_merge_message=Apagar mensagem de integração
19731974
pulls.clear_merge_message_hint=Apagar a mensagem de integração apenas remove o conteúdo da mensagem de cometimento e mantém os rodapés do git, tais como "Co-Autorado-Por …".
19741975

@@ -2768,6 +2769,8 @@ branch.new_branch_from=`Criar um novo ramo a partir do ramo "%s"`
27682769
branch.renamed=O ramo %s foi renomeado para %s.
27692770
branch.rename_default_or_protected_branch_error=Só os administradores é que podem renomear o ramo principal ou ramos protegidos.
27702771
branch.rename_protected_branch_failed=Este ramo está protegido por regras de salvaguarda baseadas em padrões glob.
2772+
branch.commits_divergence_from=Divergência nos cometimentos: %[1]d atrás e %[2]d à frente de %[3]s
2773+
branch.commits_no_divergence=Idêntico ao ramo %[1]s
27712774

27722775
tag.create_tag=Criar etiqueta %s
27732776
tag.create_tag_operation=Criar etiqueta
@@ -2781,6 +2784,7 @@ topic.done=Concluído
27812784
topic.count_prompt=Não pode escolher mais do que 25 tópicos
27822785
topic.format_prompt=Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') ou pontos ('.') e podem ter até 35 caracteres. As letras têm que ser minúsculas.
27832786

2787+
find_file.follow_symlink=Seguir esta ligação simbólica para onde ela está apontando
27842788
find_file.go_to_file=Ir para o ficheiro
27852789
find_file.no_matching=Não foi encontrado qualquer ficheiro correspondente
27862790

routers/api/v1/repo/file.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,8 @@ func GetContentsExt(ctx *context.APIContext) {
812812
// required: true
813813
// - name: filepath
814814
// in: path
815-
// description: path of the dir, file, symlink or submodule in the repo
815+
// description: path of the dir, file, symlink or submodule in the repo. Swagger requires path parameter to be "required",
816+
// you can leave it empty or pass a single dot (".") to get the root directory.
816817
// type: string
817818
// required: true
818819
// - name: ref
@@ -823,7 +824,8 @@ func GetContentsExt(ctx *context.APIContext) {
823824
// - name: includes
824825
// in: query
825826
// 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.
827+
// Option "file_content" will try to retrieve the file content, "lfs_metadata" will try to retrieve LFS metadata,
828+
// "commit_metadata" will try to retrieve commit metadata, and "commit_message" will try to retrieve commit message.
827829
// type: string
828830
// required: false
829831
// responses:
@@ -832,6 +834,9 @@ func GetContentsExt(ctx *context.APIContext) {
832834
// "404":
833835
// "$ref": "#/responses/notFound"
834836

837+
if treePath := ctx.PathParam("*"); treePath == "." || treePath == "/" {
838+
ctx.SetPathParam("*", "") // workaround for swagger, it requires path parameter to be "required", but we need to list root directory
839+
}
835840
opts := files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*")}
836841
for includeOpt := range strings.SplitSeq(ctx.FormString("includes"), ",") {
837842
if includeOpt == "" {
@@ -842,6 +847,10 @@ func GetContentsExt(ctx *context.APIContext) {
842847
opts.IncludeSingleFileContent = true
843848
case "lfs_metadata":
844849
opts.IncludeLfsMetadata = true
850+
case "commit_metadata":
851+
opts.IncludeCommitMetadata = true
852+
case "commit_message":
853+
opts.IncludeCommitMessage = true
845854
default:
846855
ctx.APIError(http.StatusBadRequest, fmt.Sprintf("unknown include option %q", includeOpt))
847856
return
@@ -883,7 +892,11 @@ func GetContents(ctx *context.APIContext) {
883892
// "$ref": "#/responses/ContentsResponse"
884893
// "404":
885894
// "$ref": "#/responses/notFound"
886-
ret := getRepoContents(ctx, files_service.GetContentsOrListOptions{TreePath: ctx.PathParam("*"), IncludeSingleFileContent: true})
895+
ret := getRepoContents(ctx, files_service.GetContentsOrListOptions{
896+
TreePath: ctx.PathParam("*"),
897+
IncludeSingleFileContent: true,
898+
IncludeCommitMetadata: true,
899+
})
887900
if ctx.Written() {
888901
return
889902
}

services/repository/files/content.go

Lines changed: 33 additions & 24 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,39 +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
}
166175

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

services/repository/files/content_test.go

Lines changed: 1 addition & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,56 +5,21 @@ package files
55

66
import (
77
"testing"
8-
"time"
98

109
"code.gitea.io/gitea/models/unittest"
1110
api "code.gitea.io/gitea/modules/structs"
1211
"code.gitea.io/gitea/modules/util"
13-
"code.gitea.io/gitea/routers/api/v1/utils"
1412
"code.gitea.io/gitea/services/contexttest"
1513

1614
_ "code.gitea.io/gitea/models/actions"
1715

1816
"github.com/stretchr/testify/assert"
19-
"github.com/stretchr/testify/require"
2017
)
2118

2219
func TestMain(m *testing.M) {
2320
unittest.MainTest(m)
2421
}
2522

26-
func getExpectedReadmeContentsResponse() *api.ContentsResponse {
27-
treePath := "README.md"
28-
sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
29-
encoding := "base64"
30-
content := "IyByZXBvMQoKRGVzY3JpcHRpb24gZm9yIHJlcG8x"
31-
selfURL := "https://try.gitea.io/api/v1/repos/user2/repo1/contents/" + treePath + "?ref=master"
32-
htmlURL := "https://try.gitea.io/user2/repo1/src/branch/master/" + treePath
33-
gitURL := "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/" + sha
34-
downloadURL := "https://try.gitea.io/user2/repo1/raw/branch/master/" + treePath
35-
return &api.ContentsResponse{
36-
Name: treePath,
37-
Path: treePath,
38-
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-
Type: "file",
43-
Size: 30,
44-
Encoding: &encoding,
45-
Content: &content,
46-
URL: &selfURL,
47-
HTMLURL: &htmlURL,
48-
GitURL: &gitURL,
49-
DownloadURL: &downloadURL,
50-
Links: &api.FileLinksResponse{
51-
Self: &selfURL,
52-
GitURL: &gitURL,
53-
HTMLURL: &htmlURL,
54-
},
55-
}
56-
}
57-
5823
func TestGetContents(t *testing.T) {
5924
unittest.PrepareTestEnv(t)
6025
ctx, _ := contexttest.MockContext(t, "user2/repo1")
@@ -63,45 +28,8 @@ func TestGetContents(t *testing.T) {
6328
contexttest.LoadRepoCommit(t, ctx)
6429
contexttest.LoadUser(t, ctx, 2)
6530
contexttest.LoadGitRepo(t, ctx)
66-
defer ctx.Repo.GitRepo.Close()
67-
repo, gitRepo := ctx.Repo.Repository, ctx.Repo.GitRepo
68-
refCommit, err := utils.ResolveRefCommit(ctx, ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch)
69-
require.NoError(t, err)
70-
71-
t.Run("GetContentsOrList(README.md)-MetaOnly", func(t *testing.T) {
72-
expectedContentsResponse := getExpectedReadmeContentsResponse()
73-
expectedContentsResponse.Encoding = nil // because will be in a list, doesn't have encoding and content
74-
expectedContentsResponse.Content = nil
75-
extResp, err := GetContentsOrList(ctx, repo, gitRepo, refCommit, GetContentsOrListOptions{TreePath: "README.md", IncludeSingleFileContent: false})
76-
assert.Equal(t, expectedContentsResponse, extResp.FileContents)
77-
assert.NoError(t, err)
78-
})
79-
80-
t.Run("GetContentsOrList(README.md)", func(t *testing.T) {
81-
expectedContentsResponse := getExpectedReadmeContentsResponse()
82-
extResp, err := GetContentsOrList(ctx, repo, gitRepo, refCommit, GetContentsOrListOptions{TreePath: "README.md", IncludeSingleFileContent: true})
83-
assert.Equal(t, expectedContentsResponse, extResp.FileContents)
84-
assert.NoError(t, err)
85-
})
86-
87-
t.Run("GetContentsOrList(RootDir)", func(t *testing.T) {
88-
readmeContentsResponse := getExpectedReadmeContentsResponse()
89-
readmeContentsResponse.Encoding = nil // because will be in a list, doesn't have encoding and content
90-
readmeContentsResponse.Content = nil
91-
expectedContentsListResponse := []*api.ContentsResponse{readmeContentsResponse}
92-
// even if IncludeFileContent is true, it has no effect for directory listing
93-
extResp, err := GetContentsOrList(ctx, repo, gitRepo, refCommit, GetContentsOrListOptions{TreePath: "", IncludeSingleFileContent: true})
94-
assert.Equal(t, expectedContentsListResponse, extResp.DirContents)
95-
assert.NoError(t, err)
96-
})
9731

98-
t.Run("GetContentsOrList(NoSuchTreePath)", func(t *testing.T) {
99-
extResp, err := GetContentsOrList(ctx, repo, gitRepo, refCommit, GetContentsOrListOptions{TreePath: "no-such/file.md"})
100-
assert.Error(t, err)
101-
assert.EqualError(t, err, "object does not exist [id: , rel_path: no-such]")
102-
assert.Nil(t, extResp.DirContents)
103-
assert.Nil(t, extResp.FileContents)
104-
})
32+
// GetContentsOrList's behavior is fully tested in integration tests, so we don't need to test it here.
10533

10634
t.Run("GetBlobBySHA", func(t *testing.T) {
10735
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"

services/repository/files/file.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ import (
2222
func GetContentsListFromTreePaths(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, refCommit *utils.RefCommit, treePaths []string) (files []*api.ContentsResponse) {
2323
var size int64
2424
for _, treePath := range treePaths {
25-
fileContents, _ := GetFileContents(ctx, repo, gitRepo, refCommit, GetContentsOrListOptions{TreePath: treePath, IncludeSingleFileContent: true}) // ok if fails, then will be nil
25+
// ok if fails, then will be nil
26+
fileContents, _ := GetFileContents(ctx, repo, gitRepo, refCommit, GetContentsOrListOptions{
27+
TreePath: treePath,
28+
IncludeSingleFileContent: true,
29+
IncludeCommitMetadata: true,
30+
})
2631
if fileContents != nil && fileContents.Content != nil && *fileContents.Content != "" {
2732
// if content isn't empty (e.g., due to the single blob being too large), add file size to response size
2833
size += int64(len(*fileContents.Content))

tailwind.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default {
2929
important: true, // the frameworks are mixed together, so tailwind needs to override other framework's styles
3030
content: [
3131
isProduction && '!./templates/devtest/**/*',
32-
isProduction && '!./web_src/js/standalone/devtest.js',
32+
isProduction && '!./web_src/js/standalone/devtest.ts',
3333
'!./templates/swagger/v1_json.tmpl',
3434
'!./templates/user/auth/oidc_wellknown.tmpl',
3535
'!**/*_test.go',

templates/swagger/v1_json.tmpl

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

0 commit comments

Comments
 (0)