forked from mirror/gitea
Compare commits
7 Commits
b9f69b4a4d
...
3746a625f5
Author | SHA1 | Date | |
---|---|---|---|
silverwind | 3746a625f5 | ||
silverwind | a658e2f277 | ||
Tobias Balle-Petersen | 58b204b813 | ||
SimonErm | 6ba0c371c2 | ||
yp05327 | cf9061f44a | ||
Bo-Yi Wu | c70e442ce4 | ||
GiteaBot | 3b045ee165 |
|
@ -1553,8 +1553,9 @@ LEVEL = Info
|
|||
;; The source of the username for new oauth2 accounts:
|
||||
;; userid = use the userid / sub attribute
|
||||
;; nickname = use the nickname attribute
|
||||
;; preferred_username = use the preferred_username attribute
|
||||
;; email = use the username part of the email attribute
|
||||
;; Note: `nickname` and `email` options will normalize input strings using the following criteria:
|
||||
;; Note: `nickname`, `preferred_username` and `email` options will normalize input strings using the following criteria:
|
||||
;; - diacritics are removed
|
||||
;; - the characters in the set `['´\x60]` are removed
|
||||
;; - the characters in the set `[\s~+]` are replaced with `-`
|
||||
|
|
|
@ -608,9 +608,10 @@ And the following unique queues:
|
|||
- `ENABLE_AUTO_REGISTRATION`: **false**: Automatically create user accounts for new oauth2 users.
|
||||
- `USERNAME`: **nickname**: The source of the username for new oauth2 accounts:
|
||||
- `userid` - use the userid / sub attribute
|
||||
- `nickname` - use the nickname attribute
|
||||
- `nickname` - use the nickname
|
||||
- `preferred_username` - use the preferred_username
|
||||
- `email` - use the username part of the email attribute
|
||||
- Note: `nickname` and `email` options will normalize input strings using the following criteria:
|
||||
- Note: `nickname`, `preferred_username` and `email` options will normalize input strings using the following criteria:
|
||||
- diacritics are removed
|
||||
- the characters in the set `['´\x60]` are removed
|
||||
- the characters in the set `[\s~+]` are replaced with `-`
|
||||
|
|
|
@ -22,11 +22,13 @@ const (
|
|||
OAuth2UsernameNickname OAuth2UsernameType = "nickname"
|
||||
// OAuth2UsernameEmail username of oauth2 email field will be used as gitea name
|
||||
OAuth2UsernameEmail OAuth2UsernameType = "email"
|
||||
// OAuth2UsernameEmail username of oauth2 preferred_username field will be used as gitea name
|
||||
OAuth2UsernamePreferredUsername OAuth2UsernameType = "preferred_username"
|
||||
)
|
||||
|
||||
func (username OAuth2UsernameType) isValid() bool {
|
||||
switch username {
|
||||
case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail:
|
||||
case OAuth2UsernameUserid, OAuth2UsernameNickname, OAuth2UsernameEmail, OAuth2UsernamePreferredUsername:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package structs
|
||||
|
||||
// Compare represents a comparison between two commits.
|
||||
type Compare struct {
|
||||
TotalCommits int `json:"total_commits"` // Total number of commits in the comparison.
|
||||
Commits []*Commit `json:"commits"` // List of commits in the comparison.
|
||||
}
|
|
@ -20,6 +20,8 @@ type User struct {
|
|||
// the user's authentication sign-in name.
|
||||
// default: empty
|
||||
LoginName string `json:"login_name"`
|
||||
// The ID of the user's Authentication Source
|
||||
SourceID int64 `json:"source_id"`
|
||||
// the user's full name
|
||||
FullName string `json:"full_name"`
|
||||
// swagger:strfmt email
|
||||
|
|
|
@ -25,6 +25,7 @@ enable_javascript=このウェブサイトにはJavaScriptが必要です。
|
|||
toc=目次
|
||||
licenses=ライセンス
|
||||
return_to_gitea=Giteaに戻る
|
||||
more_items=その他の項目
|
||||
|
||||
username=ユーザー名
|
||||
email=メールアドレス
|
||||
|
@ -1003,6 +1004,7 @@ fork_visibility_helper=フォークしたリポジトリの公開/非公開は
|
|||
fork_branch=フォークにクローンされるブランチ
|
||||
all_branches=すべてのブランチ
|
||||
fork_no_valid_owners=このリポジトリには有効なオーナーがいないため、フォークできません。
|
||||
fork.blocked_user=リポジトリのオーナーがあなたをブロックしているため、リポジトリをフォークできません。
|
||||
use_template=このテンプレートを使用
|
||||
open_with_editor=%s で開く
|
||||
download_zip=ZIPファイルをダウンロード
|
||||
|
@ -1179,6 +1181,7 @@ watch=ウォッチ
|
|||
unstar=スター取消
|
||||
star=スター
|
||||
fork=フォーク
|
||||
action.blocked_user=リポジトリのオーナーがあなたをブロックしているため、アクションを実行できません。
|
||||
download_archive=リポジトリをダウンロード
|
||||
more_operations=その他の操作
|
||||
|
||||
|
@ -1427,6 +1430,8 @@ issues.new.assignees=担当者
|
|||
issues.new.clear_assignees=担当者をクリア
|
||||
issues.new.no_assignees=担当者なし
|
||||
issues.new.no_reviewers=レビューアなし
|
||||
issues.new.blocked_user=リポジトリのオーナーがあなたをブロックしているため、イシューを作成できません。
|
||||
issues.edit.blocked_user=投稿者またはリポジトリのオーナーがあなたをブロックしているため、内容を編集できません。
|
||||
issues.choose.get_started=始める
|
||||
issues.choose.open_external_link=オープン
|
||||
issues.choose.blank=デフォルト
|
||||
|
@ -1541,6 +1546,7 @@ issues.close_comment_issue=コメントしてクローズ
|
|||
issues.reopen_issue=再オープンする
|
||||
issues.reopen_comment_issue=コメントして再オープン
|
||||
issues.create_comment=コメントする
|
||||
issues.comment.blocked_user=投稿者またはリポジトリのオーナーがあなたをブロックしているため、コメントの作成や編集はできません。
|
||||
issues.closed_at=`がイシューをクローズ <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`がイシューを再オープン <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`がコミットでこのイシューを参照 <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
|
@ -1739,6 +1745,7 @@ compare.compare_head=比較
|
|||
|
||||
pulls.desc=プルリクエストとコードレビューの有効化。
|
||||
pulls.new=新しいプルリクエスト
|
||||
pulls.new.blocked_user=リポジトリのオーナーがあなたをブロックしているため、プルリクエストを作成できません。
|
||||
pulls.view=プルリクエストを表示
|
||||
pulls.compare_changes=新規プルリクエスト
|
||||
pulls.allow_edits_from_maintainers=メンテナーからの編集を許可する
|
||||
|
@ -1960,6 +1967,7 @@ wiki.original_git_entry_tooltip=フレンドリーリンクを使用する代わ
|
|||
|
||||
activity=アクティビティ
|
||||
activity.navbar.pulse=Pulse
|
||||
activity.navbar.code_frequency=コード更新頻度
|
||||
activity.navbar.contributors=貢献者
|
||||
activity.navbar.recent_commits=最近のコミット
|
||||
activity.period.filter_label=期間:
|
||||
|
@ -2080,6 +2088,8 @@ settings.branches.add_new_rule=新しいルールを追加
|
|||
settings.advanced_settings=拡張設定
|
||||
settings.wiki_desc=Wikiを有効にする
|
||||
settings.use_internal_wiki=ビルトインのWikiを使用する
|
||||
settings.default_wiki_branch_name=デフォルトのWikiブランチ名
|
||||
settings.failed_to_change_default_wiki_branch=デフォルトのWikiブランチを変更できませんでした。
|
||||
settings.use_external_wiki=外部のWikiを使用する
|
||||
settings.external_wiki_url=外部WikiのURL
|
||||
settings.external_wiki_url_error=外部WikiのURLが有効なURLではありません。
|
||||
|
@ -2110,6 +2120,9 @@ settings.pulls.default_allow_edits_from_maintainers=デフォルトでメンテ
|
|||
settings.releases_desc=リリースを有効にする
|
||||
settings.packages_desc=リポジトリパッケージレジストリを有効にする
|
||||
settings.projects_desc=プロジェクトを有効にする
|
||||
settings.projects_mode_desc=プロジェクト モード (表示するプロジェクトの種類)
|
||||
settings.projects_mode_repo=リポジトリのプロジェクトのみ
|
||||
settings.projects_mode_owner=ユーザーや組織のプロジェクトのみ
|
||||
settings.projects_mode_all=すべてのプロジェクト
|
||||
settings.actions_desc=Actionsを有効にする
|
||||
settings.admin_settings=管理者用設定
|
||||
|
@ -2136,6 +2149,7 @@ settings.convert_fork_succeed=フォークを通常のリポジトリに変換
|
|||
settings.transfer=オーナー移転
|
||||
settings.transfer.rejected=リポジトリの移転は拒否されました。
|
||||
settings.transfer.success=リポジトリの移転が成功しました。
|
||||
settings.transfer.blocked_user=新しいオーナーがあなたをブロックしているため、リポジトリを移転できません。
|
||||
settings.transfer_abort=転送をキャンセル
|
||||
settings.transfer_abort_invalid=存在しないリポジトリの移転はキャンセルできません。
|
||||
settings.transfer_abort_success=%s へのリポジトリ移転は正常にキャンセルされました。
|
||||
|
@ -2181,6 +2195,7 @@ settings.add_collaborator_success=共同作業者を追加しました。
|
|||
settings.add_collaborator_inactive_user=アクティベートされていないユーザーを共同作業者として追加することはできません。
|
||||
settings.add_collaborator_owner=共同作業者としてオーナーを追加することはできません。
|
||||
settings.add_collaborator_duplicate=共同作業者として既にこのリポジトリに追加されています。
|
||||
settings.add_collaborator.blocked_user=共同作業者がリポジトリのオーナーによってブロックされているか、またはブロックしています。
|
||||
settings.delete_collaborator=削除
|
||||
settings.collaborator_deletion=共同作業者の削除
|
||||
settings.collaborator_deletion_desc=共同作業者を削除し、このリポジトリへのアクセス権を取り消します。 続行しますか?
|
||||
|
@ -2619,12 +2634,14 @@ find_file.no_matching=一致するファイルが見つかりません
|
|||
error.csv.too_large=このファイルは大きすぎるため表示できません。
|
||||
error.csv.unexpected=このファイルは %d 行目の %d 文字目に予期しない文字が含まれているため表示できません。
|
||||
error.csv.invalid_field_count=このファイルは %d 行目のフィールドの数が正しくないため表示できません。
|
||||
error.broken_git_hook=このリポジトリのGitフックが壊れているようです。 <a target="_blank" rel="noreferrer" href="%s">ドキュメント</a>に従って修正し、その後いくつかのコミットをプッシュして状態を最新にしてください。
|
||||
|
||||
[graphs]
|
||||
component_loading=%sを読み込み中...
|
||||
component_loading_failed=%sを読み込めませんでした
|
||||
component_loading_info=少し時間がかかるかもしれません…
|
||||
component_failed_to_load=予期しないエラーが発生しました。
|
||||
code_frequency.what=コード更新頻度
|
||||
contributors.what=実績
|
||||
recent_commits.what=最近のコミット
|
||||
|
||||
|
@ -2753,6 +2770,7 @@ teams.invite.by=%s からの招待
|
|||
teams.invite.description=下のボタンをクリックしてチームに参加してください。
|
||||
|
||||
[admin]
|
||||
maintenance=メンテナンス
|
||||
dashboard=ダッシュボード
|
||||
self_check=セルフチェック
|
||||
identity_access=アイデンティティとアクセス
|
||||
|
@ -2776,6 +2794,7 @@ settings=管理設定
|
|||
|
||||
dashboard.new_version_hint=Gitea %s が入手可能になりました。 現在実行しているのは %s です。 詳細は <a target="_blank" rel="noreferrer" href="https://blog.gitea.io">ブログ</a> を確認してください。
|
||||
dashboard.statistic=サマリー
|
||||
dashboard.maintenance_operations=メンテナンス操作
|
||||
dashboard.system_status=システム状況
|
||||
dashboard.operation_name=操作の名称
|
||||
dashboard.operation_switch=切り替え
|
||||
|
@ -3282,6 +3301,7 @@ notices.op=操作
|
|||
notices.delete_success=システム通知を削除しました。
|
||||
|
||||
self_check.no_problem_found=今のところ問題は見つかっていません。
|
||||
self_check.startup_warnings=起動時の警告:
|
||||
self_check.database_collation_mismatch=データベースに想定される照合順序: %s
|
||||
self_check.database_collation_case_insensitive=データベースは照合順序 %s を使用しており、大文字小文字を区別しません。 Giteaはその照合順序でも動作するかもしれませんが、まれに期待どおり動作しないケースがあるかもしれません。
|
||||
self_check.database_inconsistent_collation_columns=データベースは照合順序 %s を使用していますが、以下のカラムはそれと一致しない照合順序を使用しており、予期せぬ問題を引き起こす可能性があります。
|
||||
|
|
|
@ -30,7 +30,7 @@ import (
|
|||
user_service "code.gitea.io/gitea/services/user"
|
||||
)
|
||||
|
||||
func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64, loginName string) {
|
||||
func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64) {
|
||||
if sourceID == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64
|
|||
|
||||
u.LoginType = source.Type
|
||||
u.LoginSource = source.ID
|
||||
u.LoginName = loginName
|
||||
}
|
||||
|
||||
// CreateUser create a user
|
||||
|
@ -83,12 +82,13 @@ func CreateUser(ctx *context.APIContext) {
|
|||
Passwd: form.Password,
|
||||
MustChangePassword: true,
|
||||
LoginType: auth.Plain,
|
||||
LoginName: form.LoginName,
|
||||
}
|
||||
if form.MustChangePassword != nil {
|
||||
u.MustChangePassword = *form.MustChangePassword
|
||||
}
|
||||
|
||||
parseAuthSource(ctx, u, form.SourceID, form.LoginName)
|
||||
parseAuthSource(ctx, u, form.SourceID)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1066,6 +1066,8 @@ func Routes() *web.Route {
|
|||
m.Post("/migrate", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate)
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Get("/compare/*", reqRepoReader(unit.TypeCode), repo.CompareDiff)
|
||||
|
||||
m.Combo("").Get(reqAnyRepoReader(), repo.Get).
|
||||
Delete(reqToken(), reqOwner(), repo.Delete).
|
||||
Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), repo.Edit)
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/convert"
|
||||
)
|
||||
|
||||
// CompareDiff compare two branches or commits
|
||||
func CompareDiff(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/compare/{basehead} Get commit comparison information
|
||||
// ---
|
||||
// summary: Get commit comparison information
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: basehead
|
||||
// in: path
|
||||
// description: compare two branches or commits
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/Compare"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
defer gitRepo.Close()
|
||||
}
|
||||
|
||||
infoPath := ctx.Params("*")
|
||||
infos := []string{ctx.Repo.Repository.DefaultBranch, ctx.Repo.Repository.DefaultBranch}
|
||||
if infoPath != "" {
|
||||
infos = strings.SplitN(infoPath, "...", 2)
|
||||
if len(infos) != 2 {
|
||||
if infos = strings.SplitN(infoPath, "..", 2); len(infos) != 2 {
|
||||
infos = []string{ctx.Repo.Repository.DefaultBranch, infoPath}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, _, headGitRepo, ci, _, _ := parseCompareInfo(ctx, api.CreatePullRequestOption{
|
||||
Base: infos[0],
|
||||
Head: infos[1],
|
||||
})
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
defer headGitRepo.Close()
|
||||
|
||||
verification := ctx.FormString("verification") == "" || ctx.FormBool("verification")
|
||||
files := ctx.FormString("files") == "" || ctx.FormBool("files")
|
||||
|
||||
apiCommits := make([]*api.Commit, 0, len(ci.Commits))
|
||||
userCache := make(map[string]*user_model.User)
|
||||
for i := 0; i < len(ci.Commits); i++ {
|
||||
apiCommit, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ci.Commits[i], userCache,
|
||||
convert.ToCommitOptions{
|
||||
Stat: true,
|
||||
Verification: verification,
|
||||
Files: files,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("toCommit", err)
|
||||
return
|
||||
}
|
||||
apiCommits = append(apiCommits, apiCommit)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, &api.Compare{
|
||||
TotalCommits: len(ci.Commits),
|
||||
Commits: apiCommits,
|
||||
})
|
||||
}
|
|
@ -414,3 +414,9 @@ type swaggerRepoNewIssuePinsAllowed struct {
|
|||
// in:body
|
||||
Body api.NewIssuePinsAllowed `json:"body"`
|
||||
}
|
||||
|
||||
// swagger:response Compare
|
||||
type swaggerCompare struct {
|
||||
// in:body
|
||||
Body api.Compare `json:"body"`
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
)
|
||||
|
||||
// CompareInfo represents the collected results from ParseCompareInfo
|
||||
type CompareInfo struct {
|
||||
HeadUser *user_model.User
|
||||
HeadRepo *repo_model.Repository
|
||||
HeadGitRepo *git.Repository
|
||||
CompareInfo *git.CompareInfo
|
||||
BaseBranch string
|
||||
HeadBranch string
|
||||
DirectComparison bool
|
||||
}
|
|
@ -386,6 +386,13 @@ func getUserName(gothUser *goth.User) (string, error) {
|
|||
switch setting.OAuth2Client.Username {
|
||||
case setting.OAuth2UsernameEmail:
|
||||
return user_model.NormalizeUserName(strings.Split(gothUser.Email, "@")[0])
|
||||
case setting.OAuth2UsernamePreferredUsername:
|
||||
preferredUsername, exists := gothUser.RawData["preferred_username"]
|
||||
if exists {
|
||||
return user_model.NormalizeUserName(preferredUsername.(string))
|
||||
} else {
|
||||
return "", fmt.Errorf("preferred_username is missing in received user data but configured as username source for user_id %q. Check if OPENID_CONNECT_SCOPES contains profile", gothUser.UserID)
|
||||
}
|
||||
case setting.OAuth2UsernameNickname:
|
||||
return user_model.NormalizeUserName(gothUser.NickName)
|
||||
default: // OAuth2UsernameUserid
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/common"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/context/upload"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
|
@ -185,21 +186,10 @@ func setCsvCompareContext(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// CompareInfo represents the collected results from ParseCompareInfo
|
||||
type CompareInfo struct {
|
||||
HeadUser *user_model.User
|
||||
HeadRepo *repo_model.Repository
|
||||
HeadGitRepo *git.Repository
|
||||
CompareInfo *git.CompareInfo
|
||||
BaseBranch string
|
||||
HeadBranch string
|
||||
DirectComparison bool
|
||||
}
|
||||
|
||||
// ParseCompareInfo parse compare info between two commit for preparing comparing references
|
||||
func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||
func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
|
||||
baseRepo := ctx.Repo.Repository
|
||||
ci := &CompareInfo{}
|
||||
ci := &common.CompareInfo{}
|
||||
|
||||
fileOnly := ctx.FormBool("file-only")
|
||||
|
||||
|
@ -576,7 +566,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
|||
// PrepareCompareDiff renders compare diff page
|
||||
func PrepareCompareDiff(
|
||||
ctx *context.Context,
|
||||
ci *CompareInfo,
|
||||
ci *common.CompareInfo,
|
||||
whitespaceBehavior git.TrustedCmdArgs,
|
||||
) bool {
|
||||
var (
|
||||
|
|
|
@ -75,6 +75,7 @@ func toUser(ctx context.Context, user *user_model.User, signed, authed bool) *ap
|
|||
if authed {
|
||||
result.IsAdmin = user.IsAdmin
|
||||
result.LoginName = user.LoginName
|
||||
result.SourceID = user.LoginSource
|
||||
result.LastLogin = user.LastLoginUnix.AsTime()
|
||||
result.Language = user.Language
|
||||
result.IsActive = user.IsActive
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
{{/* show dummy elements before Vue componment is mounted, this code must match the code in BranchTagSelector.vue */}}
|
||||
<div class="ui dropdown custom">
|
||||
<button class="branch-dropdown-button gt-ellipsis ui basic small compact button tw-flex tw-m-0">
|
||||
<span class="text tw-flex tw-items-center tw-mr-1">
|
||||
<span class="text tw-flex tw-items-center tw-mr-1 gt-ellipsis">
|
||||
{{if .release}}
|
||||
{{ctx.Locale.Tr "repo.release.compare"}}
|
||||
{{else}}
|
||||
|
@ -80,7 +80,7 @@
|
|||
{{else}}
|
||||
{{svg "octicon-git-branch"}}
|
||||
{{end}}
|
||||
<strong ref="dropdownRefName" class="tw-ml-2">{{if and .root.IsViewTag (not .noTag)}}{{.root.TagName}}{{else if .root.IsViewBranch}}{{.root.BranchName}}{{else}}{{ShortSha .root.CommitID}}{{end}}</strong>
|
||||
<strong ref="dropdownRefName" class="tw-ml-2 tw-inline-block gt-ellipsis">{{if and .root.IsViewTag (not .noTag)}}{{.root.TagName}}{{else if .root.IsViewBranch}}{{.root.BranchName}}{{else}}{{ShortSha .root.CommitID}}{{end}}</strong>
|
||||
{{end}}
|
||||
</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
|
|
|
@ -91,28 +91,28 @@
|
|||
>
|
||||
{{svg "octicon-repo-forked"}}<span class="text not-mobile">{{ctx.Locale.Tr "repo.fork"}}</span>
|
||||
</a>
|
||||
<div class="ui small modal" id="fork-repo-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.already_forked" .Name}}
|
||||
</div>
|
||||
<div class="content tw-text-left">
|
||||
<div class="ui list">
|
||||
{{range $.UserAndOrgForks}}
|
||||
<div class="ui item tw-py-2">
|
||||
<a href="{{.Link}}">{{svg "octicon-repo-forked" 16 "tw-mr-2"}}{{.FullName}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if $.CanSignedUserFork}}
|
||||
<div class="divider"></div>
|
||||
<a href="{{$.RepoLink}}/fork">{{ctx.Locale.Tr "repo.fork_to_different_account"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<a class="ui basic label" href="{{.Link}}/forks">
|
||||
{{CountFmt .NumForks}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="ui small modal" id="fork-repo-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.already_forked" .Name}}
|
||||
</div>
|
||||
<div class="content tw-text-left">
|
||||
<div class="ui list">
|
||||
{{range $.UserAndOrgForks}}
|
||||
<div class="ui item tw-py-2">
|
||||
<a href="{{.Link}}">{{svg "octicon-repo-forked" 16 "tw-mr-2"}}{{.FullName}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if $.CanSignedUserFork}}
|
||||
<div class="divider"></div>
|
||||
<a href="{{$.RepoLink}}/fork">{{ctx.Locale.Tr "repo.fork_to_different_account"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
{{$.CsrfTokenHtml}}
|
||||
</form>
|
||||
{{/* TODO: share this branch selector dropdown with the same in repo page */}}
|
||||
<div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating filter select-branch dropdown" data-no-results="{{ctx.Locale.Tr "no_results_found"}}">
|
||||
<div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating filter select-branch dropdown tw-max-w-full" data-no-results="{{ctx.Locale.Tr "no_results_found"}}">
|
||||
<div class="ui basic small button">
|
||||
<span class="text branch-name">{{if .Reference}}{{$.RefEndName}}{{else}}{{ctx.Locale.Tr "repo.issues.no_ref"}}{{end}}</span>
|
||||
<span class="text branch-name gt-ellipsis">{{if .Reference}}{{$.RefEndName}}{{else}}{{ctx.Locale.Tr "repo.issues.no_ref"}}{{end}}</span>
|
||||
{{if .HasIssuesOrPullsWritePermission}}{{svg "octicon-triangle-down" 14 "dropdown icon"}}{{end}}
|
||||
</div>
|
||||
<div class="menu">
|
||||
|
@ -37,7 +37,7 @@
|
|||
<div class="item text small" data-id="" data-id-selector="#ref_selector"><strong><a href="#">{{ctx.Locale.Tr "repo.clear_ref"}}</a></strong></div>
|
||||
{{end}}
|
||||
{{range .Branches}}
|
||||
<div class="item" data-id="refs/heads/{{.}}" data-name="{{.}}" data-id-selector="#ref_selector">{{.}}</div>
|
||||
<div class="item" data-id="refs/heads/{{.}}" data-name="{{.}}" data-id-selector="#ref_selector" title="{{.}}">{{.}}</div>
|
||||
{{else}}
|
||||
<div class="item">{{ctx.Locale.Tr "no_results_found"}}</div>
|
||||
{{end}}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
{{else}}
|
||||
<div class="ui green label issue-state-label">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.open_title"}}</div>
|
||||
{{end}}
|
||||
<div class="tw-ml-2">
|
||||
<div class="tw-ml-2 tw-flex-1 tw-break-anywhere">
|
||||
{{if .Issue.IsPull}}
|
||||
{{$headHref := .HeadTarget}}
|
||||
{{if .HeadBranchLink}}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{if $.IsStaringRepo}}{{$buttonText = ctx.Locale.Tr "repo.unstar"}}{{end}}
|
||||
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
|
||||
{{if $.IsStaringRepo}}{{svg "octicon-star-fill"}}{{else}}{{svg "octicon-star"}}{{end}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
<span aria-hidden="true">{{$buttonText}}</span>
|
||||
</button>
|
||||
<a hx-boost="false" class="ui basic label" href="{{$.RepoLink}}/stars">
|
||||
{{CountFmt .Repository.NumStars}}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{if $.IsWatchingRepo}}{{$buttonText = ctx.Locale.Tr "repo.unwatch"}}{{end}}
|
||||
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
|
||||
{{svg "octicon-eye"}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
<span aria-hidden="true">{{$buttonText}}</span>
|
||||
</button>
|
||||
<a hx-boost="false" class="ui basic label" href="{{.RepoLink}}/watchers">
|
||||
{{CountFmt .Repository.NumWatches}}
|
||||
|
|
|
@ -88,18 +88,21 @@
|
|||
</div>
|
||||
{{end}}
|
||||
{{if and .Milestone (ne $.listType "milestone")}}
|
||||
<a class="milestone flex-text-inline" {{if $.RepoLink}}href="{{$.RepoLink}}/milestone/{{.Milestone.ID}}"{{else}}href="{{.Repo.Link}}/milestone/{{.Milestone.ID}}"{{end}}>
|
||||
{{svg "octicon-milestone" 14}}{{.Milestone.Name}}
|
||||
<a class="milestone flex-text-inline tw-max-w-[300px]" {{if $.RepoLink}}href="{{$.RepoLink}}/milestone/{{.Milestone.ID}}"{{else}}href="{{.Repo.Link}}/milestone/{{.Milestone.ID}}"{{end}}>
|
||||
{{svg "octicon-milestone" 14}}
|
||||
<span class="gt-ellipsis">{{.Milestone.Name}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .Project}}
|
||||
<a class="project flex-text-inline" href="{{.Project.Link ctx}}">
|
||||
{{svg .Project.IconName 14}}{{.Project.Title}}
|
||||
<a class="project flex-text-inline tw-max-w-[300px]" href="{{.Project.Link ctx}}">
|
||||
{{svg .Project.IconName 14}}
|
||||
<span class="gt-ellipsis">{{.Project.Title}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .Ref}}
|
||||
<a class="ref flex-text-inline" {{if $.RepoLink}}href="{{index $.IssueRefURLs .ID}}"{{else}}href="{{.Repo.Link}}{{index $.IssueRefURLs .ID}}"{{end}}>
|
||||
{{svg "octicon-git-branch" 14}}{{index $.IssueRefEndNames .ID}}
|
||||
<a class="ref flex-text-inline tw-max-w-[300px]" {{if $.RepoLink}}href="{{index $.IssueRefURLs .ID}}"{{else}}href="{{.Repo.Link}}{{index $.IssueRefURLs .ID}}"{{end}}>
|
||||
{{svg "octicon-git-branch" 14}}
|
||||
<span class="gt-ellipsis">{{index $.IssueRefEndNames .ID}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
{{$tasks := .GetTasks}}
|
||||
|
|
|
@ -5340,6 +5340,51 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/compare/{basehead}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Get",
|
||||
"commit",
|
||||
"comparison"
|
||||
],
|
||||
"summary": "Get commit comparison information",
|
||||
"operationId": "information",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "compare two branches or commits",
|
||||
"name": "basehead",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/Compare"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/contents": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
@ -18717,6 +18762,25 @@
|
|||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"Compare": {
|
||||
"type": "object",
|
||||
"title": "Compare represents a comparison between two commits.",
|
||||
"properties": {
|
||||
"commits": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Commit"
|
||||
},
|
||||
"x-go-name": "Commits"
|
||||
},
|
||||
"total_commits": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TotalCommits"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"ContentsResponse": {
|
||||
"description": "ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content",
|
||||
"type": "object",
|
||||
|
@ -24196,6 +24260,12 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "Restricted"
|
||||
},
|
||||
"source_id": {
|
||||
"description": "The ID of the user's Authentication Source",
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "SourceID"
|
||||
},
|
||||
"starred_repos_count": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
|
@ -24678,6 +24748,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"Compare": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Compare"
|
||||
}
|
||||
},
|
||||
"ContentsListResponse": {
|
||||
"description": "ContentsListResponse",
|
||||
"schema": {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAPICompareBranches(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
// Login as User2.
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
repoName := "repo20"
|
||||
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/user2/%s/compare/add-csv...remove-files-b", repoName).
|
||||
AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var apiResp *api.Compare
|
||||
DecodeJSON(t, resp, &apiResp)
|
||||
|
||||
assert.Equal(t, 2, apiResp.TotalCommits)
|
||||
assert.Len(t, apiResp.Commits, 2)
|
||||
}
|
|
@ -342,6 +342,8 @@ a.label,
|
|||
|
||||
.ui.dropdown .menu > .item {
|
||||
color: var(--color-text);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ui.dropdown .menu > .item:hover {
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
}
|
||||
.ui.labeled.button > .button {
|
||||
margin: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.ui.labeled.button > .label {
|
||||
display: flex;
|
||||
|
@ -70,6 +72,14 @@
|
|||
margin: 0 0 0 -1px !important;
|
||||
font-size: 1em;
|
||||
border-color: var(--color-light-border);
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.ui.labeled.button > .label:hover {
|
||||
background: var(--color-hover);
|
||||
}
|
||||
.ui.labeled.button > .button:hover + .label {
|
||||
border-left-color: var(--color-secondary-dark-2);
|
||||
}
|
||||
|
||||
.ui.button > .icon:not(.button) {
|
||||
|
|
|
@ -107,7 +107,7 @@ a.ui.label:hover {
|
|||
a.ui.basic.label:hover {
|
||||
text-decoration: none;
|
||||
color: var(--color-text);
|
||||
border-color: var(--color-light-border);
|
||||
border-color: var(--color-secondary-dark-2);
|
||||
background: var(--color-hover);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,11 @@
|
|||
width: 300px;
|
||||
}
|
||||
|
||||
.issue-content-right .dropdown > .menu {
|
||||
max-width: 270px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.issue-content-left,
|
||||
.issue-content-right {
|
||||
|
@ -57,11 +62,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.repository .issue-content-right .menu {
|
||||
overflow-x: auto;
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
.repository .issue-content-right .ui.list .dependency {
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
|
@ -113,11 +113,6 @@
|
|||
left: 0;
|
||||
}
|
||||
|
||||
.repository .filter.menu .ui.dropdown .menu .item {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.repository .select-label .desc {
|
||||
padding-left: 23px;
|
||||
}
|
||||
|
@ -672,6 +667,7 @@ td .commit-summary {
|
|||
font-size: 14px !important;
|
||||
padding: 7px 10px !important;
|
||||
border-radius: var(--border-radius-medium) !important;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.issue-state-label .svg {
|
||||
|
@ -1170,10 +1166,6 @@ td .commit-summary {
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
.repository .ui.dropdown.filter > .menu {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.repository.branches .commit-divergence .bar-group {
|
||||
position: relative;
|
||||
float: left;
|
||||
|
|
|
@ -36,11 +36,6 @@
|
|||
gap: 0.25em;
|
||||
}
|
||||
|
||||
.repo-buttons .ui.labeled.button > .label:hover {
|
||||
color: var(--color-primary-light-2);
|
||||
background: var(--color-light);
|
||||
}
|
||||
|
||||
.repo-buttons button[disabled] ~ .label {
|
||||
opacity: var(--opacity-disabled);
|
||||
color: var(--color-text-dark);
|
||||
|
@ -67,3 +62,12 @@
|
|||
.repo-buttons .ui.labeled.button.disabled > .button {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.repo-buttons .ui.button,
|
||||
.repo-buttons .ui.label {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
}
|
||||
|
||||
#issue-list .flex-item-body .branches .branch {
|
||||
background-color: var(--color-secondary-alpha-40);
|
||||
background-color: var(--color-secondary-alpha-50);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
@ -48,7 +48,9 @@
|
|||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 10em;
|
||||
max-width: 200px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#issue-list .flex-item-body .checklist progress {
|
||||
|
|
|
@ -248,12 +248,12 @@ export default sfc; // activate IDE's Vue plugin
|
|||
<template>
|
||||
<div class="ui dropdown custom">
|
||||
<button class="branch-dropdown-button gt-ellipsis ui basic small compact button tw-flex tw-m-0" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible">
|
||||
<span class="text tw-flex tw-items-center tw-mr-1">
|
||||
<span class="text tw-flex tw-items-center tw-mr-1 gt-ellipsis">
|
||||
<template v-if="release">{{ textReleaseCompare }}</template>
|
||||
<template v-else>
|
||||
<svg-icon v-if="isViewTag" name="octicon-tag"/>
|
||||
<svg-icon v-else name="octicon-git-branch"/>
|
||||
<strong ref="dropdownRefName" class="tw-ml-2">{{ refNameText }}</strong>
|
||||
<strong ref="dropdownRefName" class="tw-ml-2 tw-inline-block gt-ellipsis">{{ refNameText }}</strong>
|
||||
</template>
|
||||
</span>
|
||||
<svg-icon name="octicon-triangle-down" :size="14" class-name="dropdown icon"/>
|
||||
|
|
Loading…
Reference in New Issue