# A tool for managing multiple git projects quickly. # Simply source this in your bashrc or zshrc. # This assumes a common directory that contains all projects. # Subfolders are detected as well. # You can set $PROJECTS before or after sourcing this script, or adjust it below. # The regular command is "p status" to update all projects and show their status. # Common root for all projects PROJECTS=${PROJECTS:-$DATA} # The max depth to search for when listing projects. # The actual depth is this value minus one, # since it searches for ".git" folders at that depth. _projects_subfolder_level=5 # Lists all projects under the current directory or $PROJECTS if none are found. # Searches for ".git" folders and lists their parent directories. listprojects() { find $1 -mindepth 1 -maxdepth $_projects_subfolder_level -type d \ -path "${1:-.}/*/.git" -exec dirname {} \; -o \ -name "_*" -o -name ".*" -prune || { test $# -eq 0 && listprojects $PROJECTS; } } # Underline the project names highlight() { echo "$1"; } # Open or select a project project() { cd $PROJECTS if [ -d $2 ] then cd "$2" && git origin "$@" else git get "$@" fi } # Lists all projects and evaluates the given command. projects() { test "$1" = "--all" && all="$1" && shift case $1 in ("build") # Builds all found gradle projects in parallel and then prints the results in batches # WARNING: This is likely to considerably slow down your computer! listprojects $all | while read d; do if test "$(find $d -maxdepth 1 -name "*gradle*")"; then builtin cd $d buildlog="/tmp/build-$(basename $d)" (nohup gradle build --no-daemon --console=rich &>$buildlog; highlight $(basename $d | awk '{print toupper($0)}') && cat $buildlog) & fi done wait ;; ("diffs") # Puts the diffs of all projects into a single diffs.txt in the current directory listprojects $all | while read d; do echo $(basename $d)>>diffs.txt git -C $d diff -G.>>diffs.txt printf "\n">>diffs.txt done ;; ("status") # Sets the current branch upstream to a remote branch of the same name, updates it and shows "git status -s -b" listprojects $all | while read d; do builtin cd $d highlight $(basename $d) git branch --set-upstream-to=origin/$(git curbranch)>/dev/null git pull --all | grep -v "Already up to date." git status -s -b done ;; (*) # A one-line summary of the status of each project # and execute the command entered on every project com="$@" listprojects $all | while read d; do builtin cd $d if [[ $com != gradle* ]] || (( $(f1 -name "*gradle*" | wc -l) > 0 )); then #local st=() declare -a st local ahead=$(command git rev-list "${branch_name}"@{upstream}..HEAD 2>/dev/null | wc -l) test $ahead -gt 0 && st+=("ahead $ahead") local behind=$(command git rev-list HEAD.."${branch_name}"@{upstream} 2>/dev/null | wc -l) test $behind -gt 0 && st+=("behind $behind") local stashes=$(git stash list | wc -l) test $stashes -gt 0 && st+=("stashed $stashes") test "$st" && name+=" [$(IFS=, eval 'JOINED="${st[*]}"' && echo $JOINED)]" highlight $(basename $d) eval "$com" fi done esac builtin cd $PROJECTS }