5

I've got a folder, which contains about 10 subfolders each containing a separate git repo. So something like this:

MainFolder/:
-- GitRepoA/
-- GitRepoB/
-- GitRepoC/
-- GitRepoD/
-- etc.

I often want to check whats going on, specifically I would like a command which lists the output for git status for all subfolders in which something has changed. Does anybody know a solution for this? (I'm on Mac OSX by the way).

kramer65
  • 45,059
  • 106
  • 285
  • 459
  • 1
    Duplicate of [Check status of all git repositories at once](http://stackoverflow.com/questions/24352701/check-status-of-all-git-repositories-at-once). Seriously, like an **exact** duplicate. –  Jun 24 '14 at 18:23
  • Nevermind, that's the Windows solution, but I wouldn't be surprised if someone else already asked for an OS X or a *nix solution elsewhere. –  Jun 24 '14 at 18:26

5 Answers5

7

If you need recursion (or will work as well if you don't):

find . -name .git -type d -execdir git status \;

For each directory named .git will execute git status from within the directory that contains it (-execdir). Wow, exactly what you want.

You can append -prune too so as to not go further in subdirectories of a git project to be more efficient (but might skip git submodules—I have no ideas how submodules work I never use them):

find . -name .git -type d -execdir git status \; -prune
gniourf_gniourf
  • 41,910
  • 9
  • 88
  • 99
4

Iterate over each directory, and set the working directory and .git directory with the commandline options --work-tree and --git-dir respectively:

for x in *; do git --work-tree="$x" --git-dir="$x/.git" status; done
user229044
  • 222,134
  • 40
  • 319
  • 330
0

You can create a script. Perhaps also just create it as a function and place in .bash_profile.

#!/bin/bash

REPOS=(GitRepoA GitRepoB GitRepoC AnotherRepoA)

for R in "${REPOS[@]}"; do
    echo "Checking repo $R."
    pushd "$R" >/dev/null && {
        git status
        popd >/dev/null
    }
done

Place it in the main folder and run

bash script_name.sh

If your repos are in uniform, you can just do some things like:

shopt -s nullglob
REPOS=(GitRepo{A..Z} AnotherRepoA)

Or perhaps just

shopt -s nullglob
REPOS=(*)

Just as a function:

function check_repos {
    REPOS=(GitRepoA GitRepoB GitRepoC AnotherRepoA)

    for R in "${REPOS[@]}"; do
        echo "Checking repo $R."
        pushd "$R" >/dev/null && {
            git status
            popd >/dev/null
        }
    done
}
konsolebox
  • 66,700
  • 11
  • 93
  • 101
  • 1
    Is there a way to do this for every subfolder so that I don't have to manually define all folders? – kramer65 Jun 24 '14 at 15:10
0

I dealt with this by writing a shell script, mgit, that reads a hidden file .mgit in the current directory which contains a list of folders that are individual git repositories. It does something similar to this:

$ for d in */; do git -C $d status; done
holygeek
  • 14,885
  • 1
  • 39
  • 47
0
find . -maxdepth 1 -mindepth 1 -type d -exec sh -c '(echo {} && cd {} && git status -s && echo)' \;

It works recursively. You can change maxdepth and mindepth for your requirements

hakkikonu
  • 5,515
  • 6
  • 59
  • 105