TL;DR: We are renaming our Git master
branches to main
. This post explains why, shows how we are approaching this, and gives some suggestions that might be useful if you want to make similar changes.
Note that this blog post assumes you have already experience with Git , the world’s most popular version control tool.
Why are we doing this?
Inline with the global Black Lives Matter movement, various developer communities have been looking at behaviours and language to see how we can all be more inclusive. As part of this, the Git community has been doing some soul searching about using master
as the default branch name in the git init
command. To that end rel 2.28 of Git now provides support to reconfigure the default.
You will find it useful to review GitHub’s corresponding release blog post and some of the linked documents. In addition, this quote from Brian M. Carlson on the Git mailing list sums it up very nicely:
…“master”, even though from a different origin, brings the idea of human bondage and suffering to mind for a non-trivial number of people, which of course was not the intention and is undesirable. I suspect if we were making the decision today, we’d pick another name, since that’s not what we want people to think of when they use Git"
PaperCut needs to: authentically live our
anti-racist
values; meet expecations in the broader community; and, most importantly, respect our diverse colleagues and partners. These goals need to be addressed with real change. As part of the process PaperCut is examining our use of technical terms and labels as a small part of that change, so renaming the master
branch in as many of our repos as possible seems like an obvious thing to do.
On our GitHub repos (public and private) we are changing master
branch to main
over the next few weeks. GitHub will be automating this process later this year, but we didn’t want to wait. Repos on other systems will follow as well, but will take longer because of some of the issues listed below.
The following notes explain how we are doing this. They also provide some additional information if you want to do something similar.
Note that there are some risks when you rename branches like this.
For example:
- Open pull requests may reference non existent branches
- A local repo with multiple remotes can get confusing if only one of the remotes renames a branch
- Build tools may try and check out or commit on non existent branches
- API calls on services like GitHub may not work if they have hard coded branch names
- Git Hook scripts may fail as well for the same reason
- Developers (particularly on public projects) may get confused
Making the change on existing repositories
Did you know you can change the name of your git master branch in about the same time as it takes to tweet about changing the name of your git master branch??? pic.twitter.com/Q56SoZf90f
— Sy Brand (@TartanLlama) June 12, 2020
I have created a Bash script, adopted from information and examples in various sources (mainly here and here ), and you are welcome to adapt it.
#!/bin/bash
# Run this script in a local repo to rename a branch and push the change to remote hosting service.
# Usage: mv-branch [<old-branch> [<new-branch> [<remote>]]]
# Default values
# old branch => master
# new branch => main
# remote => origin
oldb="${1:-master}"
newb="${2:-main}"
remote="${3:-origin}"
git checkout $oldb
git pull || ( echo "pull failed, fix and run again" && exit 1 )
git branch -m $oldb $newb
git push -u $remote $newb
echo
echo "Please modify the default (or main) branch on your Git hosting server. Follow the appropriate links for more information"
echo
echo " GitLab: https://docs.gitlab.com/ee/user/project/repository/branches/#default-branch"
echo " BitBucket: https://community.atlassian.com/t5/Bitbucket-questions/How-to-change-MAIN-branch-in-BitBucket/qaq-p/977418 "
echo " GitHub: https://docs.github.com/en/github/administering-a-repository/setting-the-default-branch"
echo
read -p "Press any key when the change is complete" x
git push $remote --delete $oldb
This should be run inside a local repository clone. It:
- Checks out the old branch
- Makes sure that all changes for the old branch are pulled down and merged locally (if this fails the process stops)
- Renames the old branch to the new branch (you can provide arguments to override the
master
andmain
defaults, as well as the default name of the remoteorigin
) - Changes are then pushed to the remote, which does not have to be hosted on GitHub.
- The user is then prompted to make changes on the hosting site for the default branch (Instructions here for BitBucket , GitLab , and GitHub )
- Finally the old branch is deleted on the
origin
host.
Because of this change your fellow contributors will need to run the following commands in their local repository clones – This script is adapted from Scott Hanleman’s post .
#!/bin/bash
# Run this script in a local repo to rename a branch (usually master) that has been renamed on a remote
# Usage: update-branch-from-remote [<old-branch> [<new-branch> [<remote>]]]
# Default values
# old branch => master
# new branch => main
# remote => origin
oldb="${1:-master}"
newb="${2:-main}"
remote="${3:-origin}"
git checkout $oldb
git branch -m $oldb $newb
git fetch
git branch --unset-upstream
git branch -u $remote/$newb
git symbolic-ref refs/remotes/$remote/HEAD refs/remotes/$remote/$newb
Changing the default for new local repositories
As explained in the GitHub release
blog post
, if you upgrade to Git 2.28 or above then you can run the command git config --global init.defaultBranch main
and all future git init
commands will use main
as default branch. However, if you can’t upgrade Git at the moment then there is a work around using the Git template directory (this information was adapted from this Stackoverflow
reply
).
For instance on my Debian Linux system:
cp -a /usr/share/git-core/templates/ ~/.config/git
printf "ref: refs/heads/main\n" > ~/.config/git/templates/HEAD
git config --global init.templateDir ~/.config/git/templates
On Windows, using Powershell, the following will work assuming you have used the Git Windows installer defaults:
Copy-Item -recurse "C:\Program Files\Git\mingw64\share\git-core\templates" "$env:USERPROFILE\.config\git\templates"
Write-Output "ref: refs/heads/main" > "$env:USERPROFILE\.config\git\templates\HEAD"
git config --global init.templateDir "$env:USERPROFILE\.config\git\templates"
Please post below if you have any questions or comments.