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
Revert changes made by merge
提问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:
在哪里:
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 that1,2,3...
corresponds to a list of mappings to the commits immediately beforedd8cbe3e4
, sorted by ascendingchronological order (oldest first - which is usually what you want to revert to).
- I can't find a good explanation of what the
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.
现在让我解释并浏览现有的参考资料。
- Git revert of merge commit causes issues when merge is actually done.
- Git merge, then revert, then revert the revert
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
)。他们可能会遇到一些合并冲突......请记住这一点。