如何在 git 中将推送的常规合并转换为壁球合并?

问题描述

我不小心使用 regular commitfeature branch 合并了我的 20 个提交到 main 分支。有什么办法可以恢复它并使其成为squash and merge吗?目的是使 main 分支干净。对于我在 feature branch 中的 20 次提交,它应该只有一次提交。

解决方法

首先,免责声明。 Git 中的标准经验法则是:

不要强行推送共享分支,因为这会搞砸其他人。

当然,如果您愿意承担后果,经验法则可以有例外,就您而言,这听起来像是:

小组中的每个人都注意到了这一点,所以我们想先弄清楚这一点。

所以解决这个问题是相当简单的:

# tell everyone you are going to rewrite the main branch
git checkout main
git pull main
# look at main and make sure other people didn't add more commits after yours
git reset --hard <last-good-commit-id-before-your-feature-branch>
git merge feature-branch --squash
# at this point a single squashed commit is staged and ready to be committed
git commit -m "Merge and squash feature branch"
# now replace the remote main branch with your copy
git push --force-with-lease
# now tell everyone it is fixed and they can resume work

注意:您询问了“还原”,但在 Git 中,“还原”一词的意思是创建一个新提交,该提交撤消先前的现有提交。这将使历史保持完整并改变功能。您实际上想要相反的内容,因为您希望保持功能完好无损并更改历史记录。要更改历史记录,您需要“重写”提交,在这种情况下,这包括向后重置以删除提交,并重新创建新提交。

旁注:您可能需要考虑在 main 上设置分支策略并使用合并请求到 main。然后(让我们希望)有人审查你的代码会在你的 PR 中看到很多提交,并且可以告诉你先压缩它们。或者,您可以设置压缩合并策略,以便在 PR 完成时自动执行。