Revert changes made by merge

♀尐吖头ヾ 提交于 2019-11-30 02:57:19

git revert --mainline

Usually:

git revert --mainline 1 dd8cbe3e4

Where:

  • dd8cbe3e4 is the bad merge commit you want to undo, and
  • --mainline tells you which of the multiple previous commits is the one to restore (remember, a merge commit has multiple parent commits and you can only keep one of them).
    • I can't find a good explanation of what the 1 means, but my guess is that 1,2,3... corresponds to a list of mappings to the commits immediately before dd8cbe3e4, sorted by ascending chronological order (oldest first - which is usually what you want to revert to).

Source:

http://thezencoder.com/2013/09/05/how-to-correctly-revert-a-bad-merge-in-git/

sehe

In short, WARNING: there is no real safe way to undo a merge except to actually reset the branch to the commit before the merge.

Let me explain and browse for an existing reference for now.

Quoting the linked answer from How do you revert a faulty git merge commit

Basically, reverting a merge will undo the data changes, but not the history (graph) changes. Therefore it is expected that reverting your faulty merge does nothing.

Certainly, resetting the branch would be the most simple approach, but it has drawbacks if the result of the merge has already been pushed to a shared repo (because you're effectively rewriting published history).

Here is the breakdown

  • git merge <someref> to merge (optionally commit after resolving conflicts)
  • If you find out right away that you want to reset the branch to before the merge:

    git reset HEAD@{1} 
         # optionally pass --hard to reset the working tree too
    
  • if you found out only later,

    • per-use the reflog to find the point before the merge. (HEAD@{1} is short for the previous value of the current head reference, but the reflog tracks a limited history of values for the head reference)

      git reflog
      
    • reset the branch

      git reset HEAD@{n} # substitute reflog entry index
      
    • optionally rebase/cherry-pick the commits done after the merge

      git cherry-pick HEAD@{1} # just an example. interactive tools will make this easier
      

Another (more safe) approach is to create a diff between the last good and the current version of the file and then restore the lost parts by copy&paste.

This always works, doesn't need any odd command line options, and it doesn't tamper with things that you should leave alone :-)

Eclipse, for example, has good tools to cherry pick each individual difference and copy it to either version. Just use the "Compare" menu to open both versions side by side.

In short, you can do a git reset --soft <commit> where commit can be HEAD^ (previous), HEAD~2 (current-2), a SHA, etc.

With --soft all the changes will be ready to commit, so you can actually change the commit. With --hard the changes will all be lost.

After you altered the commit you have to force push the changes to the shared repo with git push --force.

Note that you will need to tell the other developers that they should rebase their repos onto the shared repo. (use git pull --rebase). They could get some merge conflicts though... Please keep that in mind.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!