#!/bin/sh ## ## OSSP svs -- Stupid/Silly/Simple Versioning System ## Copyright (c) 2003-2009 Ralf S. Engelschall ## Copyright (c) 2003-2009 The OSSP Project ## ## This file is part of OSSP svs, a stupid/silly/simple versioning ## system which can found at http://www.ossp.org/pkg/tool/svs/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## svs.sh: program (language: Bourne Shell) ## # check command line if [ $# -eq 0 ]; then echo "Usage: svs vi [...]" echo "Usage: svs diff [| [...]]" echo "Usage: svs backout [| [...]]" echo "Usage: svs status [| [...]]" exit 1 fi # helper function for portable creating a file difference do_diff () { diff -U3 "$1" "$2" 2>/dev/null if [ $? -gt 1 ]; then diff -u "$1" "$2" 2>/dev/null if [ $? -gt 1 ]; then diff -C3 "$1" "$2" 2>/dev/null if [ $? -gt 1 ]; then diff "$1" "$2" fi fi fi } # a newline character NL=' ' # dispatch into commands cmd="$1" shift case "$cmd" in v|vi|vim | e|em|ema|emac|emacs ) ## ## EDIT ONE OR MORE FILES ## # iterate over all files for file in "$@"; do # preserve original file if [ ! -f "$file.orig" ]; then cp -p "$file" "$file.orig" orig=new else orig=old fi # edit file chmod u+w "$file" if [ ".${EDITOR-vi}" = .vim -a -f "$file.rej" ]; then ${EDITOR-vi} -o2 "$file" "$file.rej" else ${EDITOR-vi} "$file" fi # check for editing results if cmp "$file.orig" "$file" >/dev/null 2>&1; then if [ ".$orig" = .new ]; then echo "svs: no changes made (keeping original)" else echo "svs: changes reversed (restoring original)" fi cp -p "$file.orig" "$file" rm -f "$file.orig" else echo "svs: changes made (preserving original)" if [ -f "$file.rej" ]; then rm -f "$file.rej" fi fi done ;; d|di|dif|diff ) ## ## GENERATE PATCHING DIFFERENCE ## # determine file list if [ $# -eq 0 ]; then set -- . fi files="" for file in "$@"; do if [ -d "$file" ]; then OIFS=$IFS; IFS=$NL for f in `find "$file" -type f -name "*.orig" -print | sort`; do files="$files \"$f\"" done IFS=$OIFS elif [ -f "$file" ]; then files="$files \"$file\"" else echo "svs:ERROR: \"$file\" neither regular file nor directory" 1>&2 exit 1 fi done # generate patch eval set -- $files for file; do file=`echo "$file" | sed -e 's;^\./;;' -e 's;/\./;/;g' -e 's;\([^/][^/]*\)/\.\.;;g' -e 's;//*;/;g'` orig=`echo "$file" | sed -e 's;\.orig$;;' -e 's;$;.orig;'` edit=`echo "$file" | sed -e 's;\.orig$;;'` if [ ! -f "$orig" ]; then echo "svs:WARNING: original file \"$orig\" not found" 1>&2 continue fi if [ ! -f "$edit" ]; then # special case: removed file echo "Index: $edit" do_diff "$orig" /dev/null | sed -e "1s/^--- $orig/--- $edit/" elif [ ! -r "$orig" ] && [ ! -s "$orig" ]; then # special case: new file echo "Index: $edit" do_diff /dev/null "$edit" else # regular case: edited file if cmp "$orig" "$edit" >/dev/null 2>&1; then : else echo "Index: $edit" do_diff "$orig" "$edit" fi fi done ;; b|ba|bac|back|backo|backou|backout ) ## ## BACKOUT EDITING CHANGES ## # determine file list if [ $# -eq 0 ]; then set -- . fi files="" for file in "$@"; do if [ -d "$file" ]; then OIFS=$IFS; IFS=$NL for f in `find "$file" -type f -name "*.orig" -print | sort`; do files="$files \"$f\"" done IFS=$OIFS elif [ -f "$file" ]; then files="$files \"$file\"" else echo "svs:ERROR: \"$file\" neither regular file nor directory" 1>&2 exit 1 fi done # backout changes eval set -- $files for file; do file=`echo "$file" | sed -e 's;^\./;;' -e 's;/\./;/;g' -e 's;\([^/][^/]*\)/\.\.;;g' -e 's;//*;/;g'` orig=`echo "$file" | sed -e 's;\.orig$;;' -e 's;$;.orig;'` edit=`echo "$file" | sed -e 's;\.orig$;;'` if [ ! -f "$orig" ]; then echo "svs:WARNING: original file \"$orig\" not found" 1>&2 continue fi echo "svs: backing out changes to \"$edit\"" if [ ! -f "$edit" ]; then # special case: removed file cp -p "$orig" "$edit" rm -f "$orig" elif [ ! -r "$orig" ] && [ ! -s "$orig" ]; then # special case: new file chmod u+w "$orig" rm -f "$orig" rm -f "$edit" else # regular case: edited file cp -p "$orig" "$edit" rm -f "$orig" fi done ;; s|st|sta|stat|statu|status ) ## ## CHANGE STATUS ## # determine file list if [ $# -eq 0 ]; then set -- . fi files="" for file in "$@"; do if [ -d "$file" ]; then OIFS=$IFS; IFS=$NL for f in `find "$file" -type f \( -name "*.orig" -or -name "*.rej" \) -print | sort`; do base=`echo "$f" | sed -e 's;\.orig$;;' -e 's;\.rej$;;'` if [ ".$f" = ".$base.orig" ] && [ -f "$base.orig" ] && [ -f "$base.rej" ]; then continue fi files="$files \"$f\"" done IFS=$OIFS elif [ -f "$file" ]; then files="$files \"$file\"" else echo "svs:ERROR: \"$file\" neither regular file nor directory" 1>&2 exit 1 fi done # show status on files eval set -- $files for file; do file=`echo "$file" | sed -e 's;^\./;;' -e 's;/\./;/;g' -e 's;\([^/][^/]*\)/\.\.;;g' -e 's;//*;/;g'` base=`echo "$file" | sed -e 's;\.orig$;;' -e 's;\.rej$;;'` prefix="?" case "$file" in *.orig ) prefix="M" ;; *.rej ) prefix="C" ;; esac echo "$prefix $base" done ;; * ) echo "svs:ERROR: invalid command \"$cmd\"" 1>&2 exit 1 ;; esac