使用git中的历史记录恢复已删除的文件

Ram*_*ams 7 git github

如何在推送后在git中恢复意外删除的文件和文件夹.以下是场景.

  1. 意外删除了一个文件夹,该文件夹包含一个文件,并对其他文件进行了一系列更改.
  2. 现在,推动所有这些变化.因此,此推送具有已删除的文件夹以及其他已更改的文件.
  3. 除此之外,还有一些推动.

现在,我可以恢复已删除的文件以及历史记录,然后再回到repo.

Ry-*_*Ry- 8

当然,只需从存在的提交中查看它.如果删除文件的提交是您当前检出的任何提示,那就是HEAD^(最后提交):

git checkout HEAD^ -- path/to/file
Run Code Online (Sandbox Code Playgroud)

然后你可以提交并推送它.

  • 这并没有为我保留历史;我只看到文件历史记录中的最新提交。FWIW我使用提交哈希签出。 (5认同)
  • 您可以用提交 SHA 替换 HEAD^ ,这也可以。 (2认同)
  • 我试过了,但它并没有为我恢复历史。 (2认同)
  • @ Ry-:我确实找回了文件,但历史记录丢失了。但是,当我在文件上执行git blame时,我只会得到我的名字,而不会得到原始提交者的名字。 (2认同)
  • 这并没有为我保留历史。 (2认同)

Mad*_*ter 8

刚刚遇到类似的情况:之前删除了一个文件,现在需要恢复它。

步骤1:找到删除文件的提交(假设文件名为test.log):

$ git log --all --stat --diff-filter=D -- test.log
commit aec72339081df3bc621a6c0cd3687257778466e4
(Author, Date, commit message etc appear here)
Run Code Online (Sandbox Code Playgroud)

步骤 2:从该提交恢复文件(上面的 aec723390),注意^包含尚未删除的文件的先前提交:

$ git restore --source aec723390^ -- test.log
Run Code Online (Sandbox Code Playgroud)

第 3 步:该文件将恢复到您的工作树(但在您实际提交之前不会恢复到存储库),您可以通过添加它git add test.log然后进行提交:

$ git status
On branch main
Your branch is up-to-date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    test.log

nothing added to commit but untracked files present (use "git add" to track)
$ 
Run Code Online (Sandbox Code Playgroud)


cos*_*rgi 5

有可能,在Git 复制文件保留历史记录的帮助下,您需要在文件被删除之前复制文件。

我会在这里写一个完整的例子。首先,我将准备一些测试存储库:

git init
echo "test content" > file.txt
git add file.txt
git commit -m "start"
echo "test content 2" >> file.txt
git commit -am "next commit"
rm file.txt
git commit -am "Delete file, lose history"
Run Code Online (Sandbox Code Playgroud)

现在我们有一个没有文件的测试存储库。要使用其提交历史恢复文件,过程如下:在文件确实存在的地方创建一个分支。然后制作此文件的两个副本,每个副本都有历史记录。然后合并回母版,合并期间只有两个副本中的一个会被删除。请务必使用您的提交哈希而不是190112b下面的示例。

git checkout 190112b -b before-deletion
git mv file.txt file1.txt
git commit -m "Move file (1)"
SAVED=`git rev-parse HEAD`
git reset --hard "HEAD^"
git mv file.txt file2.txt
git commit -m "Move file (2)"
git merge $SAVED
git commit -a -n
Run Code Online (Sandbox Code Playgroud)

好的,现在在这个分支中,我们有这个文件的两个副本。每个副本都保留了历史。现在,当我们将其合并回 master 时,一个文件将消失(或将有错误的历史记录),另一个将保留历史记录。

git checkout master
git merge before-deletion
git commit -a -n
git rm file1.txt
git mv file2.txt file.txt
git commit -m "recovery finished"
Run Code Online (Sandbox Code Playgroud)

就是这样。