In the past I have already worked with a project that consisted of multiple Git repositories in a common project folder. For tracking each repository’s individual state together, Google’s repo tool was used. I ended up using mostly its powerful repo forall subcommand to execute various bash or git commands over the whole or subset of those projects.
Now, I was faced with the same situation, but without repo already in place. Could I get some of that forall feeling back, but without installing that (relatively) giant tool? It turns out, 9 lines of bash give me most of what I missed:
The following function, added to my ~/.bash_aliases
is sufficient:
function git-forall() { for d in */.git; do local f f="${d%/.git}" echo "${f}" git -C "${f}" "$@" echo "" done }
It enables me to quickly check the status of all repos using git-forall status
, refresh all branches to their current origin state using git-forall fetch
, or even give me a short tree-view of the latest commits on any branch using git-forall lg --all -10
. In the last command, lg
is my custom alias for git log
, but with custom columns and graph drawing enabled.
The only noteworthy bash feature might be the ${VAR%SUFFIX}
syntax which removes the string SUFFIX
from the contents of variable VAR
if present.
Forall for all
With that function in place, I realised that a more general forall
function was in order:
function forall() { for d in */; do echo "${d}" cd "${d}" "$@" echo "" cd .. done }
Now, I can quickly do something like ls -R
but limited to a single level by typing forall ls
, which otherwise would need the following, easy to remember find
one-liner:
find -mindepth 1 -maxdepth 1 \ -exec echo "{}" \; -exec ls "{}" \;
Yeah, quite easy to remember and fast to type!
Going further
Of course, this simple approach let’s lots of things to be desired. If you want more, but do not want to dive much deeper into bash scripting, see what others already have done:
- gita by nosarthur provides git-forall on steroids with nice output formatting per command in about 2000 lines of Python code.
- mr, short for “my repos” is an older (but well-maintained), 2700 Perl tool which supports not only git, but svn, bzr, cvs, hg, darcs, fossil and veracity. Impressive! Its behaviour is more driven by a central Makefile-like configuration. And even more helpful, tGhe homepage another dozen related and similar tools.