Git Rename Branch: How to Rename Local and Remote Branches Safely

Renaming a branch is one of those tasks that looks trivial until the branch is shared. Rename a branch that only exists on your machine and you are done in one command. Rename a branch that you have already pushed — especially the default branch — and you have quietly started a small migration that every collaborator and every CI pipeline needs to follow along with.

This guide walks through every scenario: renaming the branch you are currently on, renaming a different branch without checking it out, and the multi-step dance required when the branch already lives on a remote. It finishes with the most common real-world case, `master` → `main`, and the caveats that bite teams who treat a shared-branch rename as a quick edit.

Key Takeaways
• Rename the current branch with `git branch -m new-name`.
• Rename another branch with `git branch -m old-name new-name`.
• Git has no “rename remote branch” command. For a pushed branch you push the new name, delete the old name, and reset the upstream — then everyone else re-syncs.
• Renaming the default branch (`master` → `main`) also requires changing the default branch setting on the remote (GitHub, GitLab, your own server).
• Verify every step with `git branch -a` so local and remote refs match your intent.

How do you rename the branch you are currently on?

This is the easy case. The `-m` (move) flag on `git branch` renames a branch, and if you only pass one argument, it renames whichever branch you have checked out:

“`bash

git branch -m new-name “`

That is the whole operation for a purely local branch. The commits, history, and working tree are untouched — only the label moves. Git is literally rewriting a ref file under `.git/refs/heads/`, so it is instant and safe.

You can confirm the rename took effect:

“`bash git branch

“`

Use `-M` (capital) instead of `-m` if a branch with the target name already exists and you want to force the overwrite. Be deliberate about this — `-M` will clobber the other branch’s ref.

How do you rename a branch you are not on?

You do not have to check a branch out to rename it. Pass two arguments to `git branch -m`: the old name first, the new name second.

“`bash

git branch -m old-name new-name “`

This is handy when you are mid-work on a feature branch and realise a different branch is misnamed. You rename it in place and never disturb your current checkout. The same `-M` force variant applies if the target name is taken.

If you are still finding your footing with branches in general, the mechanics of creating, switching, and listing them are worth a refresher.

How do you rename a branch that’s already pushed to a remote?

Here is where the mental model has to change. Git has no operation that renames a branch on a remote. A remote branch like `origin/old-name` is just a pointer on the server; the rename flag (`git branch -m`) only touches your local refs. The server has no idea anything happened.

So “renaming” a pushed branch is really three distinct actions: rename locally, push the new name, delete the old name on the remote. Then fix the upstream tracking so future `git push` and `git pull` commands point at the right place.

“`bash

git branch -m old-name new-name

git push origin -u new-name

git push origin –delete old-name “`

After step 2, the `-u` (short for `–set-upstream`) flag links your local `new-name` to `origin/new-name`, so plain `git push` and `git pull` work without arguments going forward. If for any reason your local branch is still tracking the deleted remote branch, clear and reset the tracking explicitly:

“`bash

git branch –unset-upstream

git branch –set-upstream-to=origin/new-name “`

Finally, prune the stale remote-tracking reference so `git branch -a` stops showing the deleted branch:

“`bash git fetch –prune “`

If you are pushing branches as part of a deployment flow, the same `git push` mechanics carry over to the server side of things.

The insight that prevents most confusion: a local rename and a remote rename are not the same kind of operation. Local rename is atomic — one command relabels a ref instantly. There is no such thing as a remote rename. Under the hood you create a new branch and delete the old one, which means the branch’s identity on the server changes, and anyone who already had the old branch now holds a stale reference to a branch that no longer exists. Treat a shared-branch rename as a small coordinated migration — push new, delete old, everyone re-syncs — not a quick edit. Once you internalise “local rename = instant; remote rename = create-new + delete-old + re-sync,” the whole workflow stops feeling fragile.

Which command for which scenario?

Keep this table handy. It maps the situation you are in to the exact command — or sequence — you need.

Scenario Command
Rename the branch you’re currently on `git branch -m new-name`
Rename a different branch `git branch -m old-name new-name`
Force-rename over an existing name `git branch -M old-name new-name`
Push the renamed branch and set upstream `git push origin -u new-name`
Delete the old branch on the remote `git push origin –delete old-name`
Clear stale upstream tracking `git branch –unset-upstream`
Set upstream to the new remote branch `git branch –set-upstream-to=origin/new-name`
Remove stale remote-tracking refs `git fetch –prune`
Verify local + remote branches `git branch -a`

