从 master 回滚旧分支,而不管之后推送的其他分支

Rollback an old branch from master regardless of other branches pushed afterwards

第一种情况:

我工作过 3 个分支。分支A,分支B,分支C.

我开发、测试并 merged/pushed 掌握分支 A。我删除了分支 A,因为它已合并到 master。

一周后,分支B和C测试并推送到master。我删除了 B 和 C,因为它们已合并到 master。

又过了一周,老板走进办公室说 "A was a bad idea, I'd like to remove this."。 很明显,他想去掉A,但又想在生产中保留B和C。

我该怎么做?在这种情况下,A 完全独立于 B 和 C。

第二种情况:

这个场景和第一个场景是一样的,只是当A合并到master时,B和C变基为master。 因此,他们得到了 A 提供的新方法,并使用了它们。

现在我想知道,我们如何 "remove" A 而不破坏 B 和 C?

对我来说答案是 "tests will tell what's wrong",但我们没有测试。

谢谢。

对于第一种情况:查找分支 A 的合并提交的散列并执行

git revert <hash>

如果您将 A 合并到 master,第二种情况 应该工作相同,因为合并提交的还原将撤消更改,而将 B 和 C 合并到 master 则不会再次引入更改。

然而,您也可以通过对每个散列执行 git revert 来撤消分支 A 中的每个提交。编辑:请记住以相反的顺序还原单个提交,即从最新的开始。

因为你的老板想要从 A 分支中完全删除引入 master 的更改,你应该能够通过简单地恢复 A 中的合并提交来逃避 master。使用 git revert 将引入一个新的提交,它有效地撤消了原始提交引入的所有内容。

git checkout master
git log
# find the SHA-1 hash of merge commit A (e.g. d82n93kd...)
git revert d82n93kd -m 1

正如其他答案所说,第一种情况可以用git revert -m 1 <hash-of-merge>解决。 “-m 1”告诉 git 合并提交的 parents 中的哪一个是主线并且不应该被还原。您可以使用 git show <hash-of-merge> 查看 parents,这将为您提供类似 "Merge: " 的输出。如果你想保留来自 parents 的所有更改,你可以使用“-m 1”。

这将导致一个新的提交,它简单地撤销分支 A 所做的所有更改。

另一种方法是将 git rebase--preserve-merges 选项结合使用,这样您就可以重写历史记录并删除该合并。然而,这将改变你的历史,如果该分支已经被其他人使用(如果它是你的主人,这很可能),这不是一个好主意。

关于您的第二种情况,我很确定如果没有一些手动工作是不可能的。删除 A 将在任何情况下删除该分支引入的功能,并且如果 B 和 C 依赖于这些功能,这将破坏 B 和 C 的更改。因此,您可以手动从 A 中删除该功能,保留所有仍然需要的功能。或者您按上述方法还原 A,然后再次手动添加这些函数。哪个选项更好取决于分支 A 应该删除多少以及应该保留多少。