YON Blog

Git revert

本地开发的时候如果要回滚某次变更一般会使用 git reset --hard <目标 commit> 然后再 git push -f origin head 覆盖远端变更. 但是有时候我们代码已经合到了 master, 或者无法强制覆盖远端的分支, 这时候就需要用 git revert 命令来创建一个新的 commit, 只是这个 commit 里的变更就是反向操作某次变更.

常用的 git revert 命令:

  • get revert <需要回滚的 commit> 
    • git revert  里指定的 commit 的含义表示, 仅回滚指定 commit 里的变更, 不是说回滚 HEAD 与 指定 commit 之间所有的 commit
  • git revert -n <需要回滚的 commit> 
    • 和上一个命令唯一的不同是不会自动创建一个新的 commit, 仅仅把回滚操作放到本地
    • 由于 revert 仅回滚指定的 commit, 有时候我们需要 回滚到 某个 commit, 就需要手动连续进行 revert, 然后在最后统一 commit
  • git revert <merge 的 commit> -m <parent> 
    • 如果我们需要回滚的 commit 是一个 merge 的节点 (有多个父 commit), revert 就需要知道我们需要保留的 mainline. 因为 merge 的节点包含了多个 line 的代码变更, 所以需要指定以哪个父 commit 为 mainline (指定为父 commit 的变更不会被回滚)
    • <parent> 是一个数字的编号, 可以通过 git log <merge 的 commit> 里的 Merge: <parent1> <parent2> 查看, 从左往右依次编号为 1, 2, 3…

对于 revert 操作可以理解为 git 进行了如下操作:

  1. 从要回滚的 commit 上 checkout 一个新分支
  2. 在新分支上与待回滚的 commit 的父节点进行 diff 操作, 如果有多个父节点, 根据 -m 来确定父节点
  3. 将第二步里的 diff 全部反向操作, 如果未指定 -n 则自动提交一个 commit
  4. 将新 commit rebase 到原分支上