How do you rename master to main?

The `master` → `main` rename is the most common real-world case, and it is the trickiest because `master` is usually the default branch. The default branch is what the remote hands out on a fresh clone, what pull requests target by default, and what CI watches. Renaming it locally is not enough — you also have to tell the remote that the default has changed.

The local-and-remote steps are exactly the migration pattern from earlier:

“`bash

git branch -m master main

git push origin -u main “`

Now change the default branch on the remote before deleting `master`. If you delete the old default branch first, the remote is left without a valid default and clones/PRs break.

  • GitHub: Repository → Settings → General → Default branch → switch from `master` to `main`.
  • GitLab: Settings → Repository → Default branch → select `main`.
  • Self-hosted bare repo: update the symbolic ref on the server:

“`bash

git symbolic-ref HEAD refs/heads/main “`

Only after the default is repointed should you delete the old branch:

“`bash git push origin –delete master “`

Then verify everything lines up:

“`bash git branch -a

“`

Hosting your own remote on a VPS gives you direct control over that default-branch symbolic ref — no settings UI required.

What about collaborators and CI after a rename?

This is the part people forget. When you rename a shared branch, every other clone still references the old name. Git does not push the rename to anyone — each collaborator has to update their own local checkout. The standard recovery for a teammate after a `master` → `main` rename:

“`bash

git fetch origin –prune

git branch -m master main

git branch –set-upstream-to=origin/main main “`

Beyond human collaborators, audit everything that hard-codes the branch name:

  • CI/CD pipelines — workflow triggers like `branches: [master]` must be updated to `main`.
  • Branch protection rules — protected-branch settings usually apply to a specific name and need recreating.
  • Deploy hooks and webhooks — anything watching a branch by name.
  • Documentation and badges — README links, status badges, and raw-file URLs that embed the branch name.

Renaming the branch is the five-minute part. Chasing down every reference to the old name is the actual work, which is exactly why a shared-branch rename deserves to be planned and communicated, not done casually on a Friday afternoon.


Run serious Git workflows on infrastructure you actually control. DarazHost VPS and dedicated servers give developers full SSH and Git-friendly environments — run Git on the server, set up git-based deploys, and manage branches and remotes with full control and guaranteed resources. When you own the box, repointing a default branch, scripting branch migrations, or hosting your own remote is a direct operation, not a support ticket. It is the real environment serious Git workflows need, backed by 24/7 support. For the bigger picture on building a developer-grade setup, see our complete guide to hosting for developers.


How do you verify a branch rename worked?

Always confirm the end state rather than assuming. `git branch -a` lists both local and remote-tracking branches, so it is the single command that shows whether local and remote agree:

“`bash git branch -a

“`

You want to see the new name present and the old name absent on both sides. If the old remote branch still appears after you deleted it, run `git fetch –prune` to clear the stale reference. If your branch still pushes to the wrong place, re-run `git branch –set-upstream-to=origin/new-name`. Managing SSH access cleanly makes these remote operations friction-free.

Frequently asked questions

Does renaming a branch lose any commits or history? No. A branch is just a movable pointer to a commit. Renaming it (`git branch -m`) changes the label, not the underlying commits, history, or working tree. Nothing is rewritten or lost.

Why is there no `git rename-remote-branch` command? Because a remote branch is a server-side ref with no client-side rename primitive. Git’s design treats the create-new-plus-delete-old sequence as the rename. That is why “renaming” a pushed branch always means push the new name and delete the old one.

Can I rename a branch while I have uncommitted changes? Yes. Renaming the current branch with `git branch -m new-name` does not touch your working tree or index, so staged and unstaged changes are preserved exactly as they were.

What’s the difference between `-m` and `-M`? Lowercase `-m` refuses to rename if a branch with the target name already exists. Uppercase `-M` forces the rename and will overwrite the existing branch’s ref. Use `-M` only when you are certain you want to clobber the target.

After renaming the default branch, why do clones still get the old one? Because the remote’s default branch setting is separate from the branches themselves. You must change the default branch on the remote (GitHub/GitLab settings, or `git symbolic-ref HEAD refs/heads/main` on a self-hosted bare repo) for new clones to check out the renamed branch.

About the Author

Leave a Reply