从 Git 仓库中删除指定 commit

更新日期: 2020-04-27 阅读次数: 13624 字数: 783 分类: Git

最近接了一个客户的项目,是用 ecshop 写的,长期没有人维护,现在想做改版。

ecshop 所用的版本是 2.7.3, 只支持 PHP 5.2 (ecshop 3.0 支持了 PHP 5.6)。在我的开发机 Ubuntu 16.04 上,使用 phpbrew 死活装不上 PHP 5.2;实际上可以,主要是时间紧,下午还要和客户见面,我实在不想花时间去打 patch。于是就在同事用 phpstudy 搭建的测试环境里直接调试、提交修改了。

问题出现了。在我开发机上,实际上有一点改动,但是与测试环境的代码 merge 之后,导致测试环境无法运行。明显是我开发机改错了东西。现在想把这次 merge commit 取消掉。即 9ca2e8b 这个提交。

$ git lg2
*   9ca2e8b - Mon, 10 Oct 2016 10:31:43 +0800 (in the future) (HEAD, origin/master, master)
|\            Merge branch 'master' of xxx — Zhongwei Sun
| * 88be24f - Sun, 9 Oct 2016 12:52:52 +0800 (22 hours ago)
| |           去掉 xxx — Zhongwei Sun
| * 6fd8f9f - Sun, 9 Oct 2016 12:33:47 +0800 (22 hours ago)
| |           调整 xxx — Zhongwei Sun
| * 30a1fc7 - Sun, 9 Oct 2016 12:26:09 +0800 (22 hours ago)
| |           去掉 xxx — Zhongwei Sun
| * 1c6ca06 - Sun, 9 Oct 2016 09:31:35 +0800 (25 hours ago)
|             init — Zhongwei Sun
* 05388d7 - Mon, 10 Oct 2016 10:29:02 +0800 (in the future)
|           update ignore — Zhongwei Sun
* f3079b6 - Sat, 8 Oct 2016 17:15:06 +0800 (2 days ago)
            init — Zhongwei Sun

Google 搜索 "git remove commit" 会得到提示

git revert

  1. The git revert command undoes a committed snapshot. ...
  2. Generate a new commit that undoes all of the changes introduced in commit , then apply it to the current branch.
  3. Reverting should be used when you want to remove an entire commit from your project history.

看来 git revert 就是我要的功能。

git revert

但是,当我执行了

$ git revert 9ca2e8b

错误出现了

error: Commit 9ca2e8bbeda345302f85c2040eb90ea6b8006be2 is a merge but no -m option was given. fatal: revert failed

使用 git help revert 得知, revert 一个 merge commit 需要指定 parent number

Usually you cannot revert a merge because you do not know which side of the merge should be considered the mainline. This option specifies the parent number (starting from 1) of the mainline and allows revert to reverse the change relative to the specified parent.

但是如何获取一个提交对应的 parent number 呢?

$ git show --format="%P" 9ca2e8b

05388d747c8b5f752ec2350093deacc703aea632 88be24fecf26175285f251766fbcbdaa6e84d1dc

88be 那个分支即是测试环境上的对应分支,所以对应的 parent number 为 2. 执行

$ git revert 9ca2e8b -m 2

即可,然后就可以看到,history 发生了更改

* 31bb69f - Mon, 10 Oct 2016 10:31:57 +0800 (10 seconds ago) (HEAD, master)
|           Revert "Merge branch 'master' of xxx" — Zhongwei Sun
*   9ca2e8b - Mon, 10 Oct 2016 10:31:43 +0800 (24 seconds ago) (origin/master)
|\            Merge branch 'master' of xxx — Zhongwei Sun
| * 88be24f - Sun, 9 Oct 2016 12:52:52 +0800 (22 hours ago)
| |           去掉 xxx — Zhongwei Sun
| * 6fd8f9f - Sun, 9 Oct 2016 12:33:47 +0800 (22 hours ago)
| |           调整 xxx — Zhongwei Sun
| * 30a1fc7 - Sun, 9 Oct 2016 12:26:09 +0800 (22 hours ago)
| |           去掉 xxx — Zhongwei Sun
| * 1c6ca06 - Sun, 9 Oct 2016 09:31:35 +0800 (25 hours ago)
|             init — Zhongwei Sun
* 05388d7 - Mon, 10 Oct 2016 10:29:02 +0800 (3 minutes ago)
|           update ignore — Zhongwei Sun
* f3079b6 - Sat, 8 Oct 2016 17:15:06 +0800 (2 days ago)
            init — Zhongwei Sun

测试环境也恢复正常了。

使用 git revert 的好处是,即使删除一次 commit 也会在 history 中留下记录,方便知道修改了什么。

参考

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式