]> oss.titaniummirror.com Git - git-utils.git/commitdiff
git-overview walks a subtree commenting on git repos contained within.
authorR. Steve McKown <rsmckown@gmail.com>
Wed, 16 Dec 2009 23:27:39 +0000 (16:27 -0700)
committerR. Steve McKown <rsmckown@gmail.com>
Wed, 16 Dec 2009 23:27:39 +0000 (16:27 -0700)
git-overview [new file with mode: 0755]

diff --git a/git-overview b/git-overview
new file mode 100755 (executable)
index 0000000..7012705
--- /dev/null
@@ -0,0 +1,145 @@
+#!/bin/bash
+# git-overview
+#
+# Review a filesystem subtree for git repos and show their overall state.
+# Runs on the current directory if no argument is provided
+
+usage()
+{
+  [ -n "$1" ] && echo "$1" >&2
+  echo "usage: $0 [directory]" >&2
+  exit 1
+}
+
+# __gitdir accepts 0 or 1 arguments (i.e., location)
+# returns location of .git repo
+__gitdir ()
+{
+       if [ -z "${1-}" ]; then
+               if [ -n "${__git_dir-}" ]; then
+                       echo "$__git_dir"
+               elif [ -d .git ]; then
+                       echo .git
+               else
+                       git rev-parse --git-dir 2>/dev/null
+               fi
+       elif [ -d "$1/.git" ]; then
+               echo "$1/.git"
+       else
+               echo "$1"
+       fi
+}
+
+# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
+# returns text to add to bash PS1 prompt (includes branch name)
+__git_ps1 ()
+{
+       local g="$(__gitdir)"
+       if [ -n "$g" ]; then
+               local r
+               local b
+               if [ -f "$g/rebase-merge/interactive" ]; then
+                       r="|REBASE-i"
+                       b="$(cat "$g/rebase-merge/head-name")"
+               elif [ -d "$g/rebase-merge" ]; then
+                       r="|REBASE-m"
+                       b="$(cat "$g/rebase-merge/head-name")"
+               else
+                       if [ -d "$g/rebase-apply" ]; then
+                               if [ -f "$g/rebase-apply/rebasing" ]; then
+                                       r="|REBASE"
+                               elif [ -f "$g/rebase-apply/applying" ]; then
+                                       r="|AM"
+                               else
+                                       r="|AM/REBASE"
+                               fi
+                       elif [ -f "$g/MERGE_HEAD" ]; then
+                               r="|MERGING"
+                       elif [ -f "$g/BISECT_LOG" ]; then
+                               r="|BISECTING"
+                       fi
+
+                       b="$(git symbolic-ref HEAD 2>/dev/null)" || {
+
+                               b="$(
+                               case "${GIT_PS1_DESCRIBE_STYLE-}" in
+                               (contains)
+                                       git describe --contains HEAD ;;
+                               (branch)
+                                       git describe --contains --all HEAD ;;
+                               (describe)
+                                       git describe HEAD ;;
+                               (* | default)
+                                       git describe --exact-match HEAD ;;
+                               esac 2>/dev/null)" ||
+
+                               b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
+                               b="unknown"
+                               b="($b)"
+                       }
+               fi
+
+               local w
+               local i
+               local s
+               local u
+               local c
+
+               if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
+                       if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
+                               c="BARE:"
+                       else
+                               b="GIT_DIR!"
+                       fi
+               elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
+                       if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
+                               if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
+                                       git diff --no-ext-diff --ignore-submodules \
+                                               --quiet --exit-code || w="*"
+                                       if git rev-parse --quiet --verify HEAD >/dev/null; then
+                                               git diff-index --cached --quiet \
+                                                       --ignore-submodules HEAD -- || i="+"
+                                       else
+                                               i="#"
+                                       fi
+                               fi
+                       fi
+                       if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
+                               git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
+                       fi
+
+                       if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
+                          if [ -n "$(git ls-files --others --exclude-standard)" ]; then
+                             u="%"
+                          fi
+                       fi
+               fi
+
+               if [ -n "${1-}" ]; then
+                       printf "$1" "$c${b##refs/heads/}$w$i$s$u$r"
+               else
+                       printf " (%s)" "$c${b##refs/heads/}$w$i$s$u$r"
+               fi
+       fi
+}
+
+# MAIN
+
+if [ $# -eq 1 ]; then
+    cd "$1" || usage "Bad directory"
+fi
+
+(
+for path in $(find . -maxdepth 3 -name .git -type d); do
+    repo="${path/\/.git}"
+    (
+       cd $repo
+       echo $repo: $(__git_ps1)
+       for remote in $(git remote show); do
+           echo "    $remote:"
+           git remote show $remote | grep "pushes to"
+       done
+       echo
+    )
+done
+) 2>&1