Blog/Models/GitRepositories.cs 5.6 K · 148 lines · raw · history
| 1 | namespace Blog.Models; |
| 2 | |
| 3 | /// <summary> |
| 4 | /// A name, an address and a time — git's author and committer lines, flattened out of libgit2's |
| 5 | /// handles so a page can still read them after the repository has been closed. |
| 6 | /// </summary> |
| 7 | public sealed record GitSignature(string Name, string Email, DateTimeOffset When); |
| 8 | |
| 9 | /// <summary>One repository under the repository root, as the index lists it.</summary> |
| 10 | /// <param name="Name">The directory name, which is also the route segment: <c>blog.git</c>.</param> |
| 11 | /// <param name="DisplayName">The same without the suffix, for headings: <c>blog</c>.</param> |
| 12 | /// <param name="Description"> |
| 13 | /// The <c>description</c> file, unless it still holds the placeholder <c>git init</c> writes. |
| 14 | /// </param> |
| 15 | /// <param name="Owner"><c>gitweb.owner</c> from the repository config, which is what cgit reads.</param> |
| 16 | /// <param name="Head">The branch HEAD points at, or null when it is unborn.</param> |
| 17 | /// <param name="Tip">The commit on that branch, and when it landed.</param> |
| 18 | public sealed record GitRepoSummary( |
| 19 | string Name, |
| 20 | string DisplayName, |
| 21 | string? Description, |
| 22 | string? Owner, |
| 23 | string? Head, |
| 24 | GitCommitInfo? Tip); |
| 25 | |
| 26 | /// <summary>A commit, with everything a page shows about it.</summary> |
| 27 | /// <param name="Refs"> |
| 28 | /// The branch and tag names whose tips are this commit. Filled in on the log, where the badges |
| 29 | /// mark where each branch has got to; empty everywhere else. |
| 30 | /// </param> |
| 31 | public sealed record GitCommitInfo( |
| 32 | string Sha, |
| 33 | string Summary, |
| 34 | string Body, |
| 35 | GitSignature Author, |
| 36 | GitSignature Committer, |
| 37 | IReadOnlyList<string> Parents, |
| 38 | IReadOnlyList<string> Refs) |
| 39 | { |
| 40 | /// <summary>Enough of the hash to be unambiguous, and short enough to sit in a table.</summary> |
| 41 | public string ShortSha => Sha.Length >= 10 ? Sha[..10] : Sha; |
| 42 | |
| 43 | /// <summary>A commit with two or more parents is diffed against the first, as git does.</summary> |
| 44 | public bool IsMerge => Parents.Count > 1; |
| 45 | } |
| 46 | |
| 47 | /// <summary>A page of history, and whether there is another one behind it.</summary> |
| 48 | public sealed record GitLogPage(IReadOnlyList<GitCommitInfo> Commits, bool HasMore); |
| 49 | |
| 50 | /// <summary>What a tree entry is, as far as the listing cares.</summary> |
| 51 | public enum GitEntryKind |
| 52 | { |
| 53 | Directory, |
| 54 | File, |
| 55 | |
| 56 | /// <summary>Mode 100755. Worth marking: it is the difference between a script and a text file.</summary> |
| 57 | Executable, |
| 58 | |
| 59 | Symlink, |
| 60 | |
| 61 | /// <summary>Another repository, pinned at a commit. There is nothing here to browse into.</summary> |
| 62 | Submodule |
| 63 | } |
| 64 | |
| 65 | /// <param name="Path">Full path from the repository root, which is what the tree links carry.</param> |
| 66 | public sealed record GitTreeEntry(string Name, string Path, GitEntryKind Kind, long Size, string Sha); |
| 67 | |
| 68 | /// <param name="IsBinary"> |
| 69 | /// Decided the way git decides it: a NUL byte anywhere in the first few kilobytes. Binary blobs |
| 70 | /// are linked to the raw endpoint instead of being printed. |
| 71 | /// </param> |
| 72 | /// <param name="Lines">The blob's text split for numbering, or null when it is not shown.</param> |
| 73 | public sealed record GitBlob( |
| 74 | string Path, |
| 75 | string Sha, |
| 76 | long Size, |
| 77 | bool IsBinary, |
| 78 | bool TooLarge, |
| 79 | IReadOnlyList<string>? Lines); |
| 80 | |
| 81 | /// <summary> |
| 82 | /// One path in one revision: a directory listing, or a file. Which of the two is set says which |
| 83 | /// the path turned out to be. |
| 84 | /// </summary> |
| 85 | /// <param name="Reference">The revision as it was asked for, for links that stay on this branch.</param> |
| 86 | public sealed record GitPathView( |
| 87 | GitCommitInfo Commit, |
| 88 | string Reference, |
| 89 | string Path, |
| 90 | IReadOnlyList<GitTreeEntry>? Entries, |
| 91 | GitBlob? Blob); |
| 92 | |
| 93 | public enum GitChange |
| 94 | { |
| 95 | Added, |
| 96 | Deleted, |
| 97 | Modified, |
| 98 | Renamed, |
| 99 | Copied, |
| 100 | TypeChanged |
| 101 | } |
| 102 | |
| 103 | /// <param name="Origin"> |
| 104 | /// <c>' '</c> context, <c>'+'</c> added, <c>'-'</c> removed, <c>'\'</c> for git's |
| 105 | /// "No newline at end of file" note. |
| 106 | /// </param> |
| 107 | public sealed record GitDiffLine(char Origin, int? OldNumber, int? NewNumber, string Text); |
| 108 | |
| 109 | /// <param name="Header">The <c>@@ -a,b +c,d @@</c> line, section heading and all.</param> |
| 110 | public sealed record GitDiffHunk(string Header, IReadOnlyList<GitDiffLine> Lines); |
| 111 | |
| 112 | /// <param name="Hunks">Empty for a binary file, and for one dropped to keep the page finite.</param> |
| 113 | public sealed record GitDiffFile( |
| 114 | string Path, |
| 115 | string? OldPath, |
| 116 | GitChange Change, |
| 117 | int Added, |
| 118 | int Deleted, |
| 119 | bool IsBinary, |
| 120 | bool Skipped, |
| 121 | IReadOnlyList<GitDiffHunk> Hunks); |
| 122 | |
| 123 | /// <param name="Truncated"> |
| 124 | /// Set when the diff ran past the line budget and the rest of the files kept their stats but lost |
| 125 | /// their hunks. A commit that vendors a 4 MB file should not render 4 MB of green. |
| 126 | /// </param> |
| 127 | public sealed record GitDiff(IReadOnlyList<GitDiffFile> Files, int Added, int Deleted, bool Truncated); |
| 128 | |
| 129 | /// <summary> |
| 130 | /// One file's bytes at one revision, for the raw endpoint. <paramref name="IsBinary"/> decides |
| 131 | /// whether it is handed over as text or as a download. |
| 132 | /// </summary> |
| 133 | public sealed record GitRawBlob(byte[] Bytes, bool IsBinary, string Name); |
| 134 | |
| 135 | /// <summary>A commit and the diff that goes with it — everything the commit page renders.</summary> |
| 136 | public sealed record GitCommitView(GitCommitInfo Commit, GitDiff Diff); |
| 137 | |
| 138 | /// <summary>A branch or a tag, with the commit it points at.</summary> |
| 139 | /// <param name="Message">An annotated tag's own message. Null for branches and lightweight tags.</param> |
| 140 | public sealed record GitRef( |
| 141 | string Name, |
| 142 | bool IsTag, |
| 143 | string Sha, |
| 144 | GitCommitInfo? Tip, |
| 145 | string? Message); |
| 146 | |
| 147 | /// <summary>Every ref in a repository, branches and tags kept apart as the refs page shows them.</summary> |
| 148 | public sealed record GitRefsView(IReadOnlyList<GitRef> Branches, IReadOnlyList<GitRef> Tags); |