refray logo

# refray A tool to keep your repos in sync across all git platforms, while being able to work from everywhere all at once. Created becasue github is so unusable and [unreliable](https://red-squares.cian.lol/) and I want to leave, but I don't want to leave the community behind. - **∞-side sync**: Sync between any number of hosted/self-hosted git accounts/orgs/groups - **read-write mirrors**: Make changes from any provider, and the changes will sync to the others - **webhook support**: Sync right after push, reduce potential divergence window - **conflict handling**: Rebase or open pull requests when two platforms diverge - **tracks deletions**: Branches/repo deletions sync across platforms (with backup) - **selective sync**: Sync subset of repos by regex white/black list, or by private/public visibility - **multithreaded**: Process multiple repos simultaneously! Supported platforms: GitHub, GitLab, Gitea, Forgejo > [!NOTE] > My cat made this codebase, meow ![demo](./docs/demo.webp) ## Install ### Option 1. Install with Cargo 1. Install rust cargo if you don't have it: https://rustup.rs 2. `cargo install refray` ### Option 2. Download binary Go to the [releases page](https://github.com/MaigoLabs/refray/releases), find the latest release, and download the appropriate binary for your platform. ### Option 3. Docker Compose ```sh docker compose run --rm refray config # Start the webhook receiver as a service docker compose up -d --build # If you want to edit config manually: docker compose run --rm --entrypoint nano refray /data/config/refray/config.toml ``` ## Usage ### 1. Configure Run the interactive configuration wizard: ```sh refray config ```
Example Config ```toml jobs = 8 [[sites]] name = "github" provider = "github" base_url = "https://github.com" token = { value = "github_pat_..." } [[sites]] name = "gitea" provider = "gitea" base_url = "https://gitea.example.com" token = { value = "gitea_pat_..." } [[mirrors]] name = "personal" sync_visibility = "all" repo_whitelist = "^important-" repo_blacklist = "-archive$" create_missing = true visibility = "private" conflict_resolution = "auto_rebase_pull_request" [[mirrors.endpoints]] site = "github" kind = "user" namespace = "hykilpikonna" [[mirrors.endpoints]] site = "gitea" kind = "user" namespace = "azalea" ```
### 2. One-time Sync Run all configured mirror groups: ```sh refray sync ```
Sync options Run one group: ```sh refray sync --group personal ``` Preview commands without writing to Git remotes: ```sh refray sync --dry-run ``` Skip repository creation even when `create_missing = true` in the mirror group: ```sh refray sync --no-create ``` To restrict which repositories sync, set `repo_whitelist` and/or `repo_blacklist` on the mirror group in config. Retry only repositories that failed during the previous non-dry-run sync: ```sh refray sync --retry-failed ``` Control parallelism for sync, serve, and webhook commands in config. The default is 10 workers: ```toml jobs = 8 ```
### 3. Service & Webhooks You can run `refray` as a service that listens for webhook events and runs full sync periodically. This is the recommended way to run `refray`. > [!NOTE] > If you want to use webhooks, you need to expose port 8787 to a public URL that can be accessed by the git provider.
> This can be done using e.g. port forwarding, reverse proxy, cloudflare tunnel, or tailscale funnel. Start the service (to sync on push and also do full sync periodically): ```sh refray serve ``` Install webhooks on all repos (with the URL in config): ```sh refray webhook install ``` To uninstall webhooks previously installed by `refray`: > [!WARNING] > If you want to stop using `refray`, make sure you run this! Otherwise, all of your repos will keep trying to send webhooks to the URL. ```sh refray webhook uninstall ``` By default, uninstall uses `[webhook].url` from your config. To remove hooks for a previous URL, pass it explicitly: ```sh refray webhook uninstall https://old.example.com/webhook ``` To move installed hooks to a new public URL, use `webhook update`. It removes hooks matching the current configured `[webhook].url`, installs the new URL, updates `[webhook].url` in the config, and refreshes local webhook state: ```sh refray webhook update https://new.example.com/webhook ``` ## Issues and Pull Requests Issues and pull requests are not mirrored.