#!/bin/bash
# tinyos-mirror.sh - Maintain a local git mirror of the tinyos CVS repository.
#
+# ------
+# NOTE: On or shortly after 2010-07-12, the official TinyOS repository was
+# migrated from CVS to Subversion, at http://tinyos-main.googlecode.com/svn.
+# As of this writing, tinyos-2.x-contrib remains hosted on CVS at sf.net.
+# ------
+#
# This utility allows updating a local mirror of the TinyOS CVS modules as
# a set of three git repositories, one per notable CVS module:
-# tinyos-1.x -> tinyos-1.x.git
-# tinyos-2.x -> tinyos-2.x.git
+# # (don't need) tinyos-1.x -> tinyos-1.x.git
+# # (deprecated) tinyos-2.x -> tinyos-2.x.git
# tinyos-2.x-contrib -> tinyos-2.x-contrib.git
#
# The utility actually allows both for creation and update of the local
#
# Usage:
#
-# tinyos-mirror.sh [--cvslocal|--cvsdirect|--localonly] [module [module ...]]
+# tinyos-mirror.sh [--cvslocal|--cvsdirect|--localonly|--rsynconly] [module [module ...]]
# No --xxx option implies update from upstream git.
# No module(s) implies update of all as defined in $MODULES.
#
# 2. To create or update the local git repos from the upstream CVS source,
# which may be more definitive but much slower, run tinyos-mirror.sh with
# the --cvslocal option.
+# --rsynconly does only the rsync update of the remote CVS to local CVS.
+# --localonly does everything of --cvslocal except the rsync.
#
# 3. To update (not create!) the local git repos from the upstream CVS source
# directly via pserver (see the UPCVSROOT variable), then run the
# perhaps faster than option #2 above if relatively few changesets have
# been added upstream since the last invocation of tinyos-mirror.sh.
#
-# 4. If you just wish to update the final git repositories with the interim
-# git repositories created by --cvslocal, then give --localonly. You can
-# do a full recreate of the final git repo this way by first removing it,
-# from /var/lib/git/<module>.git. --localonly only updates the final git
-# module to the state of the /var/lib/git/cvsimports/<module>-import repo.
-#
# It should be possible to invoke tinyos-mirror.sh using different update
# methods without creating problems. We have tested creating and initially
# populating the local git repos using --cvslocal and then following with
# Ensure these variables are correct for your installation
-MODULES="tinyos-1.x tinyos-2.x tinyos-2.x-contrib"
+MODULES="tinyos-2.x-contrib"
GITBASE=/var/lib/git
UPGITBASE=git://hinrg.cs.hju.edu/git
CVSBASE=/var/lib/cvs
+CVSREPO=tinyos
+CVSROOT=$CVSBASE/$CVSREPO
UPCVSROOT=:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos
-UPCVSRSYNC=rsync://tinyos.cvs.sourceforge.net/cvsroot/tinyos/
+UPCVSRSYNC=rsync://tinyos.cvs.sourceforge.net/cvsroot/tinyos
+
+# Uncomment this or export DEBUG=-v in your shell to get verbose output
+#DEBUG=-v
# There should be no need to change anything below this line
-do_rsync()
+do_backups()
{
- echo "Update local CVS mirror via rsync"
+ echo "Rotate local CVS mirror backups"
links=""
- if [ -d $CVSBASE/tinyos ]; then
- if [ -d $CVSBASE/tinyos.backup ]; then
- if [ -d $CVSBASE/tinyos.backup2 ]; then
- echo "Mv $CVSBASE/tinyos.backup2 $CVSBASE/tinyos.backup3"
- mv $CVSBASE/tinyos.backup2 $CVSBASE/tinyos.backup3
+ if [ -d $CVSROOT ]; then
+ if [ -d $CVSROOT.backup ]; then
+ if [ -d $CVSROOT.backup2 ]; then
+ echo "Mv $CVSROOT.backup2 $CVSROOT.backup3"
+ mv $CVSROOT.backup2 $CVSROOT.backup3
fi
- echo "Mv $CVSBASE/tinyos.backup $CVSBASE/tinyos.backup2"
- mv $CVSBASE/tinyos.backup $CVSBASE/tinyos.backup2
- links="--link-dest=$CVSBASE/tinyos.backup2 $links"
+ echo "Mv $CVSROOT.backup $CVSROOT.backup2"
+ mv $CVSROOT.backup $CVSROOT.backup2
+ links="--link-dest=$CVSROOT.backup2 $links"
fi
- echo "Mv $CVSBASE/tinyos -> $CVSBASE/tinyos.backup"
- mv $CVSBASE/tinyos $CVSBASE/tinyos.backup
- links="--link-dest=$CVSBASE/tinyos.backup $links"
- if [ -d $CVSBASE/tinyos.backup3 ]; then
- echo "Mv $CVSBASE/tinyos.backup3 -> $CVSBASE/tinyos"
- mv $CVSBASE/tinyos.backup3 $CVSBASE/tinyos
+ echo "Mv $CVSROOT -> $CVSROOT.backup"
+ mv $CVSROOT $CVSROOT.backup
+ links="--link-dest=$CVSROOT.backup $links"
+ if [ -d $CVSROOT.backup3 ]; then
+ echo "Mv $CVSROOT.backup3 -> $CVSROOT"
+ mv $CVSROOT.backup3 $CVSROOT
fi
else
- echo "Cp $CVSBASE/tinyos.backup3 $CVSBASE/tinyos.backup"
- cp -al $CVSBASE/tinyos.backup $CVS/tinyos # ok to fail
+ echo "Cp $CVSROOT.backup3 $CVSROOT.backup"
+ cp -al $CVSROOT.backup $CVSROOT 2>/dev/null # ok if it errors
fi
- echo "Rsync from sourceforge -> $CVSBASE/tinyos"
+}
+
+do_rsync()
+{
+ do_backups
+ echo "Rsync from sourceforge -> $CVSROOT"
echo " links: $links"
- rsync -avz --delete --no-p --no-g --chmod=Dg+s,Du+w,Fu+w $links \
- $UPCVSRSYNC $CVSBASE/tinyos/
+ filters="--exclude '/CVSROOT/CVS'"
+ for i in CVSROOT Attic $MODULES; do
+ filters="$filters --include '/$i' --include '/$i/**'"
+ done
+ filters="$filters --exclude '/**'"
+ eval rsync -az $DEBUG --delete --no-g --chmod=Dg+s,Du+w $links $filters \
+ $UPCVSRSYNC/ $CVSROOT
if [ $? -ne 0 ]; then
echo "rsync failed"
exit 1
fi
}
-locks_present()
-{
- lines=$(find . -name "#cvs*" | wc -l)
- if [ $lines -gt 0 ]; then
- return 0 # locks are present
- else
- return 1 # no locks present
- fi
-}
-
do_bare()
{
# Ensure the bare repos are present
echo "git init failed"
exit 1
fi
+ echo "Mirror of the $i CVS module" > $i.git/description
- # This line allows us to do cvsimport directly into this git repo,
- # as git-cvsimport doesn't know how to work with bare repos.
+ # git-cvsimport doesn't know how to work with bare repos, so
+ # create in each repo a .git that is a symlink to itself.
ln -s ../$i.git $i.git/.git
fi
done
}
-do_import()
+locks_present()
{
- # Now, do the imports. We limit the number of commits to prevent memory
- # leaks from taking out the VE. This command is incremental, just adding
- # new commits since the last run.
- if [ ! -d $GITBASE/cvsimports ]; then
- rm -rf $GITBASE/cvsimports
- mkdir $GITBASE/cvsimports
- chgrp repo $GITBASE/cvsimports
- chmod 755 $GITBASE/cvsimports
- chmod g+s $GITBASE/cvsimports
+ # $1 is the local CVS module to check
+ lines=$(find "$CVSROOT/$1" -name "#cvs*" | wc -l)
+ if [ $lines -gt 0 ]; then
+ return 0 # locks are present
+ else
+ return 1 # no locks present
fi
- cd $GITBASE/cvsimports
- for i in $MODULES; do
- echo "Import cvs module $i -> git"
- git cvsimport -v -o master -d $CVSBASE/tinyos -C $i-import -i -k \
- -L2000 $i
- if [ $? -ne 0 ]; then
- echo "cvsimport failed"
- exit 1
- fi
- done
}
-do_push()
+do_import()
{
- # Now we need to push the new commits in each of the import repos into the
- # bare repos which are the pseudo-centralized shared repos.
- cd $GITBASE/cvsimports
+ # Now, do the imports. We limit the number of commits to prevent memory
+ # leaks from taking out the VE. This command is incremental, just adding
+ # new commits since the last run.
+ cd $GITBASE
for i in $MODULES; do
- echo "Push git import module cvsimports/$i-import -> $i.git"
- git --git-dir=$i-import/.git push --mirror ../$i.git/
- if [ $? -ne 0 ]; then
- echo "git push failed"
- exit 1
+ if locks_present $i; then
+ echo "SKIP cvs module $i; locks present in the CVS repo."
+ else
+ echo "Import cvs module $i -> git"
+ git cvsimport $DEBUG -o master -d $CVSROOT -C $i.git -i -k \
+ -L2000 $i
+ if [ $? -ne 0 ]; then
+ echo "cvsimport failed"
+ exit 1
+ fi
fi
done
}
# memory leaks from taking out the VE. This command is incremental, just
# adding new commits since the last run.
+ echo "Importing directly from remote CVS repository"
cd $GITBASE
for i in $MODULES; do
echo "Update from CVS module DIRECT $i -> git"
- git cvsimport -v -o master -d $UPCVSROOT -C $i.git -i -k -L2000 $i
+ git cvsimport $DEBUG -o master -d $UPCVSROOT -C $i.git -i -k -L2000 $i
if [ $? -ne 0 ]; then
echo "cvsimport failed"
exit 1
done
}
+do_import_localonly()
+{
+ # Do the cvs-gitimports from the local CVS.
+
+ echo "Importing from local copy of remote CVS repository"
+ do_bare
+ do_import
+}
+
do_import_cvslocal()
{
# Do the imports by first using rsync to sync a local CVS from sf.net,
# then do cvs-gitimports from the local CVS.
do_rsync
- if locks_present; then
- echo "Locks present in the CVS upstream. We won't import this time."
- else
- do_bare
- do_import
- do_push
- fi
+ do_import_localonly
}
do_import_git()
# tinyos-1.x is 14 months old when the last update was 3/17/09, and
# tinyos-2.x-contrib.git is 5 months old when the last update was 4/7/09.
+ echo "Importing from remote git repositories"
fail=0
cd $GITBASE
for i in $MODULES; do
ln -s ../$i.git $i.git/.git
else
echo "Pull gitupstream -> $i.git"
- git --git-dir=$i.git fetch $UPGITBASE/$i.git
+ git --git-dir=$i.git fetch $UPGITBASE/$i.git master:master
if [ $? -ne 0 ]; then
echo "git fetch failed"
fail=$(($fail + 1))
fi
}
+env_ok()
+{
+ ret=0
+ if [ ! -d "$GITBASE" ]; then
+ echo "$GITBASE is not a directory" >&2
+ ret=1
+ else
+ if [ $(ls -ld $GITBASE | awk '{ print $1 }') != "drwxr-sr-x" ]; then
+ echo "$GITBASE must have permissions drwxr-sr-x" >&2
+ ret=1
+ fi
+ fi
+ if [ ! -d "$CVSBASE" ]; then
+ echo "$CVSBASE is not a directory" >&2
+ ret=1
+ else
+ if [ $(ls -ld $CVSBASE | awk '{ print $1 }') != "drwxr-sr-x" ]; then
+ echo "$CVSBASE must have permissions drwxr-sr-x" >&2
+ ret=1
+ fi
+ fi
+ return $ret
+}
+
# MAIN
+if ! env_ok; then
+ echo "$0: no work done" >&2
+ exit 1
+fi
+
unset option
unset opt_modules
while [ -n "$1" ]; do
if echo "$1" | grep -q -- "--"; then
- if [ "$1" = "--cvslocal" -o "$1" = "--cvsdirect" ]; then
+ if [ "$1" = "--cvslocal" -o "$1" = "--cvsdirect" -o "$1" = "--localonly" -o "$1" = "--rsynconly" ]; then
if [ -z "$option" ]; then
option=$1
fi
if [ -n "$opt_modules" ]; then
MODULES="$opt_modules"
fi
-echo "Updating modules $MODULES"
+echo "Updating modules: $MODULES"
if [ "$option" = "--cvsdirect" ]; then
do_import_cvsdirect
elif [ "$option" = "--cvslocal" ]; then
do_import_cvslocal
elif [ "$option" = "--localonly" ]; then
- do_push
+ do_import_localonly
+elif [ "$option" = "--rsynconly" ]; then
+ do_rsync
else
+ echo "$0: incorrect usage" >&2
+ exit 1
do_import_git
fi
+echo "Import actions complete."
exit 0