#! /bin/sh : # # cvsrmvend - 'cvs rm' vendor removed files # # (c) Copyright 1998 by Greg A. Woods # # Freely redistibutable. # All other rights reserved. # Return all fixes/modifications to . # #ident "@(#)LOCAL:cvsrmvend.sh 1.4 98/09/14 14:07:54 (woods)" # # ### # # # ## ##### # # # # # #### ### # # # # # # # ## # # ## # # # ### # # # # # # # # # # # # # # # # # # # ###### ##### # # # # # # # # ### # # # # # # # # ## # # ## # # ### ## ## # # # # # # # # # #### ### # # WARNING: This script is effectively obsolete if you use CVS-1.10 or # newer! It is sufficient to simply run a merge, so long as you do # not use the silly magic ":yesterday". I.e. if you use the exact # vendor release tags given in the import command to do the merge, # then CVS will automatically remove and/or resurrect files that the # vendor has removed or re-added. # # This should find the VENDOR-BRANCH-TAG: # # cvs -q log -h | sed -n -e 's/^ *\([^:]*\): 1\.1\.1$/\1/p' | head -1 # # This might find the most recent VENDOR-RELEASE-TAG, if we knew # "a-vendor-file"'s name, i.e. a file that was sure to be vendor # branched, which of course would be the one in which the # VENDOR-BRANCH-TAG was found above...: # # cvs log -h a-vendor-file | sed -n 's/^ \([^:]*\): .*$/\1/p' | head -1 DEBUG=false VERBOSE=false DOCOMMIT=false SPEWREMOVED=false argv0=`basename $0` USAGE="Usage: $argv0 [-clv] VENDOR-BRANCH-TAG VENDOR-RELEASE-TAG" HELP="$USAGE -c do the commit of the removed files too. -l print the list of removed files on stdout. -v be verbose. eg: cvs import -I ! 'new foobar-1.3 release' misc/foobar FOOBAR FOOBAR-1_3 cd work.d/foobar cvs update cvsrmvend FOOBAR FOOBAR-1_3 and if you didn't use '-c' above: cvs commit -m 'removed prior to FOOBAR-1_3' " while getopts "cdhv" OPTCHAR ; do case $OPTCHAR in c) DOCOMMIT=true ;; d) DEBUG=true ;; l) SPEWREMOVED=true ;; v) VERBOSE=true ;; h) echo "$HELP" exit 0 ;; \?) echo "$USAGE" 1>&2 exit 2 ;; esac done shift `expr $OPTIND - 1` if [ $# != 2 ] ; then echo $USAGE exit 2 fi VENDBR=$1 VENDREL=$2 $DEBUG || trap "RC=$?; rm /tmp/cvsrm.*.$$; exit $RC" 0 1 2 15 $VERBOSE && echo "$argv0: creating list of locally added files..." 1>&2 cvs -nq tag $VENDBR | sed -e '/^W /d' -e 's/^D //' -e 's/^T //' | sort > /tmp/cvsrm.localfiles.$$ $VERBOSE && echo "$argv0: creating list of files removed by vendor..." 1>&2 cvs -nq tag -F -r $VENDBR $VENDREL | sed -e 's/^T //' | sort | comm -23 - /tmp/cvsrm.localfiles.$$ > /tmp/cvsrm.removedfiles.$$ if [ -s /tmp/cvsrm.removedfiles.$$ ] ; then $VERBOSE && echo "$argv0: doing 'cvs rm' for all files removed by vendor..." 1>&2 $DEBUG || xargs cvs rm -f < /tmp/cvsrm.removedfiles.$$ RC=$? if [ $RC -ne 0 ] ; then trap 0 1 2 15 $VERBOSE && echo "$argv0: file lists left in /tmp/cvsrm.*.$$" 1>&2 exit $RC fi if $DOCOMMIT ; then $VERBOSE && echo "$argv0: committing removed files..." 1>&2 $DEBUG || xargs cvs commit -m "removed prior to vendor release tagged $VENDREL" < /tmp/cvsrm.removedfiles.$$ RC=$? if [ $RC -ne 0 ] ; then trap 0 1 2 15 $VERBOSE && echo "$argv0: commit failed, file lists left in /tmp/cvsrm.*.$$" 1>&2 exit $RC fi # I'm not sure tagging the removed files like this will # be much of a help, but it shouldn't hurt either.... # $VERBOSE && echo "$argv0: tagging removed files..." 1>&2 $DEBUG || xargs cvs tag -r 1 $VENDREL < /tmp/cvsrm.removedfiles.$$ RC=$? if [ $RC -ne 0 ] ; then trap 0 1 2 15 $VERBOSE && echo "$argv0: tag failed, file lists left in /tmp/cvsrm.*.$$" 1>&2 exit $RC fi fi if $SPEWREMOVED ; then $VERBOSE && echo "$argv0: list of vendor removed files follows..." 1>&2 cat /tmp/cvsrm.removedfiles.$$ fi else $VERBOSE && echo "$argv0: no files to remove" 1>&2 fi # TODO: in order to have (vendor) resurrected files re-appear in the # working directory we need to revert those (and only those?) files to # the vendor branch and move them back out of the Attic sub-dir. # # Currently because of bugs in CVS we must do this with raw RCS # commands in the repository: # # mv `cat CVS/Repository`/Attic/${filename},v `cat CVS/Repository`/${filename},v # rcs -b1.1.1 `cat CVS/Repository`/${filename},v # cvs update ${filename} # # I suppose one might argue that "cvs import" should have done the # first two of the above for us (i.e. if the current HEAD is "dead"). # # The real trick is going to be how to find the list of resurrected # files! exit 0 # The alternate algorithm of marking the removal on the vendor branch # is far more complex and leads to far more edge conditions that are # not possible to deal with within one operation.... # # first case: normal vendor-only files (no local non-dead deltas) # # 1. check if the file has un-commited modifications: # if expr "`cvs update filename`" : '^M ' > /dev/null ; then # : modified # not_modified=false # else # : not modified # not_modified=true # fi # # 2. save a copy of the file: # cp filename filename-SAVED # 3. revert to the un-modified version branch: # cvs update -r1.1.1 -p filename > filename # 4. force a new blank delta on vendor branch: # cvs commit -f -m 'deleted by vendor' -r 1.1.1 filename # 5. mark the new delta as dead: # cvs admin -sdead:1.1.1 filename # 6. label dead rev with latest vendor release tag: # cvs admin -nREL:1.1.1 filename # 7. if there were no un-committed local modifications, remove the file: # if $not_modified; then # rm filename filename-SAVED # else # mv filename-SAVED filename # fi # # second case: there have been local changes.... # # 1. save a copy of the file: # cp filename filename-SAVED # 2. revert to the vendor branch: # cvs admin -b1.1.1 filename # 3. force a new blank delta on vendor branch: # cvs commit -f -m 'deleted by vendor' -r 1.1.1 filename # 4. mark the new delta as dead: # cvs admin -sdead:1.1.1 filename # 5. label dead rev with latest vendor release tag: # cvs admin -nREL:1.1.1 filename # 6. revert again to the local branch: # cvs update -A filename # 3. mark the local rev as removed too: # cvs rm -f filename # 7. put the saved copy back in place: # mv filename-SAVED filename # # Not yet handled by above: # # 1. when the file is resurrected by a local change it will be # committed to the vendor branch. One might consider this a bug in # CVS since it's now impossible to add the file on the local branch. # .