#!/bin/sh -e
# This script is put in the public domain by Henrik Nordström
# <hno@squid-cache.org>. It 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.
#
# If you find this script useful then you are encouraged to send feedback
# to the author, but you have absolutely no obligation to do so.
#
# Author:
#   Henrik Nordström <hno@squid-cache.org>
#   http://hem.passagen.se/hno/
#
# Distribution URL:
#   http://devel.squid-cache.org/CVS.html
#
# Version history:
#   2002-10-19  Added -nocommit option in case manual commit is preferred
#   2001-10-18  _merge-old_ tags to allow easier post-diagnostics after
#               a merge, or recovery if the merge process screws up.
#   2001-09-25	First public domain release
#
do_shell=
while [ $# -gt 1 ]; do
    case $1 in
    -shell)
    	do_shell=1
	shift
	;;
    -noc*)
	no_commit=1
	shift
	;;
    *)	break;;
    esac
done
mergefrom=
if [ $# -eq 0 ] && [ -f merge.log ]; then
    mergefrom=`head -1 merge.log | grep ^Merg | sed -e 's/.* //'`
fi
if [ $# -eq 1 ]; then
    mergefrom=$1
fi
if [ -z "$mergefrom" ]; then
   echo "Usage: $0 [-shell] [-nocommit] merge-from"
   echo "    where merge-from is the branch you want to merge changes from"
   echo "    -shell forces a shell before commit even if there was no conflicts"
   exit 1
fi
if [ ! -f CVS/Root ] || [ ! -f CVS/Repository ]; then
    echo "ERROR: The script must be run from a CVS working directory"
    exit 1
fi
if [ -f CVS/Tag ]; then
    localtag=`cat CVS/Tag|cut -c2-`
else
    localtag=HEAD
fi
rootdir=`cat CVS/Root|sed -e 's/.*://'`
module=`cat CVS/Repository|sed -e "s#^$rootdir##"`
mergetag="Z-${localtag}_merge_${mergefrom}"
newtag="Z-${localtag}_merge-new_${mergefrom}"
oldtag="Z-${localtag}_merge-old_${mergefrom}"

ecvs() {
    echo cvs $* >&2
    cvs "$@"
}
eecvs() {
    echo cvs $* >&2
    cvs "$@" 2>/dev/null
}
o () {
    echo "# $*..."
}

echo "Merging changes from ${mergefrom}" > merge.log

o Check if there is any pending changes in the repository
diffl=`eecvs -q rdiff -kk -r ${mergetag} -r ${mergefrom} ${module} | head | wc -l`
if [ $diffl -eq 0 ]; then
    o No pending changes
    echo No pending changes >> merge.log
    exit 0
fi

o Make sure the working directory is up to date
ecvs -q update -kk -d -P 2>&1 | tee -a merge.log

o Make sure there is no pending changes in the working directory
diffl=`ecvs -q diff -kk | grep -v '^\?' | wc -l`
if [ $diffl -ne 0 ]; then
    echo "ERROR: You must first commit any pending changes"
    exit 1
fi

o Set a temporary tag at the new version we are merging towards
ecvs -q rtag -F -r ${mergefrom} ${newtag} ${module}

o Merge changes into the working directory
ecvs -q update -kk -d -P -j ${mergetag} -j ${newtag} 2>&1 | tee -a merge.log

o Prune out RCS keywords
files=`find . -type f -print | xargs grep -l '\$Id:' || true`
if [ -n "$files" ]; then
    perl -i -p -e 's/\$(Id|Revision):[^\$]*\$/\$$1\$/' $files
fi

o Checking for conflicts
if grep conflict merge.log ; then
    echo "WARNING: CONFLICTS!"
    echo "Please correct the conflicts (see merge.log) and then exit from"
    echo "this shell to have the changes committed"
    $SHELL || true
elif [ $do_shell ]; then
    echo "Exit from this shell to have the changes committed"
    $SHELL || true
fi

o Commit the changes
if [ -z "$no_commit" ]; then
    ecvs -q commit -m "Merged changes from ${mergefrom}"
fi

o Move our baseline to the new version"(s)"
ecvs -q rtag -F -r ${mergetag} ${oldtag} ${module}
ecvs -q rtag -F -r ${newtag} ${mergetag} ${module}

echo "Done."