Git Reset
最后更新
git reset 把当前分支移动到另一个提交,并根据所选模式更新暂存区(索引)和工作区,让它们与之对应。三种模式的区别只在于更新的范围:--soft 只移动分支,--mixed(默认)还会重置暂存区,--hard 还会覆盖工作区中的文件。
由于 --hard 会丢弃未提交的工作,运行之前要清楚自己需要哪种模式。对于已经推送的提交,最好改用 git revert。在终端在线编辑器中放心试试这些命令,浏览器里就是真正的 shell。
三种模式
| 模式 | 移动分支 | 重置暂存区 | 重置工作区 |
|---|---|---|---|
--soft | 是 | 否 | 否 |
--mixed(默认) | 是 | 是 | 否 |
--hard | 是 | 是 | 是 |
语法
| 命令 | 作用 |
|---|---|
git reset --soft HEAD~1 | 撤销最后一个提交,改动保留在暂存区 |
git reset HEAD~1 | 撤销最后一个提交,改动保留为未暂存 |
git reset --hard HEAD~1 | 撤销最后一个提交,并丢弃改动 |
git reset <file> | 取消暂存某个文件(保留其改动) |
git reset --hard origin/main | 强制让本地分支与远程一致 |
常见用法
| 目标 | 命令 |
|---|---|
| 取消暂存所有文件 | git reset |
| 取消暂存一个文件 | git reset README.md |
| 回退 3 个提交,保留工作内容 | git reset --soft HEAD~3 |
| 丢弃某个提交之后的所有本地改动 | git reset --hard <hash> |
git reset 常见问题
--soft、--mixed 和 --hard 有什么区别?
三者都会把分支指针移动到目标提交,区别在于还会影响哪些地方。
--soft 不改动其他任何东西,所以你的改动仍在暂存区。--mixed(默认)还会清空暂存区,改动变为未暂存,但仍保留在文件中。--hard 还会覆盖工作区,使其与目标提交一致,丢弃所有未提交的改动。怎么用 git reset 取消暂存文件?
运行
git reset <file>(例如 git reset README.md),或者不带路径运行 git reset,取消暂存所有文件。这会把文件移出暂存区,但工作区中的修改都会保留。在较新的 Git 中,也可以用 git restore --staged <file>,效果相同,意图更明确。git reset --hard 可以撤销吗?
工作区无法恢复:
--hard 会永久丢弃未提交的改动。不过,被 reset 掉的已提交工作通常可以找回:运行 git reflog 找到该提交的哈希值,再运行 git reset --hard <hash>(或在它上面创建一个分支)。从未暂存或提交过的改动无法恢复,所以使用 --hard 要谨慎。git reset 和 git revert 有什么区别?
git reset 通过把分支往回移动来改写历史,对本地提交没问题,但对已经推送的提交很危险。git revert 不改动历史,而是新增一个提交来撤销之前的提交,这才是共享分支上的安全选择。git reset --soft HEAD~1 是做什么的?
它撤销最后一个提交,但把该提交的所有改动保留在暂存区。
HEAD~1 表示当前提交的前一个提交,所以分支会后退一步,而暂存区和工作区保持不变。这是重做一次提交最快的方法:修改文件或提交信息,然后重新提交。其他做法请看 git 撤销最后一次提交。HEAD~1 是什么意思?
HEAD 是你当前所在的提交,~1 表示它的第一个父提交,也就是往前一个提交。HEAD~2 是往前两个提交,以此类推。对于普通提交,HEAD^ 和 HEAD~1 是一样的。可以在线练习吗?
可以。打开终端在线编辑器,就能在浏览器里的真实 shell 中运行
git reset,无需安装。Coddy 的免费互动 Git 课程也会一步步教你重置和撤销更改。