#!/bin/sh # crossmatch # Keep two CVS trees (stored in different repositories) in sync with # each other. Changes can be made in either or both repositories, # and this script aims to cross-copy those changes across to the other # tree. ghc=/usr/malcolm/local/haskell/compilers/ghc/cvs-rw/libraries/core nhc=/usr/malcolm/local/haskell/compilers/nhccvs/src/libraries safecopy=/usr/malcolm/local/haskell/libraries/safety # Deal with commandline arguments case $# in 1) if [ "$1" = "-c" ] then echo "`basename $0`: -c option requires argument nhc or ghc" else echo "Usage: `basename $0` [ -c (nhc|ghc) ]" fi exit 1 ;; 2) if [ "$1" = "-c" ] then commit () { true; } else echo "Usage: `basename $0` [ -c (nhc|ghc) ]" exit 1 fi case $2 in ghc) toGhc () { true; } ;; nhc) toGhc () { false; } ;; *) echo "Usage: `basename $0` [ -c (nhc|ghc) ]" exit 1 ;; esac ;; *) commit () { false; } toGhc () { false; } ;; esac listDirectories () { root=$1 for dir in $root/* do if [ -d "$dir" ] then if [ `basename $dir` != "CVS" ] then echo $dir listDirectories $dir fi fi done } listHaskellFilesInDirectory () { dir=$1 cd $nhc/$dir for file in `echo *.hs *.lhs` do if [ -f "$ghc/$dir/$file" ] then echo $dir/$file fi done } listAllFilesOfInterest () { cd $nhc for dir in `listDirectories .` do listHaskellFilesInDirectory $dir done } # main program for file in `listAllFilesOfInterest` do if [ ! -f $safecopy/$file ] then echo "U $file" if [ ! -d `dirname $safecopy/$file` ] then mkdir -p `dirname $safecopy/$file` fi cp $ghc/$file $safecopy/$file fi if diff -q $ghc/$file $safecopy/$file >/dev/null then if diff -q $nhc/$file $safecopy/$file >/dev/null then echo " $file" # neither ghc nor nhc differ from safecopy else echo "M [nhc] $file" # only nhc copy has changed commit && toGhc && cp $nhc/$file $ghc/$file commit && toGhc && cp $nhc/$file $safecopy/$file fi else if diff -q $nhc/$file $safecopy/$file >/dev/null then echo "M [ghc] $file" # only ghc copy has changed commit && { toGhc || cp $ghc/$file $nhc/$file; } commit && { toGhc || cp $ghc/$file $safecopy/$file; } else if diff -q $nhc/$file $ghc/$file >/dev/null then echo "O [g/n] $file" # both differ from safecopy in the same way commit && cp $ghc/$file $safecopy/$file else # both differ but in different ways if diff3 -m -E $nhc/$file $safecopy/$file $ghc/$file \ >/tmp/`basename $file` then echo "M g->n $file" commit && { toGhc || cp /tmp/`basename $file` $nhc/$file; } else echo "C g->n $file" # there were conflicts in the merge commit && { toGhc || cp /tmp/`basename $file` $nhc/$file; } fi if diff3 -m -E $ghc/$file $safecopy/$file $nhc/$file \ >/tmp/`basename $file` then echo "M n->g $file" commit && toGhc && cp /tmp/`basename $file` $ghc/$file else echo "C n->g $file" # there were conflicts in the merge commit && toGhc && cp /tmp/`basename $file` $ghc/$file fi fi fi fi done