Git:撤销提交
最后更新
怎么撤销一个提交,取决于它是哪个提交,以及是否已经推送。埋在历史中的较早提交,或者任何已经分享出去的提交,都应该用 git revert,它会新增一个提交来抵消原提交,不改写任何历史。最近的一串本地提交则可以直接用 git reset 回退掉。如果你只需要撤销最近一次提交,git 撤销最后一次提交页面介绍了这种快速修复的各种做法。
在终端在线编辑器中试试这些命令:浏览器里就是真正的 shell,无需安装。
该用哪个命令
| 情况 | 命令 |
|---|---|
| 撤销一个较早的提交,保留它之后的所有提交 | git revert <hash> |
| 撤销已经推送的提交 | git revert <hash> |
| 撤销最近 3 个本地提交,保留工作内容 | git reset --soft HEAD~3 |
| 撤销最近 3 个本地提交,丢弃工作内容 | git reset --hard HEAD~3 |
| 用新的反向提交撤销一段范围 | git revert HEAD~3..HEAD |
reset vs revert
| 特性 | git reset | git revert |
|---|---|---|
| 改写历史 | 是 | 否 |
| 对已推送的提交安全 | 否 | 是 |
| 创建新提交 | 否 | 是 |
| 适用于历史中间的旧提交 | 否 | 是 |
| 可以丢弃改动 | 是(--hard) | 否 |
完整示例
撤销某个指定的较早提交(即使已经推送),同时不影响它之后的提交。
| 步骤 | 命令 | 结果 |
|---|---|---|
| 1 | git log --oneline | 找到出错提交的哈希值(例如 a1b2c3d) |
| 2 | git revert a1b2c3d | 新提交抵消它,之后的提交不受影响 |
| 3 | git push | 分享修复,没有改写任何历史 |
Git 撤销提交常见问题
怎么撤销一个较早的提交,又不丢失它之后的提交?
使用
git revert <hash>。revert 会创建一个新提交,只抵消你指定的那个提交,之后的每个提交都保持原样。先用 git log --oneline 找到哈希值。如果 revert 和后来的改动发生冲突,Git 会暂停,让你解决冲突后运行 git revert --continue。怎么一次撤销多个提交?
对于只在本地的提交,
git reset --soft HEAD~3 会移除最后三个提交,同时把它们的改动保留在暂存区(用 --hard 则会丢弃改动)。对于已推送的提交,改为 revert 这个范围:git revert --no-commit HEAD~3..HEAD 会抵消这三个提交,然后用一次 git commit 记录这次撤销。已经推送的提交怎么撤销?
用
git revert <hash>,不要用 reset。revert 会创建一个新提交,撤销目标提交的改动,历史保持完整。这是撤销共享提交的安全方式:用 reset 改写已推送的历史,会迫使其他人去协调他们的副本。什么时候用 reset,什么时候用 revert?
提交只属于你、并且还在本地时,用 reset:它只是把分支往回移,就像这些提交从未发生过一样。提交已经推送、被共享,或者位于历史中间时,用 revert:它用一个新提交撤销改动,每个人都可以放心拉取。
可以在线练习吗?
可以。打开终端在线编辑器,就能在浏览器里的真实 shell 中运行这些命令,无需安装。Coddy 的免费互动 Git 课程也会一步步教你撤销更改。