--- /dev/null
+#!/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
--- /dev/null
+#!/bin/bash
+# git-push-public
+#
+# Push changes from local git repositories marked as public, via the
+# git-daemon-export-ok flag, to the public server.
+
+LOCALBASE=/var/lib/git
+PUBLICBASE=/var/cache/git
+PUBLICSERVER="$1"
+[ -z "$PUBLICSERVER" ] && PUBLICSERVER=oss.titaniummirror.com
+
+echo "Updating git repos on server $PUBLICSERVER"
+cd $LOCALBASE
+for path in $(find . -name git-daemon-export-ok); do
+ repo="${path/\/git-daemon-export-ok/}"
+ repo="${repo/.\//}"
+ echo "Repository $repo"
+ if ! ssh $PUBLICSERVER test -d $PUBLICBASE/$repo ; then
+ # Repo does not exist on public server, so create it
+ echo "Creating repository $repo on remote"
+ ssh $PUBLICSERVER git --git-dir=$PUBLICBASE/$repo init --bare
+ ssh $PUBLICSERVER touch $PUBLICBASE/$repo/git-daemon-export-ok
+ scp $repo/description $PUBLICSERVER:$PUBLICBASE/$repo/
+ ssh $PUBLICSERVER "echo \"git://$PUBLICSERVER/$repo\" \
+ > $PUBLICBASE/$repo/cloneurl"
+ fi
+ git --git-dir=$repo push --mirror $PUBLICSERVER:$PUBLICBASE/$repo
+done
--- /dev/null
+#!/bin/bash
+#
+# Backup git DB's to sporian. This is an alternate facility to SVN, for
+# the paranoid like me. Also allows me to keep temp branches.
+
+
+# Ensure we have an ssh key on SVHOST
+SVHOST=iweb.sporian.com
+SVDIR=TMI/git
+SVURL=$SVHOST:$SVDIR
+
+rsync_proj()
+{
+ proj=$1
+ echo "Project $proj [via rsync]"
+ (
+ # SVHOST may not have git
+ ssh $SVHOST mkdir -p $SVDIR/${proj}.git
+ rsync -avz --delete $proj/.git/ $SVURL/${proj}.git/
+ )
+}
+
+git_proj()
+{
+ proj=$1
+ echo "Project $proj [via git]"
+ (
+ # Easier when SVHOST has git
+ cd $proj
+ ssh $SVHOST test -d $SVDIR/${proj}.git || \
+ ssh $SVHOST git --git-dir $SVDIR/${proj}.git init --bare --shared=true
+ git push --mirror "$SVURL/${proj}.git"
+ )
+}
+
+#cd ~/workspace/sporian
+if [ -n "$1" ]; then
+ if [ -d "$1" -a -d "$1/.git" ]; then
+ #rsync_proj $1
+ git_proj $1
+ else
+ echo "$0: skip ~/workspace/sporian/$1; not a git project" >&2
+ exit 1
+ fi
+else
+ for i in $(find . -name .git -type d 2>/dev/null); do
+ #rsync_proj $(basename $(dirname $i))
+ git_proj $(basename $(dirname $i))
+ done
+fi
+exit 0
--- /dev/null
+#!/bin/bash
+# push-public
+#
+# Push changes to everything local that can be exported to the public
+# web server.
+
+git-push-public $*
+repo-push-public $*
--- /dev/null
+#!/bin/bash
+#
+# Push changes to the local TMI repo to the public repo. We really should be
+# using launchpad to host the public version of the TMI repo.
+
+PUBLICSERVER="$1"
+[ -z "$PUBLICSERVER" ] && PUBLICSERVER=oss.titaniummirror.com
+
+echo "Updating APT repo on $PUBLICSERVER"
+rsync -avz --delete /var/local/aptrepo/ $PUBLICSERVER:/var/local/aptrepo/
--- /dev/null
+#!/bin/sh
+#
+# server-gc -- Run git-gc on each git repository found within the provided
+# filesystem directory tree. Useful for shared on-server repos that don't
+# automatically do gc operations. This script was first posted at
+# http://groups.google.com/group/repo-discuss/web/repository-repacking
+#
+# NOTE: THIS UTILITY DOES NOT REALLY APPEAR TO BE NEEDED.
+
+if [ $(whoami) != "root" ]; then
+ echo "usage: $0 must be ran as root" >&2
+ exit 1
+fi
+
+TOP=$1
+if [ ! -d "$TOP" ]; then
+ echo "usage: $0 <topdir>>" >&2
+ exit 1
+fi
+
+cd $TOP
+for p in $(find . -type d -name \*.git | sed 's,^./,,')
+do
+ d=$TOP/$p
+ echo
+ echo "*** Repository $d ***"
+
+ git --git-dir=$d config repack.usedeltabaseoffset true
+ git --git-dir=$d config pack.compression 9
+ git --git-dir=$d config pack.indexversion 2
+
+ git --git-dir=$d config gc.autopacklimit 4
+ git --git-dir=$d config gc.packrefs true
+ git --git-dir=$d config gc.reflogexpire never
+ git --git-dir=$d config gc.reflogexpireunreachable never
+
+ case $p in
+ kernel/lk.git)
+ : use defaults
+ ;;
+ kernel/*)
+ git --git-dir=$d config pack.threads 6
+ git --git-dir=$d config pack.window 250
+ git --git-dir=$d config pack.depth 50
+ ;;
+ esac
+
+ rm -rf $d/logs/refs/changes 2>/dev/null
+
+ git --git-dir=$d gc --auto --aggressive --prune || break
+
+ (find $d/refs/changes -type d | xargs rmdir;
+ find $d/refs/changes -type d | xargs rmdir
+ ) 2>/dev/null
+done
--- /dev/null
+#!/bin/bash
+#
+# Usage: update-mirror <url of upstream> <local project dirname>
+#
+# Derived from girocco's taskd/clone.sh script. See
+# http://repo.or.cz/w/girocco.git
+
+set -e
+
+cfg_gitweburl=http://$(hostname)/gitweb
+cfg_reporoot=/var/lib/git/mirrors
+
+url=$1
+projdir=$2
+
+proj="${projdir%.git}"
+
+echo "[$proj] update mirror"
+echo "[$proj] $url -> $projdir"
+
+if [ ! -d "$cfg_reporoot/$projdir" ]; then
+ echo "[$proj] $projdir is a new project"
+ mkdir -p "$cfg_reporoot/$projdir"
+ touch "$cfg_reporoot/$projdir/.new_clone"
+fi
+touch "$cfg_reporoot/$projdir/.clone_in_progress"
+
+cd "$cfg_reporoot/$projdir"
+trap "echo \"[$proj] clone failed\"; touch .clone_failed" EXIT
+
+mail="sysadmin"
+
+# Initial mirror
+echo "[$proj] mirroring..."
+case "$url" in
+ svn://* | svn+http://* | svn+https://*)
+ # we just remove svn+ here, so svn+http://... becomes http://...
+ svnurl="${url#svn+}"
+ if [ -f "$cfg_reporoot/$projdir/.new_clone" ]; then
+ echo "[$proj] initial git-svn setup"
+ git --git-dir . --bare init
+ git --git-dir . svn init -s --prefix=svn-origin/ "$svnurl"
+ # have git-svn store branches under svn-origin/heads/* not svn-origin/*
+ # FIXME: may need to do similar when new branches are added
+ git --git-dir . config svn-remote.svn.branches \
+ "$(git config --get svn-remote.svn.branches | \
+ sed 's|:refs/remotes/svn-origin/\*$|:refs/remotes/svn-origin/heads/*|')"
+ git --git-dir . svn fetch
+ # Neat Trick suggested by Miklos Vajna
+ git --git-dir . config remote.origin.url .
+ git --git-dir . config remote.origin.fetch \
+ '+refs/remotes/svn-origin/heads/*:refs/heads/*'
+ git --git-dir . config --add remote.origin.fetch \
+ '+refs/remotes/svn-origin/trunk:refs/heads/master'
+ git --git-dir . config --add remote.origin.fetch \
+ '+refs/remotes/svn-origin/tags/*:refs/tags/*'
+ rm -f "$cfg_reporoot/$projdir/.new_clone"
+ fi
+ echo "[$proj] fetching new commits from upstream"
+ git --git-dir . svn fetch
+ git --git-dir . fetch
+ ;;
+
+ darcs://*)
+ echo "[$proj] darcs mirrors not yet supported"
+ exit 1
+ httpurl="${url/darcs:\/\//http://}"
+ /usr/bin/darcs-fast-export --export-marks=$(pwd)/dfe-marks "$httpurl" | \
+ git fast-import --export-marks=$(pwd)/gfi-marks
+ # This is here because by default only the exit code of
+ # git fast-import is checked
+ [ ${PIPESTATUS[0]} = 0 -a ${PIPESTATUS[1]} = 0 ]
+ ;;
+
+ bzr://*)
+ echo "[$proj] bazaar mirrors not yet supported"
+ exit 1
+ # we just remove bzr:// here, a typical bzr url is just
+ # "lp:foo"
+ bzrurl="${url#bzr://}"
+ bzr fast-export --export-marks=$(pwd)/bfe-marks "$bzrurl" | \
+ git fast-import --export-marks=$(pwd)/gfi-marks
+ [ ${PIPESTATUS[0]} = 0 -a ${PIPESTATUS[1]} = 0 ]
+ ;;
+
+ *)
+ if [ -f "$cfg_reporoot/$projdir/.new_clone" ]; then
+ echo "[$proj] initial git setup"
+ git --git-dir . --bare init
+ git --git-dir . remote rm origin >/dev/null 2>&1 || :
+ git --git-dir . remote add --mirror origin "$url"
+ fi
+ echo "[$proj] fetching new commits from upstream"
+ git --git-dir . remote update
+ git --git-dir . remote prune origin
+ ;;
+esac
+
+# The rest
+git update-server-info
+trap "" EXIT
+rm .clone_in_progress
+echo "[$proj] clone updated. See $cfg_gitweburl/?p=mirrors/$projdir;a=summary"