The man page of git filter branch
says:
use "--tag-name-filter cat" to simply update the tags.
Later it even says:
use --tag-name-filter cat -- --all
However --all
should include --tags
, hence all tags should properly get rewritten.
A small test verifies this:
$ 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
Therefore the question:
In which situation do I need --tag-name-filter cat
?
There is also Why has git-filter-branch not rewritten tags?, but I don't see, how to get into such a situation.
git-filter-branch can be used to get rid of a subset of files, usually with some combination of --index-filter and --subdirectory-filter .
The difference between tags and branches are that a branch always points to the top of a development line and will change when a new commit is pushed whereas a tag will not change. Thus tags are more useful to "tag" a specific version and the tag will then always stay on that version and usually not be changed.
Tags are ref's that point to specific points in Git history. Tagging is generally used to capture a point in history that is used for a marked version release (i.e. v1. 0.1). A tag is like a branch that doesn't change.
Tags and branch are completely unrelated, since tags refer to a specific commit, and branch is a moving reference to the last commit of a history. Branches go, tags stay. So when you tag a commit, git doesn't care which commit or branch is checked out, if you provide him the SHA1 of what you want to tag.
You need '--tag-name-filter
' for git filter-branch
any time you want it to actually update/create your tags - rather than just create rewritten commits those tags point to. The command you supply the switch is a shell script that gets the old tag name as input, and git-filter-branch uses the command passed to '--tag-name-filter
' to work out what you want the new tag name to be.
For instance, if you had a tag called 'work-by-sun' and used '--tag-name-filter sed s/sun/oracle/
', then instead of updating the tag, a new tag would be created called 'work-by-oracle'.
More normally, if you use '--tag-name-filter cat
', the command is just cat
, and the tag name used is the same as the original tag - so the tag is overwritten to point to the new commit.
The '--all
' part of the command-line arguments specifies what refs should get rewritten, but tags won't get updated unless you use the --tag-name-filter
parameter.
If all this seems a bit fiddly, you may want to consider if you can achieve what you want using the BFG Repo-Cleaner.
Full disclosure: I'm the author of the BFG Repo-Cleaner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With