撤消git filter-branch

Chi*_*hin 63 git

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

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch images/thumb/a.JPG' HEAD
Run Code Online (Sandbox Code Playgroud)

我该怎么撤消这个?可能吗?即文件被永久删除?

Wil*_*uta 108

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

refs/original/refs/heads/master
Run Code Online (Sandbox Code Playgroud)

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

git reset --hard refs/original/refs/heads/master
Run Code Online (Sandbox Code Playgroud)

  • 我得到了错误消息`致命:不能用路径进行硬重置.所以我先做了`git reflog`并找到了行`HEAD @ {integer}:filter-branch:rewrite`,然后我记下整数并执行了`git reset --hard HEAD @ {integer}`然后我回来了. (5认同)
  • 感谢您重置我的心脏病发作.在过滤器命令删除除文件夹之外的所有内容之后,工作得非常完美. (2认同)

Eld*_*mov 24

可能比仅仅对原始主机进行硬重置更合适的方法是恢复所有重写的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
Run Code Online (Sandbox Code Playgroud)

在那之后:

git reset --hard master
Run Code Online (Sandbox Code Playgroud)

UPD.

在没有shell 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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.我相信这个脚本应该在[git-filter-branch](http://git-scm.com/docs/git-filter-branch)文档页面上,因为它没有关于如何从中恢复的任何说明备份. (4认同)

che*_*che 5

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


Mr_*_*s_D 5

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

git fetch . +refs/original/*:*
Run Code Online (Sandbox Code Playgroud)

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

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

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