- mirror a repository from GitHub, GitLab, Bitbucket, Gitea, Forgejo, Codeberg, or SourceHut
- push to Code Storage and have those writes forwarded to the upstream provider
- keep using Code Storage APIs, JWT-backed remotes, ephemeral branches, and webhooks on the mirrored repo
Sync modes
Code Storage currently supports three Git Sync modes:| Mode | Best for | Authentication |
|---|---|---|
| GitHub App | Private GitHub repositories and webhook-driven sync | GitHub App installation token |
| Public GitHub | Public GitHub repositories you want to pull from without credentials | No GitHub credentials |
| Generic HTTPS Git | GitLab, Bitbucket, Gitea, Forgejo, Codeberg, SourceHut, and similar hosts | Stored username/password or token |
GitHub App sync
GitHub has the most direct SDK flow today. Create the repository with a GitHub base, then callpullUpstream() whenever you want to force a refresh.
- when you create a repo with
baseRepo, Code Storage links it to the specified GitHub repository pullUpstream()fetches the latest changes from GitHub- you can then use all SDK features (diffs, commits, file access) on the synced content
- the provider is automatically set to
"github"when usingbaseRepowithownerandname
409 Conflict:
Public GitHub mode
If the upstream repository is public, you can skip GitHub App auth and create a synced repository in public mode.- does not subscribe to GitHub webhooks
- does not maintain ongoing bidirectional sync with GitHub
- changes in GitHub are not automatically mirrored into Code Storage
- changes in Code Storage are not automatically pushed back to GitHub
- the GitHub repository must be publicly accessible — if it becomes private later, sync operations fail until you switch to authenticated mode
Public mode vs GitHub App sync
| Capability | Public mode (authType: public) | GitHub App mode |
|---|---|---|
| Sync model | One-time sync/import | Continuous sync |
| Webhooks | Not configured | Configured and used for ongoing updates |
| GitHub to Code Storage updates | One-time pull only | Automatically synced via webhook-driven flow |
| Code Storage to GitHub updates | Not automatically mirrored | Forwarded to GitHub |
| Access requirements | Public repo only, no GitHub credentials | GitHub App installation with repository permissions |
Setting up a GitHub App
To enable GitHub App sync, you need to create a GitHub App and configure it for Code Storage.Set permissions
Repository permissions:Webhook events:Or use your own handler.
- Contents: Read (required) or Read and write (required for full functionality)
- Metadata: Read (required)
Read-only access lets you sync content from GitHub into Code Storage. To push changes back to GitHub — including commits, branch creation, and pull request workflows — you need Read and write on Contents.
- Push
- Create
- Pull Request (optional, if you want PR sync)
Automatic sync with webhooks
Your GitHub App can emit webhook events to automatically sync changes. You can either handle them yourself or let Code Storage manage them.Option A: handle webhooks yourself
If you already have a webhook handler or want more control, set the webhook callback URL to point to your handler. Your handler should process GitHub events and call Code Storage as needed.repo.pullUpstream() to trigger a sync from GitHub when
handling events manually. For more on webhook verification and validation, see
Webhooks.
Option B: let Code Storage handle webhooks
If you don’t want to run your own webhook handler:- In your GitHub App settings, set the webhook URL to
https://[your-organization].code.storage/webhooks/github - Generate a webhook secret and save it.
- In the Code Storage dashboard, go to the Integrations tab, enter your webhook secret, and save.
Generic HTTPS Git sync
Generic Git Sync covers named providers that authenticate over HTTPS using a username/password pair or a token:gitlabbitbucketgiteaforgejocodebergsr.htorsourcehut
gitlab->gitlab.combitbucket->bitbucket.orgcodeberg->codeberg.orgsr.ht->git.sr.ht
gitea and
forgejo, pass upstream_host when you create the repo.
Generic Git setup
Generic provider setup happens in three steps:- create the Code Storage repository with a generic Git base
- store the HTTPS credential for that repo
- trigger an initial pull
1. Create the synced repository
This example creates a repository backed by GitLab. For self-hosted instances, includeupstreamHost / upstream_host.
upstreamHost / upstream_host:
repo_id. Use that value in the next step.
2. Store the Git credential
Create a credential record for the repository.username is optional for providers that accept a token on its own.
3. Trigger the initial pull
How Git Sync behaves
Once a repository is configured for Git Sync:git clone,git fetch, andgit pullread from Code Storagerepo.pullUpstream()andPOST /api/repos/{repo_name}/pull-upstreamtrigger an async refresh from the configured providergit pushto the default remote is forwarded to the external Git host- successful pushes trigger background sync so Code Storage storage nodes stay current
Git Sync vs Forking vs Imports
| Workflow | Source | Ongoing connection | Best for |
|---|---|---|---|
| Git Sync | External Git provider | Yes | Repositories that should stay mirrored |
| Forking | Code Storage repository | No | Templates, snapshots, isolated copies |
| Imports | External or local Git repo | No | One-time ingestion and migration |