撤消git filter-branch


73

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

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

我该如何撤消呢?可能吗?即文件是否被永久删除?


2
今年的问题,现在
jimh

Answers:


130

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

refs/original/refs/heads/master

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

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

7
我收到了错误消息fatal: Cannot do hard reset with paths.,所以我首先做了git reflog发现行HEAD@{integer}: filter-branch: rewrite,然后记下了整数并执行了,然后git reset --hard HEAD@{integer}又回来了。
hermansc 2014年

这对我有用。我包括了git push -f之后git reset --hard HEAD@{integer}
千焦耳

我想使用它git filter-branch来删除意外地将库提交给我们的仓库的大量行。因此,在图中,它显示了8000行的添加/删除,我认为过滤器分支将要重写。图表将更新,但没有更新。它使所有行数加倍。这样做是否会使线路计数恢复到旧状态?还是再翻一番?
Arian Faurtosh 2015年

是的,此命令将使您的代码返回到“ filter-branch”命令之前的状态。
William Seiti Mizuta 2015年

3
感谢您重置我的心脏病发作。过滤器命令删除除文件夹以外的所有内容后,都可以正常工作。
jHilscher

30

与仅对原始主服务器执行硬重置相比,一种更合适的方法可能是还原所有由重写的ref git filter-branch,甚至以后删除备份ref以便能够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。

这(可以说)在不使用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

5
谢谢。我认为该脚本应该在git-filter-branch文档页面上,因为它没有有关如何从备份还原的任何说明。
用户

1
别客气!我猜你总可以建议对他们的文档进行增强;-)
Eldar Abusalimov

怎么样的建议在这里:stackoverflow.com/a/23483576/281545 - git fetch . +refs/original/*:*
Mr_and_Mrs_D

认为这样做之后,仍然需要从上游重新拉动标签。可以预期吗?
山姆·布莱曼

@SamBrightman手册页中没有提到,而且我也不知道TBH ...
Eldar Abusalimov

6

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

git fetch . +refs/original/*:*

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

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

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

如果您要还原多个分支,这绝对是一个更简单的解决方案。工作完美。
Mike Scannell

2

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.