Migrating the Git default branch from master to mainEdit
For new repositories, set the Git init.defaultBranch
to "main", overriding the Git default of "master". This affects newly created repositories.
Likewise, all major Git hosting platforms (eg. GitHub, GitLab, BitBucket) provide options in their GUI to set the preferred default branch for newly created repositories, as well as changing it for existing repositories. To my knowledge, the "default for the default" is now main
on most or all of them.
GitHub allows you to rename a branch and "redirect" requests from the old branch to the new one. I haven’t used this feature, because I am not a huge fan of the idea of requiring users who have previously cloned a repo to have to take manual steps to adjust their set-up to track your upstream configuration changes.
So, as reported here, I recently "migrated" the main branch on my dotfiles repo from "master" to "main" in the following way.
-
Create a new "main" branch locally, based on "master":
git checkout -b main
-
Tweak settings to make local
master
track localmain
rather than the other way around, while localmain
will track the remotemain
on the origin:git config branch.master.merge refs/heads/main git config branch.master.remote . git config branch.main.remote origin git config branch.main.merge refs/heads/main
-
Add a hook to
.git/hooks/pre-push
that will update the localmaster
whenevermain
is pushed, and a remotepost-receive
hook that does the analogous job on git.wincent.dev, where I am running my owngit-daemon
. -
Push
main
for the first time. -
Set the default branch to
main
in GitHub, GitLab, and BitBucket. -
Additionally, on git.wincent.dev, it is necessary to update the
HEAD
so thatgit clone
operations from it check outmain
instead ofmaster
:sudo -u git git symbolic-ref HEAD refs/heads/main
Appendix: gitweb
I looked into the source code for gitweb
to see how it figures out which order to display the branch heads in the UI. At the time I write this, it’s currently showing this order for my dotfiles repo:
master
main
pu
next
media
It is using --sort=-committerdate
in its git_get_heads_list()
function as seen here:
open my $fd, '-|', git_cmd(), 'for-each-ref',
($limit ? '--count='.($limit+1) : ()), '--sort=-committerdate',
'--format=%(objectname) %(refname) %(subject)%00%(committer)',
@patterns
or return;
I was able to confirm the ordering by running this on the server:
sudo -u git git for-each-ref --count=10 --sort=-committerdate --format='%(objectname) %(refname) %(subject)%00%(committer)'
I submitted a patch upstream to change that to:
sudo -u git git for-each-ref --count=10 --sort=-committerdate --sort=-HEAD --format='%(objectname) %(refname) %(subject)%00%(committer)'
but I have no idea whether it is the kind of behavior change that they’ll accept. We’ll see.