diff options
-rwxr-xr-x | server/mkrepo (renamed from server/mkrepo.sh) | 24 | ||||
-rwxr-xr-x | server/mrrepo | 149 |
2 files changed, 166 insertions, 7 deletions
diff --git a/server/mkrepo.sh b/server/mkrepo index adf48fa..f372d2e 100755 --- a/server/mkrepo.sh +++ b/server/mkrepo @@ -1,13 +1,16 @@ #! /usr/bin/env bash -# Create remote git repository (on the server). You must run this script -# from the directory where you want the repository to be created. +# Create remote git repository (on the server). You must run this script from +# the "repositories root" (e.g., /var/scm) where you want the repository to be +# created. If the repository is public, also add it to the manifest file (used +# for mirroring). # -# Usage: mkrepo.sh [<options>] <name> +# Usage: mkrepo [<options>] <name> # -# --private make the repository private +# --private +# make the repository private # -# Note: <name> if without the .git suffix. +# Note: <name> is without the .git suffix. # trap 'exit 1' ERR @@ -39,9 +42,12 @@ if [ "$1" = "" ]; then exit 1 fi -r=$1.git +r=$1 +if [ `basename $1` = `basename --suffix=.git $1` ]; then + r="$r.git" +fi -mkdir $r +mkdir -p $r chgrp scm $r git --bare init --shared=all $r error "Enter project description (one line; or edit $r/descrition later)" @@ -61,3 +67,7 @@ else fi mv $r/hooks/post-update.sample $r/hooks/post-update + +if [ "$public" = "y" ]; then + echo "$r" >>manifest +fi diff --git a/server/mrrepo b/server/mrrepo new file mode 100755 index 0000000..1210725 --- /dev/null +++ b/server/mrrepo @@ -0,0 +1,149 @@ +#! /usr/bin/env bash + +# Mirror repositories. For example: +# +# mrrepo -s git.example.org /var/scm +# +# Will first download (via http or https if -s specified) the manifest file +# from git.example.org which should list all publicly available repositories. +# It will then mirror each repository in /var/scm using the git protocol. +# +# -v +# Run verbose. +# +# -s +# Use https rather than http to download the manifest (git protocol is still +# used for mirroring). +# +# Notes: +# - needs curl +# - run from cron as user scm (which belongs to the group scm). +# +usage="usage: $0 [-v] [-s] <host> <path>" + +owd=`pwd` +trap "{ cd $owd; exit 1; }" ERR +set -o errtrace # Trap in functions. + +function info () { echo "$*" 1>&2; } +function error () { info "$*"; exit 1; } + +prot=http +host= +path= +verb=0 + +while [ $# -gt 0 ]; do + case $1 in + -v) + verb=1 + shift + ;; + -s) + prot=https + shift + ;; + *) + if [ -z "$host" ]; then + host=$1 + elif [ -z "$path" ]; then + path=$1 + else + error "$usage" + fi + shift + ;; + esac +done + +if [ -z "$host" -o -z "$path" ]; then + error "$usage" +fi + +if [ ! -d "$path" ]; then + error "$path is not a directory" +fi + +cd $path + +curl_ops="-f" # Fail on HTTP errors. +curl_ops+=" --max-time 10" # Finish in 10 seconds. + +if [ $verb -ge 1 ]; then + curl_ops+=" --progress-bar" +else + curl_ops+=" -s -S" # Silent but show errors. +fi + +function fetch () # <url> [<curl-options>] +{ + local u=$1; shift + + if [ $verb -ge 1 ]; then + info "curl $curl_ops $* $u" + fi + + curl $curl_ops $* $u +} + +fetch $prot://$host/manifest -z manifest -o manifest + +new=() +while read r || [ -n "$r" ]; do + new+=("$r") +done <manifest + +# Find all existing repositories (directories that end with .git). +# +old=(`find . -type d -name '*.git' -print -prune | sed -e 's%^./%%' -`) + +git_ops= +if [ $verb -eq 0 ]; then + git_ops+="-q" +fi + +for r in ${new[@]}; do + if [ -d $r ]; then + if [ -z "$(ls -A $r)" ]; then + rm -r $r + fi + fi + if [ ! -d $r ]; then + if [ $verb -ge 1 ]; then + info "new repository $r in manifest, cloning" + info "git clone $git_ops --mirror git://$host/$r $r" + fi + mkdir -p $r + git clone $git_ops --mirror git://$host/$r $r + + # Also copy the description file. + # + fetch $prot://$host/$r/description -o $r/description + else + if [ $verb -ge 1 ]; then + info "existing repository $r, fetching" + info "git -C $r fetch $git_ops --tags" + fi + git -C $r fetch $git_ops --tags + fi +done + +# Remove old repositories. +# +for o in ${old[@]}; do + for n in ${new[@]}; do + if [ $o = $n ]; then + o= + break + fi + done + + if [ -n "$o" ]; then + if [ $verb -ge 1 ]; then + info "repository $o is no longer in manifest, removing" + fi + rm -rf $o + fi +done + +cd $owd |