Some random notes about federated collaborators that I wrote:
The goal of federated collaborators is to add a remote user as a collaborator to a repository. This is mainly difficult because the collaborator will only be able to modify the repository on their remote instance (unless we do some SSO wizardry), so changes must be synchronized between the copies on the two instances.
Why do we need federated collaborators?
One "solution" to this problem would be to simply not implement federated collaborators. Then the collaborators for a repo can only be users on the same instance as the repo. This is very inconvenient because if you are a maintainer of two projects on different instances, you will have to create two accounts to be a collaborator on both projects, which is contrary to the federation goal of using one account across all instances. For a concrete example of this, I would like to eventually collaborate on the ForgeFed Codeberg repo using my account on git.exozy.me instead of my Codeberg account.
Why exactly is this so difficult?
Here's an example scenario. Alice runs a Gitea instance at alice.com and Bobert runs a Gitea instance at bobert.com. Alice adds Bobert as a collaborator to her https://alice.com/Alice/Hello-world repo. Bobert can now access the repo on his instance at https://bobert.com/Alice@alice.com/Hello-world. If Bobert modifies his copy of the repo by, for instance, changing the repository description, then this must be synced back to Alice's instance. This would require a lot of code for handling each repo setting that can be modified, and we would need to create a format for syncing these changes.
For synchronizing code, there are several methods we could use here, since we really don't want sync conflicts and changes to be overwritten.
- All copies force push to the main copy upon receiving commits, and the main copy force pushes to all other copies upon receiving commits. This can cause changes to be overwritten when two people push to different copies simultaneously, which is bad.
- When pushing to a copy, the copy first pulls from the main copy.
- When pushing to a copy, the copy is not modified and the push is redirected to the main copy using Git. The main copy force pushes to all other copies.
- When pushing to a copy, the copy is not modified and the push is redirected to the main copy using ForgeFed. The main copy force pushes to all other copies.
- The copies display the main copy's clone URL, so all Git operations only go to the main copy. This requires some work to be able to authenticate a push by a user from another instance. The main copy force pushes to all other copies.
I don't think sync conflicts are actually a big issue here, since the main repo at alice.com is always correct, and when it receives a sync update, it pushes out the update to all other copies, which keeps everything in sync. For example, if both Alice and Bobert modified the description at the same time, Alice's instance would first send out Alice's modification, then receive Bobert's modification and send it out to all copies. At the end, all copies now contain Bobert's modifications. Alice's modification is overwritten, but all copies are consistent.