[GH-ISSUE #315] Starred repos get duplicated on every sync #4504

Closed
opened 2026-06-13 07:17:07 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @Quadrubo on GitHub (Jun 7, 2026).
Original GitHub issue: https://github.com/RayLabsHQ/gitea-mirror/issues/315

Originally assigned to: @arunavo4 on GitHub.

Starred repos get re-duplicated on every sync (repo, repo-owner, repo-owner-1, ...)

What happens

A starred repo gets mirrored into a brand new Gitea repo on every scheduled sync, with an incrementing name. One starred source ended up as five separate repos, all mirroring the same upstream:

starred/immich
starred/immich-immich-app
starred/immich-immich-app-1
starred/immich-immich-app-2

The app keeps a single DB row and just repoints mirrored_location at the newest copy, so the older ones become orphans. It happened to more than one starred repo, so it isn't repo-specific.

Version / setup

  • v3.17.0
  • Starred repos, dedicated-org mode (org starred), default suffix duplicate strategy
  • AUTO_MIRROR_STARRED=true with scheduled sync, metadata mirroring enabled

Why

The scheduled sync calls mirrorGithubRepoToGitea directly (scheduler-service.ts:269). For a starred repo it picks the destination name via generateUniqueRepoName (gitea.ts:1185) before any reuse check. That function's isNameTaken only asks "does a repo with this name exist", never "is it already a mirror of this same source". So it treats the repo's own previous mirror as a collision and moves on to the next free suffix, creating a new repo each run. The "already mirrored" reuse check right after (gitea.ts:606) runs against the freshly generated unique name, so it never matches.

It compounds with the scheduler's selection (scheduler-service.ts:214): only repos in status imported, pending, or failed get re-mirrored. If a sync never finishes (e.g. metadata mirroring of a huge repo times out), the repo never reaches mirrored, so every cycle re-runs the create path and adds another duplicate.

Expected

Reuse the existing mirror instead of creating a new one. If repository.mirroredLocation is set, or a repo at the candidate name is already a mirror of the same source, sync that one. Only allocate a new name for a genuine collision with a different source.

Originally created by @Quadrubo on GitHub (Jun 7, 2026). Original GitHub issue: https://github.com/RayLabsHQ/gitea-mirror/issues/315 Originally assigned to: @arunavo4 on GitHub. ## Starred repos get re-duplicated on every sync (`repo`, `repo-owner`, `repo-owner-1`, ...) ### What happens A starred repo gets mirrored into a brand new Gitea repo on every scheduled sync, with an incrementing name. One starred source ended up as five separate repos, all mirroring the same upstream: ``` starred/immich starred/immich-immich-app starred/immich-immich-app-1 starred/immich-immich-app-2 ``` The app keeps a single DB row and just repoints `mirrored_location` at the newest copy, so the older ones become orphans. It happened to more than one starred repo, so it isn't repo-specific. ### Version / setup - v3.17.0 - Starred repos, `dedicated-org` mode (org `starred`), default `suffix` duplicate strategy - `AUTO_MIRROR_STARRED=true` with scheduled sync, metadata mirroring enabled ### Why The scheduled sync calls `mirrorGithubRepoToGitea` directly (`scheduler-service.ts:269`). For a starred repo it picks the destination name via `generateUniqueRepoName` (`gitea.ts:1185`) before any reuse check. That function's `isNameTaken` only asks "does a repo with this name exist", never "is it already a mirror of this same source". So it treats the repo's own previous mirror as a collision and moves on to the next free suffix, creating a new repo each run. The "already mirrored" reuse check right after (`gitea.ts:606`) runs against the freshly generated unique name, so it never matches. It compounds with the scheduler's selection (`scheduler-service.ts:214`): only repos in status `imported`, `pending`, or `failed` get re-mirrored. If a sync never finishes (e.g. metadata mirroring of a huge repo times out), the repo never reaches `mirrored`, so every cycle re-runs the create path and adds another duplicate. ### Expected Reuse the existing mirror instead of creating a new one. If `repository.mirroredLocation` is set, or a repo at the candidate name is already a mirror of the same source, sync that one. Only allocate a new name for a genuine collision with a different source.
Author
Owner

@arunavo4 commented on GitHub (Jun 13, 2026):

@Quadrubo try the latest version

<!-- gh-comment-id:4697264141 --> @arunavo4 commented on GitHub (Jun 13, 2026): @Quadrubo try the latest version
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea-mirror#4504