All of the WordPress themes that I work on for iThemes are managed as Git repositories. Recently, we moved past the 100 repositories mark. That’s a lot of repositories to manage, and unfortunately, too many of those repositories contain duplicated information.

Later on, I might delve into how we use Git to manage our theme repos. For today, however, I’d like to focus on how I quickly and easily pushed up changes to more than a dozen repos in a single, albeit long, Bash command.

I had finished making updates to 16 Flexx repos, and I needed to push all of those changes up. Since I had multiple working repos in that folder, I was lucky that each of these repos began with the text “Flexx”. Also, since they are all part of the same series and need to keep the same version number, that simplified the tagging as all could be tagged as 2.5.0.

Given this information, I simply ran the following command from the directory that contained all the repository directories:

for i in `ls|grep Flexx`; do echo "--- Pushing $i"; cd $i; git commit -am '2.5.0' && git push && git tag 2.5.0 && git push --tags; cd ..; echo "--- Finished $i"; done

There’s a lot going on here, so I’ll break it up and explain what I’m doing.

for i in `ls|grep Flexx`

This is basically a compound command. Bash’s for command is being used to step through the results of ls|grep Flexx. Each result will be stored to the variable i which can be referred to with $i.

In other words, I’m going to loop through each directory that contains the text “Flexx” (technically, it isn’t limited to just directories, but I don’t have any files containing “Flexx”, so I’m safe). For each iteration of the loop, the variable $i will contain the name of the folder I’m interested in.

do echo "--- Pushing $i"

The most important bit here is do. do simply begins the functional part of the loop and could be followed by any command that I wanted to start the loop with.

The echo command isn’t technically necessary. I simply have it there so that I can better determine what output belongs to which repository.

cd $i

This is a very important command. It changes the directory to the repository I wish to run commands on.

git commit -am '2.5.0' && git push && git tag 2.5.0 && git push --tags

This is the command that actually does what I want to do in each repo directory. This adds all the modified files, commits them with a message of “2.5.0”, pushes the changes to the remote repository, creates a new tag of 2.5.0, and pushes up the new tag.

I have all of these commands chained together with && so that if one command fails, the other ones won’t run. This prevents tagging in the event that the repository couldn’t be committed or pushed.

cd ..

It’s a small command but necessary. This switches back to the main directory that holds all the repos, thus returning us back to a state that the next loop iteration can work with.

echo "--- Finished $i"

As with the other echo command, this simply allows me to keep track of what is going on more easily.


The done command finishes out the loop iteration.

I hope that by sharing this you can gain a bit of insight into how I work with repositories while also learning more about how you can do things with Bash.

Did I help you?