diff options
author | JakobDev <jakobdev@gmx.de> | 2024-01-15 17:42:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-15 17:42:15 +0100 |
commit | 885cc32b14584ee2d01009768895b7a776441504 (patch) | |
tree | 3eb87de74da708b35945d32e30443de2f649077c | |
parent | 2c3da59e275b69ebf984bb70954f42a7bcb0b49d (diff) | |
download | gitea-885cc32b14584ee2d01009768895b7a776441504.tar.gz gitea-885cc32b14584ee2d01009768895b7a776441504.zip |
Show latest commit for file (#28067)
If you view a file, you can now see the latest commit that changed that file.
![grafik](https://github.com/go-gitea/gitea/assets/15185051/272c3120-6db7-4f88-86e1-60080c9aabe5)
---------
Co-authored-by: Denys Konovalov <kontakt@denyskon.de>
-rw-r--r-- | routers/web/repo/view.go | 64 | ||||
-rw-r--r-- | templates/repo/latest_commit.tmpl | 31 | ||||
-rw-r--r-- | templates/repo/view_file.tmpl | 16 | ||||
-rw-r--r-- | templates/repo/view_list.tmpl | 32 | ||||
-rw-r--r-- | web_src/css/repo.css | 18 |
5 files changed, 107 insertions, 54 deletions
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index c2daa3e5e6..aa07d5939d 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -341,6 +341,35 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr } } +func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool { + // Show latest commit info of repository in table header, + // or of directory if not in root directory. + ctx.Data["LatestCommit"] = latestCommit + if latestCommit != nil { + + verification := asymkey_model.ParseCommitWithSignature(ctx, latestCommit) + + if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) { + return repo_model.IsOwnerMemberCollaborator(ctx, ctx.Repo.Repository, user.ID) + }, nil); err != nil { + ctx.ServerError("CalculateTrustStatus", err) + return false + } + ctx.Data["LatestCommitVerification"] = verification + ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(ctx, latestCommit) + + statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptions{ListAll: true}) + if err != nil { + log.Error("GetLatestCommitStatus: %v", err) + } + + ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses) + ctx.Data["LatestCommitStatuses"] = statuses + } + + return true +} + func renderFile(ctx *context.Context, entry *git.TreeEntry) { ctx.Data["IsViewFile"] = true ctx.Data["HideRepoInfo"] = true @@ -357,6 +386,16 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) { ctx.Data["FileName"] = blob.Name() ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) + commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath) + if err != nil { + ctx.ServerError("GetCommitByPath", err) + return + } + + if !loadLatestCommitData(ctx, commit) { + return + } + if ctx.Repo.TreePath == ".editorconfig" { _, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) if editorconfigWarning != nil { @@ -846,29 +885,8 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri return nil } - // Show latest commit info of repository in table header, - // or of directory if not in root directory. - ctx.Data["LatestCommit"] = latestCommit - if latestCommit != nil { - - verification := asymkey_model.ParseCommitWithSignature(ctx, latestCommit) - - if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) { - return repo_model.IsOwnerMemberCollaborator(ctx, ctx.Repo.Repository, user.ID) - }, nil); err != nil { - ctx.ServerError("CalculateTrustStatus", err) - return nil - } - ctx.Data["LatestCommitVerification"] = verification - ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(ctx, latestCommit) - - statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptions{ListAll: true}) - if err != nil { - log.Error("GetLatestCommitStatus: %v", err) - } - - ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses) - ctx.Data["LatestCommitStatuses"] = statuses + if !loadLatestCommitData(ctx, latestCommit) { + return nil } branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() diff --git a/templates/repo/latest_commit.tmpl b/templates/repo/latest_commit.tmpl new file mode 100644 index 0000000000..b2f0798917 --- /dev/null +++ b/templates/repo/latest_commit.tmpl @@ -0,0 +1,31 @@ +{{if not .LatestCommit}} + <div class="ui active tiny slow centered inline">…</div> +{{else}} + {{if .LatestCommitUser}} + {{ctx.AvatarUtils.Avatar .LatestCommitUser 24 "gt-mr-2"}} + {{if .LatestCommitUser.FullName}} + <a class="muted author-wrapper" title="{{.LatestCommitUser.FullName}}" href="{{.LatestCommitUser.HomeLink}}"><strong>{{.LatestCommitUser.FullName}}</strong></a> + {{else}} + <a class="muted author-wrapper" title="{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}" href="{{.LatestCommitUser.HomeLink}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a> + {{end}} + {{else}} + {{if .LatestCommit.Author}} + {{ctx.AvatarUtils.AvatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 24 "gt-mr-2"}} + <span class="author-wrapper" title="{{.LatestCommit.Author.Name}}"><strong>{{.LatestCommit.Author.Name}}</strong></span> + {{end}} + {{end}} + <a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified}} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" href="{{.RepoLink}}/commit/{{PathEscape .LatestCommit.ID.String}}"> + <span class="shortsha">{{ShortSha .LatestCommit.ID.String}}</span> + {{if .LatestCommit.Signature}} + {{template "repo/shabox_badge" dict "root" $ "verification" .LatestCommitVerification}} + {{end}} + </a> + {{template "repo/commit_statuses" dict "Status" .LatestCommitStatus "Statuses" .LatestCommitStatuses}} + {{$commitLink:= printf "%s/commit/%s" .RepoLink (PathEscape .LatestCommit.ID.String)}} + <span class="grey commit-summary" title="{{.LatestCommit.Summary}}"><span class="message-wrapper">{{RenderCommitMessageLinkSubject $.Context .LatestCommit.Message $commitLink ($.Repository.ComposeMetas ctx)}}</span> + {{if IsMultilineCommitMessage .LatestCommit.Message}} + <button class="ui button js-toggle-commit-body ellipsis-button" aria-expanded="false">...</button> + <pre class="commit-body gt-hidden">{{RenderCommitBody $.Context .LatestCommit.Message ($.Repository.ComposeMetas ctx)}}</pre> + {{end}} + </span> +{{end}} diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index e7d1c04c12..e6591df7e3 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -9,6 +9,22 @@ <div class="text left gt-whitespace-pre">{{.FileWarning}}</div> </div> {{end}} + + {{if not .ReadmeInList}} + <div id="repo-file-commit-box" class="ui top attached header list-header gt-mb-4"> + <div> + {{template "repo/latest_commit" .}} + </div> + {{if .LatestCommit}} + {{if .LatestCommit.Committer}} + <div class="ui text grey right age"> + {{TimeSince .LatestCommit.Committer.When ctx.Locale}} + </div> + {{end}} + {{end}} + </div> + {{end}} + <h4 class="file-header ui top attached header gt-df gt-ac gt-sb gt-fw"> <div class="file-header-left gt-df gt-ac gt-py-3 gt-pr-4"> {{if .ReadmeInList}} diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index 504032aa78..c1ef4ff4cb 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -2,37 +2,7 @@ <thead> <tr class="commit-list"> <th colspan="2" {{if not .LatestCommit}}class="notready"{{end}}> - {{if not .LatestCommit}} - <div class="ui active tiny slow centered inline">…</div> - {{else}} - {{if .LatestCommitUser}} - {{ctx.AvatarUtils.Avatar .LatestCommitUser 24 "gt-mr-2"}} - {{if .LatestCommitUser.FullName}} - <a class="muted author-wrapper" title="{{.LatestCommitUser.FullName}}" href="{{.LatestCommitUser.HomeLink}}"><strong>{{.LatestCommitUser.FullName}}</strong></a> - {{else}} - <a class="muted author-wrapper" title="{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}" href="{{.LatestCommitUser.HomeLink}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a> - {{end}} - {{else}} - {{if .LatestCommit.Author}} - {{ctx.AvatarUtils.AvatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 24 "gt-mr-2"}} - <span class="author-wrapper" title="{{.LatestCommit.Author.Name}}"><strong>{{.LatestCommit.Author.Name}}</strong></span> - {{end}} - {{end}} - <a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified}} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" href="{{.RepoLink}}/commit/{{PathEscape .LatestCommit.ID.String}}"> - <span class="shortsha">{{ShortSha .LatestCommit.ID.String}}</span> - {{if .LatestCommit.Signature}} - {{template "repo/shabox_badge" dict "root" $ "verification" .LatestCommitVerification}} - {{end}} - </a> - {{template "repo/commit_statuses" dict "Status" .LatestCommitStatus "Statuses" .LatestCommitStatuses}} - {{$commitLink:= printf "%s/commit/%s" .RepoLink (PathEscape .LatestCommit.ID.String)}} - <span class="grey commit-summary" title="{{.LatestCommit.Summary}}"><span class="message-wrapper">{{RenderCommitMessageLinkSubject $.Context .LatestCommit.Message $commitLink ($.Repository.ComposeMetas ctx)}}</span> - {{if IsMultilineCommitMessage .LatestCommit.Message}} - <button class="ui button js-toggle-commit-body ellipsis-button" aria-expanded="false">...</button> - <pre class="commit-body gt-hidden">{{RenderCommitBody $.Context .LatestCommit.Message ($.Repository.ComposeMetas ctx)}}</pre> - {{end}} - </span> - {{end}} + {{template "repo/latest_commit" .}} </th> <th class="text grey right age">{{if .LatestCommit}}{{if .LatestCommit.Committer}}{{TimeSince .LatestCommit.Committer.When ctx.Locale}}{{end}}{{end}}</th> </tr> diff --git a/web_src/css/repo.css b/web_src/css/repo.css index f1356fc39b..dfe0d6c77f 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1260,6 +1260,7 @@ .repository #commits-table td.sha .sha.label, .repository #repo-files-table .sha.label, +.repository #repo-file-commit-box .sha.label, .repository #rev-list .sha.label, .repository .timeline-item.commits-list .singular-commit .sha.label { border: 1px solid var(--color-light-border); @@ -1267,6 +1268,7 @@ .repository #commits-table td.sha .sha.label .ui.signature.avatar, .repository #repo-files-table .sha.label .ui.signature.avatar, +.repository #repo-file-commit-box .sha.label .ui.signature.avatar, .repository #rev-list .sha.label .ui.signature.avatar, .repository .timeline-item.commits-list .singular-commit .sha.label .ui.signature.avatar { height: 16px; @@ -1276,6 +1278,7 @@ .repository #commits-table td.sha .sha.label .detail.icon, .repository #repo-files-table .sha.label .detail.icon, +.repository #repo-file-commit-box .sha.label .detail.icon, .repository #rev-list .sha.label .detail.icon, .repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon { background: var(--color-light); @@ -1291,6 +1294,7 @@ .repository #commits-table td.sha .sha.label .detail.icon img, .repository #repo-files-table .sha.label .detail.icon img, +.repository #repo-file-commit-box .sha.label .detail.icon img, .repository #rev-list .sha.label .detail.icon img, .repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon img { margin-right: 0; @@ -1298,6 +1302,7 @@ .repository #commits-table td.sha .sha.label .detail.icon .svg, .repository #repo-files-table .sha.label .detail.icon .svg, +.repository #repo-file-commit-box .sha.label .detail.icon .svg, .repository #rev-list .sha.label .detail.icon .svg, .repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon .svg { margin: 0 0.25em 0 0; @@ -1305,6 +1310,7 @@ .repository #commits-table td.sha .sha.label .detail.icon > div, .repository #repo-files-table .sha.label .detail.icon > div, +.repository #repo-file-commit-box .sha.label .detail.icon > div, .repository #rev-list .sha.label .detail.icon > div, .repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon > div { display: flex; @@ -1313,6 +1319,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isWarning, .repository #repo-files-table .sha.label.isSigned.isWarning, +.repository #repo-file-commit-box .sha.label.isSigned.isWarning, .repository #rev-list .sha.label.isSigned.isWarning, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning { border: 1px solid var(--color-red-badge); @@ -1321,6 +1328,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isWarning .detail.icon, .repository #repo-files-table .sha.label.isSigned.isWarning .detail.icon, +.repository #repo-file-commit-box .sha.label.isSigned.isWarning .detail.icon, .repository #rev-list .sha.label.isSigned.isWarning .detail.icon, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning .detail.icon { border-left: 1px solid var(--color-red-badge); @@ -1329,6 +1337,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isWarning:hover, .repository #repo-files-table .sha.label.isSigned.isWarning:hover, +.repository #repo-file-commit-box .sha.label.isSigned.isWarning:hover, .repository #rev-list .sha.label.isSigned.isWarning:hover, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning:hover { background: var(--color-red-badge-hover-bg) !important; @@ -1336,6 +1345,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerified, .repository #repo-files-table .sha.label.isSigned.isVerified, +.repository #repo-file-commit-box .sha.label.isSigned.isVerified, .repository #rev-list .sha.label.isSigned.isVerified, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified { border: 1px solid var(--color-green-badge); @@ -1344,6 +1354,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerified .detail.icon, .repository #repo-files-table .sha.label.isSigned.isVerified .detail.icon, +.repository #repo-file-commit-box .sha.label.isSigned.isVerified .detail.icon, .repository #rev-list .sha.label.isSigned.isVerified .detail.icon, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified .detail.icon { border-left: 1px solid var(--color-green-badge); @@ -1352,6 +1363,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerified:hover, .repository #repo-files-table .sha.label.isSigned.isVerified:hover, +.repository #repo-file-commit-box .sha.label.isSigned.isVerified:hover, .repository #rev-list .sha.label.isSigned.isVerified:hover, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified:hover { background: var(--color-green-badge-hover-bg) !important; @@ -1359,6 +1371,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted, .repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted, +.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted, .repository #rev-list .sha.label.isSigned.isVerifiedUntrusted, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted { border: 1px solid var(--color-yellow-badge); @@ -1367,6 +1380,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted .detail.icon, .repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted .detail.icon, +.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted .detail.icon, .repository #rev-list .sha.label.isSigned.isVerifiedUntrusted .detail.icon, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted .detail.icon { border-left: 1px solid var(--color-yellow-badge); @@ -1375,6 +1389,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted:hover, .repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted:hover, +.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted:hover, .repository #rev-list .sha.label.isSigned.isVerifiedUntrusted:hover, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted:hover { background: var(--color-yellow-badge-hover-bg) !important; @@ -1382,6 +1397,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched, .repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched, +.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched, .repository #rev-list .sha.label.isSigned.isVerifiedUnmatched, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched { border: 1px solid var(--color-orange-badge); @@ -1390,6 +1406,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched .detail.icon, .repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched .detail.icon, +.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched .detail.icon, .repository #rev-list .sha.label.isSigned.isVerifiedUnmatched .detail.icon, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched .detail.icon { border-left: 1px solid var(--color-orange-badge); @@ -1398,6 +1415,7 @@ .repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched:hover, .repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched:hover, +.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched:hover, .repository #rev-list .sha.label.isSigned.isVerifiedUnmatched:hover, .repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched:hover { background: var(--color-orange-badge-hover-bg) !important; |