红联Linux门户
Linux帮助

如何恢复git reset --hard删除的文件

发布时间:2015-09-12 19:07:39来源:linux网站作者:cqbamboo

昨天,不小心使用了下面的Git命令,结果导致了文件被删除了,花了很大力气才恢复出来。


起因:

刚提交了代码,发现还有些文件忘记提交了,于是想revert这个提交。

随便从网上搜了篇文章,然后执行 git reset --hard xxx

结果 ... 发现工作区最近这几天的改动,新创建的文件都没有了。

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:   Linux/device_driver_pci.mm
# modified:   Linux/device_driver_pci.png
# deleted:    Linux/driver/pci/pci-config-space.png
# deleted:    Linux/driver/pci/pci_init.png
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# Linux/driver/pci/pci-config-space-260px.png
# Linux/driver/pci/pci-config-space-520px.png
# Linux/driver/pci/pci-init.png
# Linux/driver/pci/pci-pin-list.png
# Linux/driver/pci/pci-system-block-diagram.png
# Network/
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -am 'update pci driver and add network stuff'
[master 9510636] update pci driver and add network stuff
4 files changed, 792 insertions(+), 72 deletions(-)
rewrite Linux/device_driver_pci.png (91%)
delete mode 100644 Linux/driver/pci/pci-config-space.png
delete mode 100644 Linux/driver/pci/pci_init.png

$ git add Network/

$ git add Linux/driver/pci
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# new file:   Linux/driver/pci/pci-config-space-260px.png
# new file:   Linux/driver/pci/pci-config-space-520px.png
# new file:   Linux/driver/pci/pci-init.png
# new file:   Linux/driver/pci/pci-pin-list.png
# new file:   Linux/driver/pci/pci-system-block-diagram.png
# new file:   Network/MAC_PHY Interface.mm
# new file:   Network/MAC_PHY Interface.png
# new file:   Network/XAUI_XLAUI_CAUI Interface.png
#

$ git log
commit 9510636becf35f83d78622da7cbf02e9231b9e8b
Author: bambreeze <bambreeze@gmail.com>
Date:   Tue Jan 7 22:13:32 2014 +0800

update pci driver and add network stuff

commit 1d2b02818e8faac92927048e05c0ce98ca88096c
Author: bambreeze <bambreeze@gmail.com>
Date:   Tue Dec 31 18:55:34 2013 +0800

update pci driver

$ git reset --hard 1d2b02818e8fa
HEAD is now at 1d2b028 update pci driver
$ git status
# On branch master
nothing to commit (working directory clean)


解决办法:

当时,看到“working directory clean”,感觉就不对劲。检查了一下目录/文件,发现最近的改动全没有了,果然是干干净净啊!

所以,使用这个命令 git reset --hard 一定要小心!


第一步,从网上搜索到可以恢复到最近提交的代码

$ git reflog
1d2b028 HEAD@{0}: reset: moving to 1d2b02818e8fa
9510636 HEAD@{1}: commit: update pci driver and add network stuff
1d2b028 HEAD@{2}: commit: update pci driver
e4e042b HEAD@{3}: commit: add infrastructure of Linux pci driver
eb7ac57 HEAD@{4}: commit: update i2c driver - add at24 device
034034f HEAD@{5}: commit: update i2c linux driver - example of mini2440
17e0bfb HEAD@{6}: commit: add some diagram for i2c driver
1f382d7 HEAD@{7}: commit: update i2c driver - overview
ff6f096 HEAD@{8}: commit: update i2c driver - SMBus extention
d5bd8cf HEAD@{9}: commit: update i2c device driver - i2c stub driver
8a51d9c HEAD@{10}: commit: update i2c device driver - Multiplexed I2C bus driver
2eab503 HEAD@{11}: commit: update i2c device driver - reorgnized the blocks
e03169e HEAD@{12}: commit: update i2c device driver mindmap
0a5ffa9 HEAD@{13}: commit: add device driver for i2c subsystem
ca46ee2 HEAD@{14}: clone: from git@github.com:bambreeze/mindmap.git
$ git reset 9510636
Unstaged changes after reset:
M Linux/device_driver_pci.mm
M Linux/device_driver_pci.png
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:   Linux/device_driver_pci.mm
# modified:   Linux/device_driver_pci.png
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# Linux/driver/pci/
no changes added to commit (use "git add" and/or "git commit -a")


好吧,现在恢复出了上次已经提交的东东,有了一点进展,赶快备份到另外一个地方。

可是,我还有不少已经 staged ,但是还没有提交的文件被删除了呢!

继续找办法,终于在 stackoverflow 找到了 (我估计这里也有)

If you didn't already commit your local changes (or at least stage them via git add, they're gone. git reset --hard is a destructive operation for uncommitted changes. If you did happen to stage them, but didn't commit them, try git fsck --lost-found and then search through the contents of .git/lost-found - it will contain all of the objects that aren't referenced by a known commit, and may include versions of files that were staged.

You can recover anything you git added, with git fsck --lost-found and poke around in.git/lost-found. find .git/objects -type f | xargs ls -lt | sed 60q will give you the last 60 things to get added to the repo, that'll help. Anything you didn't git add is gone as surely as if you'd deleted it yourself.


简而言之,就是你 staged 了,但是还没有提交的东西,还是可以恢复的。具体的恢复过程,又找了篇文章(参考2)

