OSSP CVS Repository

ossp - ossp-pkg/svs/svs.sh
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/svs/svs.sh
#!/bin/sh
##
##  OSSP svs -- Stupid/Silly/Simple Versioning System
##  Copyright (c) 2003-2009 Ralf S. Engelschall <rse@engelschall.com>
##  Copyright (c) 2003-2009 The OSSP Project <http://www.ossp.org/>
##
##  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 <file> [...]"
    echo "Usage: svs diff [<file>|<dir> [...]]"
    echo "Usage: svs backout [<file>|<dir> [...]]"
    echo "Usage: svs status [<file>|<dir> [...]]"
    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


CVSTrac 2.0.1