[O] Rewrite readme

This commit is contained in:
2026-05-08 05:58:02 +00:00
parent 9a9cbba767
commit d19b061f7c
+23 -92
View File
@@ -1,24 +1,26 @@
# refray
`refray` mirrors repositories between Git hosting providers when you run it. It can run as a one-shot sync command, or as a webhook receiver that triggers one-repo syncs after push events.
A tool to keep ALL of your repos in sync across ALL git platforms, while being able to work from any one of them.
Supported providers:
Created becasue github is so unusable and unreliable and I want to leave, but I don't want to leave the community behind.
- GitHub
- GitLab
- Gitea
- Forgejo
- **∞-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
The program uses provider APIs to list and create repositories, then uses the local `git` CLI to fetch and push branches and tags.
Forgejo uses the same API shape as Gitea.
Supported platforms: GitHub, GitLab, Gitea, Forgejo
## Install
```sh
cargo build --release
```
### Option 1. Install from source
The binary will be at `target/release/refray`.
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.
## Configure
@@ -28,36 +30,7 @@ Run the interactive configuration wizard:
refray config
```
The wizard creates or updates the config file. It asks for profile or organization URLs, reuses existing credentials when it can, asks for a PAT only when needed, then offers webhook setup. Webhooks are strongly recommended because they sync soon after pushes and greatly reduce the chance of divergent histories.
Example wizard flow:
1. Enter `https://github.com/alice`.
2. Paste a PAT if no existing GitHub credential can access that namespace.
3. Enter `https://git.wonder.land/alice`.
4. Pick the provider if the instance cannot be detected.
5. Paste a PAT if needed.
6. Optionally add a third endpoint for 3-way sync.
7. Enable webhooks and enter the public webhook URL.
PAT quick setup:
- GitHub: open `https://github.com/settings/tokens`, create a classic PAT with `repo` permissions, then copy the token.
- GitLab: open `<base-url>/-/user_settings/personal_access_tokens?name=refray&scopes=api,write_repository`, select `api` and `write_repository`, create the token, then copy it.
- Gitea: open `<base-url>/user/settings/applications`, create a token with repository access, then copy it.
- Forgejo: open `<base-url>/user/settings/applications`, create a token with repository access, then copy it.
There are no separate configuration mutation commands. If you do not want to use the wizard, edit the config TOML directly; see the example config below. For self-hosted providers, `base_url` is the web root. API URLs default to:
- GitHub.com: `https://api.github.com`
- GitHub Enterprise: `<base-url>/api/v3`
- GitLab: `<base-url>/api/v4`
- Gitea: `<base-url>/api/v1`
- Forgejo: `<base-url>/api/v1`
Set `api_url` in the TOML if your instance is different.
## Sync
## One-time Sync
Run all configured mirror groups:
@@ -65,6 +38,8 @@ Run all configured mirror groups:
refray sync
```
<details><summary>Sync options</summary>
Run one group:
```sh
@@ -95,38 +70,18 @@ Control repo-level parallelism:
refray sync --jobs 8
```
While jobs run, the bottom of the terminal shows one live status line per worker. When a repository finishes, its detailed log is printed as one complete block above those status lines. The default is 4 workers; use `--jobs 1` for serial sync.
</details>
`refray` stores a small ref cache in the work directory. On later runs it first checks each repository with `git ls-remote --heads --tags`; when all endpoints report the same refs as the last successful sync, or the existing local bare mirror cache already has those refs, it skips the full fetch/push pass for that repository.
## Service & Webhooks
Use cron or another scheduler for automatic execution:
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`.
```cron
*/15 * * * * GITHUB_TOKEN=... GITEA_TOKEN=... /path/to/refray sync
```
## Webhooks
Webhook mode reduces the window for divergent commits by syncing a repository immediately after a provider sends a push event. It is still conservative: if two endpoints receive independent commits before webhook sync catches up, the normal divergence rules still apply.
The interactive wizard can configure webhooks for you. During setup it starts a temporary test listener on `127.0.0.1:8787`, asks for the public URL, checks that the URL is reachable from the current machine, creates a webhook secret, and can enable periodic full syncs while `refray serve` is running.
Example config:
```toml
[webhook]
install = true
url = "https://mirror.example.com/webhook"
secret = { value = "generated-secret" }
full_sync_interval_minutes = 60
reachability_check_interval_minutes = 15
```
If you want to use webhooks, you need to expose port 8787 to a public URL that can be accessed by the git provider (e.g. using port forwarding, reverse proxy, or cloudflare tunnel).
Start the receiver:
```sh
refray serve \
--listen 127.0.0.1:8787
refray serve
```
Expose that listener with your reverse proxy or tunnel, then install repository webhooks. If `[webhook]` is configured, the URL and secret can come from config:
@@ -135,20 +90,6 @@ Expose that listener with your reverse proxy or tunnel, then install repository
refray webhook install
```
Manual `webhook install` always checks the selected repositories on the provider and repairs or records the hook state. To install or repair one repository exactly:
```sh
refray webhook install important-repo
```
You can also pass them explicitly:
```sh
refray webhook install \
--url https://mirror.example.com/webhook \
--secret-env REFRAY_WEBHOOK_SECRET
```
Useful install filters:
```sh
@@ -255,14 +196,4 @@ namespace = "azalea"
## Issues and Pull Requests
Mirroring issues and pull requests is possible, but it is not the same kind of operation as mirroring Git branches.
Repository Git data has a shared protocol and object model. Issues and pull requests are provider-specific application data. GitHub, GitLab, and Gitea have different fields, permissions, labels, milestones, users, review states, CI metadata, cross-links, attachments, reactions, and webhook/event histories.
A practical implementation should be designed as a separate feature with explicit tradeoffs:
- **Issues:** feasible to copy title, body, state, labels, assignees by mapping usernames, milestones, and labels. Comments can be copied, but original authors and timestamps usually need to be represented in the comment body unless the target API supports impersonation.
- **Pull requests / merge requests:** feasible to copy open PR metadata and comments, but the source and target branches must already exist on the target. Review approvals, check statuses, merge queues, and provider-specific refs do not map cleanly.
- **Bidirectional sync:** much harder than one-time migration. You need durable external IDs, per-provider mapping tables, conflict policy for edits on both sides, deletion/close policy, and rate-limit handling.
Recommended path: keep Git mirroring in this tool's core sync loop, then add an optional `sync-issues` feature with a local state database and provider-specific mappers. Start with one-way issue copy, then add comments, then consider bidirectional updates only after identity and conflict rules are explicit.
Issues and pull requests are not mirrored.