Batch processing¶
All files in a repository¶
Occasionally, you may want to change all files in your repository or those that match a pattern. This is possible with the combination of git ls-files and xargs:
$ git ls-files -z | xargs -0 COMMAND
change all files in a repository.
$ git ls-files -z -- "*.SUFFIX" | xargs -0 COMMAND
only changes the files with a specific file extension.
-z
,-0
uses the zero-byte separator.
Example¶
$ git ls-files -z -- ‘*.py’ | xargs -0 git update-index --chmod=+x
changes the permissions for all files with the suffix
.py
from100644
to100755
, if necessary, so that they become executable.
All files changed in the working or staging area¶
git diff --name-only
outputs the files that are managed by Git and have been changed in the working area.
git diff --staged --name-only
outputs the files added to the staging area.
git diff --staged --name-only "*.SUFFIX"
also filters for a specific file extension.
git diff --name-only --diff-filter d
excludes deleted files.
This is the most common case for me, which is why I have created a
list-changed
alias for this:git config --global alias.list-changed 'diff --name-only --diff-filter d'
.
Example¶
To execute commands for the changed file list, you can use the shell Command Substitution:
$ uv run codespell $(git list-changed '*.py')
The shell executes the
git list-changed
in brackets and inserts its output into the outer command.codespell
therefore receives the list of changed text files as an argument.uv run pytest $(git diff --staged --name-only "tests/*test_*.py")
calls pytest to execute only those test modules that have been changed in the working directory.