撤消“git filter-branch ... - --all”?在一个命令?

时间:2014-05-05 22:40:00

标签: git git-filter-branch

我开始搞乱git filter-branch。 --all选项重写所有分支和标记。凉。 git filter-branch创建它在refs / original中覆盖的所有引用的备份。很酷。现在我想把我filter-branch的所有试验都吹走。

是否有一种简单的方法可以完全撤消git filter-branch <whatever filter> -- --all的效果?即一次性将所有重写的分支恢复到原始状态?

如果没有预先存在的方式,应该有。如果没有预先存在的方式,是否有人会有一个简短的脚本来执行此操作?

显然有解决方法。我可以手动恢复它,一次一个分支,如this question。或者我可以直接核对并重新克隆。要么会在一个包含许多分支/标签的仓库中快速繁琐,这些分支/标签会被分成更小的回购。

2 个答案:

答案 0 :(得分:7)

这是一种撤消过滤器分支的简单而安全的方法:

git fetch . +refs/original/*:*

如果当前签出的分支(HEAD)是要还原的分支之一,则此命令将失败。您可以事先运行git checkout --detach,让git fetch更新所有分支。请记得在运行git fetch后检查分支机构!

成功恢复引用后,您可以使用以下命令安全删除refs/original引用:

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

旧答案:

git for-each-ref refs/heads refs/tags \
        --format='git update-ref "%(refname)" "%(refname)@{1 hour ago}"'

为了增加安全性,您可以测试filter-branch是否确实更新了ref:

git for-each-ref refs/heads refs/tags --format='
        { git reflog -1 "%(refname)" | sed -n "/filter-branch: rewrite$/Q1"; } \
                  || git update-ref -m "reset to before filter-branch" \
                             %(refname) %(refname)@{1}' | sh -x

答案 1 :(得分:2)

嗯,将所有裁判从.git/refs/original移到他们.git/refs/heads的位置?我的意思是字面移动,这些是纯文本文件。您也可以查看.git/packed-refs是否存在。