执行 git reset --hard HEAD^ 后恢复添加的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1108853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:42:44  来源:igfitidea点击:

Recovering added file after doing git reset --hard HEAD^

gitversion-control

提问by Susheel Javadi

I added a new file F1 and made changes to another file F2 but then did a "git reset --hard HEAD^" and I have lost all the changes to the files.

我添加了一个新文件 F1 并对另一个文件 F2 进行了更改,但随后执行了“git reset --hard HEAD^”,并且我丢失了对文件的所有更改。

Is there SOMEway, I can get them back.

有没有一些方法,我可以让他们回来。

I did look at a related question here: How can I undo git reset --hard HEAD~1?but, that question assumes that the one has done a git commit.

我确实在这里查看了一个相关问题:How can I undo git reset --hard HEAD~1? 但是,这个问题假设一个人已经完成了 git commit。

回答by Jakub Nar?bski

You can (with some work) recover state of file at the last "git add <file>". You can use

您可以(通过一些工作)在最后一个“git add <file>”恢复文件状态。您可以使用

$ git fsck --cache --no-reflogs --lost-found --unreachable  HEAD

and then examine files in '.git/lost-found/other' directory.

然后检查“.git/lost-found/other”目录中的文件。

Please read git fsckmanpage.

请阅读git fsck联机帮助页。

回答by Mikko Rantalainen

(I'm assuming that the missing file is notpart of any commit. Otherwise, git log --all -g --diff-filter=D --statis your friend.)

(我假设丢失的文件不是任何提交的一部分。否则,git log --all -g --diff-filter=D --stat就是你的朋友。)

  1. Get list of unreachable files that gitknows a file name:

    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
    
  2. If you see something interesting, git cat-file blob SHA-1-of-interesting-filewill output the file to standard output. (Example: git cat-file blob b8f0bdf56 > recovered-logo.png)

  1. 获取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
    
  2. 如果你看到有趣的东西,git cat-file blob SHA-1-of-interesting-file就会把文件输出到标准输出。(实施例:git cat-file blob b8f0bdf56 > recovered-logo.png

Unfortunately, if the missing file is not part of the any commit, git does not have a timestamp and as such, you cannot print various versions of files ordered by time.

不幸的是,如果丢失的文件不是任何提交的一部分,git 没有时间戳,因此,您无法打印按时间排序的各种版本的文件。

If the missing file has never been staged (git stageor git add) or stashed (git stash), you're pretty much out of luck because as far as git knows, the file never did exist. (You may still try doing a git fsck --no-reflogs --lost-foundand looking around in directory .git/lost-found/otherto see if you have anything worth keeping in case git indeed has a copy of your missing file by some lucky accident. You do not have file names to help you in this case, only file contents.)

如果丢失的文件从未被暂存 (git stagegit add) 或隐藏 ( git stash),那么你就很不走运了,因为据 git 所知,该文件从未存在过。(您仍然可以尝试git fsck --no-reflogs --lost-found在目录.git/lost-found/other中查看并查看是否有任何值得保留的内容,以防 git 确实因某些幸运意外拥有丢失文件的副本。在这种情况下,您没有文件名来帮助您,只有文件内容。)

In case you just lost some commits (instead of just files), you'll probably want to run something like this:

如果你只是丢失了一些提交(而不仅仅是文件),你可能想要运行这样的东西:

gitk --all $( git fsck | awk '/dangling commit/ {print }'; git log -g --pretty='format:%H' )

That will run gitkwith all the branches, all the reflog and all the dangling commits. You may want to add -n 10000or some other limit in case your repo has really many commits (say linux kernel). If you do not have gitk, you may instead run lesser version using only command line like this:

这将gitk与所有分支、所有引用日志和所有悬空提交一起运行。-n 10000如果您的 repo 确实有很多提交(比如 linux 内核),您可能想要添加或其他一些限制。如果你没有gitk,你可以只使用命令行来运行较小的版本,如下所示:

git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print }'; git log -g --pretty='format:%H' )

or a version with less verbose output

或具有较少详细输出的版本

git log --all --decorate --oneline --graph --date-order $( git fsck | awk '/dangling commit/ {print }'; git log -g --pretty='format:%H' )

If you see some commit you want to save as branch recovered1, simply do git checkout -b recovered1 <sha1-of-the-commit>.

如果您看到某些提交要另存为分支recovered1,只需执行git checkout -b recovered1 <sha1-of-the-commit>.

回答by Ravi Krishna P

Try this http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html

试试这个http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html

I got a heart attack for the changes I lost. But after following this post. I got my changes back

我因为失去的改变而心脏病发作。但是在关注这个帖子之后。我找回了我的更改

回答by Alexar

There is a git pluginthat does this out of the box:

有一个git plugin开箱即用的方法:

https://github.com/pendashteh/git-recover-index

https://github.com/pendashteh/git-recover-index

$ cd /path/to/disatered/repo
$ git clone [email protected]:pendashteh/git-recover-index.git $HOME/.git-recover-index
$ $HOME/.git-recover-index/git-recover-index.sh

回答by Matt Enright

Actually, if you've added the object to the index (by using git add), there is a blob created for that state of the object - but there is no tree (and thus, commit) object that is referring to it. This is how one gets a 'dangling' loose object file, and if you run git fsck it will show you the unreferenced blob (git gc will delete these types of objects if it is run).

实际上,如果您已将对象添加到索引(通过使用 git add),则会为该对象的该状态创建一个 blob - 但没有引用它的树(因此,提交)对象。这就是一个“悬空”松散对象文件的获取方式,如果您运行 git fsck 它将向您显示未引用的 blob(如果运行 git gc 将删除这些类型的对象)。

Because of this, you can use the reflog, if you have it enabled, to try and restore the index state for your file F1 that has been added. If you haven't added F2 at all, then as Greg said, git doesn't know anything about it and you're out of luck there.

因此,您可以使用 reflog(如果已启用)来尝试恢复已添加的文件 F1 的索引状态。如果您根本没有添加 F2,那么正如 Greg 所说,git 对此一无所知,您在那里就不走运了。