你什么时候需要`-tag-name-filter cat`用于`git filter-branch`?

时间:2014-01-09 01:16:21

标签: git git-filter-branch

git filter branch的手册页说:

use "--tag-name-filter cat" to simply update the tags.

后来甚至说:

use --tag-name-filter cat -- --all

但是--all应该包含--tags,因此应该正确地重写所有标记。

小测试验证了这一点:

$ git init
$ mkdir dir
$ touch dir/file
$ git add .
$ git commit -am init
$ git ls-files
dir/file
$ git tag tag
$ git for-each-ref
3006eb0a031e40901122ac8984c85ad533982f8b commit refs/heads/master
3006eb0a031e40901122ac8984c85ad533982f8b commit refs/tags/tag
$ git filter-branch --subdirectory-filter dir -- --all
Rewrite 3006eb0a031e40901122ac8984c85ad533982f8b (1/1)
Ref 'refs/heads/master' was rewritten
Ref 'refs/tags/tag' was rewritten
$ git for-each-ref
8e5f09c93a2fbdb435dbe7019abeb841cb5857b2 commit refs/heads/master
3006eb0a031e40901122ac8984c85ad533982f8b commit refs/original/refs/heads/master
3006eb0a031e40901122ac8984c85ad533982f8b commit refs/original/refs/tags/tag
8e5f09c93a2fbdb435dbe7019abeb841cb5857b2 commit refs/tags/tag

因此问题:

在哪种情况下我需要--tag-name-filter cat

还有Why has git-filter-branch not rewritten tags?,但我没有看到,如何进入这种情况。

1 个答案:

答案 0 :(得分:23)

只要您希望--tag-name-filter实际更新/创建标记,就需要git filter-branch',而不是仅创建这些标记所指向的重写提交。您为交换机提供的命令是一个shell脚本,它将旧的标记名称作为输入,并将git-filter-branch uses the command传递给“--tag-name-filter”以计算出您想要的新标记名字是。

例如,如果你有一个名为'work-by-sun'并使用'--tag-name-filter sed s/sun/oracle/'的标签,那么不会更新标签,而是创建一个名为'work-by-oracle'的新标签

更常见的情况是,如果您使用“--tag-name-filter cat”,则命令只是cat,并且使用的标记名称与原始标记相同 - 因此标记会被覆盖以指向< em> new commit。

命令行参数的“--all”部分指定应重写哪些引用,但除非使用--tag-name-filter参数,否则标记不会更新。

如果所有这些看起来有点繁琐,您可能想要考虑是否可以使用BFG Repo-Cleaner达到您想要的效果。

完全披露:我是BFG Repo-Cleaner的作者。