Container Images:
Mirror GitHub repositories to Forgejo/Codeberg instances
A fast, reliable CLI tool for mirroring repositories from GitHub to Forgejo/Codeberg. Supports both push and pull mirror modes, with flexible filtering and container-ready deployment.
- GitHub as source - Mirror personal and organization repositories
- Forgejo/Codeberg as targets - Create mirror repos on any Forgejo instance
- Flexible filtering - Filter by personal repos, orgs, or explicit repo list
- Wildcard support - Use
owner/*to mirror all repos from an owner - Dual mirror types - Push mirrors (clone + push) or pull mirrors (Forgejo MigrateRepo API)
- Token-only auth - Secure authentication via Personal Access Tokens
- Container-ready - Docker image and Kubernetes manifests included
- Multiarch support - Linux amd64/arm64 binaries and Docker images
Use this tool responsibly and only for repositories you own or have permission to mirror.
- Personal Use: This tool is designed for mirroring your own repositories or repositories you have explicit permission to mirror.
- GitHub ToS: Ensure your usage complies with GitHub's Terms of Service, including API rate limits and acceptable use policies.
- Rate Limits: GitHub's API has rate limits (5,000 authenticated requests/hour). Be mindful when mirroring large numbers of repositories.
- Data Portability: GitHub's ToS supports user data portability for your own content.
- No Warranty: This software is provided "as is" without warranty of any kind. The authors are not responsible for any issues arising from its use.
By using this tool, you agree to:
- Only mirror repositories you own or have permission to mirror
- Comply with GitHub's API Terms of Service
- Respect rate limits and not abuse the API
- Use it for legitimate data portability purposes
source:
type: github
token: ${GITHUB_TOKEN}
filters:
personal: true
orgs:
- my-org
repos:
- owner/repo1
- owner/*
targets:
- name: codeberg
type: forgejo
url: https://codeberg.org
token: ${CODEBERG_TOKEN}export GITHUB_TOKEN="ghp_xxx"
export CODEBERG_TOKEN="xxx"# Using Just
just run
# Or directly
go run ./cmd/gitmeout
# Or with Docker
docker run --rm \
-e GITHUB_TOKEN \
-e CODEBERG_TOKEN \
-v $(pwd)/config.yaml:/app/config.yaml:ro \
ghcr.io/guilycst/gitmeout:latest| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | Provider type. Currently only github |
token |
string | Yes | GitHub Personal Access Token. Use ${VAR} for env vars |
filters.personal |
bool | No | Mirror personal repos. Default: true |
filters.orgs |
[]string | No | List of organization names to mirror |
filters.repos |
[]string | No | Explicit repo list. Use owner/* for all repos from an owner |
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Friendly name for logging |
type |
string | Yes | Provider type. Currently only forgejo |
url |
string | Yes | Base URL of the Forgejo instance |
token |
string | Yes | Forgejo Personal Access Token. Use ${VAR} for env vars |
mirror_type |
string | No | push (default) or pull - see Mirror Types below |
Push Mirrors (mirror_type: push):
- Clones the repository from GitHub, then pushes
--mirrorto the target - Syncs every run - changes on source are pushed to target
- Use for: Codeberg (pull mirrors disabled by admin)
Pull Mirrors (mirror_type: pull):
- Uses Forgejo's MigrateRepo API to create a pull mirror
- Forgejo periodically fetches changes from the source automatically
- Use for: Self-hosted Forgejo instances where pull mirrors are enabled
- Skips if a mirror already exists
Use ${VAR_NAME} syntax in config values to reference environment variables:
source:
token: ${GITHUB_TOKEN} # Reads from $GITHUB_TOKEN env var- Personal repos: If
personal: true, fetches all repos owned by the authenticated user - Organization repos: For each org in
orgs, fetches all repos the user can access - Explicit repos: Resolves each entry in
repos:owner/repo-name: Specific repoowner/*: All repos from that owner
- Existing mirrors: If a mirror repo already exists on the target, it is skipped
- New mirrors: Creates a new mirror repo pointing to the source
GitHub:
repo(for private repos)read:org(if filtering by orgs)
Forgejo/Codeberg:
read:user- required to get authenticated user infowrite:repository- required to create mirror repositories
docker build -t gitmeout:latest .
docker run --rm \
-e GITHUB_TOKEN \
-e CODEBERG_TOKEN \
-v $(pwd)/config.yaml:/app/config.yaml:ro \
gitmeout:latestCreate a secret for your config:
kubectl create secret generic gitmeout-config --from-file=config.yaml=config.yamlApply the CronJob:
kubectl apply -f deploy/k8s/cronjob.yamlSee deploy/k8s/ for Job and CronJob examples.
For GitOps workflows, see deploy/k8s/job.yaml for a Job CR that can be used with tools like ArgoCD or Flux.
# Install dependencies
go mod download
# Build
just build
# Run tests
just test
# Lint
just lint
# Format
just fmt
# Run all checks
just validateMIT License - see LICENSE for details.