Skip to content

Instantly share code, notes, and snippets.

@ddemaree
Last active February 4, 2022 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ddemaree/9f1deae1a9e75b740adf356058fcc457 to your computer and use it in GitHub Desktop.
Save ddemaree/9f1deae1a9e75b740adf356058fcc457 to your computer and use it in GitHub Desktop.
Draft blog post for renaming Git master branches

No More Masters

In my book Git for Humans, published in 2016, I made copious references to master as the primary branch name used in Git repositories.

The term master can refer to a "master copy," meaning the original or canonical version of something from which other copies are made. But its primary meaning in the English language is "a person who has general authority over others." And, especially in American and British English, it's hard to separate the word "master," and that meaning of it, from another related word: "slave."

If we're being honest, folks in tech have known that "master" and "slave" are problematic terms for a while, even if they haven't felt motivated to change them. There are those who say that if these words refer to objects or systems, rather than people, then they can't be offensive, just as people argue that tech is a meritocracy and algorithms can't be biased. These arguments are wrong. You can't separate the word "master" from its real-world connotation — in fact, it's the connotation that gives it meaning. (How is a "master copy" considered authoritative and canonical if "masters" don't rule over other human beings?)

Anyway, I fully support efforts being made now (however belatedly) to remove the word "master" from our tech lexicon, including from our Git repos. GitHub has even announced they are working on changing the default for everyone, though they haven't shipped this yet, and it will probably only apply to newly created repositories.

It may not be feasible to update the Git for Humans manuscript to remove all references to master (but I'll be reaching out to the awesome team at A Book Apart to find out what can be done), but in the meantime here is some information on how to rename your primary branch and set different defaults in your favorite Git-based tools.

The easy part: creating your new primary branch

While master is a long-standing convention, one of the great things about Git is that it doesn't really require your main branch to be named master (or anything else). You can choose any name you want, and you can change names at any time, so long as you're willing to do some work.

I chose to rename my personal site's main branch to stable, as a subtle reminder that stuff in that branch is meant to be, well, stable (whereas breaking changes can and should live in other branches). But main works too, as would primary, production, fhqwhgads, or anything else you like.

In an existing Git repo, the simplest way to switch names away from master is to just create a new branch and start using that one instead:

git checkout master # if you're not already there
git checkout -b stable

Alternatively, if checking out master is not convenient, you can use git branch to create a new branch based on its current commit:

git branch stable master

Either way, your master branch will be left intact, and a new stable branch is created that's an identical copy of master, which you can use instead for all the things you used to do with master.

Before you forget, make sure to push stable to GitHub (or whatever remote server you use):

git push -u origin stable

At this point, a new stable branch exists, but no one is using it yet. Next we need to work on the hard part: switching all the people and things over to the new branch.

Updating your primary branch in GitHub and other tools

Naming the primary branch master is a convention, not a rule. But because it's a strong, long-lived convention, a lot of your Git tools probably assume that you're following it. Fortunately this can also be easy to change.

GitHub

Open your repo page on GitHub while signed in, and click on the Settings tab.

In the Settings page, click Branches in the left-hand navigation. Then, on the right-hand side, you'll see a drop-down that lets you change the name of your default branch. (Remember, though here you see me changing it to stable, but you could set it to main or whatever name you chose.)

Once this is done, new pull requests will automatically be set up to merge into stable, and git clones from GitHub will also check out stable by default.

Netlify

A whole lot of people use Netlify to publish and host static web sites, and a lot of those people use Netlify's Git/GitHub integration to automatically publish changes when you push to your default branch.

If you (like me) are one of those folks, you'll need to go into your Netlify site settings to select a new production branch. This is under Build & deploy > Deploy contexts.

Other integrations

If you have complex integrations with your Git projects, such as continuous integration or deployment systems, before making these changes — and certainly before you delete or disable the old master branch — you should talk with your team and make a plan for how to update everything to use a new name.

Depending on the size and scale of your project, this may require changing some files in your repo or some settings in your hosting or other service providers, but may also require some dev-ops type work to plan and roll out a change. In my opinion this work is worth doing, and the sooner the better, but you should balance the urgency of adopting more inclusive terminology with ensuring a stable experience for your users.

The hard part: getting rid of the old branch

Sadly, Git doesn't have any such thing as "branch redirects." If all you do is create a new branch named stable, your teammates may keep pushing changes into master, and systems that hook into your repo will keep treating master as the main branch.

Hopefully getting collaborators to change names should be as simple as talking to them, telling them you think stable (or whatever) should be the main branch name going forward, and that they should treat it as such.

Of course, muscle memory can be very strong, and even on a team that agrees to use stable instead of master, someone might push changes to master out of habit. If you want to make pushes to master trigger an error, one simple thing you can do is to replace the content on your master branch with a commit that's disconnected from the rest of your repo.

First, you'll want to create an "orphan" branch, which (as the name implies) is a branch/commit with no parent.

git checkout --orphan no-masters

Then remove all the content from the repo while in this branch. Using git rm (as opposed to regular 'ol rm) will only delete files and folders that are checked into Git, leaving behind ignored content.

git rm -fr .

Depending on the technology stack you use, this may leave behind some content that had previously been hidden by .gitignore, which will now show up when you run git status. You can restore the gitignore file to make sure these files are not committed or deleted:

git checkout stable .gitignore

Lastly, you may want to leave a note explaining why this branch is empty. We'll add and commit a README.md Markdown file with the following text:

# This branch is deprecated

This project's primary branch is now called `stable`.

You should `git checkout stable` and `git pull origin stable` from now on.

Then you can commit these changes:

git add .gitignore README.md
# … output deleted …
git commit -m "Deprecation message for `master` branch"

Because this is an orphaned branch, if you run git log you'll only see this commit, none of the history before it:

git log --oneline
> cd2b2c2 (HEAD -> no-masters) Deprecation message for `master` branch

OK, now for the scary part — replacing master with this content. Which means deleting your old master branch:

git branch -D master

This will delete master locally, allowing you to create a new master branch that points to this new, empty-except-for-deprecation-message commit.

git branch master no-masters

If you were to then git checkout master, you'll see the deprecation message.

git checkout master
git log --oneline
> cd2b2c2 (HEAD -> master) Deprecation message for `master` branch

Whew. Okay. One last step: pushing this master branch to GitHub. Because this is a new, orphaned branch, you will need to force-push. This may (hell, probably will) break any integrations you have hooked up to master, so you may want to wait until your team and infrastructure are fully migrated over to main until you do this.

git push -f origin master

Ahhhhhhhhh, so nice to have that done. Here's the deprecation message as shown on one of my GitHub repos:

Screenshot of GitHub repo showing master branch deprecation message

Because master now points to this orphaned commit, whenever you or someone on your team tries to pull from it Git will raise an error:

git pull origin master
From <your-repo-url-here>
 * branch            master     -> FETCH_HEAD
fatal: refusing to merge unrelated histories

If only it was this easy to break free from history in real life.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment