使用Git rebase删除commit记录

2022-03-11
2分钟阅读时长

Warning: 项目上不建议像我这样做,有丢失代码风险。下面操作如有纰漏欢迎指正,谢谢!

之前调试 Waline 服务端的配置,需要频繁变动 Github 模板仓库里面的某些参数值,造成了许多无用的 commit,虽说没什么影响,但是强迫症看着很难受,于是我试图把中间那些 commit 记录全部剔除掉。(其实直接回退到开始改之前那个版本可能更好,不过当时没想到😂)

使用 Git rebase

官方文档:https://git-scm.com/book/zh/v2/Git-分支-变基

rebase 的主要作用是整合来自不同分支的修改,这有点像 merge,不过它能用于对提交记录的篡改。

git rebase -i <commit-id>

我们想撤销某次 commit,可以用上面这个命令(不仅会撤销 commit 记录,还会撤回修改的内容),commit-id 替换成你想要撤销那次 commit 前的任意一个 commit-id。可以用 git log 查看 commit-id。

执行完会打开编辑器,找到你想要撤销的那次 commit,把前面的 pick 改为 drop,然后保存,当然也可以把多个 commit 都改成 drop 来删除多个记录。

不过使用这种方法通常会出现冲突问题,像下面这样。。。

冲突产生的探究

假设我们的项目中有 a.txt 这样一个文件,然后每次提交的修改如下

first   // 第一次提交,id:6bfc98b
second  // 第二次提交  id:8ee4488
third   // 第三次提交  id:b2f6f69

我们每次在之前的基础上添加一行,然后进行提交。 这时如果想撤回第二次的提交,可以使用前面提到的命令 git rebase -i 6bfc98b,然后修改

pick 8ee4488 second    // 改为 drop 8ee4488 second
pick b2f6f69 third
......

保存后出来,会有一个提示,而且这时分支被切换了,你需要对分支下的冲突进行处理

Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
......

因为 rebase 本质上是一个合并的过程,查看冲突就能发现

first
<<<<<<< HEAD
=======
second
third
>>>>>>> b2f6f69 (third)

所有基于第二次 commit 的修改都受到了牵连,需要手动解决冲突。

那不基于前面 commit 的修改呢?我们先取消 rebase,再创建一个文件试试,并进行第四次提交。

git rebase --abort    // 取消 rebase 并回到原来的分支
touch b.txt
git add .
git commit -m "fourth"

然后撤销第三次提交(撤回第二次的话虽然和第四次不冲突,但和第三次冲突了)

没有提示冲突,查看 a.txt 内容,第三次提交的内容已经没有了

first
second

再查看项目文件夹,发现 b.txt 还在,即第四次提交没被影响

$ git:(master) ls
a.txt  b.txt

总结

虽然可以删除记录,但相当于撤回 commit 的修改,有一定风险!!!