77

我不小心使用 git filter-branch 从我的仓库中删除了一个文件:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch images/thumb/a.JPG' HEAD

我该如何撤消此操作?是否可以?即文件是否被永久删除?

4

4 回答 4

145

使用时git filter-branch,会创建一个备份文件

refs/original/refs/heads/master

如果您在分支中使用了该命令master。您可以检查目录中是否有备份.git/refs。考虑到这一点,您可以使用此备份来恢复您的文件:

git reset --hard refs/original/refs/heads/master
于 2013-01-27T04:52:09.923 回答
32

可能比仅仅对原始 master 进行硬重置更合适的方法是恢复所有由 重写的 refs git filter-branch,甚至可能在之后删除备份 refs 以便能够在git filter-branch没有 的情况下再次调用--force

for orig_ref in $(git for-each-ref --format="%(refname)" refs/original/); do
    git update-ref "${orig_ref#refs/original/}" $orig_ref
    git update-ref -d $orig_ref  # to also remove backup refs
done

在那之后:

git reset --hard master

UPD。

这是(可以说)在没有外壳 for 循环的情况下执行相同操作的更 git'ish 方式:

git for-each-ref --format="update %(refname:lstrip=2) %(objectname)" refs/original/ | git update-ref --stdin
git for-each-ref --format="delete %(refname) %(objectname)" refs/original/ | git update-ref --stdin
于 2015-01-16T00:04:41.480 回答
7

@jthill在这个答案中给出了一个更清洁的解决方案。

git fetch . +refs/original/*:*

如该答案中所述,如果要恢复当前签出的分支,您可能需要分离 HEAD。

要删除refs/original参考,请发出:

git for-each-ref refs/original --format='delete %(refname) %(objectname)' | git update-ref --stdin
于 2018-01-08T12:03:20.513 回答
5

您的旧分支提示可能会保留在您的reflog中。然后,您应该能够使用所有先前的历史记录检查未更改的提交。

于 2013-01-26T22:50:22.770 回答