使用
git for-each-ref --format="%(objectname:short) %(refname)"
我得到:
207e698 refs/heads/main
f78d212 refs/original/refs/heads/main
24f61e4 refs/original/refs/tags/Cấutrúc1
4248ddd refs/original/refs/tags/Cấutrúc1.1
207e698 refs/remotes/origin/main
bc5335c refs/tags/Cấutrúc2.0
a03c71f refs/tags/Cấutrúc2.0.1
c72d77c refs/tags/Cấutrúc2.1.0
03f6aa0 refs/tags/Cấutrúc2.2.0
391fcd5 refs/tags/cấutrúc2.3.0
refs/original/
有什么作用? Remove refs/original/heads/master from git repo after filter-branch --tree-filter?中的答案说:
是作为备份,以防你弄乱你的过滤器分支。相信我,这真是个好主意。refs/original/*
filter-branch
的备份,而是一种阻止你使用它的方法。我想前面引用的“真是个好主意”意味着不使用filter-branch
是一个非常好的主意。但这是触发其创建的唯一操作吗?我看到它有各种子路径:refs/heads
、refs/tags
、heads
。他们想说什么?
前面的布道:好的,有一句名言谈到理解可能产生这样一个问题的思想混乱。它适用于此,如果您解释了引发此问题的原因,那么就更容易找出推动此问题的原因。这很可能是纯粹的运气,在我看来,这不像是无聊的好奇心或一些不正当的狩猎,所以我做了一些挖掘。真的:当您因同一情况提出多个问题时(这根本不是坏事),请将它们全部链接起来并解释情况。
您进行了一些历史重写,包括过滤分支,然后看起来您做了变基或只是放弃了一个分支,这个序列将产生提示您我链接的其他问题的症状:
$ sh <<EOD
cd `mktemp -d`; git init --template= -b example
echo >file; git add .; git commit -mA
git checkout -b deadfeature
echo >>file; git commit -amZ
git checkout -
echo >>file; git commit -amB
sleep 1 # to give the C commit a clearly later timestamp:
echo >>file; git commit -amC
FILTER_BRANCH_SQUELCH_WARNING=1 \
git filter-branch --env-filter 'export GIT_{AUTHOR,COMMITTER}_NAME="Kilroy"' -- --all
git branch -D deadfeature
git log --graph --oneline --all
EOD
[…setup chatter…]
* 61ac5bc (HEAD -> example) C
* a90a3b2 B
* f62d81a A
* fc6f2d4 C
* 090789e B
| * 7e8c2d0 Z
|/
* 79c4fde A
$
并且日志输出令人困惑。我什至称其为
git log
的一个缺陷,这个缺陷尚未修复,也许是因为它很少遇到,很容易克服,而简单的修复也有其自身的问题。
$ git log --graph --oneline --all --boundary --min-parents=1 --decorate-refs=*
* cf2fd07 (example) C
* 62b4fb9 B
| * 3b18524 (refs/original/refs/heads/example) C
| * 0598ba4 B
| | * 9c91f5c (refs/original/refs/heads/deadfeature) Z
| |/
| o e5d9cec A
o a79a75e A
$
显示细节
git log
通常隐藏。为行政裁判添加装饰很容易变得非常烦人,这里这是明智的,但情况并非总是如此;并且使用“排除边界标记”功能标记根提交与其他git log
选项有一些更糟糕的交互,我可以对我想象中的观点表示同情:最好不要打开那罐蠕虫,只是展示当人们感到困惑时发生了什么。
所以
refs/original/
是参考前缀 git filter-branch
用于记住历史在重写之前是什么样子。如果你很懒,并且在一个修复损坏的存储库中执行此操作,那么修复损坏可能会很昂贵,git fetch -u . +refs/original/*:*
会将其重写的每个引用恢复到过滤器分支之前的状态,你的历史记录会回到它的来源,任何工作树和索引由于过滤器分支仍然存在,因此您可以使用它们做任何适合您的事情。
花一些时间看看这里发生了什么,运行这里的例子。 Git 不会从存储库中删除历史记录,直到它在相当长一段时间内没有被引用,两周到一个月,具体取决于它被放弃的具体方式(出厂默认值)。过滤器分支可以做出巨大的改变。
refs/original
的速度使撤销在短期内变得容易,并且可能直到您明确决定您确实不需要它为止。 git log
的默认显示简化隐藏了一些会妨碍的东西,用现有的设施显示它们会令人困惑甚至容易出错。您遇到了通常启发式方法的主要缺点,您很幸运。