Skip to content

Commit 357aec6

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Reduce unnecessary database queries on actions table (go-gitea#30509) [skip ci] Updated translations via Crowdin Tweak and fix toggle checkboxes (go-gitea#30527) Tweak repo buttons on mobile and labeled button border-radius (go-gitea#30503) Fix long branch name overflows (go-gitea#30345) Update API to return 'source_id' for users (go-gitea#29718) Allow `preferred_username` as username source for OIDC (go-gitea#30454) Fix empty field `login_name` in API response JSON when creating user (go-gitea#30511) feat(api): implement branch/commit comparison API (go-gitea#30349)
2 parents 9c37592 + 6f7d70f commit 357aec6

File tree

32 files changed

+403
-86
lines changed

32 files changed

+403
-86
lines changed

custom/conf/app.example.ini

+2-1
Original file line numberDiff line numberDiff line change
@@ -1553,8 +1553,9 @@ LEVEL = Info
15531553
;; The source of the username for new oauth2 accounts:
15541554
;; userid = use the userid / sub attribute
15551555
;; nickname = use the nickname attribute
1556+
;; preferred_username = use the preferred_username attribute
15561557
;; email = use the username part of the email attribute
1557-
;; Note: `nickname` and `email` options will normalize input strings using the following criteria:
1558+
;; Note: `nickname`, `preferred_username` and `email` options will normalize input strings using the following criteria:
15581559
;; - diacritics are removed
15591560
;; - the characters in the set `['´\x60]` are removed
15601561
;; - the characters in the set `[\s~+]` are replaced with `-`

docs/content/administration/config-cheat-sheet.en-us.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -608,9 +608,10 @@ And the following unique queues:
608608
- `ENABLE_AUTO_REGISTRATION`: **false**: Automatically create user accounts for new oauth2 users.
609609
- `USERNAME`: **nickname**: The source of the username for new oauth2 accounts:
610610
- `userid` - use the userid / sub attribute
611-
- `nickname` - use the nickname attribute
611+
- `nickname` - use the nickname
612+
- `preferred_username` - use the preferred_username
612613
- `email` - use the username part of the email attribute
613-
- Note: `nickname` and `email` options will normalize input strings using the following criteria:
614+
- Note: `nickname`, `preferred_username` and `email` options will normalize input strings using the following criteria:
614615
- diacritics are removed
615616
- the characters in the set `['´\x60]` are removed
616617
- the characters in the set `[\s~+]` are replaced with `-`

models/activities/action_list.go

+6
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]*
8383
_, alreadyLoaded := userMap[action.Repo.OwnerID]
8484
return action.Repo.OwnerID, !alreadyLoaded
8585
})
86+
if len(missingUserIDs) == 0 {
87+
return nil
88+
}
8689

8790
if err := db.GetEngine(ctx).
8891
In("id", missingUserIDs).
@@ -129,6 +132,9 @@ func (actions ActionList) LoadComments(ctx context.Context) error {
129132
commentIDs = append(commentIDs, action.CommentID)
130133
}
131134
}
135+
if len(commentIDs) == 0 {
136+
return nil
137+
}
132138

