10

I have a folder with several repositories inside. Is there any way I can run git branch or whatever git command inside each folder?

$ ls
project1            project2                project3            project4

And I'd like to have some kind of output like the following

$ command
project1 [master]
project2 [dev]
project3 [master]
project4 [master]

5 Answers 5

10

Try this. $1 should be the parent dir containing all of your repositories (or use "." for the current dir):

#!/bin/bash

function git_branches()
{
    if [[ -z "$1" ]]; then
        echo "Usage: $FUNCNAME <dir>" >&2
        return 1
    fi

    if [[ ! -d "$1" ]]; then
        echo "Invalid dir specified: '${1}'"
        return 1
    fi

    # Subshell so we don't end up in a different dir than where we started.
    (
        cd "$1"
        for sub in *; do
            [[ -d "${sub}/.git" ]] || continue
            echo "$sub [$(cd "$sub"; git  branch | grep '^\*' | cut -d' ' -f2)]"
        done
    )
}

You can make this its own script (but replace $FUNCNAME with $0), or keep it inside a function and use it in your scripts.

1
for dir in */
  do (cd $dir && echo "$dir [$(git rev-parse --abbrev-ref HEAD)]")
done

or even as an alias

alias brall='for dir in $(ls -d */);do (cd $dir && echo "$dir [$(git rev-parse --abbrev-ref HEAD)]") ; done'

It will output (almost) what you want.

project1/ [master]
project2/ [dev]
project3/ [master]
project4/ [master]
6
  • 2
    $(ls -d */) is a brittle way of saying */.
    – muru
    Commented Aug 22, 2019 at 7:54
  • I don't get it, how would you do that : 'for dir in */ ... ' ?
    – Antoine
    Commented Aug 22, 2019 at 8:25
  • Yes, exactly that: for d in */
    – muru
    Commented Aug 22, 2019 at 8:35
  • Ok, I'm far from an expert in bash and it certainly works in other version of shell. But with my version of zsh (5.7.1 (x86_64-apple-darwin17.7.0)), it doesn't work : "zsh: no matches found: */"
    – Antoine
    Commented Aug 22, 2019 at 9:00
  • 1
    Then there are no matches. In that case, your loop would have failed as well.
    – muru
    Commented Aug 22, 2019 at 10:19
1

I had to do some tweaks as the git directories were in some sub- sub-folders. It also supports from the cwd or dir specified on $1. Here is an alias to add to .bashrc:

git_branches() {
    if [[ -z "$1" ]]; then
        search_dir=$(pwd)
        echo "Using current dir: '${search_dir}'"
    else
        search_dir=$1
    fi
    
    if [[ ! -d "$search_dir" ]]; then
        echo "Invalid dir specified: '${search_dir}'"
        return 1
    fi
    
    # Subshell so we don't end up in a different dir than where we started.
    (
        cd "$search_dir"
        for dir in $(find . -name .git -type d -prune); do
        (
            cd $dir
            echo "$dir [$(git rev-parse --abbrev-ref HEAD)]"
        );
        done
    )
}
0
ls | xargs -P10 -I{} git -C {} branch

You can use any git command in place of branch. for e.g:

ls | xargs -P10 -I{} git -C {} pull --rebase
ls | xargs -P10 -I{} git -C {} fetch

Only caveat is output may not contain the directory name. But if it is not an issue, this command is simple.

0

The basic command is

git branch --show-current

in the appropriate folder

so, one liner can be:

for d in project*; do cd "$d" && b="`git branch --show-current`" && cd - >/dev/null && echo "$d [$b]"; done

This can be made an alias or put into a script to be used as a command

2
  • Use $(command) instead of backticks.
    – annahri
    Commented Aug 2, 2021 at 3:07
  • No problem. I prefer backtick. $(command) will also work. Readability is the same for me.
    – Oguz Ozhan
    Commented Aug 3, 2021 at 11:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .