我添加了一个新文件F1,并对另一个文件F2进行了更改,但随后执行了“git reset --hard HEAD ^”,我丢失了对文件的所有更改。
是否有某种方式,我可以让它们回来。
我确实在这里查看了一个相关的问题:How can I undo git reset --hard HEAD~1?但是,这个问题假定那个人做了一个git提交。
答案 0 :(得分:97)
您可以(通过一些工作)在最后一个“git add < file> ”恢复文件状态。你可以使用
$ git fsck --cache --no-reflogs --lost-found --unreachable HEAD
然后检查'.git / lost-found / other'目录中的文件。
请阅读git fsck联机帮助页。
答案 1 :(得分:24)
(我假设丢失的文件不是任何提交的一部分。否则,git log --all -g --diff-filter=D --stat
是你的朋友。)
获取git
知道文件名的无法访问的文件列表:
git fsck --unreachable --no-reflogs --no-cache HEAD | fgrep " tree " \
| cut -d " " -f3 | xargs -r -n1 git ls-tree \
| fgrep " blob " | cut -d " " -f 3- | sort -k2 -u
如果您看到有趣的内容,git cat-file blob SHA-1-of-interesting-file
会将文件输出到标准输出。 (例如:git cat-file blob b8f0bdf56 > recovered-logo.png
)
不幸的是,如果丢失的文件不是任何提交的一部分,git没有时间戳,因此,您无法打印按时间排序的各种版本的文件。
如果丢失的文件从未上过阶段(git stage
或git add
)或被隐藏(git stash
),那么你几乎没有运气,因为就git所知,文件从未存在过。 (您仍然可以尝试执行git fsck --no-reflogs --lost-found
并在目录.git/lost-found/other
中查看,看看您是否有任何值得保留的内容,以防git确实拥有您遗失的文件的副本,但是您还没有。在这种情况下,文件名可以帮助您,只有文件内容。)
如果你刚刚丢失了一些提交(而不仅仅是文件),你可能想要运行这样的东西:
gitk --all $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
这将运行gitk
所有分支,所有reflog和所有悬空提交。如果您的repo有很多提交(比如linux内核),您可能需要添加-n 10000
或其他一些限制。如果您没有gitk
,则可以仅使用如下命令行运行较小版本:
git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
或具有较少详细输出的版本
git log --all --decorate --oneline --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
如果您看到某些提交要保存为分支recovered1
,只需执行git checkout -b recovered1 <sha1-of-the-commit>
。
答案 2 :(得分:5)
有一个git plugin
开箱即用:
https://github.com/pendashteh/git-recover-index
$ cd /path/to/disatered/repo
$ git clone git@github.com:pendashteh/git-recover-index.git $HOME/.git-recover-index
$ $HOME/.git-recover-index/git-recover-index.sh
答案 3 :(得分:4)
实际上,如果你已经将对象添加到索引中(通过使用git add),则会为该对象的状态创建一个blob - 但是没有树(因此,commit)对象引用它。这就是人们获取“悬空”松散目标文件的方法,如果你运行git fsck,它会显示未引用的blob(如果运行git gc会删除这些类型的对象)。
因此,您可以使用reflog(如果已启用它)尝试恢复已添加的文件F1的索引状态。如果你还没有添加F2,那么就像格雷格所说的那样,git对此一无所知,你在那里运气不好。
答案 4 :(得分:4)
试试这个http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html
我因为失去的变化而心脏病发作。但在关注这篇文章之后。我得到了我的更改