恢复推送的合并以删除错误推送的本地不需要的更改

Posted

技术标签:

【中文标题】恢复推送的合并以删除错误推送的本地不需要的更改【英文标题】:Revert a pushed merge to erase local undesired changes pushed by mistake 【发布时间】:2021-05-18 14:07:58 【问题描述】:

我在带有子模块的父存储库中推送了一个合并。 假设我将我的main 分支合并到我的feature/Foo 分支中。 错误地我推送了合并、本地更改和本地创建的不应该推送的新文件。

例如我有:

本地更改:(未提交的更改)

5 个本地更改的文件 5 个本地新文件

合并更改:(来自main 分支)

5 合并文件的变化 5 由合并文件新增

现在我需要恢复推送的合并。 我知道 git revert 如何恢复提交,只创建具有相反更改的提交,因此在恢复合并时,它会恢复所有更改。 本地更改 + 合并带来的更改将被还原,因此创建相反的更改以撤消在合并提交中执行的所有更改/创建的文件。

我采用的解决方案:

因此,要保留我想要的版本,即仅由 MERGE CHANGES 而不是本地更改带来的更改,我必须逐个文件选择/丢弃我想要在还原提交中的更改,这是,手动检查日志并丢弃我不希望还原的更改。 这些是合并带来的,因为我只想恢复错误地在本地更改/添加的文件。

为什么?

因为如果我恢复所有更改,我也会恢复合并带来的更改,如果我重新合并该评论以及我需要的更改,则不会发生任何事情,因为合并流程已经解决。 我的意思是main 分支更改不会再次带到feature/Foo 分支。似乎即使我在还原后比原始合并提前了 2 次提交,但合并流程在原始合并提交中得到了解决(在解释图中检查“最终提交以恢复原始合并”)。

我的愿望:

了解使用 git 执行此操作的方法,而不是手动检查每个文件的日志以进行选择性还原。 理想情况下,不以最安全的方式删除远程分支/提交。如果还原出现在历史记录中,则无关紧要。

说明图:

【问题讨论】:

【参考方案1】:

我认为使用从旧版本中签出的一些本地文件简单地创建一个新提交要容易得多。无需还原合并,然后对该合并提交应用花哨的魔法:)

应该很简单:

git checkout commit-before-merge -- file1 file2 file3
git commit -m 'Remove accidental local changes'

描述:从合并前的提交中复制指定文件的内容。使用这些更改创建提交。这有效地“还原”了这些更改。

【讨论】:

非常感谢您的回答。我明白您的观点,您的解决方案实际上比我采用的解决方案简单得多,但关键是从本地更改和合并中添加的文件的选择必须在您的提案结帐时手动设置。想象一下,您有很多更改,而是手动进行(因此容易出错),我想知道是否可能有一些“机械/自动”的方式使用 git 而不是手动处理这个。我的意思是避免选择性签出文件,因为提交中的更改数量可能很大。 @rustyBucketBay 也许我错过了你的问题,但由于合并提交包含“真实”更改和“本地”更改,Git 怎么知道哪些更改要恢复,哪些不是?您需要以某种方式指定应保留哪些更改以及应恢复哪些更改 通过“真正的”更改,我取消了“来自合并”。是的,这实际上是我问题的重点。我知道,所以我可以手动还原,这就是我采用的解决方案。我的问题是,git 也可能会知道哪些更改来自哪里(本地/合并),如何以另一种方式完成,以确保谨慎的提交还原器不会弄乱他已经是在:) 更多还原上一次提交的更改,我可能还想“删除”合并本身,这样如果我重新合并,这些更改将再次作为要提交的更改带来到我的分支。如果我还原,重新合并不会带来任何东西,因为该文件的合并之前已解决,并且重新合并不会将它们带回我的 feature/Foo... @rustyBucketBay 我还是不明白,抱歉 :) “来自合并的变化”是什么意思?你的意思是这是一个“脏”的合并,即合并提交包含来自两个父级的更改(直接添加到合并提交中的更改,而不是来自现有分支的更改)?

以上是关于恢复推送的合并以删除错误推送的本地不需要的更改的主要内容,如果未能解决你的问题,请参考以下文章

Git混淆-如何将本地更改恢复为最新的远程推送?

将推送的分支恢复为具体的提交

git学习3

我们可以撤消 Mercurial 中的推送更改吗?

如何将多个 Git 提交(已推送)还原到已发布的存储库?

git合并分支后还能在旧分支推送吗