Skip to content

Mirror a GitHub repository

A mirror is a read-only copy of a repository that syncs from its source on a schedule. Code, branches, and tags stay up to date. If the source goes offline, the mirror keeps serving.

This is not the same as a one-time import. An import creates an independent repo and cuts ties to the source. A mirror stays connected and pulls changes automatically. Use a mirror when you want a live copy; use an import when you are moving permanently.

There are two ways to create a mirror: the GitHub App (recommended) or a personal access token.

No token to manage. Codebahn mints a short-lived, repo-scoped token on each sync. Nothing is stored except the installation ID, which is not a secret.

  1. Sign in to Codebahn
  2. Click + > Import repository > GitHub
  3. On the Connect GitHub tab, click Connect GitHub account
  4. Authorize the Codebahn app on GitHub. If this is your first time, install it on your account or organization and grant access to the repos you want to mirror
  5. Check This repository will be a mirror. Metadata checkboxes (issues, PRs, etc.) are disabled because mirrors are git-only
  6. Select the repos to mirror
  7. Choose an owner and click Import selected

The 30-minute connection window applies to the initial setup only. Once the mirror is created, syncs run unattended.

If you cannot install the GitHub App (e.g. an account where you lack admin rights), use a token instead.

  1. Create a fine-grained personal access token with Contents: Read-only. Set a long expiration (90 days or the maximum your org allows). If the token expires, syncs stop until you update it in mirror settings
  2. Click + > Import repository > GitHub
  3. Switch to the Personal access token tab
  4. Paste the HTTPS clone URL, e.g. https://github.com/your-org/your-repo.git
  5. Paste the token in the Access token field
  6. Check This repository will be a mirror
  7. Choose an owner and confirm the repo name
  8. Click Migrate repository

You can convert a token mirror to the GitHub App later from the mirror’s settings page, which removes the stored token.

Mirrors pull all Git refs: branches, tags, and commits. Every sync is a full git remote update.

Mirrors are git-only. Issues, pull requests, labels, milestones, and releases are not imported, even if those options appear in the form. If you need issue history alongside the mirror, do a one-time import first, then delete it and create the mirror into the same name.

The default sync interval is eight hours. You can change it per repo:

  1. Go to Settings > Repository on the mirror repo
  2. Under Mirror Settings, set the interval (minimum ten minutes)
  3. Click Save

A shorter interval means fresher data but more traffic to GitHub. For active repos where you want near-real-time redundancy, 15 to 30 minutes works well.

You can also click Synchronize Now on the mirror settings page to trigger an immediate sync.

You can convert a token-based mirror to the GitHub App without deleting and re-importing. Stars, forks, webhooks, and the repo URL are preserved.

  1. Go to Settings > Repository on the mirror repo
  2. Under Mirror Settings, click Connect GitHub App
  3. Complete the GitHub authorization flow
  4. The stored token is removed. Future syncs mint short-lived tokens automatically

If you uninstall the Codebahn app from GitHub or change its repository access, syncs fail with a notice. To fix it:

  1. Reinstall the app on GitHub (or update its repository access)
  2. Go to Settings > Repository on the mirror repo
  3. Click Reconnect GitHub App
  4. Authorize on GitHub

A mirror repo looks and works like any other Codebahn repo for reading: browse code, view commit history, compare branches, download archives. CI workflows do not run on mirror repos.

The one difference: you cannot push to a mirror. Git operations are read-only. If you clone the mirror locally and try to push, you get a rejection.

When GitHub is unreachable, mirror syncs fail and retry on the next interval. The mirror keeps serving whatever it had at the last successful sync.

If you need to push (because GitHub is down and work cannot wait), convert the mirror to a regular repository:

  1. Go to Settings > Repository on the mirror repo
  2. Scroll to Danger Zone
  3. Click Convert to regular repository
  4. Confirm

This removes the mirror link and makes the repo writable. You can push, open pull requests, and run CI. Your .github/workflows/ files run on Codebahn’s runners without changes. See CI workflows for what works and what to watch for.

When GitHub comes back online, you will have commits on Codebahn that GitHub does not have. To reconcile:

Terminal window
# Add both remotes
git remote add codebahn git@codebahn.net:your-org/your-repo.git
git remote add github git@github.com:your-org/your-repo.git
# Pull from Codebahn (where you pushed during the outage)
git pull codebahn main
# Push to GitHub
git push github main

If both sides have new commits (someone pushed to GitHub after it recovered, before you reconciled), you will need to merge or rebase as with any diverged branch.

To mirror many repos at once, use the migration API with a personal access token:

Terminal window
# For each repo, POST to the migration endpoint
curl -X POST "https://codebahn.net/api/v1/repos/migrate" \
-H "Authorization: token YOUR_CODEBAHN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clone_addr": "https://github.com/your-org/repo-name.git",
"auth_token": "YOUR_GITHUB_TOKEN",
"repo_name": "repo-name",
"repo_owner": "your-codebahn-org",
"service": "github",
"mirror": true
}'

Repeat for each repository. The Codebahn CLI does not yet have a bulk mirror command, but the API call above can be scripted.

The GitHub App flow does not support the migration API. For scripted bulk mirrors, use a token.

  • Issues and PRs are not included. Mirrors import git refs only. No issues, PRs, labels, milestones, or releases.
  • Wiki is not mirrored. Codebahn does not enable wikis.
  • LFS objects sync if configured. Set the LFS endpoint in mirror settings if the source repo uses Git LFS.
  • Token mirrors: the token must stay valid. If it expires or is revoked, syncs fail. Update the token in Settings > Repository > Mirror Settings. Consider converting to the GitHub App to avoid token rotation entirely.
  • GitHub App mirrors: the app must stay installed. If you uninstall the Codebahn app from GitHub, syncs fail. Reinstall the app and click Reconnect in mirror settings.
  • CI does not run on mirror repos. Convert to a regular repo first. After conversion, .github/workflows/ files run on Codebahn’s runners.