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 COMMANDchange all files in a repository.
$ git ls-files -z -- "*.SUFFIX" | xargs -0 COMMANDonly changes the files with a specific file extension.
-z,-0uses the zero-byte separator.
Example¶
$ git ls-files -z -- ‘*.py’ | xargs -0 git update-index --chmod=+xchanges the permissions for all files with the suffix
.pyfrom100644to100755, if necessary, so that they become executable.
All files changed in the working or staging area¶
git diff --name-onlyoutputs the files that are managed by Git and have been changed in the working area.
git diff --staged --name-onlyoutputs 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 dexcludes deleted files.
This is the most common case for me, which is why I have created a
list-changedalias 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-changedin brackets and inserts its output into the outer command.codespelltherefore 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.