133139
commentsMap := make(map[int64]*issues_model.Comment, len(commentIDs))
134140
if err := db.GetEngine(ctx).In("id", commentIDs).Find(&commentsMap); err != nil {

modules/setting/oauth2.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ const (
2222
OAuth2UsernameNickname OAuth2UsernameType = "nickname"
2323
// OAuth2UsernameEmail username of oauth2 email field will be used as gitea name
2424
OAuth2UsernameEmail OAuth2UsernameType = "email"
25+
// OAuth2UsernameEmail username of oauth2 preferred_username field will be used as gitea name
26+
OAuth2UsernamePreferredUsername OAuth2UsernameType = "preferred_username"
2527
)
2628

2729
func (username OAuth2UsernameType) isValid() bool {
2830
switch username {
29-
case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail:
31+
case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail, OAuth2UsernamePreferredUsername:
3032
return true
3133
}
3234
return false

modules/structs/repo_compare.go

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package structs
5+
6+
// Compare represents a comparison between two commits.
7+
type Compare struct {
8+
TotalCommits int `json:"total_commits"` // Total number of commits in the comparison.
9+
Commits []*Commit `json:"commits"` // List of commits in the comparison.
10+
}

modules/structs/user.go

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type User struct {
2020
// the user's authentication sign-in name.
2121
// default: empty
2222
LoginName string `json:"login_name"`
23+
// The ID of the user's Authentication Source
24+
SourceID int64 `json:"source_id"`
2325
// the user's full name
2426
FullName string `json:"full_name"`
2527
// swagger:strfmt email

options/locale/locale_zh-CN.ini

+41
Original file line numberDiff line numberDiff line change
@@ -163,18 +163,23 @@ no_results_found=未找到结果
163163
search=搜索...
164164
type_tooltip=搜索类型
165165
fuzzy=模糊
166+
fuzzy_tooltip=包含近似匹配搜索词的结果
166167
match=匹配
168+
match_tooltip=仅包含精确匹配搜索词的结果
167169
repo_kind=搜索仓库...
168170
user_kind=搜索用户...
169171
org_kind=搜索组织...
170172
team_kind=搜索团队...
171173
code_kind=搜索代码...
174+
code_search_unavailable=代码搜索当前不可用。请与网站管理员联系。
175+
code_search_by_git_grep=当前代码搜索结果由“git grep”提供。如果站点管理员启用仓库索引器,可能会有更好的结果。
172176
package_kind=搜索软件包...
173177
project_kind=搜索项目...
174178
branch_kind=搜索分支...
175179
commit_kind=搜索提交记录...
176180
runner_kind=搜索runners...
177181
no_results=未找到匹配结果
182+
keyword_search_unavailable=按关键字搜索当前不可用。请联系站点管理员。
178183

179184
[aria]
180185
navbar=导航栏
@@ -281,6 +286,7 @@ email_title=电子邮箱设置
281286
smtp_addr=SMTP 主机地址
282287
smtp_port=SMTP 端口
283288
smtp_from=电子邮件发件人
289+
smtp_from_invalid=`"发送电子邮件为"地址无效`
284290
smtp_from_helper=请输入一个用于 Gitea 的电子邮件地址,或者使用完整格式:"名称" <email@example.com>
285291
mailer_user=SMTP 用户名
286292
mailer_password=SMTP 密码
@@ -389,6 +395,7 @@ forgot_password_title=忘记密码
389395
forgot_password=忘记密码?
390396
sign_up_now=还没帐户?马上注册。
391397
sign_up_successful=帐户创建成功。欢迎!
398+
confirmation_mail_sent_prompt_ex=一封新的确认邮件已经发送到 <b>%s</b>请在下一个 %s 中检查您的收件箱以完成注册过程。 如果您的注册电子邮件地址不正确,您可以重新登录并更改它。
392399
must_change_password=更新您的密码
393400
allow_password_change=要求用户更改密码(推荐)
394401
reset_password_mail_sent_prompt=确认电子邮件已被发送到 <b>%s</b>。请您在 %s 内检查您的收件箱 ,完成密码重置过程。
@@ -398,6 +405,7 @@ prohibit_login=禁止登录
398405
prohibit_login_desc=您的帐户被禁止登录,请与网站管理员联系。
399406
resent_limit_prompt=您请求发送激活邮件过于频繁,请等待 3 分钟后再试!
400407
has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 <b>%s</b> 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。
408+
change_unconfirmed_mail_address=如果您的注册电子邮件地址不正确,您可以在此更改并重新发送新的确认电子邮件。
401409
resend_mail=单击此处重新发送确认邮件
402410
email_not_associate=您输入的邮箱地址未被关联到任何帐号!
403411
send_reset_mail=发送账户恢复邮件
@@ -578,6 +586,7 @@ team_name_been_taken=团队名称已被使用。
578586
team_no_units_error=至少选择一项仓库单元。
579587
email_been_used=该电子邮件地址已在使用中。
580588
email_invalid=此邮箱地址无效。
589+
email_domain_is_not_allowed=用户 <b>%s</b> 与EMAIL_DOMAIN_ALLOWLIT 或 EMAIL_DOMAIN_BLOCKLIT 冲突。请确保您的操作是预期的。
581590
openid_been_used=OpenID 地址 "%s" 已被使用。
582591
username_password_incorrect=用户名或密码不正确。
583592
password_complexity=密码未达到复杂程度要求:
@@ -589,6 +598,8 @@ enterred_invalid_repo_name=输入的仓库名称不正确
589598
enterred_invalid_org_name=您输入的组织名称不正确。
590599
enterred_invalid_owner_name=新的所有者名称无效。
591600
enterred_invalid_password=输入的密码不正确
601+
unset_password=登录用户没有设置密码。
602+
unsupported_login_type=此登录类型不支持手动删除帐户。
592603
user_not_exist=该用户不存在
593604
team_not_exist=团队不存在
594605
last_org_owner=您不能从 "所有者" 团队中删除最后一个用户。组织中必须至少有一个所有者。
@@ -643,8 +654,24 @@ block.block.user=屏蔽用户
643654
block.block.org=屏蔽用户访问组织
644655
block.block.failure=屏蔽用户失败: %s
645656
block.unblock=取消屏蔽
657+
block.unblock.failure=屏蔽用户失败: %s
658+
block.blocked=您已屏蔽此用户。
646659
block.title=屏蔽一个用户
660+
block.info=屏蔽用户会阻止他们与仓库进行交互,例如打开或评论合并请求或出现问题。了解更多关于屏蔽用户的信息。
661+
block.info_1=阻止用户在您的帐户和仓库中进行以下操作:
647662
block.info_2=关注你的账号
663+
block.info_3=通过@提及您的用户名向您发送通知
664+
block.info_4=邀请您作为协作者到他们的仓库中
665+
block.info_5=在仓库中点赞、派生或关注
666+
block.info_6=打开和评论工单或合并请求
667+
block.info_7=在问题或合并请求中对您的评论做出反应
668+
block.user_to_block=要屏蔽的用户
669+
block.note=备注
670+
block.note.title=可选备注:
671+
block.note.info=该备注对被屏蔽的用户不可见。
672+
block.note.edit=编辑备注
673+
block.list=已屏蔽用户
674+
block.list.none=您没有已屏蔽的用户。
648675

649676
[settings]
650677
profile=个人信息
@@ -982,7 +1009,9 @@ fork_visibility_helper=无法更改派生仓库的可见性。
9821009
fork_branch=要克隆到 Fork 的分支
9831010
all_branches=所有分支
9841011
fork_no_valid_owners=这个代码仓库无法被派生,因为没有有效的所有者。
1012+
fork.blocked_user=无法克隆仓库,因为您被仓库所有者屏蔽。
9851013
use_template=使用此模板
1014+
open_with_editor=用 %s 打开
9861015
download_zip=下载 ZIP
9871016
download_tar=下载 TAR.GZ
9881017
download_bundle=下载 BUNDLE
@@ -1035,6 +1064,7 @@ watchers=关注者
10351064
stargazers=称赞者
10361065
stars_remove_warning=这将清除此仓库的所有点赞数。
10371066
forks=派生仓库
1067+
stars=点赞数
10381068
reactions_more=再加载 %d
10391069
unit_disabled=站点管理员已禁用此仓库单元。
10401070
language_other=其它
@@ -1156,6 +1186,7 @@ watch=关注
11561186
unstar=取消点赞
11571187
star=点赞
11581188
fork=派生
1189+
action.blocked_user=无法执行操作,因为您已被仓库所有者屏蔽。
11591190
download_archive=下载此仓库
11601191
more_operations=更多操作
11611192

@@ -1202,6 +1233,8 @@ file_view_rendered=渲染模式
12021233
file_view_raw=查看原始文件
12031234
file_permalink=永久链接
12041235
file_too_large=文件过大,无法显示。
1236+
code_preview_line_from_to=在 %[3]s 的第 %[1]d 行到 %[2]d 行
1237+
code_preview_line_in=在 %[2]s 的第 %[1]d 行
12051238
invisible_runes_header=`此文件含有不可见的 Unicode 字符`
12061239
invisible_runes_description=`此文件含有人类无法区分的不可见的 Unicode 字符,但可以由计算机进行不同的处理。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。`
12071240
ambiguous_runes_header=`此文件含有模棱两可的 Unicode 字符`
@@ -1284,6 +1317,8 @@ editor.file_editing_no_longer_exists=正在编辑的文件 %s 已不存在。
12841317
editor.file_deleting_no_longer_exists=正在删除的文件 %s 已不存在。
12851318
editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" rel="noopener noreferrer" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。
12861319
editor.file_already_exists=此仓库已经存在名为 %s 的文件。
1320+
editor.commit_id_not_matching=提交ID与您开始编辑时的ID不匹配。请提交到补丁分支然后合并。
1321+
editor.push_out_of_date=推送似乎已经过时。
12871322
editor.commit_empty_file_header=提交一个空文件
12881323
editor.commit_empty_file_text=您要提交的文件是空的,继续吗?
12891324
editor.no_changes_to_show=没有可以显示的变更。
@@ -1402,6 +1437,8 @@ issues.new.assignees=指派成员
14021437
issues.new.clear_assignees=取消指派成员
14031438
issues.new.no_assignees=未指派成员
14041439
issues.new.no_reviewers=无审核者
1440+
issues.new.blocked_user=无法创建工单,因为您已被仓库所有者屏蔽。
1441+
issues.edit.blocked_user=无法编辑内容,因为您已被仓库所有者或工单创建者屏蔽。
14051442
issues.choose.get_started=开始
14061443
issues.choose.open_external_link=开启
14071444
issues.choose.blank=默认模板
@@ -1516,6 +1553,7 @@ issues.close_comment_issue=评论并关闭
15161553
issues.reopen_issue=重新开启
15171554
issues.reopen_comment_issue=评论并重新开启
15181555
issues.create_comment=评论
1556+
issues.comment.blocked_user=无法创建或编辑评论,因为您已被仓库所有者或工单创建者屏蔽。
15191557
issues.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭此工单`
15201558
issues.reopened_at=`重新打开此问题 <a id="%[1]s" href="#%[1]s">%[2]s</a>`
15211559
issues.commit_ref_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 在代码提交中引用了该工单`
@@ -1714,6 +1752,7 @@ compare.compare_head=比较
17141752

17151753
pulls.desc=启用合并请求和代码评审。
17161754
pulls.new=创建合并请求
1755+
pulls.new.blocked_user=无法创建合并请求,因为您已被仓库所有者屏蔽。
17171756
pulls.view=查看拉取请求
17181757
pulls.compare_changes=创建合并请求
17191758
pulls.allow_edits_from_maintainers=允许维护者编辑
@@ -1797,6 +1836,7 @@ pulls.merge_pull_request=创建合并提交
17971836
pulls.rebase_merge_pull_request=变基后快进
17981837
pulls.rebase_merge_commit_pull_request=变基后创建合并提交
17991838
pulls.squash_merge_pull_request=创建压缩提交
1839+
pulls.fast_forward_only_merge_pull_request=仅快进
18001840
pulls.merge_manually=手动合并
18011841
pulls.merge_commit_id=合并提交 ID
18021842
pulls.require_signed_wont_sign=分支需要签名的提交,但这个合并将不会被签名
@@ -1933,6 +1973,7 @@ wiki.page_name_desc=输入此 Wiki 页面的名称。特殊名称有:'Home', '
19331973
wiki.original_git_entry_tooltip=查看原始的 Git 文件而不是使用友好链接。
19341974

19351975
activity=动态
1976+
activity.navbar.pulse=活动
19361977
activity.navbar.code_frequency=代码频率
19371978
activity.navbar.contributors=贡献者
19381979
activity.navbar.recent_commits=最近的提交

routers/api/v1/admin/user.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import (
3030
user_service "code.gitea.io/gitea/services/user"
3131
)
3232

33-
func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64, loginName string) {
33+
func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64) {
3434
if sourceID == 0 {
3535
return
3636
}
@@ -47,7 +47,6 @@ func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64
4747

4848
u.LoginType = source.Type
4949
u.LoginSource = source.ID
50-
u.LoginName = loginName
5150
}
5251

5352
// CreateUser create a user
@@ -83,12 +82,13 @@ func CreateUser(ctx *context.APIContext) {
8382
Passwd: form.Password,
8483
MustChangePassword: true,
8584
LoginType: auth.Plain,
85+
LoginName: form.LoginName,
8686
}
8787
if form.MustChangePassword != nil {
8888
u.MustChangePassword = *form.MustChangePassword
8989
}
9090

91-
parseAuthSource(ctx, u, form.SourceID, form.LoginName)
91+
parseAuthSource(ctx, u, form.SourceID)
9292
if ctx.Written() {
9393
return
9494
}

routers/api/v1/api.go

+2
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,8 @@ func Routes() *web.Route {
10661066
m.Post("/migrate", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate)
10671067

10681068
m.Group("/{username}/{reponame}", func() {
1069+
m.Get("/compare/*", reqRepoReader(unit.TypeCode), repo.CompareDiff)
1070+
10691071
m.Combo("").Get(reqAnyRepoReader(), repo.Get).
10701072
Delete(reqToken(), reqOwner(), repo.Delete).
10711073
Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), repo.Edit)

routers/api/v1/repo/compare.go

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package repo
5+
6+
import (
7+
"net/http"
8+
"strings"
9+
10+
user_model "code.gitea.io/gitea/models/user"
11+
"code.gitea.io/gitea/modules/gitrepo"
12+
api "code.gitea.io/gitea/modules/structs"
13+
"code.gitea.io/gitea/services/context"
14+
"code.gitea.io/gitea/services/convert"
15+
)
16+
17+
// CompareDiff compare two branches or commits
18+
func CompareDiff(ctx *context.APIContext) {
19+
// swagger:operation GET /repos/{owner}/{repo}/compare/{basehead} Get commit comparison information
20+
// ---
21+
// summary: Get commit comparison information
22+
// produces:
23+
// - application/json
24+
// parameters:
25+
// - name: owner
26+
// in: path
27+
// description: owner of the repo
28+
// type: string
29+
// required: true
30+
// - name: repo
31+
// in: path
32+
// description: name of the repo
33+
// type: string
34+
// required: true
35+
// - name: basehead
36+
// in: path
37+
// description: compare two branches or commits
38+
// type: string
39+
// required: true
40+
// responses:
41+
// "200":
42+
// "$ref": "#/responses/Compare"
43+
// "404":
44+
// "$ref": "#/responses/notFound"
45+
46+
if ctx.Repo.GitRepo == nil {
47+
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
48+
if err != nil {
49+
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
50+
return
51+
}
52+
ctx.Repo.GitRepo = gitRepo
53+
defer gitRepo.Close()
54+
}
55+
56+
infoPath := ctx.Params("*")
57+
infos := []string{ctx.Repo.Repository.DefaultBranch, ctx.Repo.Repository.DefaultBranch}
58+
if infoPath != "" {
59+
infos = strings.SplitN(infoPath, "...", 2)
60+
if len(infos) != 2 {
61+
if infos = strings.SplitN(infoPath, "..", 2); len(infos) != 2 {
62+
infos = []string{ctx.Repo.Repository.DefaultBranch, infoPath}
63+
}
64+
}
65+
}
66+
67+
_, _, headGitRepo, ci, _, _ := parseCompareInfo(ctx, api.CreatePullRequestOption{
68+
Base: infos[0],
69+
Head: infos[1],
70+
})
71+
if ctx.Written() {
72+
return
73+
}
74+
defer headGitRepo.Close()
75+
76+
verification := ctx.FormString("verification") == "" || ctx.FormBool("verification")
77+
files := ctx.FormString("files") == "" || ctx.FormBool("files")
78+
79+
apiCommits := make([]*api.Commit, 0, len(ci.Commits))
80+
userCache := make(map[string]*user_model.User)
81+
for i := 0; i < len(ci.Commits); i++ {
82+
apiCommit, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ci.Commits[i], userCache,
83+
convert.ToCommitOptions{
84+
Stat: true,
85+
Verification: verification,
86+
Files: files,
87+
})
88+
if err != nil {
89+
ctx.ServerError("toCommit", err)
90+
return
91+
}
92+
apiCommits = append(apiCommits, apiCommit)
93+
}
94+
95+
ctx.JSON(http.StatusOK, &api.Compare{
96+
TotalCommits: len(ci.Commits),
97+
Commits: apiCommits,
98+
})
99+
}

0 commit comments

Comments
 (0)