Geo: Secondary doesn't set HEAD ref properly in certain cases
Original problem
A customer has a Geo Secondary with 17k repos failing verification but resyncing without error because the secondary doesn't write the HEAD
ref properly. It is set to ref: refs/heads/master
, yet there is no master branch on these repos.
How does this happen?
HEAD
gets set to master
when the repo is created on the secondary (this is normal git
behavior).
Then we fetch
, and then we update_root_ref
.
In our problem case, during Project#update_root_ref
https://gitlab.com/gitlab-org/gitlab-ee/blob/be31aff9/ee/app/models/ee/project.rb#L477, root_ref
equals default_branch
because default_branch
just returns the first branch:
- When there is only 1 branch (regardless of what
HEAD
is set to). - Or when
HEAD
doesn't point to an actual branch (i.e. non-existentmaster
). Related issue gitaly#1446.
But we need HEAD
to be updated. We're using default_branch
as if it always returns HEAD
but that's not true.
Proposal
Don't prevent updating HEAD
based on default_branch
.
change_head(root_ref) if root_ref.present? && root_ref != default_branch
Performance-wise, @stanhu noted that this only adds a filesystem write call. It doesn't add a git fetch
or anything like that.
Crosslinks
Slack conversation (internal link): https://gitlab.slack.com/archives/C32LCGC1H/p1546848615034900