Git 回退到某个 commit
核心总结:如何选择?
先给你一个快速决策指南:
- 只想看看旧版本的代码,不修改历史:用
git checkout。 - 本地分支搞砸了,想彻底删除最近的提交(未推送到远程):用
git reset。 - 已经推送到远程的提交需要撤销,且需要保留撤销记录(安全):用
git revert。
方法一:git reset (重置)
会移动 指针,可以用来彻底'抹掉'某个 commit 之后的所有提交。它会修改历史记录。
介绍 Git 回退到指定 Commit 的三种主要方法。git reset 用于本地分支重置历史,分为 soft、mixed、hard 模式;git revert 通过创建新提交撤销更改,适用于已推送的共享分支;git checkout 用于临时查看旧版本或创建新分支。此外,git reflog 可用于恢复误删的提交记录。根据是否涉及远程共享及是否需要保留历史记录选择合适的命令。
先给你一个快速决策指南:
git checkout。git reset。git revert。git reset (重置)会移动 指针,可以用来彻底'抹掉'某个 commit 之后的所有提交。它会修改历史记录。
git resetHEAD适用场景:仅限私有分支/本地分支。如果你回退的 commit 已经被推送到了远程共享分支(如 main 或 develop),请不要使用 git reset,因为它会造成其他协作者的历史记录混乱。
git reset 的三种模式:假设你的提交历史是 A - B - C - D (当前在 D),你想回退到 B。
--soft (软重置)
git reset --soft <commit-id>HEAD 指针移动到 <commit-id>。C 和 D 的代码更改,并将它们放回暂存区 (Staging Area)。--mixed (混合重置,默认模式)
git reset --mixed <commit-id> 或 git reset <commit-id>HEAD 指针移动到 <commit-id>。C 和 D 的代码更改,但将它们放回工作目录 (Working Directory),而不是暂存区。--hard (硬重置,最常用也最危险)
git reset --hard <commit-id>HEAD 指针移动到 <commit-id>。C 和 D 的所有代码更改。<commit-id> 的状态。--hard)git log 查看提交历史。git log --oneline
# a1b2c3d (HEAD -> main) feat: add new feature D
# e4f5g6h fix: resolve bug C
# i7j8k9l chore: update readme B <-- 目标 commit
# m0n1p2q initial commit A
假设你想回退到 i7j8k9l 这个 commit。
git reset --hard i7j8k9l
此时你的本地 main 分支现在就只到 i7j8k9l 了,a1b2c3d 和 e4f5g6h 这两个 commit 在你的分支历史上'消失'了。
如果你之前已经把 D commit 推送上去了,现在想用回退后的版本覆盖远程分支,你需要强制推送。
# 警告:这个操作会重写远程仓库的历史记录,请确保没有其他人在这个分支上工作!
git push origin main --force
git revert (撤销)git revert 会创建一个新的 commit,这个新 commit 的内容是用来抵消你想要撤销的那个 commit 的修改。它不会修改历史记录,而是向前追加历史。
适用场景:任何情况,尤其是已经推送到远程的共享分支。这是最安全的回退方式,因为它保留了完整的提交历史,方便追溯。
假设你想撤销 e4f5g6h 这个 commit 的更改。
git log --oneline
# a1b2c3d (HEAD -> main) feat: add new feature D
# e4f5g6h fix: resolve bug C <-- 目标 commit
# i7j8k9l chore: update readme B
git revert e4f5g6h
执行命令后,Git 会自动打开一个编辑器,让你编辑这个'撤销 commit'的提交信息。默认信息通常是 Revert "fix: resolve bug C"。你可以直接保存退出。
因为是新增 commit,所以可以像正常提交一样推送。
git push origin main
结果
你的提交历史会变成这样:
# r3s4t5u (HEAD -> main) Revert "fix: resolve bug C" <-- 新增的 revert commit
# a1b2c3d feat: add new feature D
# e4f5g6h fix: resolve bug C
# i7j8k9l chore: update readme B
代码状态上,e4f5g6h 的修改已经被移除了,但这个 commit 本身还存在于历史记录中。
git checkout (检出)git checkout 主要用于切换分支或恢复文件,但也可以用来查看某个旧版本的状态。
适用场景:只想临时查看一下某个旧版本的内容,或者基于某个旧版本创建一个新的分支。
git log --oneline
# ...
# i7j8k9l chore: update readme B <-- 目标 commit
# ...
git checkout i7j8k9l
结果
i7j8k9l 这个 commit 的样子。基于这个旧版本创建一个新分支继续工作:
# 从当前分离头指针状态创建一个名为 new-feature 的新分支
git checkout -b new-feature
回到原来的分支:
git checkout main
git reflog如果你用 git reset --hard 搞错了,把不该删的 commit 删掉了怎么办?别慌!只要这些 commit 还在你的本地仓库里(没被 Git 的垃圾回收机制清理),你就可以用 git reflog 找回来。
git reflog 记录了你本地 HEAD 的所有移动历史。
git reflog
# 0a8b7c6 HEAD@{0}: reset: moving to i7j8k9l
# a1b2c3d HEAD@{1}: commit: feat: add new feature D <-- 这是你误删的 commit
# e4f5g6h HEAD@{2}: commit: fix: resolve bug C
# ...
你可以看到 a1b2c3d 就是你 reset 之前的 HEAD 位置。你可以再次用 reset 跳回去。
git reset --hard a1b2c3d
现在,你的分支就神奇地恢复到 reset 之前的状态了!

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online