Migrating Forgejo Repositories into an existing instance (without overwriting the database)
This is a Forgejo migration scenario where multiple approaches were attempted, including official documentation, community guides, and requesting help on Mastodon.
In the end, the working solution was a repository-level migration combined with Forgejo’s “Adopt Repositories” feature, without touching or overwriting the existing database.
The goal was to merge repositories from an old Forgejo server into a new one.
However, the situation was more complex than anticipated:
- Both servers already had active Forgejo installations
- The new server already contained repositories and users
- The database on the new server could not be overwritten
- The old server was only accessible via filesystem (URL was demised in error)
I tried taking this into account: Migrate your Forgejo site - community blog, and going through the forgejo upgrades & cheat-sheets.
While helpful for full-instance migrations, these guides assume:
- A complete database export is available
- The target system is being fully replaced
- There are no existing repositories on the destination instance
This did not match the constraints I was facing.
Moreover, restoring an existing SQLite database dump to another running instance has its own problems:
- The new server already has an active database
- Overwriting the database would cause data loss
- Merging two Forgejo databases is not safely supported
I then tried Various Git-based backup options:
git clone --mirror
git bundle
- direct filesystem copying
While these successfully preserved Git history, they did not solve the core issue:
Forgejo does not automatically register repositories that exist on disk.
As a result, repositories did not appear in the web interface after transfer.
While I tried to find help on Mastodon (directly from Forgejo team) and on XMPP, the responses I received either:
- Referred back to full database migration guides
- Suggested rebuilding repositories manually
- Did not account for the “existing instance + filesystem-only source” scenario
I was honestly stuck.
I finally found this approach:
- Filesystem-level repository transfer
- Forgejo’s built-in repository adoption feature
- Preservation of the existing database on the new server
This allowed both systems to be merged safely.
Stop Forgejo on the source server
To ensure consistency, Forgejo was stopped before copying repositories:
```bash id="s1"
sudo systemctl stop forgejo
---
Backup repositories from the source server
Repositories are stored as bare Git repositories in:
```id="s2"
/var/lib/forgejo/data/forgejo-repositories
They were archived using:
```bash id="s3"
tar czf forgejo-repositories.tar.gz /var/lib/forgejo/data/forgejo-repositories
This preserves full Git history, branches, and tags.
---
Transfer to the new server
The archive was copied to the new server:
```bash id="s4"
scp forgejo-repositories.tar.gz user@new-server:/root/
Extract into a staging directory (You can copy directly to the prod folder as well)
To avoid disrupting existing repositories on the new instance, the archive was extracted safely:
```bash id="s5"
mkdir -p /root/forgejo-import
tar xzf forgejo-repositories.tar.gz -C /root/forgejo-import
---
Merge repositories into Forgejo storage
The repositories were then merged into the active Forgejo repository directory:
```bash id="s6"
rsync -a /root/forgejo-import/var/lib/forgejo/data/forgejo-repositories/ \
/var/lib/forgejo/data/forgejo-repositories/
Correct ownership was applied (I applied to only the updated repo folders and files):
```bash id="s7"
sudo chown -R git:git /var/lib/forgejo/data/forgejo-repositories
---
Restart Forgejo
Forgejo was restarted:
```bash id="s8"
sudo systemctl start forgejo
At this moment, the repositories existed on disk but were not yet visible in the web interface.
This is expected behaviour because Forgejo relies on its database for repository registration.
Using “Unadopted Repositories”
Forgejo provides a built-in mechanism for handling this situation.
In the web interface:
- Log in as an administrator
- Navigate to Site Administration
- Open Repositories
- Select Unadopted Repositories
- Click the scan icon (magnifying glass)
Forgejo scanned the repository directory and listed all repositories that existed on disk but were not yet registered in the database.
Adopting repositories
Each repository was then:
- Selected individually
- Assigned to a user or organisation
- Adopted into Forgejo
For my instance, I had separate user wise repositories listed for me.
Once adopted, Forgejo automatically:
- Created the required database entries
- Linked repository metadata to the filesystem
- Made the repositories visible in the UI
Verifying the details
- All repositories appeared in the interface
- Branches and commit histories were intact
- Git cloning worked via HTTPS and SSH
- Existing repositories on the new server remained unaffected
I have written a steps only blog too, since I am sure several people will face this or maybe facing it already.