Migrate to only using HEAD to determine default branch
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Proposal
Server-side git repositories use the pseudo ref HEAD to determine which branch is the default branch. This reference is set even for newly created empty repositories. The HEAD file is required for a repository to be valid. This branch is called "unborn".
Gitlab for historic reasons does not strictly rely on HEAD and instead uses a heuristic to determine the default branch:
- If a branch exists that matches HEAD, use it.
- If a branch exists that has the name
heads/refs/main, use it. - If a branch exists that has the name
heads/refs/master, use it. - If there are no branches, use nothing.
- Otherwise, use the first branch as determined by git ordering.
This leads to confusing default branch selection:
- Empty repositories end up having no default branch even though git has set one.
- If there are no branches that match HEAD/main/master a default is picked arbitrarily.
We already know that this causes confusion - gitaly#1446
In gitaly!5880 (merged) a parameter was added to the RPC FindDefaultBranch called head_only which makes sure that the RPC will only use HEAD for the default branch. This parameter has already been added to gitlab-rails.
I propose that all usages of Repository#head_ref in gitlab-rails be converted to have head_only: true. This conversion was already attempted wholesale from the gitaly side, but there were too many failures. So instead we likely need to proceed with this conversion on a case-by-case basis.