跳过正文
  1. 教程/
  2. Git 入门到实操:新手从 0 到会用提交、分支、回退和远程仓库/

Git 撤销与回退

·1430 字·3 分钟
Evan Wu
作者
Evan Wu
记录 AI、技术实践、效率工具、项目经验与学习思考。
Git Mastery - 系列专栏
✦ 8: 本文

在使用 Git 时,经常会遇到这些问题:代码改错了想撤销、已经 git add 了想取消暂存、commit 写错了想修改、提交后想回退版本,甚至 reset 误操作后想恢复提交。

这些情况都属于 Git 的“撤销与回退”,但不同场景要使用不同命令。本章会按照实际开发流程,系统讲清 restore、commit –amend、revert、reset、reflog 的用法和区别。

学习本章节前需要理解 Git 工作区、暂存区、本地仓库的概念,可以跳转至 Git 的核心概念

Git 撤销与回退常用命令
#

场景推荐命令是否安全是否改历史
撤销工作区未暂存修改git restore <file>安全
取消暂存git restore --staged <file>安全
修改最后一次提交信息git commit --amend谨慎
撤销某次已提交记录git revert <commit>安全
回退到某个提交git reset --soft/mixed/hard谨慎
reset 后想恢复git reflog救命命令可恢复

撤销工作区未暂存的修改
#

# 撤销工作区指定文件 file.txt 的修改
git restore file.txt

# 撤销工作区所有未暂存修改
git restore .
警告

撤销操作会丢弃工作区未提交的修改,执行前应确认这些内容不再需要。


取消暂存
#

如果不小心把不需要提交的文件加入了暂存区(staging area),可以使用下面的命令将其移出暂存区。

# 取消暂存区指定文件 file.txt 的暂存
git restore --staged file.txt

# 取消暂存区所有暂存文件
git restore --staged .
笔记

git restore --staged 只会把文件从暂存区移回工作区,不会删除你的代码修改。


修改最后一次提交
#

# 修改最后一次 commit message
git commit --amend

# 修改提交信息但不打开编辑器
git commit --amend -m "新的提交信息"

# 把遗漏文件补进上一次提交,--no-edit 表示保留原提交信息。
git add missed-file.txt
git commit --amend --no-edit
提示

如果这次提交已经 push 到远程仓库,不建议随意 amend,因为它会改写提交历史。


撤销已提交内容
#

git revert 不会删除原来的提交,而是生成一个新的提交,用来抵消指定提交的改动。

git revert <commit-id>
# 撤销指定 Commit

适合:

  • 已经推送到远程的提交;
  • 已经被团队共享的提交;
  • 公共分支中的错误修改。

回退版本
#

git reset 会移动当前分支的 HEAD 指针,可以用来回退到某个历史提交。

1. soft 模式:保留暂存区和工作区
#

git reset --soft <commit-id>
# 回退到指定 Commit

git reset --soft HEAD~1
# 从当前提交往回数 1 个提交(即上一次提交)

效果:

  • 移动分支位置;
  • 保留暂存区;
  • 保留工作区修改。

适合重新组织最近一次提交。

2. mixed 模式:保留工作区,清空暂存区
#

git reset --mixed <commit-id>
# 回退到指定 Commit

git reset --mixed HEAD~1
# 从当前提交往回数 1 个提交(即上一次提交)

等同于:

git reset <commit-id>
# 回退到指定 Commit

git reset HEAD~1
# 从当前提交往回数 1 个提交(即上一次提交)

效果:

  • 移动分支位置;
  • 清空相应暂存状态;
  • 保留工作区修改。

3. hard 模式:彻底回退
#

git reset --hard <commit-id>
# 回退到指定 Commit

git reset --hard HEAD~1
# 从当前提交往回数 1 个提交(即上一次提交)

效果:

  • 移动分支位置;
  • 重置暂存区;
  • 重置工作区。
警告

git reset --hard 会丢弃目标提交之后的提交和工作区修改,谨慎使用。

soft、mixed、hard 对比表
#

命令移动 HEAD保留暂存区保留工作区风险
reset --soft
reset --mixed
reset --hard

git revert 和 git reset 的区别
#

git revert 是新增一个提交来撤销旧提交;git reset 是移动 HEAD 指针来回退历史。

对比项git revertgit reset
是否保留原提交保留可能不保留
是否生成新提交
是否改写历史
是否适合已 push 的提交适合不建议
是否适合本地未 push 提交可以适合
  • 什么时候用 revert:提交已经推送到远程仓库,并且别人可能已经基于这个提交开发。

  • 什么时候用 reset:提交还在本地,没有 push,想整理提交历史或回到某个版本。


恢复误删提交
#

git reflog 会记录 HEAD 的移动历史,即使 commit 被 reset 掉,也通常可以通过 reflog 找回来。

# 查看操作记录
git reflog

# 找回 reset --hard 前的提交
git reset --hard <commit-id>

# 更安全的恢复方式:新建分支
git branch recover-branch <commit-id>

reflog 可以帮助恢复:

  • 错误 reset 的提交;
  • 误删分支中的提交;
  • 意外丢失的 HEAD 位置。
Git Mastery - 系列专栏
✦ 8: 本文