chr4

Devops. I've never asked for this.

gittree: bash/zsh function to run git commands recursively

I’m using Androids repo tool from time to time when dealing with large groups of git repositories. In most situations, it is too bloated though. Some git “batch” commands I found very useful, like repo status, checking the status of all git repositories recursively.

To mimic this (and other) behaviour in a simple way, I created the following bash/zsh function (put this in your .bashrc or .zshrc, or another file where you define functions in your dotfiles)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Recursively traverse directory tree for git repositories, run git command
# e.g.
#   gittree status
#   gittree diff
gittree() {
  if [ $# -lt 1 ]; then
    echo "Usage: gittree <command>"
    return 1
  fi

  for gitdir in $(find . -type d -name .git); do
    # Display repository name in blue
    repo=$(dirname $gitdir)
    echo -e "\033[34m$repo\033[0m"

    # Run git command in the repositories directory
    cd $repo && git $@
    ret=$?

    # Return to calling directory (ignore output)
    cd - > /dev/null

    # Abort if cd or git command fails
    if [ $ret -ne 0 ]; then
      return 1
    fi

    echo
  done
}

This allows me to quickly get an overview of multiple git repositories, and check e.g. whether they are all clean, or push them all at once:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
dockerfiles % gittree status

./base-go
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

./dovecot
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

./nginx
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  feeling-dirty

nothing added to commit but untracked files present (use "git add" to track)

./dnsmasq
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

gittree works with all git commands, try out e.g.

  • gittree status
  • gittree diff
  • gittree push
  • gittree --no-pager log --graph --pretty=format:'%h -%d %s (%cr) <%an>'

It’s a pretty simple script and for sure not perfect, but it get’s the job done!

If you have any suggestions how to improve it, please file a pull request on this file on Github.