微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

撤消已发布的合并并重新应用原始更改而不重写历史记录

如何解决撤消已发布的合并并重新应用原始更改而不重写历史记录

晚上好,

我们在一个实习项目中遇到了以下 git 问题。我们有两个分支,mainfeat/smth,并且在开发过程中都发生了分歧。从 feat/smthmain 创建的拉取请求显示了这些冲突。这些冲突是使用 GitHub 的图形工具解决的,基本上是执行从 mainfeat/smth 的合并以修复冲突。这次合并是错误的,导致文件损坏,目前没有注意到。

因此,feat/smth 分支被合并(使用 GitHubs Pull Request)到发现错误main 中。为了恢复更改,学生们在 main 上的合并提交上运行了 git revert 并推送了所有这些更改。现在,问题是我们希望从 feat/smth 分支中进行更改并将它们“再次”合并到主分支中。显然,这是行不通的,因为提交已经合并,因此出现在 main 上。

假设我们不想强制推送,因为许多其他开发人员已经检查了代码并继续工作。我的第一个想法是使用 git reset -m <commit_sha> 在本地恢复两个合并并重新执行合并。在合并期间,我已经“避免”了第一次合并尝试中的错误。我已经存储了文件拉取 feat/smth 分支并应用了我的存储。使用这种方法,我们从合并中获得了正确的更改,但不再应用分支上的所有其他更改,因为它们仍然在主分支上恢复。我们的 feat/smth 分支的提交已经出现在 main 上并且被还原。我们使用此尝试引入的唯一更改是合并中的正确更改。

这就是我基本上陷入困境的地方。撤消推送到 main 的合并并重新应用分支中的原始更改的正确方法是什么?我的第一个想法是樱桃选择,尽管这可能会因大量提交而变得麻烦(并可能导致大量合并冲突?)分支并将它们复制粘贴到主分支上。但是,这也可能导致不想要的更改。如果已经对 main 进行了更改,后一种方法可能会变得棘手。作者必须仔细检查所有更改,并区分来自 feat/smth 分支的更改和来自 main 分支的更改。此外,复制粘贴感觉不像是正确的“git方式”。有任何想法吗?我真的不知道如何解决“git方式”。

我绘制了 git 历史图,也用于说明目的。

Drawing of git history

非常感谢!我对这些方法很好奇。

解决方法

更新:我最初误读了您的问题,以为您想添加一个提交来修复合并,但实际上您似乎需要从原始分支中删除一个。在这种情况下,我会简单地将您的功能分支(如图所示的 4 次提交,没有合并提交)重新设置为 main 并解决当时的冲突。那么在合并到 main 之前您将不需要合并提交。事实上,这就是我首先要做的,而不是合并 main 来解决。 (我更喜欢在那里变基而不是合并的原因之一正是因为发生了什么;大多数人发现在提交中检测错误的合并工件比在合并提交中更容易。)

话虽如此,如果您不喜欢 rebase 工作流程,并希望保留这 4 次提交的原始合并基础并重做合并,那么您将需要进行下面 #2 中描述的重写。首先检查您的功能分支并在合并提交之前重置为提交(在图表中#1 标记的右侧。)然后rebase --no-ff,然后在main 中合并,然后创建您的PR .

注意:在您的特定情况下,您执行下面的 #1 没有意义。

原始答案: 更一般的情况是,您后来决定仍需要原始分支中的所有提交。在这种情况下,您通常有两种选择:

  1. 恢复恢复的合并提交。这样你就可以再次合并你在功能分支上的提交。我建议无论何时您还原任何提交,尤其是当您还原一个还原时,请在提交消息的详细信息中解释您为什么要这样做,并包括要还原的提交的提交 ID。
  2. 使用 master 重写您的功能分支(不是 git rebase --no-ff [merge-base-commit])。 (请注意,合并基础提交 ID 是 git merge-base main feat/smth,它是图表中 main 底部的第二个提交。)也许您听说过用于合并的 --no-ff,但相同选项也存在于 rebase 中。类似于合并和重新定位的含义,它只是意味着:“即使您可以快进,也要重写提交”。更改提交 ID 后,您将能够重新合并所有这些提交,以及包含修复程序的新提交。

顺便说一下,选项 2 几乎就是您在按顺序挑选提交列表时所想的,只是 rebase 是自动化的并且不太容易出错。只要您不更改父提交 ID,就不应该与cherry-picks 或rebase 发生合并冲突。

至于走哪条路,我会说这是一个品味问题。如果您不了解正在发生的事情,则还原还原有点令人困惑。但是我想如果这是唯一的更改,我可能会倾向于还原还原(例如,您决定不想要合并,然后改变主意而不添加新提交)。如果您有新的提交(通常是这种情况),如果我没有太多会重复的提交,我可能更喜欢 rebase --no-ff。也许我会重写 5 而不是 50。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。