Home | History | Annotate | Line # | Download | only in dist
commit revision 1.1.1.1.4.2
      1 #! /bin/sh
      2 
      3 # commit version 0.9.2
      4 
      5 # Copyright (C) 1999, Free Software Foundation
      6 
      7 # This script is Free Software, and it can be copied, distributed and
      8 # modified as defined in the GNU General Public License.  A copy of
      9 # its license can be downloaded from http://www.gnu.org/copyleft/gpl.html
     10 
     11 # Originally by Gary V. Vaughan <gvaughan (at] oranda.demon.co.uk>
     12 # Heavily modified by Alexandre Oliva <oliva (at] dcc.unicamp.br>
     13 
     14 # This scripts eases checking in changes to CVS-maintained projects
     15 # with ChangeLog files.  It will check that there have been no
     16 # conflicting commits in the CVS repository and print which files it
     17 # is going to commit to stderr.  A list of files to compare and to
     18 # check in can be given in the command line.  If it is not given, all
     19 # files in the current directory (and below, unless `-l' is given) are
     20 # considered for check in.
     21 
     22 # The commit message will be extracted from the differences between
     23 # the local ChangeLog and the one in the repository (unless a message
     24 # was specified with `-m' or `-F').  An empty message is not accepted
     25 # (but a blank line is).  If the message is acceptable, it will be
     26 # presented for verification (and possible edition) using the $PAGER
     27 # environment variable (or `more', if it is not set, or `cat', if the
     28 # `-f' switch is given).  If $PAGER exits successfully, the modified
     29 # files (at that moment) are checked in, unless `-n' was specified, in
     30 # which case nothing is checked in.
     31 
     32 # usage: commit [-v] [-h] [-f] [-l] [-n] [-q] [-z N]
     33 #               [-m msg|-F msg_file] [--] [file|dir ...]
     34 
     35 # -f      --fast        don't check (unless *followed* by -n), and just
     36 #         --force       display commit message instead of running $PAGER
     37 # -l      --local       don't descend into subdirectories
     38 # -m msg  --message=msg set commit message
     39 #         --msg=msg     same as -m
     40 # -F file --file=file   read commit message from file
     41 # -n      --dry-run     don't commit anything
     42 # -q      --quiet       run cvs in quiet mode
     43 # -zN     --compress=N  set compression level (0-9, 0=none, 9=max)
     44 # -v      --version     print version information
     45 # -h,-?   --help        print short or long help message
     46 
     47 name=commit
     48 cvsopt=
     49 updateopt=
     50 commitopt=
     51 dry_run=false
     52 commit=:
     53 update=:
     54 log_file="${TMPDIR-/tmp}/commitlog.$$"
     55 
     56 rm -f "$log_file"
     57 trap 'rm -f "$log_file"; exit 1' 1 2 15
     58 
     59 # this just eases exit handling
     60 main_repeat=":"
     61 while $main_repeat; do
     62 
     63 repeat="test $# -gt 0"
     64 while $repeat; do
     65     case "$1" in
     66     -f|--force|--fast)
     67 	update=false
     68 	PAGER=cat
     69 	shift
     70 	;;
     71     -l|--local)
     72 	updateopt="$updateopt -l"
     73 	commitopt="$commitopt -l"
     74 	shift
     75 	;;
     76     -m|--message|--msg)
     77 	if test $# = 1; then
     78 	    echo "$name: missing argument for $1" >&2
     79 	    break
     80 	fi
     81 	if test -f "$log_file"; then
     82 	    echo "$name: you can have at most one of -m and -F" >&2
     83 	    break
     84 	fi
     85 	shift
     86 	echo "$1" > "$log_file"
     87 	shift
     88 	;;
     89     -F|--file)
     90 	if test -f "$log_file"; then
     91 	    echo "$name: you can have at most one of -m and -F" >&2
     92 	    break
     93 	fi
     94 	if test $# = 1; then
     95 	    echo "$name: missing argument for $1" >&2
     96 	    break
     97 	fi
     98 	shift
     99 	if cat < "$1" > "$log_file"; then :; else
    100 	    break
    101 	fi
    102 	shift
    103 	;;
    104     -n|--dry-run)
    105 	commit=false
    106 	update=true
    107 	shift
    108 	;;
    109     -q|--quiet)
    110 	cvsopt="$cvsopt -q"
    111 	shift
    112 	;;
    113     -z|--compress)
    114 	if test $# = 1; then
    115 	    echo "$name: missing argument for $1" >&2
    116 	    break
    117 	fi
    118 	case "$2" in
    119 	[0-9]) :;;
    120 	*)  echo "$name: invalid argument for $1" >&2
    121 	    break
    122 	    ;;
    123 	esac
    124 	cvsopt="$cvsopt -z$2"
    125 	shift
    126 	shift
    127 	;;
    128 
    129     -m*|-F*|-z*)
    130 	opt=`echo "$1" | sed '1s/^\(..\).*$/\1/;q'`
    131 	arg=`echo "$1" | sed '1s/^-[a-zA-Z0-9]//'`
    132 	shift
    133 	set -- "$opt" "$arg" ${1+"$@"}
    134 	;;
    135     --message=*|--msg=*|--file=*|--compress=*)
    136 	opt=`echo "$1" | sed '1s/^\(--[^=]*\)=.*/\1/;q'`
    137     	arg=`echo "$1" | sed '1s/^--[^=]*=//'`
    138 	shift
    139 	set -- "$opt" "$arg" ${1+"$@"}
    140 	;;
    141 
    142     -v|--version)
    143 	sed '/^# '$name' version /,/^# Heavily modified by/ { s/^# //; p; }; d' < $0
    144 	exit 0
    145 	;;
    146     -\?|-h)
    147 	sed '/^# usage:/,/# -h/ { s/^# //; p; }; d' < $0 &&
    148 	echo
    149 	echo "run \`$name --help | more' for full usage"
    150 	exit 0
    151 	;;
    152     --help)
    153 	sed '/^# '$name' version /,/^[^#]/ { /^[^#]/ d; s/^# //; p; }; d' < $0
    154 	exit 0
    155 	;;
    156     --)
    157 	shift
    158 	repeat=false
    159 	;;
    160     -*)
    161 	echo "$name: invalid flag $1" >&2
    162 	break
    163 	;;
    164     *)
    165 	repeat=false
    166 	;;
    167     esac
    168 done
    169 # might have used break 2 within the previous loop, but so what
    170 $repeat && break
    171 
    172 $update && \
    173 if echo "$name: checking for conflicts..." >&2
    174    (cvs $cvsopt -q -n update $updateopt ${1+"$@"} 2>/dev/null \
    175     | while read line; do
    176 	echo "$line"
    177 	echo "$line" >&3
    178       done | grep '^C') 3>&1 >/dev/null; then
    179   echo "$name: some conflicts were found, aborting..." >&2
    180   break
    181 fi
    182 
    183 if test ! -f "$log_file"; then
    184   echo "$name: checking commit message..." >&2
    185   cvs $cvsopt diff -u ChangeLog \
    186   | while read line; do
    187       case "$line" in
    188       "--- ChangeLog"*) :;;
    189       "-"*)
    190 	echo "$name: *** Warning: the following line in ChangeLog diff is suspicious:" >&2
    191 	echo "$line" | sed 's/^.//' >&2;;
    192       "+ "*)
    193 	echo "$name: *** Warning: lines should start with tabs, not spaces; ignoring line:" >&2
    194 	echo "$line" | sed 's/^.//' >&2;;
    195       "+") echo;;
    196       "+	"*) echo "$line";;
    197       esac
    198     done \
    199   | sed -e 's,\+	,,' -e '/./p' -e '/./d' -e '1d' -e '$d' > "$log_file" \
    200   || break
    201 # The sed script above removes "+TAB" from the beginning of a line, then
    202 # deletes the first and/or the last line, when they happen to be empty
    203 fi
    204 
    205 if grep '[^ 	]' < "$log_file" > /dev/null; then :; else
    206   echo "$name: empty commit message, aborting" >&2
    207   break
    208 fi
    209 
    210 if grep '^$' < "$log_file" > /dev/null; then
    211   echo "$name: *** Warning: blank lines should not appear within a commit messages." >&2
    212   echo "$name: *** They should be used to separate distinct commits." >&2
    213 fi
    214 
    215 ${PAGER-more} "$log_file" || break
    216 
    217 sleep 1 # give the user some time for a ^C
    218 
    219 # Do not check for empty $log_file again, even though the user might have
    220 # zeroed it out.  If s/he did, it was probably intentional.
    221 
    222 if $commit; then
    223   cvs $cvsopt commit $commitopt -F $log_file ${1+"$@"} || break
    224 fi
    225 
    226 main_repeat=false
    227 done
    228 
    229 rm -f "$log_file"
    230 
    231 # if main_repeat was not set to `false', we failed
    232 $main_repeat && exit 1
    233 exit 0
    234