How to rename a Git branch
Renaming a local branch is one command. Renaming one that is already on a remote is three, and the one people leave out is the one that keeps the branch pointing at the right place afterwards.
Locally
$ git branch -m new-name # renames the branch you are on
$ git branch -m old-name new-name # renames another one
before : old-name
after : new-name
git branch -m takes one argument or
two. With one, it renames the current branch — which is the form you usually
want and the reason the command looks asymmetric in other people’s examples.
Nothing about your commits changes:
commit on the renamed branch : 2c7db02 work on the branch
A branch is a file containing a hash. Renaming it renames the pointer, not the history, so there is no rewriting here and nothing to worry about even if the commits are shared.
The remote does not find out
remote : main old-name
Renaming locally does not touch the remote at all. Worse, your branch is now tracking a remote branch under the old name:
upstream of new-name : origin/old-name
So a bare git push would push your renamed branch straight back to
old-name, which is exactly the confusion you were trying to avoid.
Renaming on the remote takes three commands
$ git push origin new-name # create the new one
$ git push origin --delete old-name # remove the old one
$ git branch -u origin/new-name # point the upstream at the new one
remote now : main new-name
upstream of new-name : origin/new-name
The third is the one that gets forgotten, because everything looks right without it — the remote has the correct name and the wrong upstream only shows up the next time someone pushes or pulls.
There is no rename on the remote side: git creates one ref and deletes another. That matters if anyone else has the branch, because their clone still has the old name and its upstream now points at something that no longer exists. On a shared branch, tell people rather than assuming they will notice.
If the branch is protected or is somebody’s default branch, the delete will be refused — GitHub, GitLab and the rest all have a rename function in their settings that does this properly, including moving open merge requests. Use that instead of the three commands.
-m and -M
$ git branch -m new-name taken
fatal: a branch named 'taken' already exists
$ git branch -M new-name taken
local : main taken
-M is --move --force. It renames over the top of an existing branch, and the
branch it replaced is simply gone from the branch list — no confirmation, no
message beyond the usual.
Its commits are still reachable through git reflog for a while, the same as
any other force-delete, but there is no reason to rely on that. Use -m and let
it stop you.
Incidentally, -M is what git branch -M main in every “getting started”
snippet is doing: forcing the initial branch to be called main regardless of
what it was called before.
About Netcup (advertisement)
The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).