1

Based on this question I came up with this command to find out all .git repositories on my machine.

find / -type d -name .git 2>&-

And it works relatively fast. Though I hear my CPU's fan a little, which shows that my machine does some work.

Now I want to be able to loop over the results and run git commands on each of them. For example, I want to get their status to see what should be managed.

I tried:

find / -type d -name .git 2>&- | xargs git status

But it didn't work:

fatal: not a git repository (or any of the parent directories): .git

I also tried:

find / -type d -name .git 2>&- | xargs dirname | xargs git status

Again, the same error.

What command should I use?

Hossein Fallah
  • 1,859
  • 2
  • 18
  • 44

3 Answers3

1

Your issue is simply : suppose your cwd is $HOME, and your repository is in $HOME/my/repo,
git status $HOME/my/repo will not look for a git repository stored in my/repo, it will search for a repository starting from $HOME and going upwards (and it probably won't find one).


There are several ways to fix this :

  • cd to target directory before running git status :

    cd <path/to/repo>; git status
    
  • name the target .git repository using git -C :

    git -C <path/to/repo> status
    

To combine your find command with xargs :

  • use dirname to turn /path/to/repo/.git into /path/to/repo,
  • use xargs -i to allow to place the argument somewhere else than "the last position" :
find . -name .git | xargs dirname | xargs -i git -C {} status

# or :
find . -name .git | xargs dirname |\
    xargs -i bash -c "echo ===== {}; git -C {} status"
LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • I initially posted an answer saying "only set `GIT_DIR`", but you actually also need to set `GIT_WORK_TREE`. `git -C path/to/repo` is more convenient (it sets "both"). – LeGEC Jul 09 '21 at 09:10
0

You can also try and use dirk-thomas/vcstool (python-based)

Vcstool is a version control system (VCS) tool, designed to make working with multiple repositories easier.

vcs status /path/to/several/repos /path/to/other/repos /path/to/single/repo

Other approach (shell-based): sascha-andres/devenv

devenv is a tool to manage projects containing multiple git repositories. > With a config you can setup all repositories with one command and even work with the local repositories as if they where one ( eg creating branches in all referenced projects) using the shell.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
-1

I use this:

find . \
  -type d \
  -exec sh -c '[ -e "$1/.git" ]' - {} \; \
  -prune \
  -exec git -C {} status \;

It:

  • isn’t very fast.
  • will skip nested repositories (e.g. submodules).
  • works with work trees, but not bare repositories.

Here’s an alternative that should work with bare repositories:

find . \
  -type d \
  -exec sh -c 'git -C "$1" rev-parse --git-dir >/dev/null 2>&1' - {} \; \
  -prune \
  -exec git -C {} status \;
Biffen
  • 6,249
  • 6
  • 28
  • 36