If you followed my CLI improved then you'll know I'm a fan of the fd command which I'm able to use for a mass git file rename.

Doing a mass rename is typically simple in the command line (mv *.mjs *.js - though I'm not sure off the top of my head if this will recurse directories, probably not), but doing a mass rename with git is harder, especially as there's some kind of locking going on. This means that the mass git rename must be run sequentially.

READER DISCOUNTSave $50 on terminal.training

I've published 38 videos for new developers, designers, UX, UI, product owners and anyone who needs to conquer the command line today.

In my particular recent case, I wanted to rename all instances of .mjs files (excluding node_modules) to .js. I've tried this before with xargs and kept failing but fd makes it pretty easy.

The fd command allows you execute a command against the results (similarly to xargs) and usefully fd also provides some useful additions for filename substitution:

  • {}: A placeholder token that will be replaced with the path of the search result (documents/images/party.jpg)
  • {.}: Like {}, but without the file extension (documents/images/party)
  • {/}: A placeholder that will be replaced by the basename of the search result (party.jpg)
  • {//}: Uses the parent of the discovered path (documents/images)
  • {/.}: Uses the basename, with the extension removed (party)

Armed with this information, I can find all mjs files -e mjs, and I can execute git mv with the full path to the result as the first argument and the {.} placeholder for the filename excluding the extension:

fd -e mjs -x git mv {} {.}.js -j1

The final argument (as above) is -j1 which tells fd to run the commands in a single thread (by default fd will run multiple threads - I don't recall how many) - this is important because git will lock and unlock the git metadata files upon each rename.

Otherwise, that's it. A single command to git rename.