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?,但我没有看到,如何进入这种情况。
答案 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的作者。