git 情景模式 - 撤销已经 push 的 commit

Last Modified: 2023/08/11

概述

在使用 git 的过程中,大家问的最多的可能就是如何撤销提交?撤销提交需要分为两种情况处理:如果 commit 尚未被 push 到服务器,可以使用 git reset,具体可参考这里,本文讲述另外一种情况,commit 已经 push 到服务器,但是你仍然希望撤销该 commit。

注①:文本将会混用“提交”和 commit,他们表达相同的含义。

情景再现

你提交了一个 commit 并 push 到了 git 服务器,此时你意识到这个 commit 就是一个错误,你希望撤回该 commit。此时你知道应该使用 git revert 来撤回该 commit:

git revert <commit hash>

git revert 接收一个 commit hash 参数,每个提交都有一个唯一的 commit hash,我们可以使用 git log --oneline 查看 git 提交历史,从提交历史中找到 commit hash。下图中红色方框中便是 commit hash。

假使你想撤销的是“feat:功能1”,那么可以使用该提交对应 commit hash:

git revert a754894

git revert 工作原理

git revert 可以撤销历史 commit 中的任意一个 commit,而且不会影响到该 commit 之前或者之后的 commit,所以它是安全的。它的工作方式是将那个需要撤销的 commit 所做的所有改动做一个反向操作,将这个“反向操作”作为一个新的 commit 提交。如果你还不清楚他是怎么操作的,我们来想象下以下场景:

你 push 了一个 commit 到服务器,该 commit 的改动包括:

  • 新增了 x.md
  • 修改了 y.md
  • 删除了 z.md

我们假设 y.md 在你修改之前的内容为“before”,你将 y.md 的内容改为了“after”。

现在你希望撤销这个 commit,于是你通过 git log --oneline 找到了这个 commit 对应的 commit hash,然后通过 git revert 命令撤销该 commit,当执行该命令后,git 自动新建一个 commit,且该 commit 的改动为:

  • 删除 x.md
  • 将 y.md 的内容恢复到 “before”
  • 恢复删除的 z.md

可以看到这个改动正好你希望撤销的那个 commit 的反向操作,由 git 自动帮你完成。看下面的示意图:

从图中可以看出 revert 操作并不影响历史 commit,上图中 commit3 依然存在,只是新增了一个 commit4,通过反向操作的方式达到撤销的目的。

git revert 有可能会产生冲突

拿上图来说如果在你 push commit3 之后,有其他人也修改了 y.md,你拉取了最新的改动后,此时你依然想撤销 commit3,那么 y.md 会产生冲突,git 会让你解决冲突,冲突并不可怕,冲突就是让你选择应用谁的改动而已。

有问题吗?点此反馈!

温馨提示:反馈需要登录