引言

在使用 Git 进行版本控制时,git revertgit reset 是两个可能会用到的命令,但是现对于极其频繁的 push,pull,merge 指令来说,这两个命令的使用频率就非常低了,所以我就专门建了一个项目来做测试,各种提交 commit,然后各种 revert,reset,merge,以此来学习这两个命令,建议读者也这样做,纸上得来终觉浅,绝知此事要躬行,此处仅仅抛砖引玉。

git revert

命令概述

  • git revert 用于撤销某个提交的更改,并生成一个新的提交来记录这个撤销操作。

  • 这个命令感觉非常好用,因为他很安全,主要的做法就是把原先的提交反向操作,然后生成一个新的提交,这样就保留了历史记录,同时又撤销了更改。所以这个 revert 是可以重复执行的,只是增加一些提交记录罢了,本身的代码都可以回溯,对应到 gitTortoise 中,就是按钮 revert change by this commit 这按钮,记住,这个的意思是 revert 你点击的这个按钮

  • 实验下来是这样的,如果有 6 个提交,点击最开始的第一个提交,选择 revert 的话,会 revert 所有内容到当前分支的,包含当前分支的,就是说连带前六个提交一起 revert 掉了, revert 主要针对的是已经提交的内容,可以随意 revert,影响都不大

revert按钮

使用场景

  • 当你需要保留项目的历史记录时,使用 git revert 是一个安全的选择。
  • 适用于公共分支,避免影响其他开发者的工作。

示例

1
git revert <commit_hash>
  • 解释:此命令会创建一个新的提交,撤销指定提交的更改。

git reset

命令概述

  • git reset 用于将当前分支的 HEAD 指针移动到指定的提交,并可以选择性地更改索引和工作目录。

  • git reset 更多的是将指针移动到指定的分支,同时会把原先的提交内容放到暂存区。

    1. 如果是调试的话,这会比较方便。例如,使用 reset 移动到某个指针,然后 checkout 掉这些提交内容进行调试。如果没有问题,可以通过 git pull 来还原到当前分支。
    2. 另一种情况是需要修改代码并推送到远程,此时必须使用 --hard-with-lease 来安全地推送。切记,使用一般的 push 会报错,提示你需要 pull。但一旦执行 pull,就等于没修改了,必须使用 force 来强制覆盖远程。这种操作的复杂程度说明了其危险性,基本使用 IDE 进行操作。
    3. 即便是执行了 reset,也可以通过 reFlog 日志找到相关的提交,重新恢复代码。但是,如果本地的更改没有提交,就真的会丢失了。

使用场景

  • 当你需要彻底删除某个提交的更改时,使用 git reset 是合适的选择。
  • 适用于本地分支,尤其是在尚未推送到远程仓库的情况下。

示例

1
git reset --hard <commit_hash>

总结

在日常使用中,主要涉及的命令有 git commitgit pushgit pullgit revert

  • 使用 git revert 来撤销某个提交的更改,并保留历史记录。这非常适合处理线上问题。如果线上某个功能出现了问题,现场修复 Bug 是很困难的,最好的办法是执行 revert,然后提交补丁代码。如果前后端分离,前端可以封闭入口并给出提示,后台则直接执行 revert,重新部署,这样可以最大限度地减少影响。

  • 总的来说,只要是提交过的 commit,都可以重新恢复,恢复的难易程度取决于提交的复杂性。如果提交较复杂,可能需要多个 cherry-pick 来恢复;如果提交简单,直接使用 revert 就可以恢复。

  • cherry-pick 的使用频率很高。当分支增多时,如果一个分支修复了一些 Bug,或者有一些临时功能需要合并到主线,就需要使用 cherry-pick,以便逐步合并,最大程度地减少代码之间的干扰。

  • 对于单一功能点的合并,可以直接在主分支(即 main)上执行 merge 功能分支,解决冲突后再推送到远程。

参考资料

  • Git 官方文档
  • 版本控制相关书籍
  • 在线 Git 教程