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 的修改,有一定风险!!!