Today I learned that git add has built-in support for recursively adding files by file extension. For example, to add all .py files, at all levels your current working directory's file tree, use *.py in single quotes:

git add '*.py'

The single quotes here avoids that a classic shell like bash expands the glob (which only considers matching files in current directory), and instead passes that glob *.py directly to git add, which handles it recursively.

Also applies to other git subcommands. See pathspec in gitglossary for more usage details and inspiration.