Skip to content

Commit

Permalink
Show latest commit for file (go-gitea#28067)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
2 people authored and silverwind committed Feb 20, 2024
1 parent 1d2296c commit bcf73f9
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 54 deletions.
64 changes: 41 additions & 23 deletions routers/web/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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()
Expand Down
31 changes: 31 additions & 0 deletions templates/repo/latest_commit.tmpl
Original file line number Diff line number Diff line change
@@ -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}}
16 changes: 16 additions & 0 deletions templates/repo/view_file.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
32 changes: 1 addition & 31 deletions templates/repo/view_list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
18 changes: 18 additions & 0 deletions web_src/css/repo.css
Original file line number Diff line number Diff line change
Expand Up @@ -1260,13 +1260,15 @@

.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);
}

.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;
Expand All @@ -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);
Expand All @@ -1291,20 +1294,23 @@

.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;
}

.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;
}

.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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -1329,13 +1337,15 @@

.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;
}

.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);
Expand All @@ -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);
Expand All @@ -1352,13 +1363,15 @@

.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;
}

.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);
Expand All @@ -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);
Expand All @@ -1375,13 +1389,15 @@

.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;
}

.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);
Expand All @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit bcf73f9

Please sign in to comment.