YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
โก git-multi-mirror
High-Performance Multi-Platform Git Synchronization Pipeline
๐ Languages / ๋ค๊ตญ์ด / ่จ่ช / ่ฏญ่จ / Idiomas / Langues / Sprachen / ะฏะทัะบะธ
๐ฌ๐ง English โข ๐ฐ๐ท ํ๊ตญ์ด โข ๐ฏ๐ต ๆฅๆฌ่ช โข ๐จ๐ณ ็ฎไฝไธญๆ โข ๐น๐ผ ็น้ซไธญๆ
๐ช๐ธ Espaรฑol โข ๐ซ๐ท Franรงais โข ๐ฉ๐ช Deutsch โข ๐ท๐บ ะ ัััะบะธะน โข ๐ต๐น Portuguรชs
๐ Overview
git-multi-mirror is an ultra-fast, zero-overhead automated Git mirroring pipeline. It designates GitHub as the canonical Single Source of Truth (SSOT), and concurrently broadcasts every commit, branch, and release tag across GitLab, Gitea, and Hugging Face in under 5 seconds.
flowchart LR
Dev["Developer (git push)"] --> GH["GitHub (Canonical SSOT)"]
GH --> GHA["GitHub Actions (Parallel Runners)"]
GHA --> GL["GitLab (Mirror)"]
GHA --> GT["Gitea (Mirror)"]
GHA --> HF["Hugging Face (Mirror)"]
๐ Connected Mirror Endpoints
| Platform | Target Repository | Sync Role | Latency |
|---|---|---|---|
| GitHub | GHSFS/git-multi-mirror |
๐ Canonical Primary (SSOT) | Direct Push |
| GitLab | ghsfs_4c1f7f/git-multi-mirror |
๐ Auto-Synced Mirror | ~5s |
| Gitea | GHSFS/git-multi-mirror |
๐ Auto-Synced Mirror | ~4s |
| Hugging Face | ghsfs-dev/git-multi-mirror |
๐ Auto-Synced Mirror | ~3s |
๐ Quickstart: 2-Step Repository Integration
Deploy this automated mirroring engine to any of your repositories in under 2 minutes:
Step 1: Store Platform Tokens in GitHub Secrets
Navigate to Settings > Secrets and variables > Actions in your GitHub repository and add:
GITLAB_TOKEN: GitLab Personal Access Token (Scope:write_repositoryorapi)GITEA_TOKEN: Gitea Personal Access Token (Scope:write:repository)HF_TOKEN: Hugging Face User Access Token (Scope:write)
Step 2: Commit Workflow File
Save .github/workflows/mirror.yml in your repository. Any subsequent git push or tag release will automatically mirror to all configured targets.
โ๏ธ Complete Workflow Specification (mirror.yml)
mirror.yml)name: Multi-Platform Mirror Sync
on:
push:
branches:
- '**'
tags:
- '**'
workflow_dispatch:
jobs:
mirror-gitlab:
name: Mirror -> GitLab
runs-on: ubuntu-latest
steps:
- name: Checkout Code with Full History
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Push to GitLab
run: |
echo "Syncing repository to GitLab..."
git remote set-head origin -d || true
git push --prune "https://oauth2:${{ secrets.GITLAB_TOKEN }}@gitlab.com/ghsfs_4c1f7f/${{ github.event.repository.name }}.git" "+refs/remotes/origin/*:refs/heads/*" "+refs/tags/*:refs/tags/*"
mirror-gitea:
name: Mirror -> Gitea
runs-on: ubuntu-latest
steps:
- name: Checkout Code with Full History
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Push to Gitea
run: |
echo "Syncing repository to Gitea..."
git remote set-head origin -d || true
git push --prune "https://${{ secrets.GITEA_TOKEN }}@gitea.com/GHSFS/${{ github.event.repository.name }}.git" "+refs/remotes/origin/*:refs/heads/*" "+refs/tags/*:refs/tags/*"
mirror-huggingface:
name: Mirror -> Hugging Face
runs-on: ubuntu-latest
steps:
- name: Checkout Code with Full History
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Push to Hugging Face
run: |
echo "Syncing repository to Hugging Face..."
git remote set-head origin -d || true
git push --prune "https://ghsfs-dev:${{ secrets.HF_TOKEN }}@huggingface.co/ghsfs-dev/${{ github.event.repository.name }}.git" "+refs/remotes/origin/*:refs/heads/*" "+refs/tags/*:refs/tags/*"
๐ Platform Token Generation Guide
| Platform | Navigation Path | Required Scopes | Expiration Policy |
|---|---|---|---|
| GitLab | Preferences > Access Tokens > Add new token |
write_repository, read_repository |
Max 365 Days (SaaS) |
| Gitea | Settings > Applications > Generate New Token |
repository (Read/Write) |
No Expiration |
| Hugging Face | Settings > Access Tokens > Create New Token |
Write (or Fine-grained repo.write) |
No Expiration |
All tokens can be programmatically set via GitHub CLI:
gh secret set <SECRET_NAME> --repo <OWNER>/<REPO> --body "<TOKEN_VALUE>"
๐ก๏ธ Technical Mechanics & Zero-Divergence Invariants
- Origin Refspec Mapping (
+refs/remotes/origin/*:refs/heads/*):- Rather than relying on local branches, the pipeline mirrors directly from GitHub's remote tracking branches.
- Prevents accidental branch deletion errors when triggered on tag checkouts (detached HEAD states).
- Tag Synchronization (
+refs/tags/*:refs/tags/*):- Mirrors all release tags and annotations concurrently with code branches.
- Prune Cleanliness (
--prune):- Automatically removes stale branches deleted on the primary GitHub repository.
- Runner Isolation:
- Each platform is mirrored in an isolated, parallel job so a transient timeout on one service never blocks the others.
โ Frequently Asked Questions (FAQ)
Q: What happens if one platform has an API outage?
A: Because GitLab, Gitea, and Hugging Face run in completely isolated concurrent jobs, a failure in one platform will not affect or stop the synchronization of the other two.
Q: Can I manually trigger a full synchronization?
A: Yes! The workflow includes workflow_dispatch, allowing you to trigger a manual sync directly from the GitHub Actions web UI or via gh workflow run mirror.yml.
Q: Are my tokens visible in build logs?
A: No. GitHub Actions automatically masks all secrets (***) in stdout, stderr, and execution summaries.
๐ License
Released under the MIT License.