Moving from 'master' to 'main' in Git with local changes

March 27, 2023

One of the things that various open source Git repositories are doing is changing their main branch from being called 'master' to being called 'main'. As a consumer of their repository, this is generally an easy switch for me to deal with; some day, I will do a 'git pull', get a report that there's a new 'main' branch but there's no upstream 'master', and then I'll do 'git checkout main' and I'm all good. However, with some repositories I have my own local changes, which I handle through Git rebasing. Recently I had to go through a 'master' to 'main' switch on such a repository, so I'm writing down what I did for later use.

The short version is:

git checkout main
git cherry-pick origin/master..master

(This is similar to something I did before with Darktable.)

In general I could have done this with either 'git rebase' or 'git cherry-pick', and in theory according to my old take on rebasing versus cherry-picking the 'proper' answer might have been a rebase, since I was moving my local commits onto the new 'main' branch. However it was clear to me that I would probably have wanted to use the full three-argument form of 'git rebase', which is at least somewhat tricky to understand and to be sure I was doing right. Cherry-picking was much simpler; I could easily reason about what it was doing, and it left my old 'master' state alone in case.

(Switching from rebasing to cherry-picking is an experience I've had before.)

Now that I've written this I've realized that there was probably a third way, because at a mechanical level branches in git don't entirely exist. The upstream 'master' and 'main' branches cover the same commits (up until possibly the 'main' branch adds some on top). The only thing that says my local changes are on 'master' instead of 'main' is a branch head. In theory, what I could have done was just relabeling my current state as being on 'main' instead of 'master', and then possibly a 'git pull' to be current with the new 'main'.

(In the case of this particular repository, it was only a renaming of the main branch; upstream, both the old 'master' and the new 'main' are on the same commit.)

Since I just tried it on a copy of my local repository in question, the commands to do this are:

git branch --force main master
git checkout main
# get up to date:
git pull

I believe that you only need the pull if the upstream main is ahead of the old upstream master.

This feels more magical than the rebase or cherry-pick version, so I'm probably not likely to use it in the future unless there's some oddity about the situation. One potential reason would be if I've published my repository, I don't expect upstream development (just the main branch being renamed), and other people might have changes on top of my changes. At that point, a cherry-pick (or a rebase) would change the commit hashes of my changes, while simply sticking the 'main' branch label on to them doesn't, so people who have changes on top of my changes might have an easier time.

Written on 27 March 2023.
« My pragmatic shift from PS/2 keyboards and mice to USB ones
An interesting yet ordinary consequence of ZFS using the ZIL »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Mar 27 22:07:55 2023
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.