Skip to content
LatchkeyLatchkey home

ghorg clone: Clone or Mirror a Whole Org

ghorg clone clones or pulls every repository in an organization or group in parallel.

For backups, org-wide scans, or bulk analysis, ghorg clone fetches all repos of a GitHub org or GitLab group at once, updating existing clones on re-run.

What it does

ghorg clone iterates the repositories of an org (GitHub) or group (GitLab), cloning missing ones and pulling existing ones in parallel. --backup makes bare mirror clones suitable for archival. It supports GitHub, GitLab, Bitbucket, and Gitea via --scm-type.

Common usage

Terminal
# clone all repos in a GitHub org with a token
ghorg clone my-org --token "$GH_PAT"
# GitLab group, bare backup mirror
ghorg clone my-group --scm-type gitlab --base-url https://gitlab.example.com \
  --token "$GLAB_PAT" --backup

Options

FlagWhat it does
--token <token>API token (or set GHORG_GITHUB_TOKEN etc.)
--scm-type <scm>github, gitlab, bitbucket, or gitea
--base-url <url>API base URL for self-hosted instances
--clone-type <t>org or user
--backupBare mirror clone for archival
--concurrency <n>Number of parallel clones
--clone-protocol <p>https or ssh

In CI

Set the token via --token or the GHORG_*_TOKEN env var so it never prompts. Lower --concurrency if you hit rate limits. For self-hosted GitLab/Gitea always pass --base-url. Use --clone-protocol https with a token in CI rather than relying on SSH keys.

Common errors in CI

"Error: no GitHub token provided" (or the equivalent per SCM) means --token/env is unset. "403 API rate limit exceeded" means too many parallel requests; reduce --concurrency or use a token with higher limits. "404 Not Found" on a private org means the token lacks read scope. A wrong --base-url yields "no such host".

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Frequently asked questions

ghorg clone: Clone or Mirror a Whole Org?
For backups, org-wide scans, or bulk analysis, ghorg clone fetches all repos of a GitHub org or GitLab group at once, updating existing clones on re-run.
What it does?
ghorg clone iterates the repositories of an org (GitHub) or group (GitLab), cloning missing ones and pulling existing ones in parallel. --backup makes bare mirror clones suitable for archival. It supports GitHub, GitLab, Bitbucket, and Gitea via --scm-type.
In CI?
Set the token via --token or the GHORG_*_TOKEN env var so it never prompts. Lower --concurrency if you hit rate limits. For self-hosted GitLab/Gitea always pass --base-url. Use --clone-protocol https with a token in CI rather than relying on SSH keys.
Common errors in CI?
"Error: no GitHub token provided" (or the equivalent per SCM) means --token/env is unset. "403 API rate limit exceeded" means too many parallel requests; reduce --concurrency or use a token with higher limits. "404 Not Found" on a private org means the token lacks read scope. A wrong --base-url yields "no such host".

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card