Git

How to Rename a Branch in Git Without Errors

How to Rename a Branch in Git Without Errors

Run git branch -m new-name and the local branch has a new name. The remote needs a push under the new name and a delete of the old one.

Git has no command that renames a remote branch, so those two steps stay separate unless you combine them in one push (the FAQ further down has that version).

One catch trips people up. According to the Git 2.56.0 manual, git branch -m carries the branch’s config and reflog along. So the renamed branch keeps tracking the old remote name, and git status complains about a missing upstream the moment that old name disappears.

Most renames come from a typo in a feature branch name, or from moving a default branch off master and onto main.

How to Rename a Local Branch in Git

YouTube player

On the branch you want to rename, git branch -m new-name is enough. For any other branch you give both names, as in git branch -m old-name new-name.

Only the local ref changes. The remote branch keeps its old name and the commits don’t move.

Renaming the branch you are on

Leave out the old name and Git assumes you mean the checked-out branch. The 2.56.0 manual says the config and reflog move with it, and the reflog gets an entry recording the rename.

Check it with git status or git branch -vv.

Renaming a branch you are not on

Name both and stay put. Something like git branch -m fix/typo-header fix/header-padding.

Handy mid-task. You skip the stash, checkout, fix, checkout back routine that comes with switching to another branch just to correct a name.

Why is GitHub the heart of open source?

Uncover GitHub statistics: developer community growth, repository trends, collaboration patterns, and the platform that powers modern software development.

Explore GitHub Data →

The new name still has to pass git check-ref-format, so spaces, ~, ^ and : are out, along with a few others.

How to Rename a Remote Branch in Git

You push the branch under its new name, then delete the old name from the remote. Git treats them as unrelated refs, so there’s no shortcut baked in.

  1. Rename the local branch: git branch -m old-name new-name
  2. Push the new name and set tracking: git push -u origin new-name
  3. Check that the new branch exists on the remote and that git branch -vv shows it as the upstream
  4. Delete the old remote name: git push origin --delete old-name

If your remote isn’t called origin, swap in the real name. The origin remote is just the default label Git gives the repository you cloned from.

Step two works because pushing a branch to the remote under a new name creates a fresh remote ref with no link to the old one. That’s the whole reason step four exists.

When to delete the old name

Last, and only once your teammates have switched. Skip the delete and both names live on the remote indefinitely.

Looking to sharpen your Git skills? Branching, merging, rebasing, and everything else you need - including git rebase, git stash, and commit workflows - is on one page in the Git Cheat Sheet.

The Git 2.55.0 push manual describes --delete as the same thing as putting a colon in front of the ref, so git push origin :old-name does the same job. I stick with --delete because it reads better.

How to Fix Upstream Tracking After a Rename

Because git branch -m moves the old tracking config with the branch, the renamed branch still points at the old remote name. You’ll see it in git status, either as tracking origin/old-name or as an upstream that is gone once the old name has been deleted.

Pushing with git push -u origin new-name repoints it. If there’s nothing to push, git branch --set-upstream-to=origin/new-name new-name does it without a push. And when tracking is badly tangled, git branch --unset-upstream clears it so you can set a new one from scratch.

The git-push manual explains where this lives. Upstream tracking sits in .git/config as a remote and merge pair under the branch’s section, which is why a rename can’t update it.

A half-finished rename also breaks a bare git push. Since Git 2.0 the default push.default=simple wants the upstream to have the same name as the local branch, so a mismatch makes the push fail.

▶ GIT EXPLAINED

If you commit, branch, or merge code every day, it helps to know how Git came to be. This video covers how Linus Torvalds created Git in just 10 days after a license dispute and explains how its data model actually works.

Linus Torvalds Built Git in Days Out of Spite
Built in 10 Days Out of Spite. Git and its data model explained in plain language.

Setting push.autoSetupRemote to true makes the first push of any new branch set the upstream on its own. Worth turning on if you rename often.

What Collaborators Must Run After a Branch Rename

A teammate’s clone needs the local rename, a fetch, a new upstream and a refreshed origin/HEAD, in that order. GitHub’s documentation gives the same sequence.

