当在发布系统发起回滚时, 一般会有一个选项 (但大概率默认不勾选): 是否回滚代码;
如果勾选, 发布系统一般会使用 git revert 命令对从上一次发布基线开始到当前提交的所有 commit 执行 revert 操作;
本文总结 git revert 命令及相关使用经验;

使用场景

情况一: revert commit

1
2
# revert 某一次 commit
git revert commit_id

如果是 revert 最新的 commit (即 HEAD), 是不会发生 conflict 的, 但是如果要 revert 的 commit 是好几个 commit 之前的提交, 而不巧那次 commit 修改过的内容在之后的 commit 又有了新的修改, 就会发生冲突了;
所以, 如果是真的需要 revert 掉好几次提交之前的某一次 commit, 就需要做好处理冲突的准备; 不过, 如果是需要 revert 掉某一次 commit 之后的所有 commit, 我们就可以按从新到旧的顺序依次 revert, 从而避免 conflict:

1
2
3
4
5
# 先将最近的 commit 列出来
git log --pretty=one
# 找到需要回退的点, 从新到旧依次 revert
git revert HEAD
...

不过, git revert 默认生成一次 commit; 当我们想要 revert 掉连续的多次 commit 时, 明显不希望每次 revert 就生成一个 commit, 所以这里需要用到一个选项, 阻止其自动 commit; 本文第四节会讨论该问题;

情况二: revert merge

相比 revert commit, revert merge 的概念会稍微复杂一点: 作为 merge commit, 在其基础上的回退有一个路径选择的问题, 因为该 commit 是由 2 至多个不同的分支的 commit 合并而来的;

1
2
# -m:  --mainline, 选择 revert 掉哪个 parent commit
git revert HEAD -m 1

这里 --mainline 的值, 表示 revert 掉哪个 parent commit, 是一个整数值, 于是这里就牵扯到 git merge 时各 commit 所对应的 parent commit 序号的问题:

1
> git log -1

git revert 常用选项

1.默认情况下, git revert 完成后, 会自动作一次 git commit, 将本次操作提交; 如果不希望自动提交, 有如下选项:

1
2
# -n:   --no-commit
git revert -n ${commit_id}

正如第二节所说, -n 选项比较适合需要多次 revert 多个 commit 时, 避免产生多个同类的 revert commit 记录;
 
2.默认情况下, git revert 完成后, 其默认的 commit message 是 Revert "${target_revert_commit_message}", 然后 git 会调用系统默认编辑器让操作者修改本次 commit message; 这里有一个选项可以直接使用默认的 message, 而不需要编辑:

1
2
3
# -e:           --edit, 默认选项, 需要编辑
# --no-edit: 不需要编辑 message, 使用 git revert 默认 message
git revert --no-edit ${commit_id}

3.revert merge 时指定 revert 哪一个 parent commit 的选项: --mainline, 本文第三节已详细介绍, 此处不再赘述;

参考资料