git删除中间的已push的commit记录
在日常的代码管理中,我们经常会遇到需要修改 Git 历史记录的情况,比如删除中间的某些 commit。使用 git rebase
进行变基操作可以帮助我们轻松实现这一点。本文将详细介绍如何通过 git rebase
删除特定的 commit,并提供示例代码来帮助你更好地理解和应用。
一、为什么不用reset和revert?
这两种方法在特定的情况下确实很好用。
但是我们经常会遇到这种情况:我们在 Git 仓库中提交了多个 commit 后,可能会发现其中某些 commit 是错误的、冗余的,或者包含了不必要的更改。这时,我们需要删除这些中间的 commit。例如:ABCD的提交中,B藏了个雷需要排掉。

这个时候用reset
和revert
删除中间的 commit
记录就有点不太好用了:
-
reset
的方法会直接把B之后的提交记录C、D都搞没,影响过于宽泛,后续还得把C、D的代码找回来。 -
revert
中间的commit是会在比较遥远的地方改变代码不方便查看代码历史,而且在删除多条记录时会比较麻烦(要revert很多次)。
所以,我们需要一个方法,能够无痛,精准的切掉中间commit记录。正好,我上次入坑git rebase
时,了解了一些操作。
里面的交互式变基正好能够满足我们的需求。
二、操作流程
1. 找到要删除的 commit 的前一个 commit 的 hash
首先,通过 git log
查看提交历史,并找到你要删除的 commit 的前一个 commit 的 hash 值。例如,如果你要删除 commit a1b2c3d
,找到它前一个 commit abcdefg
。
git log
2. 使用 git rebase -i
启动交互式变基
使用 git rebase -i
命令并指定前一个 commit 的 hash 值,启动交互式变基。
git rebase -i abcdefg
3. 修改提交列表
这将打开一个文本编辑器,列出从 abcdefg
到最近的所有 commit。找到你要删除的 commit,将其前面的 pick
改为 drop
,或者直接删除那一行。
pick abcdefg Initial commit
drop a1b2c3d Commit to remove
pick ijklmnop Another commit
4. 保存并退出编辑器
保存并退出编辑器后,Git 将重新应用剩余的 commit,并删除指定的 commit。如果删除过程中出现冲突,按照提示解决冲突后继续变基操作。
5. 强制推送到远程仓库
如果这些 commit 已经被推送到了远程仓库,需要使用 git push --force
来强制推送更改。
git push --force
三、操作示例
1. 找到要删除的commit的前一个commit的hash
git命令使用git reflog
然后复制对应的commit id

复制前面的0aadee4
键盘输入q就可以退出界面。
IDEA的话可以直接点击复制commit id
2. 使用git rebase -i [commit id]启动交互式变基。
git命令使用:
git rebase -i 0aadee4
进入以下界面:

3. 将要删除的commit的行(B) 前面的pick改为drop或者直接删除那行。

4. 保存并退出编辑器(按esc,然后输入:wq
后按回车键),Git将重新应用剩余的commits
如果有冲突排除冲突即可(冲突的解决贴出来有点繁琐),最后结果如下。
5. 强制推送到远程仓库
这个时候还没结束,我们的操作修改git历史,如果这些commits已经被推送到了远程仓库,需要进行git push --force
来强制推送。

四、总结
git rebase -i
确实是一个能够化腐朽为神奇的命令,但是git revert也能达到同样的效果(尽管没有那么优雅),但是git revert 不涉及git push --force这
个比较危险的命令。
所以,推荐在改动比较小的情况下用git revert 而不是git rebase -i
.
但是,这个操作确实优雅,推荐学习。
转载自:https://juejin.cn/post/7392501157733826575