Rename master branch for both local and remote Git repositories
I have the branch master
which tracks the remote branch origin/master
.
I want to rename them to master-old
both locally and on the remote. Is this possible?
For other users who tracked origin/master
(and who always updated their local master
branch via git pull
), what would happen after I renamed the remote branch?
Would their git pull
still work or would it throw an error that it couldn't find origin/master
anymore?
Then, further on, I want to create a new master
branch (both locally and remote). Again, after I did this, what would happen now if the other users do git pull
?
I guess all this would result in a lot of trouble. Is there a clean way to get what I want? Or should I just leave master
as it is and create a new branch master-new
and just work there further on?
Solution 1:
The closest thing to renaming is deleting and then recreating on the remote. For example:
git branch -m master master-old
git push remote :master # Delete master
git push remote master-old # Create master-old on remote
git checkout -b master some-ref # Create a new local master
git push remote master # Create master on remote
However, this has a lot of caveats. First, no existing checkouts will know about the rename - Git does not attempt to track branch renames. If the new master
doesn't exist yet, git pull will error out. If the new master
has been created. the pull will attempt to merge master
and master-old
. So it's generally a bad idea unless you have the cooperation of everyone who has checked out the repository previously.
Note: Newer versions of Git will not allow you to delete the master branch remotely by default. You can override this by setting the receive.denyDeleteCurrent
configuration value to warn
or ignore
on the remote repository. Otherwise, if you're ready to create a new master right away, skip the git push remote :master
step, and pass --force
to the git push remote master
step. Note that if you're not able to change the remote's configuration, you won't be able to completely delete the master branch!
This caveat only applies to the current branch (usually the master
branch); any other branch can be deleted and recreated as above.
Solution 2:
Assuming you are currently on master
:
git push origin master:master-old # 1
git branch master-old origin/master-old # 2
git reset --hard $new_master_commit # 3
git push -f origin # 4
- First make a
master-old
branch in theorigin
repository, based off of themaster
commit in the local repository. - Create a new local branch for this new
origin/master-old
branch (which will automatically be set up properly as a tracking branch). - Now point your local
master
to whichever commit you want it to point to. - Finally, force-change
master
in theorigin
repository to reflect your new localmaster
.
(If you do it in any other way, you need at least one more step to ensure that master-old
is properly set up to track origin/master-old
. None of the other solutions posted at the time of this writing include that.)
Solution 3:
With Git v1.7, I think this has changed slightly. Updating your local branch's tracking reference to the new remote is now very easy.
git branch -m old_branch new_branch # Rename branch locally
git push origin :old_branch # Delete the old branch
git push --set-upstream origin new_branch # Push the new branch, set local branch to track the new remote
Solution 4:
git checkout -b new-branch-name
git push remote-name new-branch-name :old-branch-name
You may have to manually switch to new-branch-name
before deleting old-branch-name
Solution 5:
There are many ways to rename the branch, but I am going to focus on the bigger problem: "how to allow clients to fast-forward and not have to mess with their branches locally".
First a quick picture:
This is something actually easy to do; but don't abuse it. The whole idea hinges on merge commits; as they allow fast-forward, and link histories of a branch with another.
renaming the branch:
# rename the branch "master" to "master-old"
# this works even if you are on branch "master"
git branch -m master master-old
creating the new "master" branch:
# create master from new starting point
git branch master <new-master-start-point>
creating a merge commit to have a parent-child history:
# now we've got to fix the new branch...
git checkout master
# ... by doing a merge commit that obsoletes
# "master-old" hence the "ours" strategy.
git merge -s ours master-old
and voila.
git push origin master
This works because creating a merge
commit allows fast-forwarding the branch to a new revision.
using a sensible merge commit message:
renamed branch "master" to "master-old" and use commit ba2f9cc as new "master"
-- this is done by doing a merge commit with "ours" strategy which obsoletes
the branch.
these are the steps I did:
git branch -m master master-old
git branch master ba2f9cc
git checkout master
git merge -s ours master-old