Reputation: 37660
I have a repository in Git. I made a branch, then did some changes both to the master and to the branch.
Then, tens of commits later, I realized the branch is in much better state than the master, so I want the branch to "become" the master and disregard the changes on master.
I cannot merge it, because I don't want to keep the changes on master. What should I do?
Extra: In this case, the 'old' master has already been push
-ed to another repository such as GitHub. How does this change things?
Upvotes: 2111
Views: 995944
Reputation: 496722
The problem with the other two answers is that the new master doesn't have the old master as an ancestor, so when you push it, everyone else will get messed up. This is what you want to do:
git checkout better_branch # This is the branch whose commits you want to keep
git merge --strategy=ours master # keep the content of this branch, but record a merge
git checkout master # You want to **lose** all changes on this branch
git merge better_branch # fast-forward master up to the merge
In older versions of git
, if you want your history to be a little clearer, I'd recommend adding some information to the merge commit message to make it clear what you've done. Change the second line to:
git merge --strategy=ours --no-commit master
git commit # add information to the template merge message
In newer versions of git, git
will automatically open the git message editor for you. (Or you can use git mere --strategy=ours master -m "Keeping better_branch"
)
Upvotes: 2559
Reputation: 51
I'm surprised this isn't an answer here. This is what I did.
This way, there is a single commit with all the differences included, the commit history is preserved, and no hard force pushes are required.
Upvotes: 2
Reputation: 579
Just go to the gitlab or github website and find for settings.
Then under settings find for repository.
There find for default branch, expand it and you can get the options to rename it or change it to other branch.
I tried this in gitlab and it worked.
Upvotes: 1
Reputation: 406
I know this is not what OP wanted, but you can do this if you know you will have a similar problem to OP in the future.
So here's your situation,
If this feels confusing, see the below diagram of the bad situation.
*bad situation*
initial master ---> added boring changes ----merge---> you loose boring
\ /
---> (awesome branch) added awesome changes ---
To solve this( i.e. to stop the loss of boring), do the following Basically,
git branch boring
Replace boring with whatever name you want to keepSo,
*good situation*
initial master ---> added awesome changes ---> Final master(awesome) branch
\
---> (boring branch) added boring changes ---> Dont merge to master --X-->
Upvotes: 1
Reputation: 346
For me, I wanted my develop
branch to be back to the master after it was ahead.
While on develop:
git checkout master
git pull
git checkout develop
git pull
git reset --hard origin/master
git push -f
Upvotes: 2
Reputation: 17890
I found the answer I wanted in the blog post Replace the master branch with another branch in git:
git checkout feature_branch
git merge -s ours --no-commit master
git commit # Add a message regarding the replacement that you just did
git checkout master
git merge feature_branch
It's essentially the same as Cascabel's answer. Except that the "option" below their solution is already embedded in the above code block.
It's easier to find this way.
I'm adding this as a new answer, because if I need this solution later, I want to have all the code I need to use in one code block.
Otherwise, I may copy-and-paste, then read details below to see the line that I should have changed - after I already executed it.
Upvotes: 32
Reputation: 3225
To add to Cascabel's answer, if you don't want to place a meaningless merge in the history of the source
branch, you can create a temporary branch for the ours
merge, then throw it away:
git checkout <source>
git checkout -b temp # temporary branch for merge
git merge -s ours <target> # create merge commit with contents of <source>
git checkout <target> # fast forward <target> to merge commit
git merge temp # ...
git branch -d temp # throw temporary branch away
That way the merge commit will only exist in the history of the target
branch.
Alternatively, if you don't want to create a merge at all, you can simply grab the contents of source
and use them for a new commit on target
:
git checkout <source> # fill index with contents of <source>
git symbolic-ref HEAD <target> # tell git we're committing on <target>
git commit -m "Setting contents to <source>" # make an ordinary commit with the contents of <source>
Upvotes: 6
Reputation: 7378
Make sure everything is pushed up to your remote repository (GitHub):
git checkout main
Overwrite "main" with "better_branch":
git reset --hard better_branch
Force the push to your remote repository:
git push -f origin main
Upvotes: 732
Reputation: 5614
If you are using eGit in Eclipse:
Upvotes: 2
Reputation: 427
The following steps are performed in the Git browser powered by Atlassian (Bitbucket server)
Making {current-branch} as master
master
and name it “master-duplicate”.Upvotes: 1
Reputation: 3495
My way of doing things is the following
#Backup branch
git checkout -b master_backup
git push origin master_backup
git checkout master
#Hard Reset master branch to the last common commit
git reset --hard e8c8597
#Merge
git merge develop
Upvotes: 3
Reputation: 321
I found this simple method to work the best. It does not rewrite history and all previous check-ins of branch will be appended to the master. Nothing is lost, and you can clearly see what transpired in the commit log.
Objective: Make current state of "branch" the "master"
Working on a branch, commit and push your changes to make sure your local and remote repositories are up to date:
git checkout master # Set local repository to master
git reset --hard branch # Force working tree and index to branch
git push origin master # Update remote repository
After this, your master will be the exact state of your last commit of branch and your master commit log will show all check-ins of the branch.
Upvotes: 18
Reputation: 31678
From what I understand, you can branch the current branch into an existing branch. In essence, this will overwrite master
with whatever you have in the current branch:
git branch -f master HEAD
Once you've done that, you can normally push your local master
branch, possibly requiring the force parameter here as well:
git push -f origin master
No merges, no long commands. Simply branch
and push
— but, yes, this will rewrite history of the master
branch, so if you work in a team you have got to know what you're doing.
Alternatively, I found that you can push any branch to the any remote branch, so:
# This will force push the current branch to the remote master
git push -f origin HEAD:master
# Switch current branch to master
git checkout master
# Reset the local master branch to what's on the remote
git reset --hard origin/master
Upvotes: 33
Reputation: 131
One can also checkout all files from the other branch into master:
git checkout master
git checkout better_branch -- .
and then commit all changes.
Upvotes: 13
Reputation: 213228
Edit: You didn't say you had pushed to a public repo! That makes a world of difference.
There are two ways, the "dirty" way and the "clean" way. Suppose your branch is named new-master
. This is the clean way:
git checkout new-master
git branch -m master old-master
git branch -m new-master master
# And don't do this part. Just don't. But if you want to...
# git branch -d --force old-master
This will make the config files change to match the renamed branches.
You can also do it the dirty way, which won't update the config files. This is kind of what goes on under the hood of the above...
mv -i .git/refs/new-master .git/refs/master
git checkout master
Upvotes: 85
Reputation: 1323055
The solutions given here (renaming the branch in 'master') don't insist on the consequences for the remote (GitHub) repo:
-f --force
Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it. This flag disables the check. This can cause the remote repository to lose commits; use it with care.
If others have already pulled your repo, they won't be able to pull that new master history without replacing their own master with that new GitHub master branch (or dealing with lots of merges).
There are alternatives to a git push --force for public repos.
Jefromi's answer (merging the right changes back to the original master) is one of them.
Upvotes: 14
Reputation: 74202
Rename the branch to master
by:
git branch -M branch_name master
Upvotes: 51