Git进阶 — 6、Git找回丢失代码 git fsck --lost-found
1. 查找丢失数据
1 |
|
git fsck –lost-found 是一个写出文件动作,执行该命令前不会有以下 lost-found目录。执行之后会根据情况将悬挂对象写入.git/lost-found/commit/或.git/lost-found/other/
具体取决于类型。如果对象是blob,则将内容写入文件中,而不是其对象名称。
1.1. commit目录
丢失的commit信息,丢失的stash信息
1.2. other目录
add但未commit的,请看示例
add但未commit恢复方法
2. 适用场景
2.1. 误删branch
2.2. 误删stash
2.3. 切换branch丢失commit
2.4. add后未commit执行了git reset –hard
如果你没有
commit
你的本地修改(甚至于你都没有通过git add
追踪过这些文件,当他们被删除,git reset --hard
对于这些没有被commit过也没有git add过的修改来说就是具有毁灭性的
but,如果你幸运的是曾经通过git add命令追踪过这些文件,只是没有commit它们而已!那么试试git fsck --lost-found
这个命令吧!然后你就可以在本地项目文件中路径为.git/lost-found/other
中找到它们!!并且呢,这里面包含了所有的没有被commit(指定到某次commit)的文件,甚至可能还包括你每次git add的版本(version一词实在不知道在这里怎么翻译,姑且就认为是版本吧)!
使用git fsck –lost-found这个命令,通过.git/lost-found/other这个路径,你可以恢复任何你git add过的文件!再通过find .git/objects -type f | xargs ls -lt | sed 60q这个命令,你就可以找到最近被你add到本地仓库的60个文件
当然咯,如果你没有git add过的文件呢,被git reset –hard这个命令整过之后呢,就如你自己执行delete命令一样,再也尸骨难寻啦(也就是真的毛都不剩了!!默哀三秒)!!!!
q
表示退出,不再处理后续内容。比如sed '2q' p.txt
执行到第二行后退出。
3. 演示示例
1 |
|
存储当前仓库未提交的改动,也便于后面演示如何恢复stash
1 |
|
3.1. 恢复误删除分支提交
现在repo里有两个branch
1 |
|
删除一个分支
1 |
|
1 |
|
3.2. 查看当天的丢失记录
用git fsck –lost-found命令找出刚才删除的分支里面的提交对象
或者使用下面的shell脚本
1 |
|
可以看到我们丢失的分支cool_branch中的commit为9144,正是我们演示示例中的commit
值得注意的是:此时我们执行git fsck --unreachable
不会得到任何信息,因为已经删除了
3.3. commit恢复方法
3.3.1. git rebase
1 |
|
1 |
|
我们可以发现被误删分支cool_branch的提交21a2被rebase到了master分支上
但丢失的分支是无法找回的
3.3.2. git merge
为了演示git merge方法,我们使用下面的命令把上面恢复的分支提交再次删掉
1 |
|
我们可以看到丢失的分支提交仍然是21a2
执行git merge
1 |
|
1 |
|
3.3.3. patch
git-format-patch将提交导出为补丁文件,然后可以将其应用于另一个分支或克隆的存储库。补丁文件表示单个提交,Git在导入补丁文件时重新提交。
git-format-patch是将更改从一个存储库副本转移到另一个存储库副本的短流程中的第一步。当Git只在本地使用而没有远程存储库时,旧的方式是通过电子邮件将补丁互相发送。如果您只需要向某人提交一次提交,而不需要合并分支和随之而来的开销,那么这是非常方便的。
为方便演示,这里重新执行了3.演示示例 查找丢失commit信息如下:
漾我们把丢失的commit打成补丁
1 |
|
检查patch能否正常应用
1 |
|
不报错就是最好的暗示🤭
应用patch
1 |
|
或者
1 |
|
同样的,不报错就是最好的暗示😉
查看版本库状态git status
git add .
git commit
git log
git show c73c
查看工作区文件
查看cool_file内容
可以看到丢失的分支cool_branch上的提交,以打补丁的方式补在了master分支上
3.4. blob对象恢复
可以通过查看当天的丢失记录,也可以通过以下脚本查看最近的60次add的文件列表,然后进去查看内容
1 |
|
我们恢复的时候只能恢复unreachable commit 开头的记录,unreach blob是不能用git statsh apply+sha-1来恢复的,会报not a stash-like commit 错误
3.4.1. 手动粘贴
1 |
|
1 |
|
3.5. stash恢复方法
把前面演示示例stash的内容清空
1 |
|
1 |
|
也可以用git show e38f
或者git cat-file -p e38f
查看commit对象的具体内容
3.5.1. git merge
1 |
|
因为这里的类型还是commit,git merge方法上面已经演示过,我们只演示下面的git stash apply方法
3.5.2. git stash apply
1 |
|
值得注意的是,stash类型的commit恢复可以使用git stash apply和git merge方法,但是非stash的commit对象无法使用git stash apply方法,否则会提示以下错误信息
3.6. add但未commit恢复方法
演示准备
1 |
|
我们可以看到它是一个blog对象,这种对象是无法直接rebase或者merge或者打补丁,也没法apply,只能通过手动粘贴的方式找回自己的劳动成果,请见3.4.blob对象恢复
4. 参考
https://git-scm.com/docs/git-fsck
https://www.jianshu.com/p/2c900550c076
https://www.cnblogs.com/liulaolaiu/archive/2012/08/08/11744888.html