List status of all Git repositories

find ~ -type d -name .git | sed 's?/\.git$??' | awk '{ print "-------------------------"; print "\033[1;32mGit Repo:\033[0m " $0; system("git --git-dir=\""$0"\"/.git --work-tree=\""$0"\" status")}'

October 16, 2016uMt

Explanation

To understand how this works, it's important to know that a Git work tree has a .git subdirectory at its project root folder, containing metadata of Git.

With find ~ -name .git -type d we find in the home directory of the current user ~ all the directories (-type d) named .git (-name .git), which we expect to be the metadata folders of Git work trees.

We pipe the resulting list of .git path names to Sed for further processing.

With sed 's?/\.git$??' we remove the /.git ending from the path.

We pipe the resulting list of .git path names with the /.git ending to Awk for further processing.

We print a header line with print "-------------------------".

Then we print "Git Repo:" in green, followed by the path of the work tree with print "\033[1;32mGit Repo:\033[0m " $0. Note that the $0 variable in Awk holds the value of the entire current line, in this example the path of the work tree.

Then with system we execute git status in the work tree at $0:

system("git --git-dir=\""$0"\"/.git --work-tree=\""$0"\" status")

It looks a bit horrible, but it has to, to be safe:

  • The parameter of system is a string.
  • One tricky point is that we want to embed the variable $0 inside the string.
  • For example, to embed $0 in the middle of "some string", the correct way to write in Awk is "some " $0 " string". If the value of $0 is example, then the value of the last expression becomes some example string.
  • Another tricky point is that we want to enclose the value of $0 in double-quotes, so that the shell treats it as a single string value, and does not apply word splitting, which would break the command for example when the work tree contains spaces.
  • For example if we wanted to get cd "some path" when the value of $0 is some path, we would have to write "cd \"" $0 "\"".

For example if the work tree path is X, then the above command will effectively run:

git --git-dir=X.git --work-tree=X status