CommandEffect
git branch -m old-name new-nameRenames the local copy
git fetch originCreates origin/new-name
git branch -u origin/new-name new-nameRepoints tracking
git remote set-head origin -aRefreshes origin/HEAD

Order matters here. The git-remote manual says set-head -a only works when the matching remote-tracking branch already exists, and repointing the upstream needs origin/new-name too, so the fetch has to come before both.

GitHub Docs states that GitHub does not redirect a git pull on the previous branch name. Teammates who skip the sequence get an error once the old name is gone.

Nobody loses local work. The rename moves the branch instead of recreating it, and uncommitted changes in the working tree aren’t touched.

Removing the stale reference

The old origin/old-name reference lingers in every clone. Per the Git 2.56.0 fetch manual, Git keeps remote-tracking references by default, even after the remote deletes the branch.

git fetch --prune drops it while fetching, and git remote prune origin does the same without pulling anything new.

Set fetch.prune to true and every fetch prunes by itself. On a team that renames branches now and then, that one config line saves a lot of reminder messages. It also helps to understand how fetching updates remote-tracking branches, since that explains why the new name never shows up until someone runs it.

Should You Rename on the Command Line or on the Hosting Platform?

If open pull requests, protection rules or shared links depend on the branch, use the web rename on your hosting platform. For a private branch, or a platform with no rename option, the command line sequence is fine.

MethodWhat it doesGap
Command line push and deleteCreates a new remote ref, removes the old onePull requests on the old name need manual repair
GitHub web renameRenames in placeRaw file URLs and Actions references break
GitLab default branchLocal rename, push, switch default in settingsOld default name redirects only after that branch is deleted (GitLab 14.1 and later)
Bitbucket CloudLocal rename, switch main branch in settingsNo rename button in the UI

What the GitHub web rename does

Open pull requests that target the old name, forks included, move over to the new one. A pull request whose head is the renamed branch gets closed instead. Branch protection policies and draft releases update, and web URLs containing the old name redirect.

That comes from GitHub Docs (checked October 2026). Published guides disagree on whether pull requests survive a rename, and both camps are partly right, because GitHub handles the base side and the head side differently.

The click path itself is short. A separate walkthrough covers renaming a branch on GitHub from the repository’s branch page.

What the web rename leaves broken

GitHub Docs says GitHub Actions workflows don’t follow renames. Anyone who references your action with @old-branch breaks.

The docs suggest keeping a branch under the old name with one extra commit announcing the move. Cheap, and it saves your users a confusing error.

Raw file URLs stay dead, since only regular file URLs redirect. Write permission covers most branches, but the default branch and protected branches need admin permission, and organization or enterprise rulesets can push the rename up to an organization or enterprise administrator.

GitLab and Bitbucket Cloud

GitLab’s default branch guide goes through the command line: git branch -m master main, push, switch the default in project settings, protect the new branch, then delete the old one. Since GitLab 14.1 the platform records the previous default name and, once that branch is deleted, redirects file and directory URLs that still use it.

Bitbucket Cloud has no rename option in the UI, according to an Atlassian support article. Rename locally, push, change the main branch under Repository settings, then run git push origin --delete on the old name.

How to Rename master to main in Git

Rename locally with git branch -m master main, push with git push -u origin main, set main as the default branch on the hosting platform, and only then delete master from the remote. The platform switch has to come first. GitLab’s documentation states that a default branch cannot be deleted.

git branch -m master main
git push -u origin main

# set main as default in the project settings

git push origin --delete master

Why origin/HEAD matters

The git-remote manual (Git 2.53.0) describes refs/remotes/origin/HEAD as the remote’s default branch. While it points at master, the bare name origin resolves to origin/master in commands that accept the shorthand.

A stale value rarely throws errors. It just sends a command to a branch you no longer maintain.

Setting the name for new repositories

The git-init manual (Git 2.54.0, April 2026) says the default initial branch name is currently master and will change to main with Git 3.0. Until then, init.defaultBranch overrides it.

