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

时间:2022-08-04 00:00:59

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 SOME way, 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.

我在这里看了一个相关的问题:如何撤消git reset --hard HEAD~1?但是,这个问题假设一个人做了一个git提交。

5 个解决方案

#1


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

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

$ 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 fsck manpage.

请阅读git fsck手册页。

#2


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

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

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

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

    如果你看到一些有趣的东西,git cat-file blob SHA-1-of-interesting-file会将文件输出到标准输出。 (例如:git cat-file blob b8f​​0bdf56> restored-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 stage or 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-found and looking around in directory .git/lost-found/other to 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 stage或git add)或stashed(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 $3}'; git log -g --pretty='format:%H' )

That will run gitk with all the branches, all the reflog and all the dangling commits. You may want to add -n 10000 or 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:

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

git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; 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 $3}'; 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>.

如果你看到一些你想要保存为branch1的提交,只需要执行git checkout -b recover1

#3


There is a git plugin that does this out of the box:

有一个git插件可以开箱即用:

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

#4


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 - 但是没有树(因此,commit)对象引用它。这就是人们如何得到一个“悬空”的松散目标文件,如果你运行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,那么就像格雷格所说的那样,git对此一无所知,你在那里运气不好。

#5


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

我因为失去的变化而心脏病发作。但在关注这篇文章之后。我得到了我的改变

#1


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

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

$ 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 fsck manpage.

请阅读git fsck手册页。

#2


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

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

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

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

    如果你看到一些有趣的东西,git cat-file blob SHA-1-of-interesting-file会将文件输出到标准输出。 (例如:git cat-file blob b8f​​0bdf56> restored-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 stage or 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-found and looking around in directory .git/lost-found/other to 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 stage或git add)或stashed(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 $3}'; git log -g --pretty='format:%H' )

That will run gitk with all the branches, all the reflog and all the dangling commits. You may want to add -n 10000 or 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:

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

git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; 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 $3}'; 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>.

如果你看到一些你想要保存为branch1的提交,只需要执行git checkout -b recover1

#3


There is a git plugin that does this out of the box:

有一个git插件可以开箱即用:

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

#4


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 - 但是没有树(因此,commit)对象引用它。这就是人们如何得到一个“悬空”的松散目标文件,如果你运行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,那么就像格雷格所说的那样,git对此一无所知,你在那里运气不好。

#5


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

我因为失去的变化而心脏病发作。但在关注这篇文章之后。我得到了我的改变