When do you need `--tag-name-filter cat` for `git filter-branch`?

11,093

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.

Share:
11,093

Related videos on Youtube

michas
Author by

michas

Updated on June 09, 2022

Comments

  • michas
    michas almost 2 years

    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.

  • michas
    michas over 10 years
    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.