Add a GraphQL endpoint to synchronize forked projects
What does this MR do and why?
Related issues and MRs:
- How far is your fork behind/ahead of the upstre... (#14491 - closed)
- Fetch new upstream contents when fork is behind (#330243 - closed)
- Show divergence counts for a fork on project page (!103814 - merged)
- Calculate divergence counts without fetching so... (!106634 - merged)
- Add forkDetails GraphQL field to ProjectType (!106070 - merged)
- Adds a service to sync forked projects. It allows users to update their repository by merging upstream into them.
- If a project is up-to-date the service does nothing
- If a project is behind the project updates using ff merge
- If a project is behind and ahead, the project merges upstream
- Create a GraphQL mutation to sync the project fork. This endpoint will help frontend implement fork synchronisation.
State storage
Now the fetching of upstream and merge is performed in a background job, that's why it became harder to broadcast the status and the result of the merge. Usually, we store such information in the database like for forks, mirrors, etc... But I've stored it in Redis in this iteration:
- It's easier because it doesn't require a table and database structure
- The status and the result should be stored for any branch. We don't store branches in the database so we have to introduce additional changes to guarantee the consistency of the data, for example, to clean up the data for the deleted branches
- The sync service is idempotent, so it's ok if it's run multiple times for the same params
To sum it up, Redis doesn't feel natural for this type of task, but I think it's fine for this iteration because it's much easier to experiment with and we won't need to clean up the data if anything goes wrong. But if I'm missing anything here, I'm happy to reconsider.
Testing
- Enable the feature flag
Feature.enable(:fork_divergence_counts)
- Fork a project, for example,
gitlab-org/gitlab-test, and visit thefeaturebranch of the fork: http://127.0.0.1:3000/root/gitlab-test/-/tree/feature - The following info should be displayed:
- Perform the following GraphQL request:
mutation {
projectSyncFork(input: {projectPath: "root/gitlab-test", ref: "feature"}) {
details {
ahead
behind
isSyncing
hasConflicts
}
errors
}
}
- Get the following response:
{
"data": {
"projectSyncFork": {
"details": {
"ahead": 2,
"behind": 0,
"isSyncing": false,
"hasConflicts": false
},
"errors": []
}
}
}
- And the following UI:
Edited by Igor Drozdov

