Bash – Git Bash – ls show git repo folders

bashgit

I have a folder, /c/Tools, with three folders.

I want a command like below

$ ls --show-repositories

Tools is NOT a git repository, but Tools/MyProject and Tools/MyApp both are. The output I want is:

drwxr-xr-x 1 0018121 Domain Users    0 Dec 14 14:33 MyProject/ (develop)
drwxr-xr-x 1 0018121 Domain Users    0 Dec 14 14:17 Data/
drwxr-xr-x 1 0018121 Domain Users    0 Dec 14 12:08 MyApp/ (master)
-rw-r--r-- 1 0018121 Domain Users 399K Aug  4 10:41 readme.txt
-rw-r--r-- 1 0018121 Domain Users 136K Aug  4 10:20 image.jpg

so from the parent folder I can tell if a child folder is a current valid git repository (and what branch is currently checked out)

Thanks

Best Answer

Keep it simple; look for the directory .git and run your commands from within its containing directory. Also throw in a -print to see what dir it is running in:

find . -type d -name .git -print -execdir git symbolic-ref --short HEAD \;

(Okay, actually -print shows the dir it found./path/to/repo/.git, not the ./path/to/repo/ itself. But that's a minor inconvenience.)


EDIT: You can produce the EXACT output requested in your OP by the following:

paste <(ls -ld *) <(for i in *; do if [ -d "$i"/.git ] ; then echo "($(git --git-dir="$i"/.git symbolic-ref --short HEAD))"; else echo; fi; done)

This doesn't have any real drawback that I can see.

By design it only finds top level git repos, i.e. if your "Data" directory (in your example ls output) has subdirectories which are git repos they won't be listed, whereas with the find command I gave earlier they would be. But as I say that's by design.

This doesn't preserve colors in the output of ls. You can do this by adding a --color=always to the embedded ls command:

paste <(ls -ld --color=always *) <(for i in *; do if [ -d "$i"/.git ] ; then echo "($(git --git-dir="$i"/.git symbolic-ref --short HEAD))"; else echo; fi; done)

Though, for some reason, this produces an extra newline at the end of all the output. Oh well; not a big deal IMO.


For Mac OS, ls doesn't have a --color flag, so use the following to force color output:

paste <(CLICOLOR_FORCE=true ls -ld *) <(for i in *; do if [ -d "$i"/.git ] ; then echo "($(git --git-dir="$i"/.git symbolic-ref --short HEAD))"; else echo; fi; done)
Related Question