I made quite few changes in my project (I was working on a remote branch and not the master), I committed them and created a pull request on BitBucket
and merged the branch to master. I had forgotten to push my changes after the commit. Now, after trying switching the current branch to my remote branch and reverting to the commit before the merge, I managed to get all my changes back and back them up elsewhere in my system. What I want to do now is undo the bad merge that I did. Each time I click on the merge and select "Reverse commit"
, I get the following error message:
"error: Commit <commit_id> is a merge but no -m option was given.
fatal: revert failed"
The branches look like this now:
I want to basically remove the merge and bring it to a state such that it doesn't say master(4 behind)
anymore.
I am new to source control and I would appreciate it if anyone could help me out with this.
This method is based on history deletion:
- Check out the branch you made the mistake on
- Right click on the commit you want to reset the branch to
- Click "Reset current branch to this commit"
- Select "Hard" mode and click "OK"
- Unfortunately you need terminal to do this bit. Type
git push origin name_of_branch --force
into terminal (you may need to enter your git repo username and password for it to accept the command)
If a message pops up later down the line asking if you would like to abort the rebase or continue. Click "continue". If you abort, the merge will appear on your local copy again.
This is probably the easiest way to do it but since it is based on history deletion, If others are working on the project, make sure to let them all know what you are doing so you don't break anyone's git repository.
It's very unfortunate that SourceTree doesn't make it easy for you to revert
merge commits (at least in Windows SourceTree 1.5.2.0). However, reverting the
merge can easily be accomplished from the command line, but do you want to
revert the merge by adding another commit that is the reverse of the
results of the merge commit, or do you want to just remove the merge commit from
history altogether?
If you're not sharing your master
branch with other people, the simplest thing
to do would be to simply do a hard reset to remove the merge commit from
history. However, if other people already have a copy of that merge commit, then
you'll create extra work for them as they try to re-sync their copies of
master
with the rewritten version of yours.
So you need to figure out which option you want to use. I will give the steps
for both, using the command line:
Remove Commit from History
git checkout master
git push origin master --force
That will overwrite the merge commit on origin/master
with the current state
of your local master
branch, thus removing the merge commit.
Revert Commit with another Reverse Commit
git checkout master
git merge origin/master
git revert -m 1 HEAD
That will bring your local master
branch in-sync with origin/master
, and
then you can add a reverse commit by telling git revert
that the
1st parent is the one that should be considered the "mainline"
parent, and it will create the reverse commit relative to the changes brought in
from the other parent commit.
If later on you decide that you want to bring in the changes from the other
parent again, then you'll need to add another reversion commit that reverts the
reversion commit that you just made (a technique known as "reverting the
revert").
See also:
- Undo a Git merge?.
- How do I “un-revert” a reverted Git commit?.
- git-revert(1) Manual Page.
- How to revert a faulty merge.
I found another way without command lines, a bit ugly but does the job.
So, do a hard reset to the commit you want to roll back, go to the project folder (Using Finder on Mac or Explorer on Windows) and make a copy of the whole folder. What you have inside this 'Copy' folder is the point you want to be at the end of this process.
Well... go back to source tree and then checkout the Head (the latest commit into your remote), then navigate again to the project folder, be sure you can see hidden folders because you must be able to see a folder called ".git"
Delete everything BUT ".git" from your current project, it means your current project has nothing inside but the folder called ".git", then navigate to your 'Copy' folder and copy everything but ".git" folder and paste the content inside your current project (the one with ".git" folder only)
Done. Go to source tree and commit the changes, your project is exactly where you wanted and all changes removed.
The end.
Obs1: Delete the "Copy" folder now to clean your pc from dirty files.
Obs2: This process don't remove your changes from Git, the commits will be there, what you are doing is deleting your changes and committing it.