aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-06-22 01:48:59 +0200
committerKatharina Fey <kookie@spacekookie.de>2020-06-22 01:48:59 +0200
commit84a9a0ccee713e26a28ff5e54ea3776085d93b5f (patch)
tree9a0158ecc1668e8594881a4f9be7e54c8773d6a9
parent67ad3b7a26ed0dc99f3324011fa8e5ed316a655a (diff)
Updating just like... a bunch of shit
-rw-r--r--Cargo.toml2
-rw-r--r--src/cli.rs79
-rw-r--r--src/config.rs17
-rw-r--r--src/main.rs20
-rw-r--r--src/pages/mod.rs4
-rw-r--r--src/pages/repo/about.rs44
-rw-r--r--src/pages/repo/details.rs37
-rw-r--r--src/pages/repo/mod.rs14
-rw-r--r--src/state/mod.rs14
-rw-r--r--src/types/mod.rs30
-rw-r--r--static/main.css7
-rw-r--r--templates/core.html18
-rw-r--r--templates/repo/about.html133
-rw-r--r--templates/repo/base.html37
-rw-r--r--templates/repo/details.html258
15 files changed, 426 insertions, 288 deletions
diff --git a/Cargo.toml b/Cargo.toml
index eb2edce..de806eb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,8 +7,8 @@ edition = "2018"
[dependencies]
actix-files = "0.2"
-actix-web = "2.0.0"
actix-rt = "1.0.0"
+actix-web = "2.0.0"
askama = "0.8"
env_logger = "0.6"
git2 = "0.11"
diff --git a/src/cli.rs b/src/cli.rs
new file mode 100644
index 0000000..500a901
--- /dev/null
+++ b/src/cli.rs
@@ -0,0 +1,79 @@
+use clap::{App, Arg};
+use colored::Colorize;
+use std::{
+ env,
+ fs::File,
+ path::{Path, PathBuf},
+};
+
+pub struct Paths {
+ pub config: File,
+ pub data: PathBuf,
+}
+
+/// Initialise the application by getting valid path options
+pub fn init() -> Paths {
+ let app = App::new("webgit")
+ .about("The friendly and simple git web frontend")
+ .version("0.0.0")
+ .arg(
+ Arg::with_name("CONFIG")
+ .short("c")
+ .long("config")
+ .takes_value(true)
+ .help(
+ "Provide the path to the system configuration. Alternatively \
+ set WEBGIT_CONFIG_PATH in your env",
+ ),
+ )
+ .arg(
+ Arg::with_name("DATA_DIR")
+ .short("d")
+ .long("data-dir")
+ .takes_value(true)
+ .help(
+ "Specify where webgit should save git repositories. Alternatively \
+ set WEBGIT_DATA_DIR in your env",
+ ),
+ );
+
+ let matches = app.get_matches();
+
+ Paths {
+ config: File::open(
+ env::var_os("WEBGIT_CONFIG_PATH")
+ .map(|os| match os.into_string() {
+ Ok(p) => p.to_owned(),
+ Err(_) => {
+ eprintln!("{}: Failed to parse provided config path!", "Error:".red());
+ std::process::exit(2);
+ }
+ })
+ .unwrap_or_else(|| match matches.value_of("CONFIG") {
+ Some(p) => p.to_owned(),
+ None => {
+ eprintln!("{}: No config provided!", "Error:".red());
+ std::process::exit(2);
+ }
+ }),
+ )
+ .expect(&format!("{}: Config file not found!", "Error:".red())),
+ data: Path::new(
+ &env::var_os("WEBGIT_DATA_DIR")
+ .map(|os| {
+ os.into_string().expect(&format!(
+ "{}: Failed to parse provided data-dir path!",
+ "Error".red()
+ ))
+ })
+ .unwrap_or_else(|| match matches.value_of("CONFIG") {
+ Some(p) => p.to_owned(),
+ None => {
+ eprintln!("{}: No data dir provided!", "Error:".red());
+ std::process::exit(2);
+ }
+ }),
+ )
+ .into(),
+ }
+}
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..99e8cff
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,17 @@
+//! Configuration to run octopus
+
+pub struct Config {
+ app_path: String,
+ port: u16,
+ handle_ssl: bool,
+ cache_path: String,
+ repos_path: String,
+ repo_discovery: bool,
+ repos: Vec<RepoConfig>
+}
+
+pub struct RepoConfig {
+ name: String,
+ description: String,
+ category: String,
+}
diff --git a/src/main.rs b/src/main.rs
index d6a4b36..6d0ef79 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,21 +1,25 @@
mod pages;
mod repo;
+// mod router;
+mod types;
use actix_files as fs;
use actix_web::{web, App, HttpServer};
use std::io;
+use std::path::PathBuf;
#[actix_rt::main]
async fn main() -> io::Result<()> {
- HttpServer::new(|| {
+ std::env::set_var("RUST_LOG", "actix_web=info");
+ env_logger::init();
+ let root = PathBuf::new();
+
+ HttpServer::new(move || {
App::new()
- .service(fs::Files::new("/static", "static"))
- .service(web::resource("/{repo}").route(web::get().to(pages::repo::about::render)))
- // default
- .default_service(
- // 404 for GET request
- web::resource("").route(web::get().to(pages::p404::render)),
- )
+ .service(fs::Files::new("/static", root.join("static")))
+ .service(web::resource("/{repo}").route(web::get().to(pages::repo::about)))
+ .service(web::resource("/{repo}/details").route(web::get().to(pages::repo::details)))
+ .default_service(web::resource("").route(web::get().to(pages::p404)))
})
.bind("127.0.0.1:8080")?
.run()
diff --git a/src/pages/mod.rs b/src/pages/mod.rs
index d53561b..f838eee 100644
--- a/src/pages/mod.rs
+++ b/src/pages/mod.rs
@@ -4,4 +4,6 @@
//! which is exported from the module and then called by the router
pub mod repo;
-pub mod p404;
+
+mod p404;
+pub use p404::render as p404;
diff --git a/src/pages/repo/about.rs b/src/pages/repo/about.rs
index 8797edd..fa88eb1 100644
--- a/src/pages/repo/about.rs
+++ b/src/pages/repo/about.rs
@@ -1,35 +1,35 @@
+use super::RepoWrapper;
+use crate::types::RepoData;
use actix_web::{web, HttpRequest, HttpResponse, Result};
use askama::Template;
#[derive(Template)]
-#[template(path = "repo.html")]
-struct Repo<'a> {
- project_owner: &'a str,
- project_summary: &'a str,
- project_name: &'a str,
- project_logo: &'a str,
- project_logo_alt_text: &'a str,
- first_commit: &'a str,
- num_commits: usize,
- num_contributors: usize,
+#[template(path = "repo/about.html")]
+struct AboutRepo {
+ repo: RepoWrapper,
+ readme: String,
}
/// Renders the "repository/about" subpage
pub async fn render(req: HttpRequest, path: web::Path<String>) -> Result<HttpResponse> {
- println!("Rendering path: {:#?}", path);
- dbg!(req);
-
- let repo = Repo {
- project_owner: "spacekookie",
- project_summary: "A lightweight web frontend for git repositories",
- project_name: "webgit",
- project_logo: "rust.png",
- project_logo_alt_text: "Rust logo",
- first_commit: "f6ca929",
- num_commits: 123,
- num_contributors: 3,
+ let repo = AboutRepo {
+ readme: include_str!("../../../README").to_string(),
+ repo: RepoWrapper {
+ data: RepoData {
+ owner: "spacekookie".into(),
+ name: "octopus".into(),
+ tagline: "A lightweight web frontend for git repositories".into(),
+ num_commit: 141,
+ num_branch: 1,
+ num_tag: 0,
+ num_contributor: 3,
+ size: "13.12M".into(),
+ },
+ logo: "fakeavi.png".into(),
+ },
}
.render()
.unwrap();
+
Ok(HttpResponse::Ok().content_type("text/html").body(repo))
}
diff --git a/src/pages/repo/details.rs b/src/pages/repo/details.rs
new file mode 100644
index 0000000..4745e96
--- /dev/null
+++ b/src/pages/repo/details.rs
@@ -0,0 +1,37 @@
+use super::RepoWrapper;
+use crate::types::{BranchData, CommitData, RepoData};
+use actix_web::{web, HttpRequest, HttpResponse, Result};
+use askama::Template;
+
+#[derive(Template)]
+#[template(path = "repo/details.html")]
+struct AboutRepo {
+ repo: RepoWrapper,
+ branches: Vec<BranchData>,
+ commits: Vec<CommitData>,
+}
+
+/// Renders the "repository/about" subpage
+pub async fn render(req: HttpRequest, path: web::Path<String>) -> Result<HttpResponse> {
+ let repo = AboutRepo {
+ branches: vec![],
+ commits: vec![],
+ repo: RepoWrapper {
+ data: RepoData {
+ owner: "spacekookie".into(),
+ name: "octopus".into(),
+ tagline: "A lightweight web frontend for git repositories".into(),
+ num_commit: 141,
+ num_branch: 1,
+ num_tag: 0,
+ num_contributor: 3,
+ size: "13.12M".into(),
+ },
+ logo: "fakeavi.png".into(),
+ },
+ }
+ .render()
+ .unwrap();
+
+ Ok(HttpResponse::Ok().content_type("text/html").body(repo))
+}
diff --git a/src/pages/repo/mod.rs b/src/pages/repo/mod.rs
index c339350..7d90c97 100644
--- a/src/pages/repo/mod.rs
+++ b/src/pages/repo/mod.rs
@@ -1,3 +1,15 @@
//! The repository page subtree
-pub mod about;
+mod about;
+mod details;
+
+pub use about::render as about;
+pub use details::render as details;
+
+use crate::types::RepoData;
+
+/// A template wrapper for repository data
+pub(self) struct RepoWrapper {
+ pub(self) data: RepoData,
+ pub(self) logo: String,
+}
diff --git a/src/state/mod.rs b/src/state/mod.rs
new file mode 100644
index 0000000..5e7f927
--- /dev/null
+++ b/src/state/mod.rs
@@ -0,0 +1,14 @@
+//! Core octopus state handling
+
+use std::sync::Arc;
+
+pub(crate) type StateRef = Arc<OctoState>;
+
+/// Holds all state handles for the application
+pub(crate) struct OctoState {}
+
+impl OctoState {
+ pub(crate) fn new() -> StateRef {
+ Arc::new(Self {})
+ }
+}
diff --git a/src/types/mod.rs b/src/types/mod.rs
new file mode 100644
index 0000000..d764b84
--- /dev/null
+++ b/src/types/mod.rs
@@ -0,0 +1,30 @@
+//! Octopus data types
+
+/// A simple overview of a repository
+///
+/// This type can be generated by the octopus Repository state wrapper
+pub(crate) struct RepoData {
+ pub owner: String,
+ pub name: String,
+ pub tagline: String,
+ pub num_commit: usize,
+ pub num_branch: usize,
+ pub num_tag: usize,
+ pub num_contributor: usize,
+ pub size: String,
+}
+
+/// Data about an individual commit
+pub(crate) struct CommitData {
+ pub hash: String,
+ pub message: String,
+ pub author: String,
+ pub date: String,
+ pub diff: (usize, usize),
+}
+
+/// Data about a branch
+pub(crate) struct BranchData {
+ pub name: String,
+ pub last_commit: CommitData,
+}
diff --git a/static/main.css b/static/main.css
index b567240..cea0eb1 100644
--- a/static/main.css
+++ b/static/main.css
@@ -66,6 +66,7 @@ a:hover, a:active {
grid-row-end: 3;
max-width:230px;
max-height:100px;
+ padding-right: 1em;
}
.subheader {
@@ -99,6 +100,12 @@ a:hover, a:active {
font-size: 1.25em;
}
+.details-table {
+ padding: 5ch 15ch;
+ font-size: 1.25em;
+ text-align: left;
+}
+
.details-grid {
display: grid;
grid-template-columns: 2fr 4fr repeat(3, 1fr);
diff --git a/templates/core.html b/templates/core.html
new file mode 100644
index 0000000..808dc4c
--- /dev/null
+++ b/templates/core.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <link href="/static/main.css" rel="stylesheet">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+ {% block title %}{% endblock %}
+ </head>
+ <body>
+ <div class="container">
+ {% block content %}{% endblock %}
+
+ <hr/>
+ <pre>Generated by octopus v0.0.0</pre>
+ <div>
+ </body>
+</html>
diff --git a/templates/repo/about.html b/templates/repo/about.html
index b98edbd..5c476aa 100644
--- a/templates/repo/about.html
+++ b/templates/repo/about.html
@@ -1,131 +1,6 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8" />
- <title>octopus | /spacekookie/octopus</title>
- <link href="/static/main.css" rel="stylesheet">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- </head>
- <body>
- <div class="container">
- <div class="tagline-container">
- <img class="repo-logo" src="/static/fakeavi.png" />
- <h1><a href="">spacekookie</a> / <a href="">octopus</a></h1>
- <p>šŸ™ It's a water animal</p>
- <div class="starbox">
- <a href="">Clone</a>
- <a href="">Star</a>
- <a href="">RSS</a>
- </div>
- </div> <!-- tagline container -->
- <div class="subheader">
-
- <a href="">141 commits</a>
- <a href="">1 branch</a>
- <a href="">0 tags</a>
- <a href="">1 contributor</a>
- <a href="">size: 13.12M</a>
- <input id="repo-search" type="search" placeholder="Search repository" />
- <!-- <label for="repo-search">Search for files in the repository</label> -->
- </div> <!-- subheader -->
- <hr />
- <div class="repo-navigation">
- <a href="about.html" class="nav-item nav-active">about</a>
- <a href="details.html " class="nav-item">details</a>
- <a href="" class="nav-item">files</a>
- <a href="" class="nav-item">log</a>
- <a href="" class="nav-item"> patches</a>
- <a href="" class="nav-item">contribute</a>
- </div>
+{% extends "base.html" %}
- <pre class="readme">
- .'.'
- .'-'.
- . ( o O)
- \_ ` _, _
--.___'.) ( ,-'
- '-.O.'-..-.. octopus git web frontend
- ./\/\/ | \_.-._
- ;
- ._/
+{% block child_content %}
+<pre class="readme">{{ readme }}</pre>
+{% endblock %}
-
-A git web frontend that wants to hug your code.
-
-
-Why?
-----
-
-This is a very good first question, and one that I think is important
-to answer before getting more into the project. Whenever I brought up
-this project during the creation of it, most people would react with
-"have you tried...", followed by some git web software, such as
-gitlab, gittea, and many many more. But there is a reason why I stuck
-with octopus and the design ideas I had for it.
-
-Fundamentally it's about decentralisation. The internet is a pretty
-big place (allegedly), but a lot of the services that people use are
-very centralised by a single company or even server. If this company
-or server goes away, so does valuable knowledge. There are many ways
-to create more decentralised systems, and one aspect of this for me,
-is code repos.
-
-Git is by it's nature decentralised, meaning that it doesn't require
-an "upstream" or canonical server to function. Theoretically you
-could use git to exchange code patches with people without the
-internet. Yet, a lot of people's perception of git is one that is
-dictated by the workflows on github and gitlab: centralised into a
-single service. Many git web frontends mirror this workflow, because
-after all, it is what people want and love.
-
-However, it has some flaws (which would take too long to elaborate
-here), and for octopus I had something else in mind. Instead of
-replicating the same mistakes, I took much more inspiration from cgit,
-which is used and loved by many today.
-
-Octopus is a re-imagining of cgit, trying to improve the UX and
-maintainability where possible, adding new features, but mostly
-staying true to it's core: a simple git web service, that doesn't lock
-you into a vendor, or server.
-
-Configuration
--------------
-
-octopus is easy to configure and run, even on systems that don't give
-you priviledged system access. The main server binary is configured
-primarily with a few environment variables, and an app config.
-
-+ OCTOPUS_CONFIG should contain the path of the main configuration
-
-+ OCTOPUS_SSL_KEY can optionally be set to the path of a certificate key
-
-+ OCTOPUS_SSL_CERT can optionally be set to the path of a certificate
-
-
-The main configuration file is written in yaml, and outlines things
-like the application domain, repo paths, and added modules. Because
-octopus is vory modular, you can only depend on certain features.
-
-
----
-app_path: git.octopus.example
-port: 8080
-handle_ssl: false
-cache_path: /var/cache/octopus
-repo_path: /var/lib/octopus/repos
-repo_discovery: false # Disables automatic config loading from repo_path
- # and instead let's you set a static set of repos
- # in the section below
-repos:
- - octopus:
- description: "šŸ™ It's a water animal"
- category: "/"
- - libkookie:
- description: "My personal nix expressions"
- category: "/nix"
-
-
- </pre>
- </div>
- </body>
-</html>
diff --git a/templates/repo/base.html b/templates/repo/base.html
new file mode 100644
index 0000000..9927a4a
--- /dev/null
+++ b/templates/repo/base.html
@@ -0,0 +1,37 @@
+{% extends "../core.html" %}
+{% block title %}<title>octopus | /{{ repo.data.owner }}/{{ repo.data.name }}</title>{% endblock %}
+
+{% block content %}
+<div class="tagline-container">
+ <img class="repo-logo" src="/static/{{ repo.logo }}" />
+ <h1><a href="">{{ repo.data.owner }}</a> / <a href="">{{ repo.data.name }}</a></h1>
+ <p>šŸ™ It's a water animal</p>
+ <div class="starbox">
+ <a href="">Clone</a>
+ <a href="">Star</a>
+ <a href="">RSS</a>
+ </div>
+</div> <!-- tagline container -->
+<div class="subheader">
+
+ <a href="">{{ repo.data.num_commit }} commits</a>
+ <a href="">{{ repo.data.num_branch}} branch</a>
+ <a href="">{{ repo.data.num_tag }} tags</a>
+ <a href="">{{ repo.data.num_contributor }} contributor</a>
+ <a href="">size: {{ repo.data.size }}</a>
+ <input id="repo-search" type="search" placeholder="Search repository" />
+ <!-- <label for="repo-search">Search for files in the repository</label> -->
+</div> <!-- subheader -->
+<hr />
+<div class="repo-navigation">
+ <a href="about.html" class="nav-item nav-active">about</a>
+ <a href="details.html " class="nav-item">details</a>
+ <a href="" class="nav-item">files</a>
+ <a href="" class="nav-item">log</a>
+ <a href="" class="nav-item">patches</a>
+ <a href="" class="nav-item">contribute</a>
+</div>
+
+{% block child_content %}{% endblock %}
+
+{% endblock %}
diff --git a/templates/repo/details.html b/templates/repo/details.html
index ddcc761..6a13a77 100644
--- a/templates/repo/details.html
+++ b/templates/repo/details.html
@@ -1,126 +1,132 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8" />
- <title>octopus | /spacekookie/octopus</title>
- <link href="/static/main.css" rel="stylesheet">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- </head>
- <body>
- <div class="container">
- <div class="tagline-container">
- <img class="repo-logo" src="/static/fakeavi.png" />
- <h1><a href="">spacekookie</a> / <a href="">octopus</a></h1>
- <p>šŸ™ It's a water animal</p>
- <div class="starbox">
- <a href="">Clone</a>
- <a href="">Star</a>
- <a href="">RSS</a>
- </div>
- </div> <!-- tagline container -->
- <div class="subheader">
-
- <a href="">141 commits</a>
- <a href="">1 branch</a>
- <a href="">0 tags</a>
- <a href="">1 contributor</a>
- <a href="">size: 13.12M</a>
- <input id="repo-search" type="search" placeholder="Search repository" />
- <!-- <label for="repo-search">Search for files in the repository</label> -->
- </div> <!-- subheader -->
- <hr />
- <div class="repo-navigation">
- <a href="about.html" class="nav-item">about</a>
- <a href="details.html" class="nav-item nav-active">details</a>
- <a href="" class="nav-item">files</a>
- <a href="" class="nav-item">log</a>
- <a href="" class="nav-item"> patches</a>
- <a href="" class="nav-item">contribute</a>
- </div>
-
- <div class="details-grid">
- <h3>Branch</h3>
- <h3>Commit message</h3>
- <h3>Author</h3>
- <h3 class="details-span">Date</h3>
-
- <a href="">fn-verify-9324832</a>
- <a href="">Updating to actix 2.0.0 and adding 404 handler</a>
- <p>Katharina Fey</p>
- <p class="details-span">5 months ago</p>
-
- <a href="">master</a>
- <a href="">Rebuilding the entire htlm and css styles</a>
- <p>Katharina Fey</p>
- <p class="details-span">18 hours ago</p>
-
- <!-- Switch to last commits -->
- <h3>Commit Hash</h3>
- <h3>Commit message</h3>
- <h3>Author</h3>
- <h3>Date</h3>
- <h3>Lines</h3>
-
- <a href="">270cb70</a>
- <a href="">Rebuilding the entire htlm and css stiles</a>
- <p>Katharina Fey</p>
- <p>19 hours ago</p>
- <p>-214/+75</p>
-
- <a href="">5db4c57</a>
- <a href="">Updating to actix 2.0.0 and adding 404 handler</a>
- <p>Katharina Fey</p>
- <p>2020-01-23</p>
- <p>-610/+455</p>
-
- <a href="">5e16c64</a>
- <a href="">Adding project documentation and roadmap planning</a>
- <p>Katharina Fey</p>
- <p>2020-01-23</p>
- <p>-3/+61</p>
-
- <a href="">8b38bdd</a>
- <a href="">data: adding a small wrapper around libgit2</a>
- <p>Katharina Fey</p>
- <p>2019-12-29</p>
- <p>-36/+32</p>
-
- <a href="">c896fcd</a>
- <a href="">material-ish design with gitea-style tabs</a>
- <p>Milan PƤssler</p>
- <p>2019-12-29</p>
- <p>-102/+169</p>
-
- <a href="">f2f49bb</a>
- <a href="">material-ish design with gitea-style tabs</a>
- <p>Milan PƤssler</p>
- <p>2019-12-29</p>
- <p>-1/+2</p>
-
- <a href="">4be56ee</a>
- <a href="">Adding a small limgit2 example usage</a>
- <p>Katharina Fey</p>
- <p>2019-12-29</p>
- <p>-2/+17</p>
-
- <a href="">81ae20b</a>
- <a href="">Refactoring basic project structure</a>
- <p>Katharina Fey</p>
- <p>2019-12-28</p>
- <p>-76/+209</p>
-
- <a href="">baf496a</a>
- <a href="">initial styling</a>
- <p>Milan PƤssler</p>
- <p>2019-12-13</p>
- <p>-38/+149</p>
-
- <a href="">d43a02e</a>
- <a href="">Adding AGPL-3.0 license</a>
- <p>Katharina Fey</p>
- <p>2019-12-10</p>
- <p>-0/+661</p>
- </div>
- </div>
- </body>
-</html>
+{% extends "base.html" %}
+
+{% block child_content %}
+<table class="details-table">
+ <thead>
+ <tr>
+ <th>Branch</th>
+ <th>Commit message</th>
+ <th>Author</th>
+ <th>Date</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for b in branches %}
+ <tr>
+ <td>{{ b.name }}</td>
+ <td>{{ b.last_commit.message }}</td>
+ <td>{{ b.last_commit.author }}</td>
+ <td>{{ b.last_commit.date }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+
+<table class="details-table">
+ <thead>
+ <tr>
+ <th>Hash</th>
+ <th>Commit message</th>
+ <th>Author</th>
+ <th>Date</th>
+ <th>Lines</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for c in commits %}
+ <tr>
+ <td>{{ c.hash }}</td>
+ <td>{{ c.message }}</td>
+ <td>{{ c.author }}</td>
+ <td>{{ c.date }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+
+
+<div class="details-grid">
+ <h3>Branch</h3>
+ <h3>Commit message</h3>
+ <h3>Author</h3>
+ <h3 class="details-span">Date</h3>
+
+ <a href="">fn-verify-9324832</a>
+ <a href="">Updating to actix 2.0.0 and adding 404 handler</a>
+ <p>Katharina Fey</p>
+ <p class="details-span">5 months ago</p>
+
+ <a href="">master</a>
+ <a href="">Rebuilding the entire htlm and css styles</a>
+ <p>Katharina Fey</p>
+ <p class="details-span">18 hours ago</p>
+
+ <!-- Switch to last commits -->
+ <h3>Commit Hash</h3>
+ <h3>Commit message</h3>
+ <h3>Author</h3>
+ <h3>Date</h3>
+ <h3>Lines</h3>
+
+ <a href="">270cb70</a>
+ <a href="">Rebuilding the entire htlm and css stiles</a>
+ <p>Katharina Fey</p>
+ <p>19 hours ago</p>
+ <p>-214/+75</p>
+
+ <a href="">5db4c57</a>
+ <a href="">Updating to actix 2.0.0 and adding 404 handler</a>
+ <p>Katharina Fey</p>
+ <p>2020-01-23</p>
+ <p>-610/+455</p>
+
+ <a href="">5e16c64</a>
+ <a href="">Adding project documentation and roadmap planning</a>
+ <p>Katharina Fey</p>
+ <p>2020-01-23</p>
+ <p>-3/+61</p>
+
+ <a href="">8b38bdd</a>
+ <a href="">data: adding a small wrapper around libgit2</a>
+ <p>Katharina Fey</p>
+ <p>2019-12-29</p>
+ <p>-36/+32</p>
+
+ <a href="">c896fcd</a>
+ <a href="">material-ish design with gitea-style tabs</a>
+ <p>Milan PƤssler</p>
+ <p>2019-12-29</p>
+ <p>-102/+169</p>
+
+ <a href="">f2f49bb</a>
+ <a href="">material-ish design with gitea-style tabs</a>
+ <p>Milan PƤssler</p>
+ <p>2019-12-29</p>
+ <p>-1/+2</p>
+
+ <a href="">4be56ee</a>
+ <a href="">Adding a small limgit2 example usage</a>
+ <p>Katharina Fey</p>
+ <p>2019-12-29</p>
+ <p>-2/+17</p>
+
+ <a href="">81ae20b</a>
+ <a href="">Refactoring basic project structure</a>
+ <p>Katharina Fey</p>
+ <p>2019-12-28</p>
+ <p>-76/+209</p>
+
+ <a href="">baf496a</a>
+ <a href="">initial styling</a>
+ <p>Milan PƤssler</p>
+ <p>2019-12-13</p>
+ <p>-38/+149</p>
+
+ <a href="">d43a02e</a>
+ <a href="">Adding AGPL-3.0 license</a>
+ <p>Katharina Fey</p>
+ <p>2019-12-10</p>
+ <p>-0/+661</p>
+</div>
+
+{% endblock %}