Git 版本回退操作指南
目录
一、暂存本地修改
回退前先保存当前未提交的修改。
bash
# 暂存已跟踪文件的修改
git stash
# 暂存修改 + 未跟踪的新文件
git stash -u
# 给暂存取个名字,方便查找
git stash save "my-feature-wip"
# 查看暂存列表
git stash list
二、回退版本
查看提交历史
bash
# 简洁模式查看最近 5 次提交
git log --oneline -5
三种回退模式
| 模式 | 命令 | 效果 | 适用场景 |
|---|---|---|---|
| 软回退 | git reset --soft HEAD~1 |
回退提交,改动保留在暂存区 | 回退后想修改再重新提交 |
| 混合回退 | git reset HEAD~1 |
回退提交,改动保留在工作区(未暂存) | 回退后查看改动,选择性提交 |
| 硬回退 | git reset --hard HEAD~1 |
回退提交,完全丢弃改动 | 那个提交完全不要了 |
HEAD~1表示回退 1 个版本,HEAD~3表示回退 3 个版本,也可用具体的 commit hash 替代。
用 revert 代替 reset(推荐用于受保护分支)
bash
# 生成一个新的"反向提交"来撤销目标提交,不改写历史
git revert HEAD
# 撤销指定提交
git revert <commit-hash>
# 撤销最近 3 次提交(默认会从新到旧依次撤销提交,并生成多个新的 revert 提交)
git revert HEAD~3..HEAD
revert不改写历史,生成新提交来抵消旧提交的改动,适合受保护分支和多人协作。
reset vs revert 对比
| 对比项 | git reset |
git revert |
|---|---|---|
| 是否改写历史 | 是 | 否 |
| 推送回退后是否需要 force push | 是 | 否 |
| 适合受保护分支 | 否 | 是 |
| 适合多人协作 | 需谨慎 | 推荐 |
| 适用场景 | 个人分支、本地回退 | 公共分支、已推送的提交 |
三、暂存区与工作区操作
暂存区 → 工作区(取消暂存)
bash
# 取消暂存单个文件
git restore --staged <文件名>
# 取消暂存所有文件
git restore --staged .
# 旧版写法(效果相同)
git reset HEAD <文件名>
git reset HEAD
丢弃工作区修改(慎用)
bash
# 丢弃单个文件的本地修改
git restore <文件名>
# 丢弃所有本地修改
git restore .
状态流转总结
git add git commit
工作区 ──────────→ 暂存区 ──────────→ 仓库
↑ │
│ │
│ ↓
└───────────────────
git restore --staged
git stash git stash pop
工作区 ──────────→ stash栈 ──────────→ 工作区
四、推送回退到远程
个人分支(允许 force push)
bash
# 安全强推(会检查远程是否有他人新提交)
git push --force-with-lease
# 普通强推(不推荐,可能覆盖他人代码)
git push --force
--force-with-lease比--force更安全,远程有别人新推的提交时会拒绝执行。
受保护分支(禁止 force push)
GitLab/GitHub 的受保护分支(如 release、main)会拒绝 force push,报错:
remote: You are not allowed to force push code to a protected branch
解决方案:
| 方案 | 操作 | 推荐度 |
|---|---|---|
| 方案 A | 使用 git revert 代替 git reset,正常 push |
⭐ 推荐 |
| 方案 B | 让管理员临时解除分支保护 → force push → 重新开启保护 | 需要管理员权限 |
五、完整操作流程
场景 1:个人分支回退一个版本
bash
# 1. 暂存本地修改
git stash
# 2. 查看提交历史
git log --oneline -5
# 3. 软回退一个版本(最安全)
git reset --soft HEAD~1
# 4. 恢复本地修改
git stash pop
# 5. 确认后强推到远程
git push --force-with-lease
场景 2:受保护分支回退一个版本
bash
# 1. 确保在最新代码上
git pull
# 2. 用 revert 撤销最近一次提交
git revert HEAD
# 在编辑器中保存退出(vim: Esc → :wq → Enter)
# 3. 正常推送
git push
场景 3:本地已有修改,想回退后再合并
bash
# 1. 暂存本地修改
git stash
# 2. 回退版本
git reset --soft HEAD~1
# 3. 将暂存区内容移到工作区
git restore --staged .
# 4. 恢复本地修改(可能产生冲突,手动解决)
git stash pop
# 5. 解决冲突后提交
git add .
git commit -m "fix: revert and merge changes"
六、常见问题
Q: git stash pop 后出现冲突怎么办?
打开冲突文件,找到冲突标记:
<<<<<<< Updated upstream
暂存区的内容
=======
工作区的内容
>>>>>>> Stashed changes
手动选择保留哪些代码,删除冲突标记后:
bash
git add <冲突文件>
Q: 回退后如何恢复?
bash
# 查看所有操作记录
git reflog
# 找到回退前的 commit hash,恢复
git reset --hard <commit-hash>
Q: --force-with-lease 和 --force 有什么区别?
--force:无条件覆盖远程分支--force-with-lease:检查远程是否有其他人的新提交,有则拒绝,防止误覆盖