#!/bin/sh # # USAGE # # rcs2git [FILES] # # SUMMARY # # Given an existing Git repository, this script imports the revision # history of a collection of RCS-controlled files. # # SYNOPSIS # # Import the RCS revision history at ~/rcs-proj into a new Git # repository at ~/git-proj: # # $ mkdir ~/git-proj # $ cd ~/git-proj # $ git init # $ cp -r ~/rcs-proj/RCS . # $ rcs2git # $ rm -rf RCS # # Since no files were listed, rcs2git imports all files which match # *,v and RCS/*,v. # # One can also import the history of a single RCS-controlled file # into an existing Git repository. Here, we only create a symbolic # link to the RCS file: # # $ cd ~/git-proj # $ ln -s ~/rcs-proj/RCS/file.ext,v # $ rcs2git file.ext # $ rm file.ext,v # # NOTES # # This script does not recurse into subdirectories. It assumes that # the RCS files (filename.ext,v) are present in the current # directory or the RCS directory. # # This script does not preserve author information. It assumes that # you are the sole author of the RCS project and that you have # correctly set your personal information in ~/.gitconfig. # # VERSION # # 1.00 # # LICENSE # # Copyright (C) 2008 Jason Blevins # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # Outputs revision metadata in the form: file.ext 1.25 2008-03-30 19:24 store_metadata() { rlog $1 | sed -n "/^revision [0-9]*\.[0-9]*$/{ s/^revision //g N s/\n/ / s/date: \([0-9 /]\{10\}\) \([0-9:]\{5\}\).*$/\1 \2/g s/\//-/g s/^/$1 / p }" } # Imports a single revision into the Git repository. import_revision() { file=$1 rev=$2 date=$3 time=$4 echo "=== $file $rev $date $time" # RCS checkout and log message co -r$rev -f $file &>/dev/null msg=$(rlog -r$rev $file | sed -n '/^date:/,$p' | tail -n +2 | head -n -1) echo -e "$msg\n" # Git commit GIT_AUTHOR_DATE="$date $time" GIT_COMMITTER_DATE="$date $time" export GIT_AUTHOR_DATE GIT_COMMITTER_DATE git add $file echo "$msg" | git commit -q -a -F - || true } # If no files are specified, search for all files under RCS control. # That is, all files matching *,v and RCS/*,v. if [[ $# < 1 ]]; then FILES=$(find . RCS/ -maxdepth 1 -name \*,v \ | while read F ; do echo $(basename $F ,v ) ; done | tr -s '\n' ' ') else FILES=$* fi # Create a temporary file for storing revision metadata meta="/tmp/rcs2git-$$" # Obtain revision metadata for each file for f in $FILES; do store_metadata $f >> $meta done # Sort revision metadata by date (in place) sort -k3,4 -o $meta $meta # Process each revision while read line; do file=$(echo $line | cut -f1 -d" ") rev=$(echo $line | cut -f2 -d" ") date=$(echo $line | cut -f3 -d" ") time=$(echo $line | cut -f4 -d" ") import_revision $file $rev $date $time done < $meta # Remove the temporary file rm $meta