我开始搞乱git filter-branch
。 --all选项重写所有分支和标记。凉。 git filter-branch
创建它在refs / original中覆盖的所有引用的备份。很酷。现在我想把我filter-branch
的所有试验都吹走。
是否有一种简单的方法可以完全撤消git filter-branch <whatever filter> -- --all
的效果?即一次性将所有重写的分支恢复到原始状态?
如果没有预先存在的方式,应该有。如果没有预先存在的方式,是否有人会有一个简短的脚本来执行此操作?
显然有解决方法。我可以手动恢复它,一次一个分支,如this question。或者我可以直接核对并重新克隆。要么会在一个包含许多分支/标签的仓库中快速繁琐,这些分支/标签会被分成更小的回购。
答案 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
是否存在。