Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using black with git clean filter

Tags:

git

python

I'm trying to set up black to run on any files checked into git.

I've set it up as follows:

git config filter.black.clean 'black -'
echo '*.py filter=black' >> .git/info/attributes

As far as I understand, this should work ok as black with - as the source path will read from STDIN and output to STDOUT, which is what I think the git filter needs it to do.

However this does not work. When I add an un-black file with git add I see the following output:

reformatted -
All done! ✨ 🍰 ✨
1 file reformatted.

And the file is not changed on disk. What am I doing wrong?

like image 442
user31415629 Avatar asked Sep 12 '25 17:09

user31415629


1 Answers

The Black documentation recommends using a pre-commit hook, rather than smudge and clean filters. Note that filter.black.clean defines a clean filter and you have not set up any smudge filters.

The reason you see no change to the work-tree version of the file is that a clean filter is used when turning the work-tree version of a file into the index (to-be-committed) version of the file. This has no effect on the work-tree version of the file!

A smudge filter is used in the opposite direction: Git has a file that is in the index—for whatever reason, such as because it was just copied into the index as part of the git checkout operation to switch to a specific commit—and desires to convert that in-the-index, compressed, Git-ized file to one that you can actually see and edit in your editor, or run with python. Git will, at this time, run the (de-compressed) file contents through your smudge filter.

Note that if you convert some file contents, pre-compression, in a clean filter, and then later extract that file from the repository, into the index, and on into your work-tree, you will at that time be able to see what happened in the clean filter (assuming you do not have a countervailing smudge filter that undoes the effect).

In a code-reformatting world, one could conceivably use a clean filter to turn all source files into some sort of canonical (perhaps four-space-indentation) form, and a smudge filter to turn all source files into one's preferred format (two-space or eight-space indentation). If these transformations are all fully reversible, what you would see, in your work-tree, would be in your preferred format, and what others would see in their work-trees would be their preferred format; but what the version control system itself would see would be the canonical, standardized format.

That's not how Black is actually intended to be used, though it probably can be used that way.

like image 72
torek Avatar answered Sep 15 '25 09:09

torek