Moving to main

I’ve started moving projects over from using master as the main branch, to main as the main branch. As usual, the territory has detail not represented in the map – here I hope to fill in some detail, while I’m going through the process.

Changing the branch for your own git repository

Here’s good advice on changing your default git branch to main. I’ll summarise the command-line bit in this section below, but there’s more detail in that post.

The following changes the name of master branch to main, preserving commit history and the reflog (the log of changes to refs, like renaming a branch; since refs are mutable, this is often consulted to recover old states).

It is very important to pull from origin before changing the name; if you’re like me, you’ll frequently end up on a PR branch which is merged at GitHub but not locally. Changing the name of the branch then pushing that does not have any safeguards against non-fast-forwards, so you can end up losing merges. If you do accidentally do it, you’ll need to chase down the head of master and git merge --ff-only it into main at the least; if you already deleted the branch at origin, you may need to chase down merge commits.

Pushing to the origin with -u creates the branch in the upstream repository (e.g., on gitHub), while also setting that as the upstream for the branch, so git push without arguments works.

$ # just in case you're not already there
$ git switch master
$ git pull origin master
$ git branch -m master main
$ git push -u origin main

Changing the default branch for a project in GitHub

GitHub has a setting for the “default branch”, which for instance is made the target of PRs by default.

You can set this default branch via the Settings tab for a repository, Branches item. You could also update branch protection rules if you have them, while you’re there.

At present, you can’t make a default for the default branch in new repositories, in GitHub; you’ll have to go back after creating a new repo and change that setting (ideally before it gets cloned anywhere). There are details of further changes GitHub is working on at github/renaming.

You should probably also delete the master branch from the GitHub project, which will help prevent people from unwittingly using it as an upstream. You do this through the Branches item in the code view (not via Settings, but beware that you will have to go through and retarget any pull requests that point at master. This is probably going to be easier to accomplish when GitHub have made some of those changes they’re talking about.

After deleting it, I added a branch protection rule for master, requiring PRs (and linear history, and including admins) so that pushing to master would not work easily. It’s not possible to just disallow a branch, but this will stop accidental pushes to origin master.

Changing the default branch for git init

As of git 2.28, you can set the initial branch when creating a new git repo:

git init --initial-branch main

and better still, you can give a default for this in git config:

git config --global init.defaultBranch main

Getting other people to change the branch

Also from the post linked at the top: every person that has a local clone of the git repository should do the

git branch -m master main

bit, to rename their local branch, and can change default git config as above.

They will then need to rename the branch and its upstream, otherwise they’ll end up fetching uselessly from the old branch. This is a bit different to the first instance of renaming and pushing the main branch:

$ # After the rename above
$ git switch main
$ git fetch
$ git branch --unset-ustream
$ git branch -u origin/main
$ git pull --ff-only origin main

If you’ve set the default branch for the remote (so you can git push origin rather than git push origin master), you can update that with

$ git remote set-head origin main

(In the post linked at the top, it uses git symbolic-ref to do this; I believe the command immediately above is equivalent, and it’s more obvious what it does.)

Changing CI

Another place that the git branch comes up is continuous integration, since there is often some kind of gating or dispatch based on the git branch. I found references to master branch in these three, which I use for various projects:

GitHub actions

You will likely have master mentioned in the on: stanza of workflows, and you may have it mentioned as the version of actions themselves (in a use: field). For the former, it’s a straight-forward change to main. For actions, the name may or may not be under your control – either way, consider using a version tag instead of referring to a branch. Here’s a commit with both kinds of change.

CircleCI

It’s also possible you have master branch explicitly mentioned in a .circleci/config.yaml file, though less likely since the triggers tend to work by excluding things. But, as for kubeyaml, you might have ad-hoc tests in snippets of script that determine whether to do something or not.

TravisCI

You may have a branch mentioned in a trigger clause, as I do for [amqplib][amqp-travisci]; and, similarly, master could be mentioned in snippets of script.

Changing release artifacts

Some projects name release artifacts for the branch – for Flux we tag prerelease container images as master-<sha1>, for example. You’ll need some co-ordination with people who use the artifacts, to let them know to update any automated systems.


951 Words

2020-08-13 00:00 +0000