Commit: 2edd64d
Parent: 94794a7

View commit details

Mårten Åsberg committed on 2025-11-09 at 19:12
No diffs, or browsing at commits
GitBrowser/Components/Pages/Commit.razor +152 -0
diff --git a/GitBrowser/Components/Pages/Commit.razor b/GitBrowser/Components/Pages/Commit.razor
new file mode 100644
index 0000000..d81394a
@@ -0,0 +1,152 @@
@page "/repo/commit/{Hash}"
@using LibGit2Sharp
@using Microsoft.Extensions.Options
@using Microsoft.AspNetCore.Http
@inject IOptions<RepositoryConfiguration> repoConfig
@inject IHttpContextAccessor HttpContextAccessor
@implements IDisposable
<PageTitle>Commit @Hash</PageTitle>
@if (notFound)
{
<h3>Not Found</h3>
<p>Sorry, the commit you are looking for does not exist.</p>
}
else if (commit != null)
{
<div class="container">
<div class="commit-header">
<div class="commit-hashes">
<div class="commit-hash">
<span class="hash-label">Commit:</span>
<code>@commit.Sha.Substring(0, 7)</code>
</div>
<div class="hash-spacer"></div>
@if (commit.Parents.Any())
{
<div class="parent-hash">
<span class="hash-label">Parent:</span>
<a href="/repo/commit/@commit.Parents.First().Sha">
<code>@commit.Parents.First().Sha.Substring(0, 7)</code>
</a>
</div>
}
@if (childCommit != null)
{
<div class="child-hash">
<span class="hash-label">Child:</span>
<a href="/repo/commit/@childCommit.Sha">
<code>@childCommit.Sha.Substring(0, 7)</code>
</a>
</div>
}
</div>
<h1 class="commit-title">@commitTitle</h1>
<div class="commit-meta">
<div class="commit-author">
<strong>@commit.Author.Name</strong> committed on @commit.Author.When.ToString("MMMM d, yyyy") at @commit.Author.When.ToString("h:mm tt")
</div>
</div>
@if (!string.IsNullOrEmpty(commitBody))
{
<div class="commit-body">
<pre>@commitBody</pre>
</div>
}
</div>
</div>
}
@code {
[Parameter]
public string? Hash { get; set; }
private Repository? repo = null;
private LibGit2Sharp.Commit? commit = null;
private LibGit2Sharp.Commit? childCommit = null;
private bool notFound = false;
private string commitTitle = "";
private string commitBody = "";
protected override void OnInitialized()
{
if (string.IsNullOrEmpty(Hash))
{
SetNotFound();
return;
}
var repoPath = repoConfig.Value.Path;
if (string.IsNullOrEmpty(repoPath) || !Repository.IsValid(repoPath))
{
SetNotFound();
return;
}
repo = new Repository(repoPath);
try
{
commit = repo.Lookup<LibGit2Sharp.Commit>(Hash);
if (commit == null)
{
SetNotFound();
return;
}
// Split message into title and body
var message = commit.Message;
var firstLineEnd = message.IndexOf('\n');
if (firstLineEnd > 0)
{
commitTitle = message.Substring(0, firstLineEnd).Trim();
commitBody = message.Substring(firstLineEnd + 1).Trim();
}
else
{
commitTitle = message.Trim();
commitBody = "";
}
// Find child commit
try
{
foreach (var c in repo.Commits.QueryBy(new CommitFilter { FirstParentOnly = false }))
{
if (c.Parents.Any(p => p.Sha == commit.Sha))
{
childCommit = c;
break;
}
}
}
catch
{
// If we can't find a child, just continue
}
}
catch
{
SetNotFound();
}
}
private void SetNotFound()
{
notFound = true;
var httpContext = HttpContextAccessor.HttpContext;
if (httpContext != null)
{
httpContext.Response.StatusCode = StatusCodes.Status404NotFound;
}
}
public void Dispose()
{
repo?.Dispose();
}
}
GitBrowser/Components/Pages/Commit.razor.css +103 -0
diff --git a/GitBrowser/Components/Pages/Commit.razor.css b/GitBrowser/Components/Pages/Commit.razor.css
new file mode 100644
index 0000000..478da2b
@@ -0,0 +1,103 @@
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
}
.commit-header {
background: white;
border: 1px solid #d0d7de;
border-radius: 6px;
padding: 1.5rem;
}
.commit-hashes {
display: grid;
grid-template-areas: "commit . parent child";
grid-template-columns: auto 1fr auto auto;
align-items: center;
margin-bottom: 1rem;
border-bottom: 1px solid #d0d7de;
.commit-hash {
grid-area: commit;
}
.parent-hash {
grid-area: parent;
}
.child-hash {
grid-area: child;
}
}
.commit-hash,
.parent-hash,
.child-hash {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
&:not(:first-child) {
margin-inline-start: 1rem;
}
}
.hash-label {
color: #57606a;
font-weight: 600;
}
code {
background: #f6f8fa;
padding: 0.25rem 0.5rem;
border-radius: 3px;
font-family: "Consolas", "Monaco", "Courier New", monospace;
font-size: 0.875rem;
color: #24292f;
}
.parent-hash a,
.child-hash a {
color: #0969da;
text-decoration: none;
}
.parent-hash a:hover,
.child-hash a:hover {
text-decoration: underline;
}
.commit-title {
font-size: 1.5rem;
font-weight: 600;
color: #24292f;
margin: 0;
line-height: 1.3;
}
.commit-author {
color: #57606a;
font-size: 0.875rem;
}
.commit-author strong {
color: #24292f;
font-weight: 600;
}
.commit-body {
margin-top: 1rem;
}
.commit-body pre {
margin: 0;
font-family: "Consolas", "Monaco", "Courier New", monospace;
font-size: 0.875rem;
line-height: 1.6;
color: #24292f;
white-space: pre-wrap;
word-wrap: break-word;
}
GitBrowser/Components/Pages/Repo.razor +6 -4
diff --git a/GitBrowser/Components/Pages/Repo.razor b/GitBrowser/Components/Pages/Repo.razor
index 53b115c..f18a9ce 100644
@@ -88,7 +88,7 @@ else
<td class="commit-message">
@if (commitInfo != null)
{
<span>@commitInfo.MessageShort</span>
<a href="/repo/commit/@commitInfo.Sha">@commitInfo.MessageShort</a>
}
else
{
@@ -98,7 +98,7 @@ else
<td class="commit-date">
@if (commitInfo != null)
{
<span title="@commitInfo.When.ToString("yyyy-MM-dd HH:mm:ss")">@GetRelativeTime(commitInfo.When)</span>
<a href="/repo/commit/@commitInfo.Sha" title="@commitInfo.When.ToString("yyyy-MM-dd HH:mm:ss")">@GetRelativeTime(commitInfo.When)</a>
}
else
{
@@ -145,12 +145,13 @@ else
private string? fileName = null;
private bool isReadme = false;
private Repository? repo = null;
private Commit? currentCommit = null;
private LibGit2Sharp.Commit? currentCommit = null;
private class CommitInfo
{
public string MessageShort { get; set; } = "";
public DateTimeOffset When { get; set; }
public string Sha { get; set; } = "";
}
private Dictionary<string, CommitInfo?> commitCache = new();
@@ -289,7 +290,8 @@ else
var info = new CommitInfo
{
MessageShort = lastCommit.MessageShort,
When = lastCommit.Author.When
When = lastCommit.Author.When,
Sha = lastCommit.Sha
};
commitCache[path] = info;
return info;
GitBrowser/Components/Pages/Repo.razor.css +12 -0
diff --git a/GitBrowser/Components/Pages/Repo.razor.css b/GitBrowser/Components/Pages/Repo.razor.css
index 5ad9e4d..d98c639 100644
@@ -122,6 +122,18 @@ tbody td {
font-size: 0.875rem;
}
.commit-message a,
.commit-date a {
color: #57606a;
text-decoration: none;
}
.commit-message a:hover,
.commit-date a:hover {
color: #0969da;
text-decoration: underline;
}
.commit-date {
width: 180px;
}