mygit

[UNMAINTAINED] A cgit/webgit alternative, written in Rust
Log | Files | Refs | README | LICENSE

commit 15d4a68990ae874ecbe4c48a46e9b39c23fa5392
parent 06c01109b573c98c83eac2b2383038db6add264a
Author: Johann150 <johann@qwertqwefsday.eu>
Date:   Mon, 19 Jul 2021 17:18:27 +0200

Merge https://git.alexwennerberg.com/mygit into main

Diffstat:
MCargo.toml | 2+-
MREADME.md | 30+++++++++++++-----------------
Msrc/errorpage.rs | 7++++++-
Msrc/main.rs | 4++--
Mtemplates/static/style.css | 13++++++++-----
5 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml @@ -3,7 +3,7 @@ name = "mygit" version = "0.1.0" authors = ["alex wennerberg <alex@alexwennerberg.com>"] edition = "2018" -license = "MIT" +license = "AGPL-3.0-or-later" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md @@ -1,9 +1,9 @@ # mygit -A small self-hosted git project hub +Simple self-hosted git server, written in Rust -Making self-hosting email-based git workflows simple and easy (WIP -- no email support yet, git support incomplete) +Lighter weight than [gitea](https://gitea.io/en-us/), more modern than [cgit](https://git.zx2c4.com/cgit/) or [gitweb](https://git-scm.com/book/en/v2/Git-on-the-Server-GitWeb). For people who want to run a git server themselves, rather than depending on someone else, but don't want to put too much work into it. -Live demo at https://git.alexwennerberg.com +Live demo at [https://git.alexwennerberg.com](https://git.alexwennerberg.com) ## Deploying Build your binary with `cargo build --release`. Then probably move it somewhere sensible so it's in your $PATH or use `cargo install --release`. Packages and prebuilt binaries are TBD. @@ -11,10 +11,9 @@ Build your binary with `cargo build --release`. Then probably move it somewhere Probably you want to use your linux distro's init system to keep this server running. ## Setting up your repos +Acquire a Linux server that you have ssh access to, and decide on the best place to place your repos. You can also do this locally to experiment with it. -Acquire a Linux server that you have ssh access to, and decide on the best place to place your repos. - -To initialize a repo, you'll need to run a few commands. I'm using a self-hosted instance of the mygit repo as an example. Find a directory where you want to host your repositories. This is using the default settings found in mygit.toml +To initialize a repo, you'll need to run a few commands. I'm using a self-hosted instance of the mygit repo as an example. Find a directory where you want to host your repositories. This is using the default settings found in `mygit.toml` ``` git init --bare mygit cd mygit @@ -27,26 +26,23 @@ Update the `description` file with a description of the repository Make sure the HEAD in your remote repo points to your default branch (e.g. master vs main) Pushing your changes is not handled via mygit -- this will be done over ssh. For example: - ``` git remote add origin ssh://git@git.alexwennerberg.com:/www/git/mygit git push -u origin main ``` -You'll want to modify these commands to push to your mygit server and somewhere else (e.g. a GitHub mirror). This is left as an exercise to the reader. - -## Background -Many people want to self-host Git in order to get rid of their reliance on GitHub or other institutions. However, the options for doing this are problematic in a number of ways. There are ancient CGI programs written in C or Perl like gitolite, cgit and webgit, and there are modern programs like gitea or gitlab that are essentially GitHub clones, with a lot of unnecessary complexity for many people's use cases. +Set up a reverse proxy on an http server which forwards port 8081 (or whatever port you configure) to your mygit server. -I really like [stagit](https://codemadness.org/stagit.html), but it's a bit too austere for my use case and very "suckless" philosophy: e.g. doesn't support markdown READMEs. I also really like [sourcehut](https://git.sr.ht/) but it is pretty complex to self-host a single-user instance. +## Why self-host? +Self-hosting provides self-reliance and independence from large platforms that using a git hosting platform does not. There are inconvenciences and disadvantages to self-hosting, but I think there are also advantages as well of a decentralized, self-hosted network of collaboration. Mygit is designed primraily for hobbyists or open source hosts, so it's easy to setup and maintain with little effort, rather than an unnecessarily piece of software like GitLab. The tradeoff is that you lose out on a lot of features. Self-hosting git isn't for everyone! -The simplest way to accept patches when hosting a Git repo in this manner is through [git-send-email](https://git-scm.com/docs/git-send-email). You can accept patches either to your personal email or use a mailing list. This is a somewhat archaic way of doing things, and definitely has some disadvantages, but it is the simplest way to accept patches when self-hosting Git. A single-user [Gitea](https://gitea.io/en-us/) instance, for example, requires that users register and you manage their user accounts. With git-send-email, users can contribute to your project without having to create another account. This may not be the easiest or most accessible way to handle your project (unquestionably, that would be just using GitHub) but IMO it's the best way to do things if you want a simple self-hosted solution. Unfortunately, not many people are familiar with git-send-email anymore (and self-hosting dramatically hurts your project discovery), so probably it only makes sense to do this if you're an ideological purist of some sort, or just want to try self-hosting some small, low-stakes projects for fun. +## Accepting patches +The simplest way to accept patches when self-hosting Git is through [git-send-email](https://git-scm.com/docs/git-send-email) ([guide](https://git-send-email.io/)). You can accept patches either to your personal email or use a mailing list. Basically only obsessive ideologues like myself still use git-send-email these days, so you will probably lose contributers, and not being on GitHub means you lose a lot of discoverability, so make sure that you're willing to accept that when self-hosting git. You can mitigate these issues by mirroring to GitHub, but that kind of defeats the purpose of self-hosting. -I am working on a sibling project to this that handles mailing list archives for exactly this purpose: -https://git.sr.ht/~aw/rusty-inbox - -I'm still deciding if I want that project merged into this one. I am considering it to simplify deployment and provide an all-in-one easy to deploy solution +I am working on a sibling project to this that handles mailing list archives for exactly this purpose, but it is not ready for the public yet. ## Contributing * [ticket tracker](https://todo.sr.ht/~aw/mygit) * [patches](https://lists.sr.ht/~aw/patches) + +This exists on GitHub solely for visibility sake, and probably won't forever, but while it's here feel free to use GitHub issues, etc. This is alpha software, please report any bugs, etc! diff --git a/src/errorpage.rs b/src/errorpage.rs @@ -25,10 +25,15 @@ impl<State: Clone + Send + Sync + 'static> Middleware<State> for ErrorToErrorpag // - RFC 7231 ยง 4.3.2 response.take_body(); } else { + let message = match status { + // don't expose 500 error + StatusCode::InternalServerError => "Internal Server Error".to_owned(), + _ => err.into_inner().to_string(), + }; response = ErrorTemplate { resource, status, - message: err.into_inner().to_string(), + message: message } .into(); response.set_status(status); diff --git a/src/main.rs b/src/main.rs @@ -174,7 +174,7 @@ fn repo_from_request(repo_name: &str) -> Result<Repository, tide::Error> { .decode_utf8_lossy() .into_owned(); - let repo_path = Path::new(&CONFIG.projectroot).join(repo_name); + let repo_path = Path::new(&CONFIG.projectroot).join(repo_name).canonicalize()?; // prevent path traversal if !repo_path.starts_with(&CONFIG.projectroot) { @@ -795,7 +795,7 @@ async fn git_data(req: Request<()>) -> tide::Result { .path() .strip_prefix(&format!("/{}/", req.param("repo_name").unwrap())) .unwrap_or_default(); - let path = repo.path().join(path); + let path = repo.path().join(path).canonicalize()?; if !path.starts_with(repo.path()) { // that path got us outside of the repository structure somehow diff --git a/templates/static/style.css b/templates/static/style.css @@ -134,7 +134,10 @@ Light is the default color scheme, not using a media query for browser support. color: #445050; /* SolAArized emphasis-light */ } -body, .code, .keyword.operator.comparison, .keyword.operator.assignment, .keyword.operator.arithmetic, .meta.brace.round, .meta.brace.curly, .punctuation.section, .punctuation.section.block, .punctuation.definition.parameters, .punctuation.section.group, .meta.selector.css, .text.html.basic, .meta.tag.other.html, .text.html.basic, .meta.tag.any.html, .text.html.basic, .meta.tag.block.any, .text.html.basic, .meta.tag.inline.any, .text.html.basic, .meta.tag.structure.any.html, .text.html.basic, .source.js.embedded.html, .punctuation.separator.key-value.html, .variable.other.readwrite.js, .variable.other.object.js, .variable.other.constant.js, .punctuation.definition.string { +body { + color: black; +} +.code, .keyword.operator.comparison, .keyword.operator.assignment, .keyword.operator.arithmetic, .meta.brace.round, .meta.brace.curly, .punctuation.section, .punctuation.section.block, .punctuation.definition.parameters, .punctuation.section.group, .meta.selector.css, .text.html.basic, .meta.tag.other.html, .text.html.basic, .meta.tag.any.html, .text.html.basic, .meta.tag.block.any, .text.html.basic, .meta.tag.inline.any, .text.html.basic, .meta.tag.structure.any.html, .text.html.basic, .source.js.embedded.html, .punctuation.separator.key-value.html, .variable.other.readwrite.js, .variable.other.object.js, .variable.other.constant.js, .punctuation.definition.string { color: #4f5f5f; /* SolAArized main-light */ } @@ -147,11 +150,11 @@ hr.thin { } :target, tr:hover, .navbar, .meta.paragraph.markdown, .meta.dummy.line-break, #diff { - background-color: #eee8d5; /* SolAArized background-highlight-light */ + background-color: white; /* SolAArized background-highlight-light */ } body, .code { - background-color: #fdf6e3; /* SolAArized background-light */ + background-color: white; /* SolAArized background-light */ } .variable.function, .keyword.control.class, .entity.name, .entity.name.class, .entity.name.type.class, .entity.other.attribute-name, .entity.name.function, .constant, .constant.language, .meta.preprocessor, .support.constant.color, .invalid.deprecated.color.w3c-non-standard-color-name.scss, .entity.name.tag.css, .entity.name.tag.scss, .source.less, .keyword.control.html.elements, .source.sass, .keyword.control.untitled, .entity.other.attribute-name.class, .entity.other.attribute-name.id, .text.html.basic, .entity.other.attribute-name.html, .meta.tag.xml, .entity.other.attribute-name, .variable.other.constant.ruby, .meta.array, .support.function.construct.php, .meta.group.braces.tex, .string.other.math.tex, .string.other.math.tex, .support.type.exception.python, .markup.heading, .punctuation.definition.heading.markdown, .markup.changed.git_gutter { @@ -215,11 +218,11 @@ a, .variable, .entity.other.inherited-class, .entity.name.tag, .storage.type, .m } :target, tr:hover, .navbar, .meta.paragraph.markdown, .meta.dummy.line-break, #diff { - background-color: #003a44; /* SolAArized background-highdark-dark */ + background-color: black; /* SolAArized background-highdark-dark */ } body, .code { - background-color: #002b36; /* SolAArized background-dark */ + background-color: black; /* SolAArized background-dark */ } .variable.function, .keyword.control.class, .entity.name, .entity.name.class, .entity.name.type.class, .entity.other.attribute-name, .entity.name.function, .constant, .constant.language, .meta.preprocessor, .support.constant.color, .invalid.deprecated.color.w3c-non-standard-color-name.scss, .entity.name.tag.css, .entity.name.tag.scss, .source.less, .keyword.control.html.elements, .source.sass, .keyword.control.untitled, .entity.other.attribute-name.class, .entity.other.attribute-name.id, .text.html.basic, .entity.other.attribute-name.html, .meta.tag.xml, .entity.other.attribute-name, .variable.other.constant.ruby, .meta.array, .support.function.construct.php, .meta.group.braces.tex, .string.other.math.tex, .string.other.math.tex, .support.type.exception.python, .markup.heading, .punctuation.definition.heading.markdown, .markup.changed.git_gutter {