Moving from 'master' to 'main' in Git with local changes
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 '
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
(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.