> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Gitea Sync Project States Collection

`giteaSyncProjectStates` holds one document per project that is linked to a Gitea repository: which repository, and where the last sync left off. It belongs to the `gitea-sync` web module (`services/web/modules/gitea-sync`). The schema is in `services/web/modules/gitea-sync/app/models/giteaSyncProjectStates.mjs`, and all access goes through `services/web/modules/gitea-sync/app/src/SyncStateManager.mjs`. The fields are the same as in [GitHub Sync Project States](https://ayakaleaf-pro.mintlify.site/dev/data-model/github-sync-project-states-collection.md).

#### Fields

| Field | Type | Meaning | Source |
| - | - | - | - |
| `_id` | ObjectId | Set by Mongoose on create. | |
| `projectId` | ObjectId | The linked project. Required. The schema says `unique: true`, but no index is built (see Indexes). | `giteaSyncProjectStates.mjs:8` |
| `repoFullName` | String | The repository as `owner/name` (Gitea's `full_name`). Required. | `giteaSyncProjectStates.mjs:9`, `GiteaApiClient.mjs:315` |
| `defaultBranchName` | String | The branch the project syncs with. Set when the project is linked and not changed afterwards: on import, the branch sent by the import form; on export, the new repository's default branch, or `main` when the API gives none. Default `null`. | `giteaSyncProjectStates.mjs:10`, `GiteaSyncHandler.mjs:175-181,233-239`, `GiteaApiClient.mjs:314-317` |
| `mergeStatus` | String | `clean`, `conflict` or `diverged`. Default `clean`. | `giteaSyncProjectStates.mjs:11` |
| `lastSyncCommit` | String | The commit SHA on the synced branch at the last sync. Default `null`. | `giteaSyncProjectStates.mjs:12` |
| `lastSyncVersion` | Number | The project history version at the last sync, from project-history `GET /project/:id/version`, read after a history flush. Default `null`. | `giteaSyncProjectStates.mjs:13`, `services/web/modules/gitea-sync/app/src/HistoryManager.mjs:8-17` |
| `unmergedBranchName` | String | During a conflict: the temporary branch with the Overleaf changes, named `overleaf-YYYY-MM-DD-HHMMSS`. `null` when there is no conflict. | `giteaSyncProjectStates.mjs:14`, `GitMerge.mjs:814-818` |
| `unmergedBranchHead` | String | During a conflict: the head commit of that branch. Default `null`. | `giteaSyncProjectStates.mjs:15` |
| `conflictVersion` | Number | During a conflict: the project history version when the conflict was recorded. Default `null`. | `giteaSyncProjectStates.mjs:16` |
| `__v` | Number | The Mongoose version key. The schema does not turn it off. | Mongoose default |

#### Who Writes It

| Code | What it does |
| - | - |
| `SyncStateManager.mjs:9-14` (`createProjectState`) | Creates the document: after importing a repository as a new project (`services/web/modules/gitea-sync/app/src/GiteaSyncHandler.mjs:175-181`), or after exporting a project to a new repository (`GiteaSyncHandler.mjs:233-239`, owner only, refused when already linked). |
| `SyncStateManager.mjs:16-21` (`updateProjectState`) | `$set` of the changed fields. `getMergeOverview` sets `mergeStatus: 'diverged'` when `lastSyncCommit` is no longer an ancestor of the synced branch (`services/web/modules/gitea-sync/app/src/GiteaApiClient.mjs:431`), or the commit is gone and the user can push (`GiteaSyncHandler.mjs:123,126-137`). A sync (`services/web/modules/gitea-sync/app/src/GitMerge.mjs`) moves `lastSyncCommit`/`lastSyncVersion` on success (for example `:152,189,231`), records a conflict with `unmergedBranchName`, `unmergedBranchHead` and `conflictVersion` (`:214-220`), and clears them once it is resolved (`:257-264`). |
| `SyncStateManager.mjs:23-25` (`removeProjectState`) | Deletes the document when the owner unlinks the project (`GiteaSyncHandler.mjs:83-97`) and when a deleted project expires (`services/web/modules/gitea-sync/index.mjs:46-48`). |

#### Who Reads It

| Code | What it does |
| - | - |
| `GiteaSyncHandler.mjs:39-60` (`getProjectState`) | Gives the editor `mergeStatus`, `repoFullName` and `unmergedBranchName`. With no document it answers `need-export`, a value that is never stored. |
| `GiteaSyncHandler.mjs:110-143` (`getMergeOverview`) | Compares `lastSyncCommit` and `lastSyncVersion` with Gitea and the project history to list the new commits. |
| `GiteaSyncHandler.mjs:200` (`exportProject`) | Refuses to export a project that is already linked. |
| `GitMerge.mjs:36` (`doGitMergeWithoutLock`) | Loads the state at the start of a sync. |

#### Indexes

| Name | Keys | Options | Migration |
| - | - | - | - |
| `_id_` | `_id: 1` | | default |

Mongoose `autoIndex` is off (`services/web/app/src/infrastructure/Mongoose.mjs:7`), so the schema's `unique: true` on `projectId` creates nothing. No migration creates indexes for this collection.

#### Notes

* Gitea's API cannot make commits outside a branch as GitHub's can. A sync commits straight onto the synced branch when it can move forward, or onto a temporary branch that is then merged through a pull request (`GitMerge.mjs:16-21`).
* A sync runs under the `gitSync` lock of the project, shared with GitHub and GitLab Sync (`GitMerge.mjs:25-32`).
* A deleted project keeps its document until the project expires.
* The user's Gitea token is in [Gitea Sync User Credentials](https://ayakaleaf-pro.mintlify.site/dev/data-model/gitea-sync-user-credentials-collection.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.