Skip to content

Instantly share code, notes, and snippets.

@beporter
Last active August 29, 2015 14:27
Show Gist options
  • Save beporter/db9d524cbfe863baf260 to your computer and use it in GitHub Desktop.
Save beporter/db9d524cbfe863baf260 to your computer and use it in GitHub Desktop.
A script to automate converting a SourceForge.net CVS repo into a git repo.
#!/usr/bin/env bash
#
#---------------------------------------------------------------------
usage ()
{
cat <<EOT
${0##*/}
Wraps up the commands required to dump a SourceForge CVS repo
(that you have SSH access to) and convert it into a git repo.
Will create a working directory in whatever path you run this
from.
Requires the cvs, git and cvs2svn commands. If these are not
already present and in your PATH, this script will attempt to
install them for you using MacPorts.
Usage:
bin/${0##*/}
EOT
exit ${1:-0} # Exit with code 0 unless an arg is passed to the method.
}
if [ "$1" = '-h' ]; then
usage
fi
#---------------------------------------------------------------------
echoerr() { echo "$@" 1>&2; }
GIT_USER=$(git config --get user.name)
GIT_EMAIL=$(git config --get user.email)
WORKING_DIR="sfcvs2git"
REQUIRED_COMMANDS=("cvs" "cvs2svn" "git" "zip")
# Input validation.
if [ -z "$1" ]; then
echoerr "!! You must provide the SourceForge project name as the first arg."
exit 1
fi
PROJECT_NAME="$1"
# Environment verification.
for CMD in "${REQUIRED_COMMANDS[@]}"; do
if ! command -v "$CMD" >/dev/null 2>&1; then
echoerr "!! You must have the \`${CMD}\` command installed."
if command -v 'port' >/dev/null 2>&1; then
echoerr "!! Trying \`sudo port install ${CMD}\`."
if ! sudo port install $CMD; then
exit 1
fi
else
echoerr "!! Please install it in your PATH before continuing."
exit 2
fi
fi
done
# Create the working dir.
if [ ! -d "$WORKING_DIR" ]; then
mkdir -p "$WORKING_DIR/tmp"
fi
cd "$WORKING_DIR" >/dev/null 2>&1
# Download a full dump of the CVS repo.
echo "## Downloading CVS repo."
rsync -aq rsync://$PROJECT_NAME.cvs.sourceforge.net/cvsroot/$PROJECT_NAME/\* "${PROJECT_NAME}"
# Loop over all module folders (other than CVSROOT) in the downloaded
# folder, as long as there isn't already an output git folder (that we
# don't want to overwrite.)
IFS="$(printf '\n\t')"
for MODULE in "$PROJECT_NAME/"* ; do
if [ -d "$MODULE" ] && [[ ! -d "output/${MODULE}" ]] && [[ ! "$MODULE" =~ CVSROOT$ ]]; then
echo "## Found module \`${MODULE}\`"
cvs2git -qq --blobfile=tmp/blob.dat --dumpfile=tmp/dump.dat --username=$USER "${MODULE}"
# Post-process the dump file to set better committer info.
sed -i '' "s/^committer $USER \<\>/committer $GIT_USER \<$GIT_EMAIL\>/" tmp/dump.dat
# Create the git repo and import blob/dump data.
(
echo "## Creating git repo."
git init --quiet --bare "output/${MODULE}"
echo "## Importing blob and dump data."
cd "output/${MODULE}" >/dev/null 2>&1
cat ../../../tmp/{blob,dump}.dat | git fast-import --quiet
)
echo "## Repo done: \`${WORKING_DIR}/output/${MODULE}\`"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment