如何将Git仓库恢复到之前的提交版本

如何将Git仓库恢复到之前的提交版本

技术背景

在使用Git进行版本控制时,经常会遇到需要将仓库恢复到之前某个提交版本的情况。可能是因为最新的提交引入了错误,或者想要尝试之前某个版本的代码状态。理解如何正确地回退到之前的提交版本,对于代码的管理和维护至关重要。

什么是HEAD

HEAD 是一个指向当前分支上最新提交的引用。在任何给定时间(不考虑 git worktree),只能有一个 HEADHEAD 的内容存储在 .git/HEAD 文件中,包含当前提交的40字节 SHA - 1哈希值。

detached HEAD

HEAD 指向历史中的某个先前提交,而不是当前分支的最新提交时,就称为 detached HEAD。在命令行中,显示的是 SHA - 1哈希值而不是分支名称。

实现步骤

临时切换到不同的提交

如果只是想临时回到某个提交,进行一些尝试后再回到当前位置,可以使用 git checkout 命令:

1
2
# 这将使 HEAD 分离,即没有检出任何分支
git checkout 0d1d7fc32

如果想在该提交处进行新的提交,可以创建一个新分支:

1
git checkout -b old-state 0d1d7fc32

要回到原来的位置,只需再次检出原来的分支。

硬删除未发布的提交

如果想彻底删除自某个提交以来的所有更改,且这些提交尚未发布,可以使用 git reset 命令:

1
2
3
4
5
6
7
8
# 这将销毁任何本地修改。如果有未提交的工作需要保留,请勿使用此命令
git reset --hard 0d1d7fc32

# 或者,如果有需要保留的工作
git stash
git reset --hard 0d1d7fc32
git stash pop
# 这会保存修改,然后在重置后重新应用该补丁。如果自重置到的提交以来修改了某些内容,可能会出现合并冲突

用新提交撤销已发布的提交

如果提交已经发布,不建议使用 reset 命令,因为这实际上是重写历史。在这种情况下,可以使用 git revert 命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 列出 0d1d7fc 和 HEAD 之间的所有合并提交
git log --merges --pretty=format:"%h" 0d1d7fc..HEAD | tr '\n' ' '

# 列出 0d1d7fc 和 HEAD 之间的所有非合并提交
git log --no-merges --pretty=format:"%h" 0d1d7fc..HEAD | tr '\n' ' '

# 创建三个单独的撤销提交,仅使用非合并提交
git revert a867b4af 25eee4ca 0766c053

# 撤销最后两个提交
git revert HEAD~2..HEAD

# 撤销一系列提交
git revert 0d1d7fc..a867b4a

# 撤销合并提交
git revert -m 1 <merge_commit_sha>

将工作副本恢复到最近的提交

要忽略任何更改,恢复到上一个提交,可以使用:

1
git reset --hard HEAD

将工作副本恢复到旧的提交

1
2
3
4
5
6
7
8
9
10
11
12
13
# 将索引重置到前一个提交;将 '56e05fced' 替换为你的提交代码
git reset 56e05fced

# 将指针移回到上一个 HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# 更新工作副本以反映新的提交
git reset --hard

# 将更改推送到相应的分支
git push -f

核心代码

临时切换提交

1
2
git checkout 0d1d7fc32
git checkout -b old-state 0d1d7fc32

硬删除未发布提交

1
2
3
4
git reset --hard 0d1d7fc32
git stash
git reset --hard 0d1d7fc32
git stash pop

撤销已发布提交

1
2
3
4
git revert a867b4af 25eee4ca 0766c053
git revert HEAD~2..HEAD
git revert 0d1d7fc..a867b4a
git revert -m 1 <merge_commit_sha>

恢复到最近提交

1
git reset --hard HEAD

恢复到旧提交

1
2
3
4
5
git reset 56e05fced 
git reset --soft HEAD@{1}
git commit -m "Revert to 56e05fced"
git reset --hard
git push -f

最佳实践

  • 未发布提交:如果提交尚未发布,可以使用 git reset --hard 安全地删除不需要的提交。
  • 已发布提交:对于已发布的提交,使用 git revert 来创建新的提交来撤销更改,避免重写历史。
  • 保留更改:如果想保留更改但撤销提交,可以使用 git reset --soft

常见问题

  • 丢失提交历史:使用 --force 选项进行推送时,会重写历史,可能导致团队成员的问题。建议使用 git push --force-with-lease 来避免覆盖远程添加的新提交。
  • 合并冲突:在使用 git stash popgit revert 时,可能会出现合并冲突,需要手动解决冲突后再进行提交。
  • detached HEAD 状态:在 detached HEAD 状态下进行操作后,记得创建新分支或切换回原来的分支,以避免丢失工作。

如何将Git仓库恢复到之前的提交版本
https://119291.xyz/posts/2025-05-07.how-to-revert-git-repo-to-previous-commit/
作者
ww
发布于
2025年5月7日
许可协议