Git 内置命令——创建一个新提交,撤销指定提交引入的改动,不改写历史。是”安全撤销”的标准方式,适合已推送到共享分支的提交。
与 git reset 的区别
| 维度 | git revert | git reset |
|---|---|---|
| 历史 | 新增一个”反向”提交,保留原提交记录 | 移动分支指针,可能丢弃提交(--hard)或改写历史 |
| 安全性 | 安全,适合已 push 的公共分支 | 危险,改写已 push 的历史会导致协作者冲突 |
| 使用场景 | 撤销某次已发布的改动,同时保留审计记录 | 本地未推送的提交想彻底重来 |
语法
git revert [--edit] [--no-edit] [-n | --no-commit] <commit>...
git revert --continue
git revert --abort
git revert --skip
git revert -m <parent-number> <commit>
基本使用
# 撤销某次提交,生成一个新提交
git revert <commit-hash>
# 撤销但不自动生成 commit message 编辑窗口
git revert --no-edit <commit-hash>
# 撤销但先不提交,留给你检查改动再手动 commit
git revert -n <commit-hash>
git revert --no-commit <commit-hash>撤销多个提交
# 撤销连续多个提交(从旧到新指定范围)
git revert <oldest-commit>^..<newest-commit>
# 撤销多个不连续提交
git revert <commit1> <commit2> <commit3>
# 撤销一段区间内所有提交,但不逐个生成 commit(合并成一次改动,最后自己 commit)
git revert -n <oldest-commit>^..<newest-commit>
git commit -m "revert: 撤销 X 功能"撤销合并提交(merge commit)
合并提交有多个父提交,revert 需要用 -m 指定以哪个父提交为基准:
# 通常撤销合并到 main 前的状态,-m 1 表示以第一个父提交(合并前的 main)为基准
git revert -m 1 <merge-commit-hash>冲突处理
revert 遇到冲突时行为类似 merge/rebase:
git revert <commit-hash>
# 若有冲突,手动编辑冲突文件后:
git add <冲突文件>
git revert --continue
# 放弃这次 revert,恢复到操作前状态
git revert --abort
# 跳过当前这个提交的 revert(用于批量 revert 多个提交时)
git revert --skip常用选项
| 选项 | 说明 |
|---|---|
-n, --no-commit | 只应用改动到工作区/暂存区,不自动生成 commit,方便合并多次 revert 或先检查改动 |
-e, --edit | 提交前打开编辑器修改 commit message(默认行为) |
--no-edit | 使用 git 自动生成的默认 message,不打开编辑器 |
-m <parent-number> | 撤销合并提交时指定父提交编号 |
--continue | 解决冲突后继续 revert |
--abort | 中止整个 revert 操作,回到之前状态 |
--skip | 跳过当前冲突提交,继续处理下一个(批量 revert 场景) |
适用场景
- 已推送到远程共享分支的提交出问题,需要撤销但不能强推改写历史
- 需要保留”这个改动被撤销”的审计痕迹(对比
reset直接抹掉记录) - CI/CD 场景:某次部署出问题,用 revert 生成新提交快速回滚,走正常发布流程
局限性
- 撤销一个提交后,若后续提交依赖被撤销的改动,可能产生连锁冲突
- 撤销合并提交只是移除该次合并引入的差异,不会自动阻止未来重新合并同一分支(需要额外处理)
- 不适合用于清理本地未推送的提交历史,这种场景
git reset更直接
相关
- git-worktree — Git 多工作目录管理