Set it once in your global Git config with git config --global init.defaultBranch main. It applies to repositories created afterward and never touches branches that already exist.

Who made the move first

GitHub said it was gradually renaming the default branch of its own repositories from master to main, and new repositories created on GitHub default to main, according to its archived github/renaming guidance repository.

GitLab projects created with version 14.0 or later start on main, while older ones start on master. That’s why mixed setups are so common.

Not every project needs the change. If nothing in your tooling or team cares, a working master is a perfectly valid choice.

Why a Branch Rename Fails and How to Fix It

Most rename errors come down to a target name that already exists, a case-only change that collides, a remote that refuses the delete, or a platform that locks the rename.

SymptomCauseFix
Branch already existsTarget name is takenUse -M after noting the old tip
Case-only rename ignored or refusedCollision on a case-insensitive file systemRename through a temporary name
Remote rejected on deleteDefault branch, protection rule, denyDeletes or hookSwitch default, lift the rule, retry
Web rename unavailableDefault or protected branch needs admin rightsAsk a repository or organization admin

Forcing a rename with -M

The Git 2.56.0 manual defines -M as shorthand for --move --force, and it’s the only way to rename onto a name that already exists. Use it when that name holds a stale branch you don’t need anymore.

You get one command instead of delete then rename, and the config and reflog of the renamed branch still move with it.

The risk is the branch you overwrite. It loses its ref, so its commits become unreachable unless something else points at them. Run git rev-parse on the target name first and keep the hash somewhere.

Case-only renames

Changing Feature to feature can collide on case-insensitive file systems. Going through a temporary name sidesteps it everywhere.

git branch -m Feature feature-tmp
git branch -m feature-tmp feature

When the remote refuses the delete

The git-push manual (Git 2.55.0) lists “remote rejected” as the status when the remote end refuses an update. Typical causes are a server-side hook, receive.denyDeletes, or receive.denyDeleteCurrent.

On a hosting platform the same refusal usually traces back to a default or protected branch. Before deleting a branch in Git under its old name, move the default branch, lift the protection rule and repeat the delete. If an organization ruleset applies, you’ll need an admin anyway.

FAQ About Renaming a Git Branch

Does renaming a branch keep its commit history?

Yes. A rename moves the branch ref and leaves every commit alone, so the hashes stay the same. The Git manual adds that the reflog is renamed too and records the rename as an entry of its own.

Can you rename a remote branch with a single command?

Almost. There’s no dedicated rename command, but one push can do both jobs.

git push origin origin/old-name:refs/heads/new-name :old-name

It creates the new name from the remote-tracking ref and deletes the old one in the same push. Fetch first so origin/old-name is current, then run git branch -u to repoint tracking.

Do Git GUI clients rename the remote branch as well?

Not always. Git Tower’s guide says its contextual menu renames local and remote branches, while GitKraken’s guide describes a right-click rename for the local branch and a separate set-upstream and delete for the remote.

Check what your client actually pushes before trusting it. Teammates still need to update their clones either way.

How do you undo a branch rename?

Swap the names back with git branch -m new-name old-name. If the old remote name is already deleted, push the restored name again with git push -u origin old-name.

How do you rename a branch in a fork?

Treat the fork as its own repository. Rename locally, push to the fork’s remote, and delete the old name there.

If the original repository renamed its branch too, update your upstream remote separately with a fetch.

When the Old Branch Name Is Safe to Delete

The old remote name is safe to delete once the new name holds every commit and nothing still points at the old one.

Test the first part with git log origin/new-name..origin/old-name. An empty result means the old name carries nothing extra.

After that, go through open pull requests and CI references, then make sure teammates have fetched and pruned, and only then run the delete. The reversible checks come first because the delete is the step that removes a ref.

Waiting has a cost. While both names stay live, a colleague can keep pushing to the old one, and that work never reaches the new branch.

Deleting early costs less than it looks, though. Any clone that still has the old name restores it with git push origin old-name.

Bogdan Sandu

Stay sharp. Ship better code.

Every week: one curated article, one tool worth knowing, one tip you can use tomorrow. No noise, no padding.