$ find .git/objects -type f | xargs ls -lt | sed 20q
-r--r--r--  1 fazhang  staff    73399 Jan  7 22:14 .git/objects/49/a787a1cd6303cadd071724196d6f81a8ed3f2f
-r--r--r--  1 fazhang  staff    61494 Jan  7 22:14 .git/objects/63/c15d529966a5a32bf9d83868554ab557a1e3f0
-r--r--r--  1 fazhang  staff    10324 Jan  7 22:14 .git/objects/9f/630c0e1d66a119b5251694a64dfb1f6adf1235
-r--r--r--  1 fazhang  staff    45197 Jan  7 22:14 .git/objects/e1/fa99d0752478a082f6e68ce4c37f44fe64041b
-r--r--r--  1 fazhang  staff    57479 Jan  7 22:14 .git/objects/82/31f83dc25e8a1274419e1f0d53ea679f309d3f
-r--r--r--  1 fazhang  staff      891 Jan  7 22:14 .git/objects/8e/552663977d7bfa8b55b29c2262dc83e66f7c1f
-r--r--r--  1 fazhang  staff    29913 Jan  7 22:14 .git/objects/96/aef1025425ee1dccd249e3325c11ac2dbd28df
-r--r--r--  1 fazhang  staff     7106 Jan  7 22:13 .git/objects/0a/89d1a50c78874927da7b7c68587b57a6876ec1
-r--r--r--  1 fazhang  staff      175 Jan  7 22:13 .git/objects/95/10636becf35f83d78622da7cbf02e9231b9e8b
-r--r--r--  1 fazhang  staff   525702 Jan  7 22:13 .git/objects/b6/1733ec44668b4019459c03123f8f8955026eb5
-r--r--r--  1 fazhang  staff      118 Jan  7 22:13 .git/objects/d2/856654cdb7a63a9a853182b74e32761b958104
-r--r--r--  1 fazhang  staff      424 Jan  7 22:13 .git/objects/d7/54daa8cb92a0dc6afd6010ad9e38fddb4163f6
-r--r--r--  1 fazhang  staff      158 Dec 31 18:55 .git/objects/1d/2b02818e8faac92927048e05c0ce98ca88096c
-r--r--r--  1 fazhang  staff       94 Dec 31 18:55 .git/objects/86/241ce44ffe2fcdbb142b3e5e50e9397e4552f1
-r--r--r--  1 fazhang  staff      117 Dec 31 18:55 .git/objects/98/b3962e067f0d06039413d5d610afea326f83b5
-r--r--r--  1 fazhang  staff      857 Dec 31 18:55 .git/objects/bf/326b01c7693515fb2d054dbc68cd6bf869f783
-r--r--r--  1 fazhang  staff      425 Dec 31 18:55 .git/objects/ee/ca3bf3cea2234a332bec71cd15216c1c72e9a0
-r--r--r--  1 fazhang  staff     2767 Dec 31 18:55 .git/objects/00/86c082b4d9a5f82a7837bd33a4c231224eecd7
-r--r--r--  1 fazhang  staff   102764 Dec 31 18:55 .git/objects/6d/911544077e1864b54e4e4a4ea2781f2eba595e
-r--r--r--  1 fazhang  staff   244721 Dec 31 18:55 .git/objects/cd/3759406069efaaf7ad5191286025e04d95eaec

$ git cat-file -p 49a787a1cd6303cadd071724196d6f81a8ed3f2f > ~/b1.png
$ git cat-file -p 63c15d529966a5a32bf9d83868554ab557a1e3f0 > ~/abc.png
$ git cat-file -p 9f630c0e1d66a119b5251694a64dfb1f6adf1235 > ~/abc.png
$ git cat-file -p e1fa99d0752478a082f6e68ce4c37f44fe64041b > ~/abc.png
$ git cat-file -p 8231f83dc25e8a1274419e1f0d53ea679f309d3f > ~/abc.png
$ git cat-file -p 8e552663977d7bfa8b55b29c2262dc83e66f7c1f > ~/abc.mm
$ git cat-file -p 96aef1025425ee1dccd249e3325c11ac2dbd28df > ~/abc.png
$ git cat-file -p 0a89d1a50c78874927da7b7c68587b57a6876ec1 > ~/abc.txt
$ git cat-file -p 0a89d1a50c78874927da7b7c68587b57a6876ec1 > ~/abc.mm
$ git cat-file -p 9510636becf35f83d78622da7cbf02e9231b9e8b > ~/abc.txt
$ git cat-file -p b61733ec44668b4019459c03123f8f8955026eb5 > ~/abc.png
$ git cat-file -p d2856654cdb7a63a9a853182b74e32761b958104 > ~/abc.txt
$ git cat-file -p d754daa8cb92a0dc6afd6010ad9e38fddb4163f6 > ~/abc.txt


使用git更新github上的开源项目:http://www.linuxdiyf.com/linux/14033.html

如何删除在Github中创建的项目:http://www.linuxdiyf.com/linux/12509.html

怎样在Github上托管开源代码库:http://www.linuxdiyf.com/linux/12226.html

通过GitHub创建个人技术博客图文详解:http://www.linuxdiyf.com/linux/8874.html

如何在GitHub创建一个“有人用”的项目:http://www.linuxdiyf.com/linux/2830.html