How to Run a Command on Many Files in Your Git Repository

Git getting you feeling crabby?

Occasionally it’s useful to run commands on files in your repository, or all files matching a pattern. This is possible by combining git ls-files and xargs.

For all files:

$ git ls-files | xargs <command>

Or for files with a given suffix:

$ git ls-files -- '*.<suffix>' | xargs <command>

A Deconstructed Example

For example, to get the line counts of all Python files:

$ git ls-files -- '*.py' | xargs wc -l
...
     255 example/urls.py
     138 example/utils.py
    3160 example/views.py
   78123 total

Let’s take that apart.

You can take the line count of a file with wc and its -l flag:

$ wc -l example/models.py
    7142 example/models.py

git ls-files -- '*.py' lists all files known to Git that end in .py, in the current folder:

$ git ls-files -- '*.py'
...
example/urls.py
example/utils.py
example/views.py

xargs takes a list of files from its input, and runs the command you give it on them, in groups. So in the combination command, it receives the list of files from git ls-files, and runs wc -l on them in batches.

Running Fixer Tools

You can also use this techinque to run “fixer” tools. For example to run my tool django-upgrade on all Python files in your repository:

$ git ls-files -- '*.py' | xargs django-upgrade --target-version 4.0
...
Rewriting example/models.py
Rewriting example/urls.py

Fin

May your mass edits not require mass reverts,

—Adam


Improve your Django develompent experience with my new book.


Subscribe via RSS, Twitter, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: