Beta · Firefox extension

Fork repos into your own Git server. One click.

Fork2Self mirrors repositories from GitHub, GitLab, Gitea, Forgejo, Gogs, OneDev, GitBucket, and Bitbucket Cloud into a self-hosted Git instance you control. Run it from the toolbar popup or the right-click context menu.

Beta: Fork2Self is functional and in active use, but rough edges are expected. Migrations can fail in surprising ways depending on the destination forge's version, the source repo's quirks, and rate limits at either end. Configuration and storage formats may still change between versions without a migration path. Please report issues on the GitHub tracker.

Features

Built around the migration APIs the destination forge already provides — no proxying through a third party.

🍴

One-click forking

Toolbar popup on any recognized repo page, plus a "Fork to…" context-menu action on links and pages.

🌐

Multiple destinations

Configure several self-hosted instances; one is the default for one-click flows. Others appear in a submenu.

🪞

Pull-mirror or snapshot

Optional pull-mirror keeps the destination in sync with upstream on backends that support it (Gitea/Forgejo).

🎫

Optional content migration

Wiki, issues, labels, pull requests, releases, milestones — toggled per fork by what the source and destination both support.

🔐

Private source repos

Per-source-host personal access tokens are used during clone. Tokens are stored only in the browser's local extension storage.

🧭

Custom hostname mapping

Map an internal hostname (e.g. git.example.lan) to GitHub/GitLab/Gitea/Gogs/OneDev/GitBucket so the popup and context menu work on it.

🗂️

Migration history

The popup keeps the last 50 migration attempts with their status, error, and a quick link to the resulting repo.

🧹

Cleanup on failure

Rate-limited migrations on Gitea are auto-cleaned up. Other failures expose a manual "Delete repo" action on the failed history item.

🛡️

Local-only data

No telemetry, no analytics, no remote configuration. The extension talks only to the source repo and the destination you configure.

Supported sources & destinations

The matrix below shows what each source can hand off to a destination that supports the same content type. Effective capability is the intersection — both sides must agree.

Sources — what can be migrated from
Source Code Wiki Issues PRs Labels Releases Milestones
GitHub
GitLab
Gitea / Forgejo
Gogs
OneDev
GitBucket
Bitbucket Cloud
Generic Git URL
Destinations — what can be migrated to
DestinationNotes
Gitea / Forgejo Full content migration via POST /api/v1/repos/migrate. Pull-mirror supported.
GitLab CE / EE Code-only via import_url. Pull-mirror is GitLab EE only.

Bitbucket and Generic Git sources clone code only via Gitea's service=git importer. Gogs, OneDev, and GitBucket use Gitea's dedicated downloaders and require Gitea/Forgejo recent enough to ship them — Gitea 1.16+ for OneDev, 1.20+ for GitBucket.

How it works

Configure a destination

Open the options page, add a Gitea/Forgejo or GitLab instance, and paste a personal access token. The extension requests host permission for that origin only when you grant it.

Open a recognized repo page

GitHub, GitLab, Gitea, Forgejo, Codeberg, Bitbucket Cloud, or any host you've mapped via the custom-hostname setting.

Click Fork

The destination forge pulls the source over its native migration API. Progress and result land in the popup's History tab.

Install

The extension is not yet listed on AMO. Build from source or grab a CI artifact.

Build from source

git clone https://github.com/RickyGrassmuck/Fork2Self.git
cd Fork2Self
bun install
bun run package
# fork2self-X.Y.Z.xpi appears at the repo root

In Firefox: about:debuggingThis FirefoxLoad Temporary Add-on… → pick dist/manifest.json.

Use the CI workflow

The repo includes a Gitea Actions workflow that builds, lints with web-ext lint, signs via web-ext sign, and uploads the signed XPI as an artifact. Triggered manually.

Permissions

Manifest permissions and what they're used for. host_permissions is empty by default — destination origins are granted on demand from the settings flow.

PermissionPurpose
storagePersist destinations, source tokens, and migration history in the browser's local extension storage.
contextMenusProvide the "Fork to…" right-click action on pages and links.
notificationsToast notifications on fork start, success, and failure.
activeTabRead the URL of the tab the user clicks the action on, to detect the source repo.
optional_host_permissionsGranted per-origin when you add or test a destination, so the extension can reach its API.

FAQ

Does it send any data to a third party?

No. Network calls go only to the source repo (for cloning) and the destination forge (for the migration API). The manifest declares data_collection_permissions: ["none"] and there is no analytics SDK in the dependencies.

Where are tokens stored?

In the browser's local extension storage (browser.storage.local). Tokens are not synced to a Mozilla account and are never transmitted anywhere except to the destination or source they belong to.

Why Firefox only?

The extension targets Manifest V3 with the browser.* namespace and Firefox's extension permission model. A Chromium port is feasible but not yet implemented.

Does it work on private source repos?

Yes, when the source supports token-based HTTP cloning. Add a per-host source token in settings and the extension will embed it during the clone request. Bitbucket Cloud requires username + app password, which this extension doesn't currently support.

What happens if a migration fails?

The failed migration shows up in the History tab with the error message. On Gitea, rate-limit failures trigger automatic cleanup of any partial repo. For other failures, a "Delete repo" action on the history item calls the destination's delete API.

Can I add support for another source or destination?

Sources and backends self-register with a small interface (src/sources/*.ts, src/backends/*.ts). Each new platform is a single file plus an import in its index.ts. See the existing implementations for the contract.

License?

GPL-3.0-only.