| .github/workflows | ||
| src | ||
| .envrc | ||
| .gitignore | ||
| .lohr | ||
| .pre-commit-config.yaml | ||
| Cargo.lock | ||
| Cargo.toml | ||
| default.nix | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE-APACHE | ||
| LICENSE-MIT | ||
| README.org | ||
| rust-toolchain | ||
| shell.nix | ||
lohr
lohr is a Git mirroring tool.
I created it to solve a simple problem I had: I host my own git server at https://git.alarsyo.net, but want to mirror my public projects to GitHub / GitLab, for backup and visibility purposes.
GitLab has a mirroring setting, but it doesn't allow for multiple mirrors, as far as I know. I also wanted my instance to be the single source of truth.
How it works
Gitea is setup to send webhooks to my lohr server on every push update. When
lohr receives a push, it clones the concerned repository, or updates it if
already cloned. Then it pushes the update to all remotes listed in the .lohr
file at the repo root.
Destructive
This is a very destructive process: anything removed from the single source of truth is effectively removed from any mirror as well.
Setup
Quickstart
Setting up lohr should be quite simple:
- Create a
Rocket.tomlfile and add your configuration. -
Run
lohr:$ cargo run # or `cargo run --release` for production usage - Configure your favorite git server to send a webhook to
lohr's address on every push event. I used Gitea's webhooks format, but I think they're similar to GitHub and GitLab's webhooks, so these should work too! (If they don't, please file an issue!) -
Add a
.lohrfile containing the remotes you want to mirror this repo to:git@github.com:you/your_repo
and push it. That's it!
lohris mirroring your repo now.
Configuration
Home directory
lohr needs a place to clone repos and store its data. By default, it's the
current directory, but you can set the LOHR_HOME environment variable to
customize it.
Extra remote configuration
lohr looks for a lohr-config.yaml file in its LOHR_HOME directory. This
file takes the following format:
default_remotes:
- "git@github:user"
- "git@gitlab:user"
additional_remotes:
- "git@git.sr.ht:~user"
default_remotesis a list of remotes to use if no.lohrfile is found in a repository.additional_remotesis a list of remotes to add in any case, whether the original set of remotes is set viadefault_remotesor via a.lohrfile.
Both settings take as input a list of "stems", i.e. incomplete remote addresses,
to which the repo's name will be appended (so for example, if my
default_remotes contains git@github.com:alarsyo, and a push event webhook
is received for repository git@gitlab.com:some/long/path/repo_name, then the
mirror destination will be git@github.com:alarsyo/repo_name.
Contributing
I accept patches anywhere! Feel free to open a GitHub Pull Request, a GitLab Merge Request, or send me a patch by email!
Why lohr?
I was looking for a cool name, and thought about the Magic Mirror in Snow White. Some furious wikipedia searching later, I found that the Magic Mirror was probably inspired by the Talking Mirror in Lohr am Main. That's it, that's the story.
License
lohr is distributed under the terms of both the MIT license and the Apache
License (Version 2.0).
See LICENSE-APACHE and LICENSE-MIT for details.