撤消git filter-branch

时间:2013-01-26 22:40:57

标签: git

我使用git filter-branch意外删除了我的仓库中的文件:

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

如何撤消此操作?可能吗?即文件被永久删除?

4 个答案:

答案 0 :(得分:92)

使用git filter-branch时,会在

中创建备份文件
refs/original/refs/heads/master

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

git reset --hard refs/original/refs/heads/master

答案 1 :(得分:22)

除了对原始主机进行硬重置之外,一个更正确的方法可能是恢复由git filter-branch重写的所有引用,甚至可能之后删除备份引用以便能够在没有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。

这里(可以说)更多的git'是没有shell for循环执行相同的方法:

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

答案 2 :(得分:3)

this answer由@jthill提供了一个更清晰的解决方案。

git fetch . +refs/original/*:*

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

要删除refs/original引用,请发出:

git for-each-ref refs/original --format='delete %(refname) %(objectname)' | git update-ref --stdin

答案 3 :(得分:2)

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