22

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.

Community
  • 1
  • 1
michas
  • 25,361
  • 15
  • 76
  • 121

1 Answers1

29

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.

Roberto Tyley
  • 24,513
  • 11
  • 72
  • 101
  • 3
    Isn't in the above example the tag `tag` exactly the same a the ref `refs/original/refs/tags/tag`? Even without `--tag-name-filter` the tag `tag` points to the new commit after the filter-branch. – michas Jan 09 '14 at 15:06