1. 概述
在实际开发过程中,我们可能会不小心删除某个 Git 分支。虽然分支被删除了,但 Git 的底层机制并不会立即清除相关提交,只要提交未被垃圾回收,我们依然有机会将其恢复。
本文将介绍如何在删除分支后找回该分支的提交,并重新创建分支。
2. 场景说明
假设我们有如下 Git 分支结构:
我们通过以下命令构建这个结构:
$ git commit --allow-empty -m "original commit"
$ git checkout -b demonstration-branch
$ git commit --allow-empty -m "first commit on demonstration branch"
$ git commit --allow-empty -m "second commit on demonstration branch"
$ git switch main
$ git commit --allow-empty -m "commit only on main branch"
接着我们删除了 demonstration-branch
:
$ git branch -D demonstration-branch
Deleted branch demonstration-branch (was b7fb867).
Git 中的分支只是一个指向某个提交的引用,删除分支并不会立即删除该提交。只要提交未被 Git 的垃圾回收机制清理,我们就可以通过提交哈希重新恢复该分支。
3. 获取提交哈希的方法
恢复分支的关键在于找到该分支最后一次提交的哈希值。以下是几种常见方式。
3.1. 从 reflog 中查找
Git 的 reflog
会记录所有引用变更,包括分支切换、提交、删除等操作。
执行如下命令查看 reflog:
$ git reflog
0eeb0fd (HEAD -> main) HEAD@{0}: commit: commit only on main branch
b2cc5bf HEAD@{1}: checkout: moving from demonstration-branch to main
b7fb867 HEAD@{2}: commit: second commit on demonstration branch
(...)
可以看到,demonstration-branch
上的最后一次提交哈希是 b7fb867
。如果需要完整哈希,可以加上 --no-abbrev
参数:
$ git reflog --no-abbrev
⚠️ 注意:reflog 默认保留 90 天,超过这个时间后会被 Git 的垃圾回收机制清理。
3.2. 使用 git fsck 查找
当 reflog 中已经找不到相关信息时,可以使用 git fsck
命令查找“悬挂”提交(dangling commit):
$ git fsck --no-reflogs --unreachable | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline
Checking object directories: 100% (256/256), done.
b7fb8673a10d204267aae6c3bce19981eb417567 second commit on demonstration branch
5990c977f78c9a5b9d6d72853bad0b699078f207 first commit on demonstration branch
命令解释如下:
--no-reflogs
:忽略 reflog 中存在的提交。--unreachable
:只查找未被引用的提交。grep commit
:筛选出提交记录。cut -d\ -f3
:提取哈希值。xargs -n 1 git log -n 1 --pretty=oneline
:展示提交信息便于识别。
✅ 优点:即使 reflog 已过期,也可以通过此方法找回提交。
4. 重新创建分支
找到提交哈希后,我们就可以重新创建分支。使用如下命令:
$ git branch demonstration-branch b7fb867
此时可以切换到该分支查看提交历史:
$ git switch demonstration-branch
$ git log
commit b7fb8673a10d204267aae6c3bce19981eb417567
(...)
second commit on demonstration branch
commit 5990c977f78c9a5b9d6d72853bad0b699078f207
(...)
first commit on demonstration branch
commit b2cc5bfa22eb733da78e2f200ffda8c6b39d4b29
(...)
original commit
✅ 提示:也可以使用 git checkout -b
来创建并切换分支。
5. 总结
Git 删除分支并不会立即清除提交记录,只要这些提交未被垃圾回收,我们就可以通过 reflog 或 git fsck 找到提交哈希并重新创建分支。
⚠️ 踩坑提醒:
- reflog 有保留时间限制(默认 90 天),不要依赖它长期保存历史信息
- 提交被 Git 垃圾回收后将无法恢复,恢复操作应尽早执行
所以,一旦发现分支误删,动作要快,姿势要帅。