git 还原合并所做的更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8323029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 12:25:00  来源:igfitidea点击:

Revert changes made by merge

gitrevert

提问by Sfisioza

The developer was commiting small changes to two files. But during this commit, he had a merge conflict which deleted a lot of stuff (probably didn't have the last up to date version). Then it was pushed to the shared repo and some other developers did some other commits.

开发人员正在对两个文件进行小的更改。但是在这次提交期间,他发生了合并冲突,删除了很多东西(可能没有最新的版本)。然后它被推送到共享仓库,其他一些开发人员做了一些其他的提交。

Now, we noticed, that the merge deleted the important files, and we want to revert it back.
How can I do this without losing the changes from the next commits?

现在,我们注意到合并删除了重要文件,我们想将其还原。
如何在不丢失下一次提交的更改的情况下执行此操作?

I was trying to git revert commitsha, but it didn't bring the changes back. Do I need to revert back the mergesha? How can I determine it?

我试图git revert commitsha,但它并没有带来变化。我需要恢复mergesha吗?我怎样才能确定它?

回答by Sridhar Sarnobat

git revert --mainline

git revert --mainline

Usually:

通常:

git revert --mainline 1 dd8cbe3e4

Where:

在哪里:

  • dd8cbe3e4is the bad merge commit you want to undo, and
  • --mainlinetells 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 1means, but my guess is that 1,2,3...corresponds to a list of mappings to the commits immediately before dd8cbe3e4, sorted by ascendingchronological order (oldest first - which is usually what you want to revert to).
  • dd8cbe3e4是您要撤消的错误合并提交,并且
  • --mainline告诉您之前的多个提交中的哪一个是要恢复的(请记住,合并提交有多个父提交,您只能保留其中一个)。
    • 我找不到对这1意味着什么的一个很好的解释,但我的猜测是它1,2,3...对应于之前提交的映射列表dd8cbe3e4,按时间升序排序(最旧的在前 - 这通常是你想要恢复的)。

Source:

来源:

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

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

回答by sehe

In short, WARNING: there is no real safeway to undo a merge except to actually resetthe branch to the commit beforethe 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

引用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 awaythat 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
      
  • git merge <someref>合并(可选地在解决冲突后提交)
  • 如果您发现马上要分支重置为在合并之前:

    git reset HEAD@{1} 
         # optionally pass --hard to reset the working tree too
    
  • 如果你后来才知道,

    • 每次使用 reflog 查找合并前的点。(HEAD@{1}是当前 head 引用的前一个值的缩写,但 reflog 跟踪了 head 引用值的有限历史记录)

      git reflog
      
    • 重置分支

      git reset HEAD@{n} # substitute reflog entry index
      
    • 可选地 rebase/cherry-pick 合并后完成的提交

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

回答by Aaron Digulla

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.

例如,Eclipse 有很好的工具来挑选每个个体差异并将其复制到任一版本。只需使用“比较”菜单并排打开两个版本。

回答by Hiery Nomus

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

简而言之,你可以做一个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.

使用 --soft 所有更改都将准备好提交,因此您可以实际更改提交。使用 --hard 更改将全部丢失。

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

更改提交后,您必须使用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.

请注意,您需要告诉其他开发人员他们应该将他们的存储库重新定位到共享存储库。(使用git pull --rebase)。他们可能会遇到一些合并冲突......请记住这一点。