Skip to content

guilycst/gitmeout

Repository files navigation

gitmeout

CI Release Go Report Card GoDoc License: MIT Go Version

Container Images:

GHCR Forgejo

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.

Features

  • 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

⚠️ Disclaimer

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

Quick Start

1. Create a config file

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}

2. Set environment variables

export GITHUB_TOKEN="ghp_xxx"
export CODEBERG_TOKEN="xxx"

3. Run

# 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

Configuration

Source Configuration

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

Target Configuration

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

Mirror Types

Push Mirrors (mirror_type: push):

  • Clones the repository from GitHub, then pushes --mirror to 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

Environment Variable Interpolation

Use ${VAR_NAME} syntax in config values to reference environment variables:

source:
  token: ${GITHUB_TOKEN}  # Reads from $GITHUB_TOKEN env var

Behavior

Repository Resolution

  1. Personal repos: If personal: true, fetches all repos owned by the authenticated user
  2. Organization repos: For each org in orgs, fetches all repos the user can access
  3. Explicit repos: Resolves each entry in repos:
    • owner/repo-name: Specific repo
    • owner/*: All repos from that owner

Mirror Creation

  • 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

Required Token Permissions

GitHub:

  • repo (for private repos)
  • read:org (if filtering by orgs)

Forgejo/Codeberg:

  • read:user - required to get authenticated user info
  • write:repository - required to create mirror repositories

Deployment

Docker

docker build -t gitmeout:latest .
docker run --rm \
  -e GITHUB_TOKEN \
  -e CODEBERG_TOKEN \
  -v $(pwd)/config.yaml:/app/config.yaml:ro \
  gitmeout:latest

Kubernetes

Create a secret for your config:

kubectl create secret generic gitmeout-config --from-file=config.yaml=config.yaml

Apply the CronJob:

kubectl apply -f deploy/k8s/cronjob.yaml

See deploy/k8s/ for Job and CronJob examples.

Kubernetes Custom Resource

For GitOps workflows, see deploy/k8s/job.yaml for a Job CR that can be used with tools like ArgoCD or Flux.

Development

# Install dependencies
go mod download

# Build
just build

# Run tests
just test

# Lint
just lint

# Format
just fmt

# Run all checks
just validate

License

MIT License - see LICENSE for details.

About

Mirror GitHub repositories to Forgejo/Codeberg instances with push and pull mirror support

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors