Git Revert 撤销指定提交指南
目标
撤销指定提交 6dea560bcb2b9e4fa23d1cfe7e919998ac0424f1 的所有代码变更,但不改写 Git 历史。
使用方式:
bash
git revert 6dea560bcb2b9e4fa23d1cfe7e919998ac0424f1它会生成一个新的反向提交,把目标提交引入的改动抵消掉。
查看图表代码
撤销后,原提交 6dea560b 仍然保留在历史中,但它的代码效果被 b6b0176 这个新提交抵消。
完整流程
查看图表代码
步骤 1:检查当前分支和工作区
bash
git status --short --branch示例输出:
bash
## dev表示当前在 dev 分支,且工作区干净。
如果看到类似下面的输出:
bash
## dev
M cmd/manager/controller/match.go说明有本地未提交修改。此时不要直接 revert,先处理本地改动:
bash
git stash或者先提交当前改动。
步骤 2:查看目标提交改了什么
bash
git show --stat --oneline --decorate --no-renames 6dea560bcb2b9e4fa23d1cfe7e919998ac0424f1用途:
- 确认提交号是否正确。
- 确认这次提交影响了哪些文件。
- 避免误撤销其他提交。
示例:
text
6dea560b feat: match pods
cmd/manager/controller/match.go | 153 ++++++++++++++++++++++++++++------------
cmd/manager/fsm/match.go | 69 +++++++++++++++---
cmd/manager/manager.go | 3 +
cmd/manager/model/once.go | 37 ++++++++++
cmd/manager/model/settle.go | 38 +++++++++-
cmd/manager/server/contab.go | 28 +++++++-
cmd/normal/state/match.go | 26 +++++++
7 files changed, 293 insertions(+), 61 deletions(-)步骤 3:确认提交在当前分支历史中
bash
git merge-base --is-ancestor 6dea560bcb2b9e4fa23d1cfe7e919998ac0424f1 HEAD
echo $?返回值说明:
text
0表示该提交是当前分支的历史提交,可以直接 revert。
text
1表示该提交不在当前分支历史中,需要先确认是否切错分支。
也可以用下面命令辅助确认:
bash
git branch --contains 6dea560bcb2b9e4fa23d1cfe7e919998ac0424f1它会列出包含该提交的分支。
步骤 4:执行 revert
bash
git revert --no-edit 6dea560bcb2b9e4fa23d1cfe7e919998ac0424f1说明:
git revert会创建一个新的提交。- 新提交的内容是目标提交的反向补丁。
--no-edit表示使用 Git 默认生成的提交信息,不打开编辑器。
示例结果:
text
[dev b6b0176f] Revert "feat: match pods"
7 files changed, 61 insertions(+), 293 deletions(-)
delete mode 100644 cmd/manager/model/once.go可以理解为:
查看图表代码
步骤 5:如果出现冲突
如果 Git 输出冲突信息,按下面流程处理:
查看图表代码
常用命令:
bash
git status查看冲突文件。
解决完成后:
bash
git add <conflict-files>
git revert --continue如果不想继续撤销:
bash
git revert --abort步骤 6:检查 revert 结果
bash
git status --short --branch确认工作区干净。
再查看最新提交:
bash
git show --stat --oneline --decorate --no-renames HEAD预期看到类似:
text
b6b0176f Revert "feat: match pods"
7 files changed, 61 insertions(+), 293 deletions(-)
delete mode 100644 cmd/manager/model/once.go步骤 7:运行测试验证
优先运行全量测试:
bash
go test ./...如果项目全量测试本身存在历史环境问题,可以对本次 revert 涉及的包做聚焦验证:
bash
go test ./cmd/manager ./cmd/manager/controller ./cmd/manager/fsm ./cmd/manager/model ./cmd/manager/server ./cmd/normal/state验证结论需要写清楚:
text
本次聚焦验证通过。
全量 go test ./... 未通过,失败原因是历史测试环境问题,例如缺少配置文件、依赖外部 Redis、测试文件缺少导入等。步骤 8:推送远端
确认无误后推送:
bash
git push origin dev为什么不用 reset
不要在多人协作分支上直接使用:
bash
git reset --hard <commit>
git push --force原因:
查看图表代码
结论:
- 已推送、多人协作分支:优先
git revert。 - 只有本地未推送提交:可以考虑
git reset。 - 不确定时,使用
git revert更稳妥。
撤销本地提交与找回引用
以下场景来自 show-cmd。只对尚未共享、且希望保留修改的最近提交使用:
bash
git reset --soft HEAD~1
git status --short修改仍留在暂存区,检查后可重新提交。引用误移动时先查看记录和旧提交:
bash
git reflog -5
git show <commit-hash> --stat核对内容后再决定恢复方式。共享分支的撤销和冲突处理仍按上文 revert 流程执行。
命令参考
继续阅读
- Git完整实践与解答
- Git上手与对象
- Git任务与配置