Removing/undoing a merge on Sourcetree

2019-01-21 05:27发布

问题:

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.

回答1:

This method is based on history deletion:

  1. Check out the branch you made the mistake on
  2. Right click on the commit you want to reset the branch to
  3. Click "Reset current branch to this commit"
  4. Select "Hard" mode and click "OK"
  5. 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.



回答2:

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:

  1. Undo a Git merge?.
  2. How do I “un-revert” a reverted Git commit?.
  3. git-revert(1) Manual Page.
  4. How to revert a faulty merge.


回答3:

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.