My problem:
In GitLab, I have one repository (called X) whose main branch mirrors the "main" branch of a public repository (called Y). So, GitLab does periodic synchronizations to the main branch of X (mirror) with the latest changes merged on the main branch of Y (mirrored), until last night when I accidentally merged some changes onto the main branch of X. Now, in GitLab, next to the main branch of X, I have a message saying: "main default> protected diverged from upstream"
If I hover over diverged from upstream I see the following message: "The branch could not be updated automatically because it has diverged from its upstream counterpart. To discard the local changes and overwrite the branch with the upstream version, delete it here and choose 'Update Now' above.", although, this message seems very ambiguous to me, especially the "delete it here and choose 'Update Now' above .".
I don't think I can delete the main branch, and right now I don't think I want to do it.
Because of this, the periodic/forced synchronization with the main branch of Y fails now.
Even after reverting the commit that I accidentally merged on the main branch of X, it didn't solve the problem, as I'm still unable to synchronize with Y.
My question:
Is there any way to get to the state where I can do periodic synchronization again from the main branch of Y and have the main branch of X in sync again with Y.
I tried a git reset --hard origin/main
and had the following message:
git reset --hard origin/main
HEAD is now at 4e4b83e Merge branch 'revert-d3a10f32' into 'main'.
Obviously, what Gitlab is suggesting, is probably impossible as the main
branch of X is the default branch which I don't think can be removed.
If the synchronization between the two remote repositories Y and X fails because X has diverged from Y, when you perform on your local repository a git reset --hard origin/main
, you're not resetting the local branch main
to the commit prior to the divergence, you're just resetting your local main
branch to X's main
branch. Both your local and remote repository are still diverging from Y.
If you want to resume the synchronization, X's main
branch shouldn't contain any additional changes than Y's main
branch, as GitLab simply performs a fast-forward between the two. You need to bring X to a point before the divergence. To do that, find the last common ancestor between X and Y's main
branches. So, add Y as a second remote, and fetch its main
branch. At that point, perform a git merge-base
between main
and y/main
and reset your local main
branch to the merge-base commit. Finally, force push to the remote repository X, so that X's main
is back to a point contained by Y's main
's history.
# add Y as the second remote
git remote add origin2 Y
# fetch main from Y
git fetch origin2 main
# find the most recent common ancestor between your local main (which corresponds to X) and Y's main
git merge-base main origin2/main
# copy the SHA1 returned from git merge-base
# reset to the most recent common ancestor
git reset --hard <SHA>
# force-push to overwrite X's `main` with your local
git push --force origin main