diff options
Diffstat (limited to 'src/sanity.sh')
-rwxr-xr-x | src/sanity.sh | 35660 |
1 files changed, 35660 insertions, 0 deletions
diff --git a/src/sanity.sh b/src/sanity.sh new file mode 100755 index 0000000..6d068ad --- /dev/null +++ b/src/sanity.sh @@ -0,0 +1,35660 @@ +#! /bin/sh +: +# sanity.sh -- a growing testsuite for cvs. +# +# The copyright notice said: "Copyright (C) 1992, 1993 Cygnus Support" +# I'm not adding new copyright notices for new years as our recent +# practice has been to include copying terms without copyright notices. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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. See the +# GNU General Public License for more details. +# +# Original Author: K. Richard Pixley + +# usage: +usage () +{ + echo "Usage: `basename $0` --help" + echo "Usage: `basename $0` [--eklr] [-c CONFIG-FILE] [-f FROM-TEST] \\" + echo " [-h HOSTNAME] [-s CVS-FOR-CVS-SERVER] CVS-TO-TEST \\" + echo " [TESTS-TO-RUN...]" +} + +exit_usage () +{ + usage 1>&2 + exit 2 +} + +exit_help () +{ + usage + echo + echo "-H|--help display this text" + echo "-c CONFIG-FILE" + echo "--config=CONFIG_FILE" + echo " use an alternate test suite config file (defaults to" + echo " \`sanity.config.sh' in the same directory as" + echo " CVS-TO-TEST is found in)" + echo "-e|--skipfail Treat tests that would otherwise be nonfatally skipped" + echo " for reasons like missing tools as failures, exiting" + echo " with an error message. Also treat warnings as" + echo " failures." + echo "-f FROM-TEST" + echo "--from-test=FROM-TEST" + echo " run TESTS-TO-RUN, skipping all tests in the list before" + echo " FROM-TEST" + echo "-h HOSTNAME" + echo "--hostname HOSTNAME" + echo " Use :ext:HOSTNAME to run remote tests rather than" + echo " :fork:. Implies --remote and assumes that \$TESTDIR" + echo " resolves to the same directory on both the client and" + echo " the server." + echo "-k|--keep try to keep directories created by individual tests" + echo " around, exiting after the first test which supports" + echo " --keep" + echo "-l|--link-root" + echo " test CVS using a symlink to a real CVSROOT" + echo "-n|--noredirect" + echo " test a secondary/primary CVS server (writeproxy)" + echo " configuration with the Redirect response disabled" + echo " (implies --proxy)." + echo "-p|--proxy test a secondary/primary CVS server (writeproxy)" + echo " configuration (implies --remote)." + echo "-r|--remote test client/server, as opposed to local, CVS" + echo "-s CVS-FOR-CVS-SERVER" + echo "--server=CVS-FOR-CVS-SERVER" + echo " use CVS-FOR-CVS-SERVER as the path to the CVS SERVER" + echo " executable to be tested (defaults to CVS-TO-TEST and" + echo " implies --remote)" + echo + echo "CVS-TO-TEST the path to the CVS executable to be tested; used as" + echo " the path to the CVS client when CVS-FOR-CVS-SERVER is" + echo " specified" + echo "TESTS-TO-RUN the names of the tests to run (defaults to all tests)" + exit 2 +} + +checklongoptarg() +{ + if test "x$1" != xoptional && test -z "$OPTARG"; then + echo "option \`--$LONGOPT' requires an argument" >&2 + exit_usage + fi +} + +# See TODO list at end of file. + +# required to make this script work properly. +unset CVSREAD + +# We want to invoke a predictable set of i18n behaviors, not whatever +# the user running this script might have set. +# In particular: +# 'sort' and tabs and spaces (LC_COLLATE). +# Messages from getopt (LC_MESSAGES) (in the future, CVS itself might +# also alter its messages based on LC_MESSAGES). +LANG=C +export LANG +LC_ALL=C +export LC_ALL + +# And a few tests want a predictable umask. +umask 0002 + +# +# Initialize the test counts. +# +passed=0 +skipped=0 +warnings=0 + + + +# +# read our options +# +unset configfile +unset fromtest +unset remotehost +unset rootoptions +keep=false +linkroot=false +noredirect=false +proxy=false +remote=false +servercvs=false +skipfail=false +while getopts Hc:ef:h:klnprs:-: option ; do + # convert the long opts to short opts + if test x$option = x-; then + # remove any argument + if echo "$OPTARG" |grep = >/dev/null; then + LONGOPT=`echo "$OPTARG" |sed 's/=.*$//'` + OPTARG=`echo "$OPTARG" |sed -e 's/^.*=//'` + else + LONGOPT=$OPTARG + OPTARG= + fi + # Convert LONGOPT to lower case + LONGOPT=`echo "$LONGOPT" |sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + case "$LONGOPT" in + c|co|con|conf|confi|config) + option=c + checklongoptarg + ;; + f|fr|fro|from|from-|from-t|from-te|from-tes|from-test) + option=f + checklongoptarg + ;; + h) + echo "\`--h' is ambiguous. Could mean \`--help' or \`--hostname'" >&2 + exit_usage + ;; + he|hel|help) + option=H + OPTARG= + ;; + ho|hos|host|hostn|hostna|hostnam|hostname) + option=h + checklongoptarg + ;; + k|ke|kee|keep) + option=k + OPTARG= + ;; + l|li|lin|link|link-|link-r]|link-ro|link-roo|link-root) + option=l + OPTARG= + ;; + n|no|nor|nore|nored|noredi|noredir|noredire|noredirec|noredirect) + option=n + OPTARG= + ;; + p|pr|pro|prox|proxy) + option=p + OPTARG= + ;; + r|re|rem|remo|remot|remote) + option=r + OPTARG= + ;; + s) + echo "\`--s' is ambiguous. Could mean \`--server' or \`--skipfail'" >&2 + exit_usage + ;; + se|ser|serv|serve|server) + option=s + checklongoptarg + ;; + sk|ski|skip|skipf|skipfa|skipfai|skipfail) + option=e + OPTARG= + ;; + *) + option=\? + OPTARG= + esac + fi + case "$option" in + c) + configfile="$OPTARG" + ;; + e) + skipfail=: + ;; + f) + fromtest="$OPTARG" + ;; + h) + # Set a remotehost to run the remote tests on via :ext: + # Implies `-r' and assumes that $TESTDIR resolves to the same + # directory on the client and the server. + remotehost="$OPTARG" + remote=: + ;; + H) + exit_help + ;; + k) + # The -k (keep) option will eventually cause all the tests to + # leave around the contents of the /tmp directory; right now only + # some implement it. Not originally intended to be useful with + # more than one test, but this should work if each test uses a + # uniquely named dir (use the name of the test). + keep=: + ;; + l) + linkroot=: + ;; + n) + proxy=: + noredirect=: + remote=: + ;; + p) + proxy=: + remote=: + ;; + r) + remote=: + ;; + s) + servercvs="$OPTARG" + remote=: + ;; + \?) + exit_usage + ;; + esac +done + +# boot the arguments we used above +while test $OPTIND -gt 1 ; do + shift + OPTIND=`expr $OPTIND - 1` +done + +# Use full path for CVS executable, so that CVS_SERVER gets set properly +# for remote. +case $1 in +"") + exit_usage + ;; +/*) + testcvs=$1 + ;; +*) + testcvs=`pwd`/$1 + ;; +esac +shift + +# Verify that $testcvs looks like CVS. +# we can't use test -x since BSD 4.3 doesn't support it. +if test ! -f $testcvs || test ! -r $testcvs; then + echo "No such file or file not readable: $testcvs" >&2 + exit 1 +fi +if $testcvs --version </dev/null 2>/dev/null | + grep '^Concurrent Versions System' >/dev/null 2>&1; then :; else + echo "Not a CVS executable: $testcvs" >&2 + exit 1 +fi + +# If $remotehost is set, warn if $TESTDIR isn't since we are pretty sure +# that its default value of `/tmp/cvs-sanity' will not resolve to the same +# directory on two different machines. +if test -n "$remotehost" && test -z "$TESTDIR"; then + echo "WARNING: CVS server hostname is set and \$TESTDIR is not. If" >&2 + echo "$remotehost is not the local machine, then it is unlikely that" >&2 + echo "the default value assigned to \$TESTDIR will resolve to the same" >&2 + echo "directory on both this client and the CVS server." >&2 +fi + +# Read our config file if we can find it. +# +# The config file should always be located in the same directory as the CVS +# executable, unless we are testing an executable outside of the build +# directory. In this case, we echo a warning and attempt to assume the most +# portable configuration. +if test -z "$configfile"; then + configfile=`dirname $testcvs`/sanity.config.sh +fi +if test -r "$configfile"; then + . "$configfile" +else + echo "WARNING: Failed to locate test suite config file" >&2 + echo " \`$configfile'." >&2 +fi + + + +# Set a default value for $CVS_RSH. The sanity.config.sh file will +# have the configured value in the RSH_DFLT variable. +# +: ${CVS_RSH=${RSH_DFLT:-ssh}}; export CVS_RSH + +if test -n "$remotehost"; then + # Verify that $CVS_RSH $remotehost works. + result=`$CVS_RSH $remotehost 'echo test'` + if test $? != 0 || test "x$result" != "xtest"; then + echo "\`$CVS_RSH $remotehost' failed." >&2 + exit 1 + fi +fi + +case "$servercvs" in +"") + exit_usage + ;; +false) + ;; +/*) + ;; +*) + servercvs=`pwd`/$servercvs + ;; +esac + +if test false != $servercvs; then + # Allow command line to override $CVS_SERVER + CVS_SERVER=$servercvs +else + # default $CVS_SERVER to ${testcvs} + : ${CVS_SERVER=$testcvs} + # With the previous command, effectively defaults $servercvs to $CVS_SERVER, + # then $testcvs + servercvs=$CVS_SERVER +fi +export CVS_SERVER +servercvs_orig=$servercvs + +# Fail in client/server mode if our ${servercvs} does not contain server +# support. +if $remote; then + if test -n "$remotehost"; then + if $CVS_RSH $remotehost "test ! -f ${servercvs} || test ! -r ${servercvs}" + then + echo "No such file or file not readable: $remotehost:${testcvs}" >&2 + exit 1 + fi + if $CVS_RSH $remotehost "${servercvs} --version </dev/null 2>/dev/null | + grep '^Concurrent Versions System' >/dev/null 2>&1"; then :; else + echo "Not a CVS executable: $remotehost:${servercvs}" >&2 + exit 1 + fi + if $CVS_RSH $remotehost "${servercvs} --version </dev/null | + grep '^Concurrent.*(.*server)$' >/dev/null 2>&1"; then :; else + echo "CVS executable \`$remotehost:${servercvs}' does not contain server support." >&2 + exit 1 + fi + else + if test ! -f ${servercvs} || test ! -r ${servercvs}; then + echo "No such file or file not readable: ${testcvs}" >&2 + exit 1 + fi + if ${servercvs} --version </dev/null 2>/dev/null | + grep '^Concurrent Versions System' >/dev/null 2>&1; then :; else + echo "Not a CVS executable: ${servercvs}" >&2 + exit 1 + fi + if ${servercvs} --version </dev/null | + grep '^Concurrent.*(.*server)$' >/dev/null 2>&1; then :; else + echo "CVS executable \`${servercvs}' does not contain server support." >&2 + exit 1 + fi + fi +fi + +# Fail in client/server mode if our ${testcvs} does not contain client +# support. +if $remote; then + if ${testcvs} --version </dev/null | + grep '^Concurrent.*(client.*)$' >/dev/null 2>&1; then :; else + echo "CVS executable \`${testcvs}' does not contain client support." >&2 + exit 1 + fi +fi + +# For the "fork" tests. +if ${testcvs} --version </dev/null | + grep '^Concurrent.*(.*server)$' >/dev/null 2>&1 +then + testcvs_server_support=: +else + testcvs_server_support=false +fi + + + +dokeep() +{ + if ${keep}; then + echo "Keeping ${TESTDIR} for test case \`${what}' and exiting due to --keep" + exit 0 + fi +} + + + +### +### GUTS +### + +# "debugger" +#set -x + +echo 'This test should produce no other output than this message, and a final "OK".' +echo '(Note that the test can take an hour or more to run and periodically stops' +echo 'for as long as one minute. Do not assume there is a problem just because' +echo 'nothing seems to happen for a long time. If you cannot live without' +echo "running status, try the command: \`tail -f check.log' from another window.)" + +# Regexp to match what the CVS client will call itself in output that it prints. +# FIXME: we don't properly quote this--if the name contains . we'll +# just spuriously match a few things; if the name contains other regexp +# special characters we are probably in big trouble. +CPROG=`basename ${testcvs} |sed 's/\.exe$//'` +# And the regexp for the CVS server when we have one. In local mode, this +# defaults to $CPROG since $servercvs already did. +# FIXCVS: There are a few places in error messages where CVS suggests a command +# and outputs $SPROG as the suggested executable. This could hopefully use +# MT (tagged text - see doc/cvs-client.texi) to request that the client print +# its own name. +SPROG=`basename ${servercvs} |sed 's/\.exe$//'` + + +# Match the hostname +hostname="[-_.a-zA-Z0-9]*" + +# Regexp to match a commitid +commitid="[a-zA-Z0-9]*" + +# Regexp to match the name of a temporary file (from cvs_temp_name). +# This appears in certain diff output. +tempfile="cvs[-a-zA-Z0-9.%_]*" +# $tempname set after $TMPDIR, below. + +# Regexp to match a date in RFC822 format (as amended by RFC1123). +RFCDATE="[a-zA-Z0-9 ][a-zA-Z0-9 ]* [0-9:][0-9:]* -0000" +RFCDATE_EPOCH="1 Jan 1970 00:00:00 -0000" + +# Special times used in touch -t commands and the regular expresions +# to match them. Now that the tests set TZ=UTC0, it +# should be easier to be more exact in their regexp. +TOUCH1971="197107040343" +# This date regexp was 1971/07/0[3-5] [0-9][0-9]:43:[0-9][0-9] +ISO8601DATE1971="1971-07-04 03:43:[0-9][0-9] [+-]0000" + +TOUCH2034="203412251801" +# This date regexp was 2034/12/2[4-6] [0-9][0-9]:01:[0-9][0-9] +ISO8601DATE2034="2034-12-25 18:01:[0-9][0-9] [+-]0000" + +# Used in admin tests for exporting RCS files. +# The RAWRCSDATE..... format is for internal ,v files and +# the ISO8601DATE..... format is to allow for a regular expression in +# 'cvs log' output patterns. The tests that use this set of specific +# ${ISO8601DATE.....} variables also force TZ=UTC0 for the test. +RAWRCSDATE2000A="2000.11.24.15.58.37" +RAWRCSDATE1996A="96.11.24.15.57.41" +RAWRCSDATE1996B="96.11.24.15.56.05" +ISO8601DATE2000A="2000-11-24 15:58:37 [+-]0000" +ISO8601DATE1996A="1996-11-24 15:57:41 [+-]0000" +ISO8601DATE1996B="1996-11-24 15:56:05 [+-]0000" + +# Regexp to match the date in cvs log command output +# This format has been enhanced in the future to accept either +# old-style cvs log output dates or new-style ISO8601 timezone +# information similar to the ISODATE format. The RCSKEYDATE is +# similar, but uses '/' instead of '-' to sepearate year/month/day +# and does not include the optional timezone offset. +ISO8601DATE="[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-6][0-9]:[0-6][0-9] [-+][0-1][0-9][0-6][0-9]" + +# Regexp to match the dates found in rcs keyword strings +RCSKEYDATE="[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]" + +# Regexp to match the date in the delta section of rcs format files. +# Dates in very old RCS files may not have included the century. +RCSDELTADATE="[0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]" + +# Regexp to match a date in standard Unix format as used by rdiff +# FIXCVS: There's no reason for rdiff to use a different date format +# than diff does +DATE="[a-zA-Z]* [a-zA-Z]* [ 1-3][0-9] [0-9:]* [0-9]*" +# ISO 8601 format "yyyy-mm-dd hh:mm -0000" +ISODATE="[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9] [+-][0-9][0-9][0-9][0-9]" +# %p format is not well defined (nil) and hex digits are common. Using +# ..* is a bad idea as the tests take a very long time to run due to +# the complexity of the expressions. If you run into any other characters +# that are used in a %p format, add them here. +PFMT="[0-9a-zA-Z()][0-9a-zA-Z()]*" + +# Which directories should Which and find_tool search for executables? +SEARCHPATH=$PATH:/usr/local/bin:/usr/contrib/bin:/usr/contrib:/usr/gnu/bin:/local/bin:/local/gnu/bin:/gnu/bin:/sw/bin:/usr/pkg/bin + +# Do not assume that `type -p cmd` is portable +# Usage: Which [-a] [-x|-f|-r] prog [$SEARCHPATH:/with/directories:/to/search] +Which() { + # Optional first argument for file type, defaults to -x. + # Second argument is the file or directory to be found. + # Third argument is the PATH to search. + # By default, print only the first file that matches, + # -a will cause all matches to be printed. + notevery=: + if [ "x$1" = "x-a" ]; then notevery=false; shift; fi + case "$1" in + -*) t=$1; shift ;; + *) t=-x ;; + esac + case "$1" in + # FIXME: Someday this may need to be fixed + # to deal better with C:\some\path\to\ssh values... + /*) test $t $1 && echo $1 ;; + *) for d in `IFS=:; echo ${2-$SEARCHPATH}` + do + test $t $d/$1 && { echo $d/$1; if $notevery; then break; fi; } + done + ;; + esac +} + + +# On cygwin32, we may not have /bin/sh. +if test -r /bin/sh; then + TESTSHELL="/bin/sh" +else + TESTSHELL=`Which -f sh` + if test ! -r "$TESTSHELL"; then + TESTSHELL="/bin/sh" + fi +fi + +# FIXME: try things (what things? checkins?) without -m. +# +# Some of these tests are written to expect -Q. But testing with +# -Q is kind of bogus, it is not the way users actually use CVS (usually). +# So new tests probably should invoke ${testcvs} directly, rather than ${CVS}. +# and then they've obviously got to do something with the output.... +# +CVS="${testcvs} -Q" + +LOGFILE=`pwd`/check.log + +# Save the previous log in case the person running the tests decides +# they want to look at it. The extension ".plog" is chosen for consistency +# with dejagnu. +test -f check.plog && mv check.plog check.plog~ +test -f check.log && mv check.log check.plog + +# Create the log file so check.log can be tailed almost immediately after +# this script is started. Otherwise it can take up to a minute or two before +# the log file gets created when $remotehost is specified on some systems, +# which makes for a lot of failed `tail -f' attempts. +touch check.log + +# Workaround any X11Forwarding by ssh. Otherwise this text: +# Warning: No xauth data; using fake authentication data for X11 forwarding. +# has been known to end up in the test results below +# causing the test to fail. +[ -n "$DISPLAY" ] && unset DISPLAY + +# The default value of /tmp/cvs-sanity for TESTDIR is dubious, +# because it loses if two people/scripts try to run the tests +# at the same time. Some possible solutions: +# 1. Use /tmp/cvs-test$$. One disadvantage is that the old +# cvs-test* directories would pile up, because they wouldn't +# necessarily get removed. +# 2. Have everyone/everything running the testsuite set +# TESTDIR to some appropriate directory. +# 3. Have the default value of TESTDIR be some variation of +# `pwd`/cvs-sanity. The biggest problem here is that we have +# been fairly careful to test that CVS prints in messages the +# actual pathnames that we pass to it, rather than a different +# pathname for the same directory, as may come out of `pwd`. +# So this would be lost if everything was `pwd`-based. I suppose +# if we wanted to get baroque we could start making symlinks +# to ensure the two are different. +if test -n "$remotehost"; then + # We need to set $tmp on the server since $TMPDIR is compared against + # messages generated by the server. + tmp=`$CVS_RSH $remotehost 'cd /tmp; /bin/pwd || pwd' 2>/dev/null` + if test $? != 0; then + echo "$CVS_RSH $remotehost failed." >&2 + exit 1 + fi +else + tmp=`(cd /tmp; /bin/pwd || pwd) 2>/dev/null` +fi + +# Now: +# 1) Set TESTDIR if it's not set already +# 2) Remove any old test remnants +# 3) Create $TESTDIR +# 4) Normalize TESTDIR with `cd && (/bin/pwd || pwd)` +# (This will match CVS output later) +: ${TESTDIR=$tmp/cvs-sanity} +# clean any old remnants (we need the chmod because some tests make +# directories read-only) +if test -d $TESTDIR; then + chmod -R a+wx $TESTDIR + rm -rf $TESTDIR +fi +# These exits are important. The first time I tried this, if the `mkdir && cd` +# failed then the build directory would get blown away. Some people probably +# wouldn't appreciate that. +mkdir $TESTDIR || exit 1 +cd $TESTDIR || exit 1 +# Ensure $TESTDIR is absolute +if echo "$TESTDIR" |grep '^[^/]'; then + # Don't resolve this unless we have to. This keeps symlinks intact. This + # is important at least when testing using -h $remotehost, because the same + # value for $TESTDIR must resolve to the same directory on the client and + # the server and we likely used Samba, and possibly symlinks, to do this. + TESTDIR=`(/bin/pwd || pwd) 2>/dev/null` +fi + +if test -z "$TESTDIR" || echo "$TESTDIR" |grep '^[^/]'; then + echo "Unable to resolve TESTDIR to an absolute directory." >&2 + exit 1 +fi +cd $TESTDIR + + + +: ${TIMING=false} +if $remote; then + # Now override our CVS_RSH in order to forward variables which affect the + # test suite through. This always needs to be done when $remotehost is + # set, needs to be done in $proxy mode for the crerepos tests, and needs to + # be done in $remote mode for the writeproxy-ssh tests. + if $TIMING; then + time="/usr/bin/time -ao'$TESTDIR/time.out'" + else + time= + fi + cat >$TESTDIR/ssh-wrapper-env <<EOF +#! $TESTSHELL +while [ \$# -gt 0 ] +do + case "\$1" in + *=*) + eval "\$1" + var=\`echo "\$1" | sed 's/^\\(.*\\)=.*\$/\\1/'\` + export \$var + ;; + *) break;; + esac + shift +done +exec \${1+"\$@"} +EOF + chmod a+x $TESTDIR/ssh-wrapper-env + cat >$TESTDIR/ssh-wrapper <<EOF +#! $TESTSHELL +hostname=\$1 +shift +exec \ +$CVS_RSH \ + \$hostname \ + $TESTDIR/ssh-wrapper-env \ + "CVS_SERVER='\$CVS_SERVER'" \ + "CVS_SERVER_SLEEP='\$CVS_SERVER_SLEEP'" \ + "CVS_PARENT_SERVER_SLEEP='\$CVS_PARENT_SERVER_SLEEP'" \ + "CVS_SERVER_LOG='\$CVS_SERVER_LOG'" \ + "CVS_SECONDARY_LOG='\$CVS_SECONDARY_LOG'" \ + "TMPDIR='\$TMPDIR'" \ + "CVS_RSH='$TESTDIR/ssh-wrapper'" \ + "CVSUMASK='\$CVSUMASK'" \ + "CVS_PID='\$CVS_PID'" \ + $time \ + \${1+"\$@"} +EOF + chmod a+x $TESTDIR/ssh-wrapper + CVS_RSH=$TESTDIR/ssh-wrapper +fi # $remotehost + + + +# Now set $TMPDIR if the user hasn't overridden it. +# +# We use a $TMPDIR under $TESTDIR by default so that two tests may be run at +# the same time without bumping heads without requiring the user to specify +# more than $TESTDIR. See the test for leftover cvs-serv* directories near the +# end of this script at the end of "The big loop". +: ${TMPDIR=$TESTDIR/tmp} +export TMPDIR +if test -d $TMPDIR; then :; else + mkdir $TMPDIR +fi + + +# Regexp to match the the full path to a temporary file (from cvs_temp_name). +# This appears in certain diff output. +tempname=$TMPDIR/$tempfile + +# Make sure various tools work the way we expect, or try to find +# versions that do. +: ${AWK=awk} +: ${EXPR=expr} +: ${ID=id} +: ${TR=tr} + +# Keep track of tools that are found, but do NOT work as we hope +# in order to avoid them in future +badtools= +set_bad_tool () +{ + badtools=$badtools:$1 +} +is_bad_tool () +{ + case ":$badtools:" in *:$1:*) return 0 ;; *) return 1 ; esac +} + +version_test () +{ + vercmd=$1 + verbad=: + if RES=`$vercmd --version </dev/null 2>&1`; then + if test "X$RES" != "X--version" && test "X$RES" != "X" ; then + echo "$RES" + verbad=false + fi + fi + if $verbad; then + echo "The command \`$vercmd' does not support the --version option." + fi + # It does not really matter that --version is not supported + return 0 +} + +# Try to find a tool that satisfies all of the tests. +# Usage: list:of:colon:separated:alternatives test1 test2 test3 test4... +# Example: find_tool awk:gawk:nawk awk_tooltest1 awk_tooltest2 +find_tool () +{ + default_TOOL=$1 + echo find_tool: ${1+"$@"} >>$LOGFILE + cmds="`IFS=:; echo $1`"; shift; tooltests="${1+$@}" + if test -z "$tooltests"; then tooltests=version_test; fi + clist=; for cmd in $cmds; do clist="$clist `Which -a $cmd`"; done + # Make sure the default tool is just the first real command name + for default_TOOL in $clist `IFS=:; echo $default_TOOL`; do break; done + TOOL="" + for trytool in $clist ; do + pass=: + for tooltest in $tooltests; do + result=`eval $tooltest $trytool` + rc=$? + echo "Running $tooltest $trytool" >>$LOGFILE + if test -n "$result"; then + echo "$result" >>$LOGFILE + fi + if test "$rc" = "0"; then + echo "PASS: $tooltest $trytool" >>$LOGFILE + elif test "$rc" = "77"; then + echo "MARGINAL: $tooltest $trytool; rc=$rc" >>$LOGFILE + TOOL=$trytool + pass=false + else + set_bad_tool $trytool + echo "FAIL: $tooltest $trytool; rc=$rc" >>$LOGFILE + pass=false + fi + done + if $pass; then + echo $trytool + return 0 + fi + done + if test -n "$TOOL"; then + echo "Notice: The default version of \`$default_TOOL' is defective." >>$LOGFILE + echo "using \`$TOOL' and hoping for the best." >>$LOGFILE + echo "Notice: The default version of \`$default_TOOL' is defective." >&2 + echo "using \`$TOOL' and hoping for the best." >&2 + echo $TOOL + else + echo $default_TOOL + fi +} + +id_tool_test () +{ + id=$1 + if $id -u >/dev/null 2>&1 && $id -un >/dev/null 2>&1; then + return 0 + else + echo "Running these tests requires an \`id' program that understands the" + echo "-u and -n flags. Make sure that such an id (GNU, or many but not" + echo "all vendor-supplied versions) is in your path." + return 1 + fi +} + +ID=`find_tool id version_test id_tool_test` +echo "Using ID=$ID" >>$LOGFILE + +# You can't run CVS as root; print a nice error message here instead +# of somewhere later, after making a mess. +for pass in false :; do + case "`$ID -u 2>/dev/null`" in + "0") + echo "Test suite does not work correctly when run as root" >&2 + exit 1 + ;; + + *) + break + ;; + esac +done + +# Cause NextStep 3.3 users to lose in a more graceful fashion. +expr_tooltest1 () +{ +expr=$1 +if $expr 'abc +def' : 'abc +def' >/dev/null; then + # good, it works + return 0 +else + echo 'Running these tests requires an "expr" program that can handle' + echo 'multi-line patterns. Make sure that such an expr (GNU, or many but' + echo 'not all vendor-supplied versions) is in your path.' + return 1 +fi +} + +# Warn SunOS, SysVr3.2, etc., users that they may be partially losing +# if we can't find a GNU expr to ease their troubles... +expr_tooltest2 () +{ +expr=$1 +if $expr 'a +b' : 'a +c' >/dev/null; then + echo 'Warning: you are using a version of expr that does not correctly' + echo 'match multi-line patterns. Some tests may spuriously pass or fail.' + echo 'You may wish to make sure GNU expr is in your path.' + return 1 +else + return 0 +fi +} + +expr_create_bar () +{ +echo 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >${TESTDIR}/foo +cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar +cat ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar >${TESTDIR}/foo +cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar +rm -f ${TESTDIR}/foo +} + +expr_tooltest3 () +{ +expr=$1 +# More SunOS lossage... +test ! -f ${TESTDIR}/bar && expr_create_bar +if $expr "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then + : good, it works +else + echo 'Warning: you are using a version of expr that does not correctly' + echo 'match large patterns. Some tests may spuriously pass or fail.' + echo 'You may wish to make sure GNU expr is in your path.' + return 1 +fi +if $expr "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then + echo 'Warning: you are using a version of expr that does not correctly' + echo 'match large patterns. Some tests may spuriously pass or fail.' + echo 'You may wish to make sure GNU expr is in your path.' + return 1 +fi +# good, it works +return 0 +} + +# That we should have to do this is total bogosity, but GNU expr +# version 1.9.4-1.12 uses the emacs definition of "$" instead of the unix +# (e.g. SunOS 4.1.3 expr) one. Rumor has it this will be fixed in the +# next release of GNU expr after 1.12 (but we still have to cater to the old +# ones for some time because they are in many linux distributions). +ENDANCHOR="$" +expr_set_ENDANCHOR () +{ +expr=$1 +ENDANCHOR="$" +if $expr 'abc +def' : 'abc$' >/dev/null; then + ENDANCHOR='\'\' + echo "Notice: An ENDANCHOR of dollar does not work." + echo "Using a workaround for GNU expr versions 1.9.4 thru 1.12" +fi +return 0 +} + +# Work around another GNU expr (version 1.10-1.12) bug/incompatibility. +# "." doesn't appear to match a newline (it does with SunOS 4.1.3 expr). +# Note that the workaround is not a complete equivalent of .* because +# the first parenthesized expression in the regexp must match something +# in order for expr to return a successful exit status. +# Rumor has it this will be fixed in the +# next release of GNU expr after 1.12 (but we still have to cater to the old +# ones for some time because they are in many linux distributions). +DOTSTAR='.*' +expr_set_DOTSTAR () +{ +expr=$1 +DOTSTAR='.*' +if $expr 'abc +def' : "a${DOTSTAR}f" >/dev/null; then + : good, it works +else + DOTSTAR='\(.\| +\)*' + echo "Notice: DOTSTAR changed from sane \`.*' value to \`$DOTSTAR\`" + echo "to workaround GNU expr version 1.10 thru 1.12 bug where \`.'" + echo "does not match a newline." +fi +return 0 +} + +# Now that we have DOTSTAR, make sure it works with big matches +expr_tooltest_DOTSTAR () +{ +expr=$1 +test ! -f ${TESTDIR}/bar && expr_create_bar +if $expr "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then + # good, it works + return 0 +else + echo 'Warning: you are using a version of expr that does not correctly' + echo 'match large patterns. Some tests may spuriously pass or fail.' + echo 'You may wish to make sure GNU expr is in your path.' + return 77 +fi +} + +EXPR=`find_tool ${EXPR}:gexpr \ + version_test expr_tooltest1 expr_tooltest2 expr_tooltest3 \ +expr_set_ENDANCHOR expr_set_DOTSTAR expr_tooltest_DOTSTAR` + +# Set the ENDANCHOR and DOTSTAR for the chosen expr version. +expr_set_ENDANCHOR ${EXPR} >/dev/null +expr_tooltest_DOTSTAR ${EXPR} >/dev/null + +echo "Using EXPR=$EXPR" >>$LOGFILE +echo "Using ENDANCHOR=$ENDANCHOR" >>$LOGFILE +echo "Using DOTSTAR=$DOTSTAR" >>$LOGFILE + +# Cleanup +rm -f ${TESTDIR}/bar + +# Work around yet another GNU expr (version 1.10) bug/incompatibility. +# "+" is a special character, yet for unix expr (e.g. SunOS 4.1.3) +# it is not. I doubt that POSIX allows us to use \+ and assume it means +# (non-special) +, so here is another workaround +# Rumor has it this will be fixed in the +# next release of GNU expr after 1.12 (but we still have to cater to the old +# ones for some time because they are in many linux distributions). +PLUS='+' +if $EXPR 'a +b' : "a ${PLUS}b" >/dev/null; then + : good, it works +else + PLUS='\+' +fi + +# Likewise, for ? +QUESTION='?' +if $EXPR 'a?b' : "a${QUESTION}b" >/dev/null; then + : good, it works +else + QUESTION='\?' +fi + +# Now test the username to make sure it contains only valid characters +username=`$ID -un` +if $EXPR "${username}" : "${username}" >/dev/null; then + : good, it works +else + echo "Test suite does not work correctly when run by a username" >&2 + echo "containing regular expression meta-characters." >&2 + exit 1 +fi + +# Only 8 characters of $username appear in some output. +if test `echo $username |wc -c` -gt 8; then + username8=`echo $username |sed 's/^\(........\).*/\1/'` +else + username8=$username +fi + +# Rarely, we need to match any username, not just the name of the user +# running this test. This variable usually shouldn't be used. $username +# contains the name of the user actually running this test. +# +# I believe this only ever actually gets compared to usernames created by this +# test. It used to be compared to the username of the user running this test, +# but this hasn't been true for a long time. Regardless, I tried to get the +# allowed character set right, based on a list in a private email from Mark +# Baushke, basically the allowed names from Linux systems (plus `.', which is +# only allowed on Gentoo Linux as of 2005-09-13). +anyusername="[_a-zA-Z0-9][-_.$a-zA-Z0-9]*" + +# now make sure that tr works on NULs +tr_tooltest1 () +{ +tr=$1 +if $EXPR `echo "123" | $tr '2' '\0'` : "123" >/dev/null 2>&1; then + echo 'Warning: you are using a version of tr which does not correctly' + echo 'handle NUL bytes. Some tests may spuriously pass or fail.' + echo 'You may wish to make sure GNU tr is in your path.' + return 77 +fi +# good, it works +return 0 +} + +TR=`find_tool ${TR}:gtr version_test tr_tooltest1` +echo "Using TR=$TR" >>$LOGFILE + +# MacOS X (10.2.8) has a /bin/ls that does not work correctly in that +# it will return true even if the wildcard argument does not match any +# files. +ls_tooltest () +{ +ls=$1 +# Force cleanup +if test -d $TESTDIR/ls-test; then + chmod -R a+wx $TESTDIR/ls-test + rm -rf $TESTDIR/ls-test +fi +if $ls $TESTDIR/ls-test >/dev/null 2>&1; then + echo "Notice: \`$ls' is defective." + echo 'This is a version of ls which does not correctly' + echo 'return false for files that do not exist. Some tests may' + echo 'spuriously pass or fail.' + echo 'You may wish to put a an ls from GNU coreutils into your path.' + return 77 +else + return 0 +fi +} +LS=`find_tool ls:gls version_test ls_tooltest` +echo "Using LS=$LS" >>$LOGFILE + +# Awk testing + +awk_tooltest1 () +{ +awk=$1 +$awk 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' </dev/null >abc +if $EXPR "`cat abc`" : \ +'one +two +three +four +five +six'; then + rm abc + return 0 +else + rm abc + echo "Notice: awk BEGIN clause or printf is not be working properly." + return 1 +fi +} + +# Format item %c check +awk_tooltest2 () +{ +awk=$1 +$awk 'BEGIN { printf "%c%c%c", 2, 3, 4 }' </dev/null \ + | ${TR} '\002\003\004' '123' >abc +if $EXPR "`cat abc`" : "123" ; then + : good, found it +else + echo "Notice: awk format %c string may not be working properly." + rm abc + return 77 +fi +rm abc +return 0 +} + +AWK=`find_tool gawk:nawk:awk version_test awk_tooltest1 awk_tooltest2` +echo "Using AWK=$AWK" >>$LOGFILE + + +### +### Functions used by tests. +### + +# Execute a command on the repository, syncing when done if necessary. +# +# Syntax is as `eval'. +modify_repo () +{ + eval "$*" + if $proxy; then + # And now resync the secondary. + $TESTDIR/sync-secondary "repo modification" modify_repo ALL "$@" + fi +} + +# Restore changes to CVSROOT admin files. +restore_adm () +{ + modify_repo rm -rf $CVSROOT_DIRNAME/CVSROOT + modify_repo cp -Rp $TESTDIR/CVSROOT.save $CVSROOT_DIRNAME/CVSROOT +} + +# Test that $RSYNC supports the options we need or try to find a +# replacement. If $RSYNC works or we replace it, and return 0. +# Otherwise, set $skipreason and return 77. +require_rsync () +{ + rsyncworks=false + # rsync is NOT a GNU tool, so do NOT use find_tool for name munging. + for rsync in ${RSYNC} `Which -a rsync`; + do + + if is_bad_tool `Which $rsync` ; then continue ; fi + # Make some data to test rsync on. + mkdir $TESTDIR/rsync-test + mkdir $TESTDIR/rsync-test/Attic && touch $TESTDIR/rsync-test/Attic/6 + mkdir $TESTDIR/rsync-test/otherdir && touch $TESTDIR/rsync-test/otherdir/7 + for file in 1 2 3 4 5; do + touch $TESTDIR/rsync-test/$file + done + + if test -f "$rsync" && test -r "$rsync" \ + && $rsync -rglop --delete $TESTDIR/rsync-test/ $TESTDIR/rsync-test-copy \ + >/dev/null 2>&1 \ + && $rsync -rglop --delete --include Attic --exclude '*/' \ + $TESTDIR/rsync-test/ $TESTDIR/rsync-test-copy2 \ + >/dev/null 2>&1 \ + && test -f $TESTDIR/rsync-test/5 \ + && mv $TESTDIR/rsync-test/5 $TESTDIR/rsync-test/Attic/5 \ + && test -f $TESTDIR/rsync-test-copy/Attic/6 \ + && $rsync -rglop --delete $TESTDIR/rsync-test/ $TESTDIR/rsync-test-copy \ + >/dev/null 2>&1 \ + && $rsync -rglop --delete --include Attic --exclude '*/' \ + $TESTDIR/rsync-test/ $TESTDIR/rsync-test-copy2 \ + >/dev/null 2>&1 \ + && test ! -f $TESTDIR/rsync-test-copy/5 \ + && test ! -f $TESTDIR/rsync-test-copy2/5 \ + && test -f $TESTDIR/rsync-test-copy2/Attic/5 \ + && test ! -f $TESTDIR/rsync-test-copy2/otherdir/7 + then + # good, it works + rsyncworks=: + RSYNC=$rsync + else + # Only use Which because of ${RSYNC} in the for loop. + set_bad_tool `Which $rsync` + fi + + rm -rf $TESTDIR/rsync-test $TESTDIR/rsync-test-copy \ + $TESTDIR/rsync-test-copy2 + + if $rsyncworks; then + return 0 + else + (echo $rsync failed to work properly;\ + echo "$rsync --version"; $rsync --version) >>$LOGFILE 2>&1 + fi + done + + unset RSYNC + skipreason="unusable or no rsync found" + return 77 +} + +# Test that $1 works as a remote shell. If so, set $host, $CVS_RSH, & +# $save_CVS_RSH to match and return 0. Otherwise, set $skipreason and return +# 77. +require_rsh () +{ + host=${remotehost-"`hostname`"} + result=`$1 $host 'echo test'` + rc=$? + if test $? != 0 || test "x$result" != "xtest"; then + skipreason="\`$1 $host' failed rc=$rc result=$result" + return 77 + fi + + save_CVS_RSH=$CVS_RSH + CVS_RSH=$1; export CVS_RSH + return 0 +} + +# Find a usable SSH. When a usable ssh is found, set $host, $CVS_RSH, and +# $save_CVS_RSH and return 0. Otherwise, set $skipreason and return 77. +require_ssh () +{ + case "$CVS_RSH" in + *ssh*|*putty*) + tryssh=`Which $CVS_RSH` + if [ ! -n "$tryssh" ]; then + skipreason="Unable to find CVS_RSH=$CVS_RSH executable" + return 77 + elif [ ! -x "$tryssh" ]; then + skipreason="Unable to execute $tryssh program" + return 77 + fi + ;; + *) + # Look in the user's PATH for "ssh" + tryssh=`Which ssh` + if test ! -r "$tryssh"; then + skipreason="Unable to find ssh program" + return 77 + fi + ;; + esac + + require_rsh "$tryssh" + return $? +} + +pass () +{ + echo "PASS: $1" >>${LOGFILE} + passed=`expr $passed + 1` +} + +# Like skip(), but don't fail when $skipfail is set. +skip_always () +{ + echo "SKIP: $1${2+ ($2)}" >>$LOGFILE + skipped=`expr $skipped + 1` +} + +skip () +{ + if $skipfail; then + # exits + fail "$1${2+ ($2)}" + fi + + skip_always ${1+"$@"} +} + +# Convenience function for skipping tests run only in remote mode. +remoteonly () +{ + skip_always $1 "only tested in remote mode" +} + +# Convenience function for skipping tests not run in proxy mode. +notproxy () +{ + skip_always $1 "not tested in proxy mode" +} + +# Convenience function for skipping tests not run in proxy mode. +notnoredirect () +{ + skip_always $1 "not tested in proxy-noredirect mode" +} + +warn () +{ + if $skipfail; then + fail "$1${2+ ($2)}" + else + echo "WARNING: $1${2+ ($2)}" >>$LOGFILE + fi + warnings=`expr $warnings + 1` +} + +fail () +{ + echo "FAIL: $1" | tee -a ${LOGFILE} + echo "*** Please see the \`TESTS' and \`check.log' files for more information." >&2 + # This way the tester can go and see what remnants were left + exit 1 +} + +verify_tmp_empty () +{ + # Test our temp directory for cvs-serv* directories and cvsXXXXXX temp + # files. We would like to not leave any behind. + if $remote && $LS $TMPDIR/cvs-serv* >/dev/null 2>&1; then + # A true value means ls found files/directories with these names. + # Give the server some time to finish, then retry. + sleep 1 + if $LS $TMPDIR/cvs-serv* >/dev/null 2>&1; then + warn "$1" "Found cvs-serv* directories in $TMPDIR." + # The above will exit if $skipfail + rm -rf $TMPDIR/cvs-serv* + fi + fi + if $LS $TMPDIR/cvs?????? >/dev/null 2>&1; then + # A true value means ls found files/directories with these names. + warn "$1" "Found cvsXXXXXX temp files in $TMPDIR." + # The above will exit if $skipfail + rm -f ls $TMPDIR/cvs?????? + fi +} + +# See dotest and dotest_fail for explanation (this is the parts +# of the implementation common to the two). +dotest_internal () +{ + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$3${ENDANCHOR}" >/dev/null; then + # Why, I hear you ask, do we write this to the logfile + # even when the test passes? The reason is that the test + # may give us the regexp which we were supposed to match, + # but sometimes it may be useful to look at the exact + # text which was output. For example, suppose one wants + # to grep for a particular warning, and make _sure_ that + # CVS never hits it (even in cases where the tests might + # match it with .*). Or suppose one wants to see the exact + # date format output in a certain case (where the test will + # surely use a somewhat non-specific pattern). + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + pass "$1" + verify_tmp_empty "$1" + # expr can't distinguish between "zero characters matched" and "no match", + # so special-case it. + elif test -z "$3" && test ! -s ${TESTDIR}/dotest.tmp; then + pass "$1" + verify_tmp_empty "$1" + elif test x"$4" != x; then + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$4${ENDANCHOR}" >/dev/null; then + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + pass "$1" + verify_tmp_empty "$1" + else + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.ex1 + echo "** or: " >>${LOGFILE} + echo "$4" >>${LOGFILE} + echo "$4" > ${TESTDIR}/dotest.ex2 + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + fi + else + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.exp + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + fi +} + +dotest_all_in_one () +{ + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ + "`cat ${TESTDIR}/dotest.exp`" >/dev/null; then + return 0 + fi + return 1 +} + +# WARNING: this won't work with REs that match newlines.... +# +dotest_line_by_line () +{ + line=1 + while [ $line -le `wc -l <${TESTDIR}/dotest.tmp` ] ; do + if $EXPR "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" : \ + "`sed -n ${line}p ${TESTDIR}/dotest.exp`" >/dev/null; then + : + elif test -z "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" && + test -z "`sed -n ${line}p ${TESTDIR}/dotest.exp`"; then + : + else + echo "Line $line:" >> ${LOGFILE} + echo "**** expected: " >>${LOGFILE} + sed -n ${line}p ${TESTDIR}/dotest.exp >>${LOGFILE} + echo "**** got: " >>${LOGFILE} + sed -n ${line}p ${TESTDIR}/dotest.tmp >>${LOGFILE} + unset line + return 1 + fi + line=`expr $line + 1` + done + unset line + return 0 +} + +# If you are having trouble telling which line of a multi-line +# expression is not being matched, replace calls to dotest_internal() +# with calls to this function: +# +dotest_internal_debug () +{ + if test -z "$3"; then + if test -s ${TESTDIR}/dotest.tmp; then + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.exp + rm -f ${TESTDIR}/dotest.ex2 + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + else + pass "$1" + verify_tmp_empty "$1" + fi + else + echo "$3" > ${TESTDIR}/dotest.exp + if dotest_line_by_line "$1" "$2"; then + pass "$1" + verify_tmp_empty "$1" + else + if test x"$4" != x; then + mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex1 + echo "$4" > ${TESTDIR}/dotest.exp + if dotest_line_by_line "$1" "$2"; then + pass "$1" + verify_tmp_empty "$1" + else + mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex2 + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "** or: " >>${LOGFILE} + echo "$4" >>${LOGFILE} + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + fi + else + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + fi + fi + fi +} + +# This function allows the test output to be filtered before being verified. +# The dotest_* functions all call this function, which runs the command +# in the env var $TEST_FILTER on its argument if $TEST_FILTER is set. If +# $TEST_FILTER is not set, this function does nothing. +# +# I found this primarily useful when running the test suite on a CVS +# executable linked with memory and function profilers which can generate +# spurious output. +run_filter () +{ + if test -n "$TEST_FILTER"; then + # Make sure there is an EOL + echo >>$1 + sed '${/^$/d}' <$1 >$1.filter1 + # Run the filter + eval "$TEST_FILTER" <$1.filter1 >$1.filter2 + diff -u $1 $1.filter2 \ + >$1.diff + mv $1.filter2 $1 + rm $1.filter1 + fi +} + +# Usage: +# dotest TESTNAME COMMAND OUTPUT [OUTPUT2] +# TESTNAME is the name used in the log to identify the test. +# COMMAND is the command to run; for the test to pass, it exits with +# exitstatus zero. +# OUTPUT is a regexp which is compared against the output (stdout and +# stderr combined) from the test. It is anchored to the start and end +# of the output, so should start or end with ".*" if that is what is desired. +# Trailing newlines are stripped from the command's actual output before +# matching against OUTPUT. +# If OUTPUT2 is specified and the output matches it, then it is also +# a pass (partial workaround for the fact that some versions of expr +# lack \|). +dotest () +{ + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp 2>&1 + status=$? + run_filter $TESTDIR/dotest.tmp + if test "$status" != 0; then + cat $TESTDIR/dotest.tmp >>$LOGFILE + echo "exit status was $status" >>${LOGFILE} + fail "$1" + fi + dotest_internal "$@" +} + +# Like dotest except only 2 args and result must exactly match stdin +dotest_lit () +{ + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp 2>&1 + status=$? + run_filter $TESTDIR/dotest.tmp + if test "$status" != 0; then + cat $TESTDIR/dotest.tmp >>$LOGFILE + echo "exit status was $status" >>$LOGFILE + fail "$1" + fi + cat >$TESTDIR/dotest.exp + if cmp $TESTDIR/dotest.exp $TESTDIR/dotest.tmp >/dev/null 2>&1; then + pass "$1" + verify_tmp_empty "$1" + else + echo "** expected: " >>$LOGFILE + cat $TESTDIR/dotest.exp >>$LOGFILE + echo "** got: " >>$LOGFILE + cat $TESTDIR/dotest.tmp >>$LOGFILE + fail "$1" + fi +} + +# Like dotest except exitstatus should be nonzero. +dotest_fail () +{ + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp 2>&1 + status=$? + run_filter $TESTDIR/dotest.tmp + if test "$status" = 0; then + cat $TESTDIR/dotest.tmp >>$LOGFILE + echo "exit status was $status" >>$LOGFILE + fail "$1" + fi + dotest_internal "$@" +} + +# Like dotest except output is sorted. +dotest_sort () +{ + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp1 2>&1 + status=$? + run_filter $TESTDIR/dotest.tmp1 + if test "$status" != 0; then + cat $TESTDIR/dotest.tmp1 >>$LOGFILE + echo "exit status was $status" >>$LOGFILE + fail "$1" + fi + $TR ' ' ' ' < $TESTDIR/dotest.tmp1 | sort > $TESTDIR/dotest.tmp + dotest_internal "$@" +} + +# Like dotest_fail except output is sorted. +dotest_fail_sort () +{ + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp1 2>&1 + status=$? + run_filter $TESTDIR/dotest.tmp1 + if test "$status" = 0; then + cat $TESTDIR/dotest.tmp1 >>$LOGFILE + echo "exit status was $status" >>$LOGFILE + fail "$1" + fi + $TR ' ' ' ' < $TESTDIR/dotest.tmp1 | sort > $TESTDIR/dotest.tmp + dotest_internal "$@" +} + +# A function for fetching the timestamp of a revison of a file +getrlogdate () { + ${testcvs} -n rlog -N ${1+"$@"} | + while read token value; do + case "$token" in + date:) + echo $value | sed "s,;.*,," + break; + ;; + esac + done +} + +# Avoid picking up any stray .cvsrc, etc., from the user running the tests +mkdir home +HOME=$TESTDIR/home; export HOME + +# Make sure this variable is not defined to anything that would +# change the format of rcs dates. Otherwise people using e.g., +# RCSINIT=-zLT get lots of spurious failures. +RCSINIT=; export RCSINIT + +# Remaining arguments are the names of tests to run. +# +# The testsuite is broken up into (hopefully manageably-sized) +# independently runnable tests, so that one can quickly get a result +# from a cvs or testsuite change, and to facilitate understanding the +# tests. + +if test x"$*" = x; then + # Basic/miscellaneous functionality + tests="version basica basicb basicc basic1 deep basic2 ls" + tests="$tests parseroot parseroot2 parseroot3 files spacefiles" + tests="${tests} commit-readonly commit-add-missing" + tests="${tests} status" + # Branching, tagging, removing, adding, multiple directories + tests="${tests} rdiff rdiff-short" + tests="${tests} rdiff2 diff diffnl death death2" + tests="${tests} rm-update-message rmadd rmadd2 rmadd3 resurrection" + tests="${tests} dirs dirs2 branches branches2 branches3" + tests="${tests} branches4 tagc tagf tag-space" + tests="${tests} rcslib multibranch import importb importc importX" + tests="$tests importX2 import-CVS import-quirks" + tests="${tests} update-p import-after-initial branch-after-import" + tests="${tests} join join2 join3 join4 join5 join6 join7" + tests="${tests} join-readonly-conflict join-admin join-admin-2" + tests="${tests} join-rm" + tests="${tests} new newb conflicts conflicts2 conflicts3" + tests="${tests} clean" + tests="${tests} keywordexpand" + # Checking out various places (modules, checkout -d, &c) + tests="${tests} modules modules2 modules3 modules4 modules5 modules6" + tests="${tests} modules7 mkmodules co-d" + tests="${tests} cvsadm emptydir abspath abspath2 toplevel toplevel2" + tests="${tests} rstar-toplevel trailingslashes checkout_repository" + # Log messages, error messages. + tests="${tests} mflag editor env errmsg1 errmsg2 adderrmsg opterrmsg" + tests="${tests} errmsg3" + tests="${tests} close-stdout" + tests="$tests debug-log-nonfatal" + # Watches, binary files, history browsing, &c. + tests="${tests} devcom devcom2 devcom3 watch4 watch5 watch6-0 watch6" + tests="${tests} edit-check" + tests="${tests} unedit-without-baserev" + tests="${tests} ignore ignore-on-branch binfiles binfiles2 binfiles3" + tests="${tests} mcopy binwrap binwrap2" + tests="${tests} binwrap3 mwrap info taginfo posttag" + tests="$tests config config2 config3 config4" + tests="${tests} serverpatch log log2 logopt ann ann-id" + # Repository Storage (RCS file format, CVS lock files, creating + # a repository without "cvs init", &c). + tests="${tests} crerepos rcs rcs2 rcs3 rcs4 rcs5" + tests="$tests lockfiles backuprecover" + tests="${tests} sshstdio" + # More history browsing, &c. + tests="${tests} history" + tests="${tests} big modes modes2 modes3 stamps" + # PreservePermissions stuff: permissions, symlinks et al. + # tests="${tests} perms symlinks symlinks2 hardlinks" + # More tag and branch tests, keywords. + tests="${tests} sticky keyword keywordlog keywordname keyword2" + tests="${tests} head tagdate multibranch2 tag8k" + # "cvs admin", reserved checkouts. + tests="${tests} admin reserved" + # Nuts and bolts of diffing/merging (diff library, &c) + tests="${tests} diffmerge1 diffmerge2" + # Release of multiple directories + tests="${tests} release" + tests="${tests} recase" + # Multiple root directories and low-level protocol tests. + tests="${tests} multiroot multiroot2 multiroot3 multiroot4" + tests="${tests} rmroot reposmv pserver server server2 client" + tests="${tests} dottedroot fork commit-d template" + tests="${tests} writeproxy writeproxy-noredirect writeproxy-ssh" + tests="${tests} writeproxy-ssh-noredirect" +else + tests="$*" +fi + +# Now check the -f argument for validity. +if test -n "$fromtest"; then + # Don't allow spaces - they are our delimiters in tests + count=0 + for sub in $fromtest; do + count=`expr $count + 1` + done + if test $count != 1; then + echo "No such test \`$fromtest'." >&2 + exit 2 + fi + # make sure it is in $tests + case " $tests " in + *" $fromtest "*) + ;; + *) + echo "No such test \`$fromtest'." >&2 + exit 2 + ;; + esac +fi + + + +# a simple function to compare directory contents +# +# Returns: 0 for same, 1 for different +# +directory_cmp () +{ + OLDPWD=`pwd` + DIR_1=$1 + DIR_2=$2 + + cd $DIR_1 + find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d1 + + # go back where we were to avoid symlink hell... + cd $OLDPWD + cd $DIR_2 + find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d2 + + if diff $TESTDIR/dc$$d1 $TESTDIR/dc$$d2 >/dev/null 2>&1 + then + : + else + return 1 + fi + cd $OLDPWD + while read a + do + if test -f $DIR_1/"$a" ; then + cmp -s $DIR_1/"$a" $DIR_2/"$a" + if test $? -ne 0 ; then + return 1 + fi + fi + done < $TESTDIR/dc$$d1 + rm -f $TESTDIR/dc$$* + return 0 +} + + + +# +# The following 4 functions are used by the diffmerge1 test case. They set up, +# respectively, the four versions of the files necessary: +# +# 1. Ancestor revisions. +# 2. "Your" changes. +# 3. "My" changes. +# 4. Expected merge result. +# + +# Create ancestor revisions for diffmerge1 +diffmerge_create_older_files() { + # This test case was supplied by Noah Friedman: + cat >testcase01 <<EOF +// Button.java + +package random.application; + +import random.util.*; + +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); + + _titleColor = Color.black; + _disabledTitleColor = Color.gray; + _titleFont = Font.defaultFont (); + } + + /* Convenience constructor for instantiating a Button with + * bounds x, y, width, and height. Equivalent to + * foo = new Button (); + * foo.init (x, y, width, height); + */ + public Button (int x, int y, int width, int height) + { + this (); + init (x, y, width, height); + } +} +EOF + + # This test case was supplied by Jacob Burckhardt: + cat >testcase02 <<EOF +a +a +a +a +a +EOF + + # This test case was supplied by Karl Tomlinson who also wrote the + # patch which lets CVS correctly handle this and several other cases: + cat >testcase03 <<EOF +x +s +a +b +s +y +EOF + + # This test case was supplied by Karl Tomlinson: + cat >testcase04 <<EOF +s +x +m +m +x +s +v +s +x +m +m +x +s +EOF + + # This test case was supplied by Karl Tomlinson: + cat >testcase05 <<EOF +s +x +m +m +x +x +x +x +x +x +x +x +x +x +s +s +s +s +s +s +s +s +s +s +v +EOF + + # This test case was supplied by Jacob Burckhardt: + cat >testcase06 <<EOF +g + + + + + + + + + + + +i +EOF + + # This test is supposed to verify that the horizon lines are the same + # for both 2-way diffs, but unfortunately, it does not fail with the + # old version of cvs. However, Karl Tomlinson still thought it would + # be good to test it anyway: + cat >testcase07 <<EOF +h +f + + + + + + + + + +g +r + + + +i + + + + + + + + + + +i +EOF + + # This test case was supplied by Jacob Burckhardt: + cat >testcase08 <<EOF +Both changes move this line to the end of the file. + +no +changes +here + +First change will delete this line. + +First change will also delete this line. + + no + changes + here + +Second change will change it here. + + no + changes + here +EOF + + # This test case was supplied by Jacob Burckhardt. Note that I do not + # think cvs has ever failed with this case, but I include it anyway, + # since I think it is a hard case. It is hard because Peter Miller's + # fmerge utility fails on it: + cat >testcase09 <<EOF +m +a +{ +} +b +{ +} +EOF + + # This test case was supplied by Martin Dorey and simplified by Jacob + # Burckhardt: + cat >testcase10 <<EOF + + petRpY ( MtatRk ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); + OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); + + Bloke_GttpfIRte_MtpeaL ( &acI ); +MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) +{ + fV ( Y < 16 ) + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + Y * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + elke + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + +} + + +/**************************************************************************** +* * +* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * +* * +****************************************************************************/ + +MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); + + petRpY ( MtatRk ); + +} + HfkQipfte ( waYdle, /* waYdle */ + waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ + (coYkt RfYt8*) nRVVep, /* nRVVep */ + 0, /* MRrepVlRoRk KfxoYfkL */ + beYgtz /* nEtek to Apfte */ + ); + + petRpY ( Zy ); +} +EOF +} + +# Create "your" revisions for diffmerge1 +diffmerge_create_your_files() { + # remove the Button() method + cat >testcase01 <<\EOF +// Button.java + +package random.application; + +import random.util.*; + +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); + + _titleColor = Color.black; + _disabledTitleColor = Color.gray; + _titleFont = Font.defaultFont (); + } +} +EOF + + cat >testcase02 <<\EOF +y +a +a +a +a +EOF + + cat >testcase03 <<\EOF +x +s +a +b +s +b +s +y +EOF + + cat >testcase04 <<\EOF +s +m +s +v +s +m +s +EOF + + cat >testcase05 <<\EOF +v +s +m +s +s +s +s +s +s +s +s +s +s +v +EOF + + # Test case 6 and test case 7 both use the same input files, but they + # order the input files differently. In one case, a certain file is + # used as the older file, but in the other test case, that same file + # is used as the file which has changes. I could have put echo + # commands here, but since the echo lines would be the same as those + # in the previous function, I decided to save space and avoid repeating + # several lines of code. Instead, I merely swap the files: + mv testcase07 tmp + mv testcase06 testcase07 + mv tmp testcase06 + + # Make the date newer so that cvs thinks that the files are changed: + touch testcase06 testcase07 + + cat >testcase08 <<\EOF +no +changes +here + +First change has now added this in. + + no + changes + here + +Second change will change it here. + + no + changes + here + +Both changes move this line to the end of the file. +EOF + + cat >testcase09 <<\EOF + +m +a +{ +} +b +{ +} +c +{ +} +EOF + + cat >testcase10 <<\EOF + + fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK; + + petRpY ( MtatRk ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + fV ( jfle_Uecopd_KRLIep < 16 ) + { + MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep ); + } + elke + { + MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); + OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); + + Bloke_GttpfIRte_MtpeaL ( &acI ); +MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + fV ( Y < 16 ) + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + Y * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + elke + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + + petRpY ( MtatRk ); + +} + + +/**************************************************************************** +* * +* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * +* * +****************************************************************************/ + +MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); + + petRpY ( MtatRk ); + +} + HfkQipfte ( waYdle, /* waYdle */ + waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ + (coYkt RfYt8*) nRVVep, /* nRVVep */ + 0, /* MRrepVlRoRk KfxoYfkL */ + beYgtz /* nEtek to Apfte */ + ); + + petRpY ( Zy ); +} + +EOF +} + +# Create "my" revisions for diffmerge1 +diffmerge_create_my_files() { + # My working copy still has the Button() method, but I + # comment out some code at the top of the class. + cat >testcase01 <<\EOF +// Button.java + +package random.application; + +import random.util.*; + +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); + + // _titleColor = Color.black; + // _disabledTitleColor = Color.gray; + // _titleFont = Font.defaultFont (); + } + + /* Convenience constructor for instantiating a Button with + * bounds x, y, width, and height. Equivalent to + * foo = new Button (); + * foo.init (x, y, width, height); + */ + public Button (int x, int y, int width, int height) + { + this (); + init (x, y, width, height); + } +} +EOF + + cat >testcase02 <<\EOF +a +a +a +a +m +EOF + + cat >testcase03 <<\EOF +x +s +c +s +b +s +y +EOF + + cat >testcase04 <<\EOF +v +s +x +m +m +x +s +v +s +x +m +m +x +s +v +EOF + + # Note that in test case 5, there are no changes in the "mine" + # section, which explains why there is no command here which writes to + # file testcase05. + + # no changes for testcase06 + + # The two branches make the same changes: + cp ../yours/testcase07 . + + cat >testcase08 <<\EOF +no +changes +here + +First change will delete this line. + +First change will also delete this line. + + no + changes + here + +Second change has now changed it here. + + no + changes + here + +Both changes move this line to the end of the file. +EOF + + cat >testcase09 <<\EOF +m +a +{ +} +b +{ +} +c +{ +} +EOF + + cat >testcase10 <<\EOF + + petRpY ( MtatRk ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); + OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); + + Bloke_GttpfIRte_MtpeaL ( &acI ); +MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) +{ + fV ( Y < 16 ) + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + Y * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + elke + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + +} + + +/**************************************************************************** +* * +* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * +* * +****************************************************************************/ + +MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); + + petRpY ( MtatRk ); + +} + HfkQipfte ( waYdle, /* waYdle */ + waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ + (coYkt RfYt8*) nRVVep, /* nRVVep */ + beYgtz /* nEtek to Apfte */ + ); + + petRpY ( Zy ); +} + +EOF +} + +# Create expected results of merge for diffmerge1 +diffmerge_create_expected_files() { + cat >testcase01 <<\EOF +// Button.java + +package random.application; + +import random.util.*; + +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); + + // _titleColor = Color.black; + // _disabledTitleColor = Color.gray; + // _titleFont = Font.defaultFont (); + } +} +EOF + + cat >testcase02 <<\EOF +y +a +a +a +m +EOF + + cat >testcase03 <<\EOF +x +s +c +s +b +s +b +s +y +EOF + + cat >testcase04 <<\EOF +v +s +m +s +v +s +m +s +v +EOF + + # Since there are no changes in the "mine" section, just take exactly + # the version in the "yours" section: + cp ../yours/testcase05 . + + cp ../yours/testcase06 . + + # Since the two branches make the same changes, the result should be + # the same as both branches. Here, I happen to pick yours to copy from, + # but I could have also picked mine, since the source of the copy is + # the same in either case. However, the mine has already been + # altered by the update command, so don't use it. Instead, use the + # yours section which has not had an update on it and so is unchanged: + cp ../yours/testcase07 . + + cat >testcase08 <<\EOF +no +changes +here + +First change has now added this in. + + no + changes + here + +Second change has now changed it here. + + no + changes + here + +Both changes move this line to the end of the file. +EOF + + cat >testcase09 <<\EOF + +m +a +{ +} +b +{ +} +c +{ +} +EOF + + cat >testcase10 <<\EOF + + fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK; + + petRpY ( MtatRk ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + fV ( jfle_Uecopd_KRLIep < 16 ) + { + MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep ); + } + elke + { + MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); + OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); + + Bloke_GttpfIRte_MtpeaL ( &acI ); +MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + fV ( Y < 16 ) + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + Y * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + elke + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + + petRpY ( MtatRk ); + +} + + +/**************************************************************************** +* * +* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * +* * +****************************************************************************/ + +MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); + + petRpY ( MtatRk ); + +} + HfkQipfte ( waYdle, /* waYdle */ + waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ + (coYkt RfYt8*) nRVVep, /* nRVVep */ + beYgtz /* nEtek to Apfte */ + ); + + petRpY ( Zy ); +} + +EOF +} + + + +# Echo a new CVSROOT based on $1, $remote, and $remotehost +newroot() { + if $remote; then + if test -n "$remotehost"; then + echo :ext$rootoptions:$remotehost$1 + else + echo :fork$rootoptions:$1 + fi + else + echo $1 + fi +} + + + +# Set up CVSROOT (the crerepos tests will test operating without CVSROOT set). +# +# Currently we test :fork: and :ext: (see crerepos test). There is a +# known difference between the two in modes-15 (see comments there). +# +# :ext: can be tested against a remote machine if: +# +# 1. $remotehost is set using the `-h' option to this script. +# 2. ${CVS_RSH=rsh} $remotehost works. +# 3. The path to $TESTDIR is the same on both machines (symlinks are okay) +# 4. The path to $testcvs is the same on both machines (symlinks are okay) +# or $CVS_SERVER is overridden in this script's environment to point to +# a working CVS exectuable on the remote machine. +# +# Testing :pserver: would be hard (inetd issues). (How about using tcpserver +# and some high port number? DRP) + +if $linkroot; then + mkdir ${TESTDIR}/realcvsroot + ln -s realcvsroot ${TESTDIR}/cvsroot +fi +CVSROOT_DIRNAME=${TESTDIR}/cvsroot +CVSROOT=`newroot $CVSROOT_DIRNAME`; export CVSROOT + + + +### +### Initialize the repository +### +dotest init-1 "$testcvs init" + +# Now hide the primary root behind a secondary if requested. +if $proxy; then + # Save the primary root. + PRIMARY_CVSROOT=$CVSROOT + PRIMARY_CVSROOT_DIRNAME=$CVSROOT_DIRNAME + # Where the secondary root will be + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/secondary_cvsroot + if $noredirect; then + rootoptions=";Redirect=no" + SECONDARY_CVSROOT=`newroot $PRIMARY_CVSROOT_DIRNAME` + else + SECONDARY_CVSROOT=`newroot $SECONDARY_CVSROOT_DIRNAME` + fi + # Now set the global CVSROOT to use the secondary. + CVSROOT=$SECONDARY_CVSROOT; export CVSROOT + + require_rsync + if test $? -eq 77; then + echo "Unable to test in proxy mode: $skipreason" >&2 + skip all "missing or broken rsync command." + exit 0 + fi + + if $noredirect; then + # Wrap the CVS server to allow --primary-root to be set by the + # secondary. + cat <<EOF >$TESTDIR/secondary-wrapper +#! $TESTSHELL +CVS_SERVER=$TESTDIR/primary-wrapper +export CVS_SERVER + +# No need to check the PID of the last client since we are testing with +# Redirect disabled. +proot_arg="--allow-root=$SECONDARY_CVSROOT_DIRNAME" +exec $CVS_SERVER \$proot_arg "\$@" +EOF + cat <<EOF >$TESTDIR/primary-wrapper +#! $TESTSHELL +if test -n "$CVS_SERVER_LOG"; then + CVS_SERVER_LOG=`dirname "$CVS_SERVER_LOG"`/cvsprimarylog + export CVS_SERVER_LOG +fi +exec $CVS_SERVER "\$@" +EOF + + CVS_SERVER_secondary=$TESTDIR/secondary-wrapper + CVS_SERVER=$CVS_SERVER_secondary + + chmod a+x $TESTDIR/secondary-wrapper \ + $TESTDIR/primary-wrapper + fi + + # Script to sync the secondary root. + cat >$TESTDIR/sync-secondary <<EOF +#! $TESTSHELL +# date >>$TESTDIR/update-log + +ps=\$1 +cmd=\$2 +dir=\$3 +shift +shift +shift + +# echo "updating from \$ps for command \\\`\$cmd' in dir \\\`\$dir'" \${1+"\$@"} \\ +# >>$TESTDIR/update-log + +# If multiple CVS executables could attempt to access the repository, we would +# Need to lock for this sync and sleep +case "\$dir" in + ALL) + # This is a hack to allow a few of the tests to play with the + # UseNewInfoFmtStrings key in CVSROOT/config. It's inefficient, but there + # aren't many tests than need it and the alternative is an awful lot of + # special casing. + $RSYNC -rglop --delete --exclude '#cvs.*' \\ + $PRIMARY_CVSROOT_DIRNAME/ \\ + $SECONDARY_CVSROOT_DIRNAME + ;; + + *) + # For the majority of the tests we will only sync the directories that + # were written to. + case "\$cmd" in + add|import) + # For \`add', we need a recursive update due to quirks in rsync syntax, + # but it shouldn't affect efficiency since any new dir should be empty. + # + # For \`import', a recursive update is necessary since subdirs may have + # been added underneath the root dir we were passed. + $RSYNC -rglop \\ + $PRIMARY_CVSROOT_DIRNAME/"\$dir" \\ + $SECONDARY_CVSROOT_DIRNAME/\`dirname -- "\$dir"\` + ;; + + tag) + # \`tag' may have changed CVSROOT/val-tags too. + $RSYNC -glop \\ + $PRIMARY_CVSROOT_DIRNAME/CVSROOT/val-tags \\ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT + # Otherwise it is identical to other write commands. + $RSYNC -rglop --delete \\ + --include Attic --include CVS \ + --exclude '#cvs.*' --exclude '*/' \\ + $PRIMARY_CVSROOT_DIRNAME/"\$dir"/ \\ + $SECONDARY_CVSROOT_DIRNAME/"\$dir" + ;; + + *) + # By default, sync just what changed. + $RSYNC -rglop --delete \\ + --include Attic --include CVS \ + --exclude '#cvs.*' --exclude '*/' \\ + $PRIMARY_CVSROOT_DIRNAME/"\$dir"/ \\ + $SECONDARY_CVSROOT_DIRNAME/"\$dir" + ;; + esac # \$cmd + + # And keep the history file up to date for all commands. + $RSYNC -glop \\ + $PRIMARY_CVSROOT_DIRNAME/CVSROOT/history \\ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT + ;; # \$dir = * +esac # \$dir + +# Avoid timestamp comparison issues with rsync. +sleep 1 +EOF + chmod a+x $TESTDIR/sync-secondary + + # And now init the secondary. + $TESTDIR/sync-secondary "- no, before - create secondary root" \ + sanity-setup ALL + + # Initialize the primary repository + mkdir proxy-init; cd proxy-init + dotest proxy-init-1 "$testcvs -Qd$PRIMARY_CVSROOT co CVSROOT" + cd CVSROOT + cat >>config <<EOF +PrimaryServer=$PRIMARY_CVSROOT +EOF + cat >>loginfo <<EOF +ALL $TESTDIR/sync-secondary loginfo %c %p %{sVv} +EOF + cat >>postadmin <<EOF +ALL $TESTDIR/sync-secondary postadmin %c %p +EOF + cat >>posttag <<EOF +ALL $TESTDIR/sync-secondary posttag %c %p %o %b %t %{sVv} +EOF + cat >>postwatch <<EOF +ALL $TESTDIR/sync-secondary postwatch %c %p +EOF + dotest proxy-init-2 \ +"$testcvs -Q ci -mconfigure-writeproxy" + + # Save these files for later reference + cp config $TESTDIR/config-clean + cp loginfo $TESTDIR/loginfo-clean + cp postadmin $TESTDIR/postadmin-clean + cp posttag $TESTDIR/posttag-clean + cp postwatch $TESTDIR/postwatch-clean + + # done in here + cd ../.. + rm -rf proxy-init +else # !$proxy + # Set this even when not testing $proxy to match messages, like $SPROG. + SECONDARY_CVSROOT_DIRNAME=$CVSROOT_DIRNAME +fi # $proxy + +# Save a copy of the initial repository so that it may be restored after the +# tests that alter it. +cp -Rp $CVSROOT_DIRNAME/CVSROOT $TESTDIR/CVSROOT.save + + +### +### The tests +### +dotest init-2 "$testcvs init" + + + +### +### The big loop +### +for what in $tests; do + if test -n "$fromtest" ; then + if test $fromtest = $what ; then + unset fromtest + else + continue + fi + fi + case $what in + + version) + # We've had cases where the version command started dumping core, + # so we might as well test it + dotest version-1 "${testcvs} --version" \ +' +Concurrent Versions System (CVS) [0-9.]*.* + +Copyright (C) [0-9]* Free Software Foundation, Inc. + +Senior active maintainers include Larry Jones, Derek R. Price, +and Mark D. Baushke. Please see the AUTHORS and README files from the CVS +distribution kit for a complete list of contributors and copyrights. + +CVS may be copied only under the terms of the GNU General Public License, +a copy of which can be found with the CVS distribution kit. + +Specify the --help option for further information about CVS' + +# Maybe someday... +# if $proxy; then +# dotest version-2r "${testcvs} version" \ +#'Client: Concurrent Versions System (CVS) [0-9p.]* (client.*) +#Server: Concurrent Versions System (CVS) [0-9p.]* (.*server) +#Secondary Server: Concurrent Versions System (CVS) [0-9p.]* (.*server)' + if $remote; then + dotest version-2r "${testcvs} version" \ +'Client: Concurrent Versions System (CVS) [0-9p.]* (client.*) +Server: Concurrent Versions System (CVS) [0-9p.]* (.*server)' + else + dotest version-2 "${testcvs} version" \ +'Concurrent Versions System (CVS) [0-9.]*.*' + fi + ;; + + + + basica) + # Similar in spirit to some of the basic1, and basic2 + # tests, but hopefully a lot faster. Also tests operating on + # files two directories down *without* operating on the parent dirs. + + # Tests basica-0a and basica-0b provide the equivalent of the: + # mkdir ${CVSROOT_DIRNAME}/first-dir + # used by many of the tests. It is "more official" in the sense + # that is does everything through CVS; the reason most of the + # tests don't use it is mostly historical. + mkdir 1; cd 1 + dotest basica-0a "$testcvs -q co -l ." + mkdir first-dir + dotest basica-0b "$testcvs add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd .. + rm -r 1 + + dotest basica-1 "$testcvs -q co first-dir" '' + cd first-dir + + # Test a few operations, to ensure they gracefully do + # nothing in an empty directory. + dotest basica-1a0 "$testcvs -q update" + dotest basica-1a1 "$testcvs -q diff -c" + dotest basica-1a2 "$testcvs -q status" + dotest basica-1a3 "$testcvs -q update ." + dotest basica-1a4 "$testcvs -q update ./" + + mkdir sdir + # Remote CVS gives the "cannot open CVS/Entries" error, which is + # clearly a bug, but not a simple one to fix. + dotest basica-1a10 "$testcvs -n add sdir" \ +"Directory $CVSROOT_DIRNAME/first-dir/sdir added to the repository" \ +"$SPROG add: cannot open CVS/Entries for reading: No such file or directory +Directory $CVSROOT_DIRNAME/first-dir/sdir added to the repository" + dotest_fail basica-1a11 \ + "test -d $CVSROOT_DIRNAME/first-dir/sdir" + dotest basica-2 "$testcvs add sdir" \ +"Directory $CVSROOT_DIRNAME/first-dir/sdir added to the repository" + cd sdir + mkdir ssdir + dotest basica-3 "$testcvs add ssdir" \ +"Directory $CVSROOT_DIRNAME/first-dir/sdir/ssdir added to the repository" + cd ssdir + echo ssfile >ssfile + + # Trying to commit it without a "cvs add" should be an error. + # The "use `cvs add' to create an entry" message is the one + # that I consider to be more correct, but local cvs prints the + # "nothing known" message and noone has gotten around to fixing it. + dotest_fail basica-notadded "${testcvs} -q ci ssfile" \ +"${CPROG} commit: use .${CPROG} add. to create an entry for \`ssfile' +${CPROG}"' \[commit aborted\]: correct above errors first!' \ +"${CPROG}"' commit: nothing known about `ssfile'\'' +'"${CPROG}"' \[commit aborted\]: correct above errors first!' + + dotest basica-4 "${testcvs} add ssfile" \ +"${SPROG}"' add: scheduling file `ssfile'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest_fail basica-4a "${testcvs} tag tag0 ssfile" \ +"${SPROG} tag: nothing known about ssfile +${SPROG} "'\[tag aborted\]: correct the above errors first!' + cd ../.. + dotest basica-5 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- sdir/ssdir/ssfile +initial revision: 1\.1" + dotest_fail basica-5a \ + "${testcvs} -q tag BASE sdir/ssdir/ssfile" \ +"${SPROG} tag: Attempt to add reserved tag name BASE +${SPROG} \[tag aborted\]: failed to set tag BASE to revision 1\.1 in ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v" + dotest basica-5b "${testcvs} -q tag NOT_RESERVED" \ +'T sdir/ssdir/ssfile' + + dotest basica-6 "${testcvs} -q update" '' + echo "ssfile line 2" >>sdir/ssdir/ssfile + dotest_fail basica-6.2 "${testcvs} -q diff -c" \ +"Index: sdir/ssdir/ssfile +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +retrieving revision 1\.1 +diff -c -r1\.1 ssfile +\*\*\* sdir/ssdir/ssfile ${RFCDATE} 1\.1 +--- sdir/ssdir/ssfile ${RFCDATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + ssfile +${PLUS} ssfile line 2" + dotest_fail basica-6.3 "${testcvs} -q diff -c -rBASE" \ +"Index: sdir/ssdir/ssfile +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +retrieving revision 1\.1 +diff -c -r1\.1 ssfile +\*\*\* sdir/ssdir/ssfile ${RFCDATE} 1\.1 +--- sdir/ssdir/ssfile ${RFCDATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + ssfile +${PLUS} ssfile line 2" + dotest_fail basica-6.4 "${testcvs} -q diff -c -rBASE -C3isacrowd" \ +"Index: sdir/ssdir/ssfile +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +retrieving revision 1\.1 +diff -c -C 3isacrowd -r1\.1 ssfile +${SPROG} diff: invalid context length argument" + dotest basica-7 "${testcvs} -q ci -m modify-it" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- sdir/ssdir/ssfile +new revision: 1\.2; previous revision: 1\.1" + dotest_fail basica-nonexist "${testcvs} -q ci nonexist" \ +"${CPROG}"' commit: nothing known about `nonexist'\'' +'"${CPROG}"' \[commit aborted\]: correct above errors first!' + dotest basica-8 "${testcvs} -q update ." '' + + # Test the -f option to ci + cd sdir/ssdir + dotest basica-8a0 "${testcvs} -q ci -m not-modified ssfile" '' + dotest basica-8a "${testcvs} -q ci -f -m force-it" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 1\.3; previous revision: 1\.2" + dotest basica-8a1 "${testcvs} -q ci -m bump-it -r 2.0" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.0; previous revision: 1\.3" + dotest basica-8a1a "${testcvs} -q ci -m bump-it -r 2.9" \ +"${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.9; previous revision: 2\.0" + # Test string-based revion number increment rollover + dotest basica-8a1b "${testcvs} -q ci -m bump-it -f -r 2" \ +"${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.10; previous revision: 2\.9" + dotest basica-8a1c "${testcvs} -q ci -m bump-it -r 2.99" \ +"${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.99; previous revision: 2\.10" + # Test string-based revion number increment rollover + dotest basica-8a1d "${testcvs} -q ci -m bump-it -f -r 2" \ +"${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.100; previous revision: 2\.99" + dotest basica-8a1e "${testcvs} -q ci -m bump-it -r 2.1099" \ +"${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.1099; previous revision: 2\.100" + # Test string-based revion number increment rollover + dotest basica-8a1f "${testcvs} -q ci -m bump-it -f -r 2" \ +"${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.1100; previous revision: 2\.1099" + # -f should not be necessary, but it should be harmless. + # Also test the "-r 3" (rather than "-r 3.0") usage. + dotest basica-8a2 "${testcvs} -q ci -m bump-it -f -r 3" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 3\.1; previous revision: 2\.1100" + + # Test using -r to create a branch + dotest_fail basica-8a3 "${testcvs} -q ci -m bogus -r 3.0.0" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- ssfile +$SPROG commit: $CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v: can't find branch point 3\.0 +$SPROG commit: could not check in ssfile" + dotest basica-8a4 "${testcvs} -q ci -m valid -r 3.1.2" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 3\.1\.2\.1; previous revision: 3\.1" + # now get rid of the sticky tag and go back to the trunk + dotest basica-8a5 "${testcvs} -q up -A ./" "[UP] ssfile" + + cd ../.. + dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" + + dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" + + # The .* here will normally be "No such file or directory", + # but if memory serves some systems (AIX?) have a different message. +: dotest_fail basica-9 \ + "${testcvs} -q -d ${TESTDIR}/nonexist update" \ +"${SPROG}: cannot access cvs root ${TESTDIR}/nonexist: .*" + dotest_fail basica-9a \ + "${testcvs} -q -d ${TESTDIR}/nonexist update" \ +"${CPROG} \[update aborted\]: ${TESTDIR}/nonexist/CVSROOT: .*" + + dotest basica-10 "${testcvs} annotate" \ +' +Annotations for sdir/ssdir/ssfile +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 .'"$username8"' *[0-9a-zA-Z-]*.: ssfile +1\.2 .'"$username8"' *[0-9a-zA-Z-]*.: ssfile line 2' + + # Test resurrecting with strange revision numbers + cd sdir/ssdir + dotest basica-r1 "${testcvs} rm -f ssfile" \ +"${SPROG} remove: scheduling .ssfile. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest basica-r2 "${testcvs} -q ci -m remove" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: delete; previous revision: 3\.1" + dotest basica-r3 "${testcvs} -q up -p -r 3.1 ./ssfile >ssfile" "" + dotest basica-r4 "${testcvs} add ssfile" \ +"${SPROG} add: Re-adding file .ssfile. after dead revision 3\.2\. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest basica-r5 "${testcvs} -q ci -m resurrect" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 3\.3; previous revision: 3\.2" + cd ../.. + + # As long as we have a file with a few revisions, test + # a few "cvs admin -o" invocations. + cd sdir/ssdir + dotest_fail basica-o1 "${testcvs} admin -o 1.2::1.2" \ +"${CPROG} admin: while processing more than one file: +${CPROG} \[admin aborted\]: attempt to specify a numeric revision" + dotest basica-o2 "${testcvs} admin -o 1.2::1.2 ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +done" + dotest basica-o2a "${testcvs} admin -o 1.1::NOT_RESERVED ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +done" + dotest_fail basica-o2b "${testcvs} admin -o 1.1::NOT_EXIST ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: Revision NOT_EXIST doesn't exist. +${SPROG} admin: RCS file for .ssfile. not modified\." + dotest basica-o3 "${testcvs} admin -o 1.2::1.3 ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +done" + dotest basica-o4 "${testcvs} admin -o 3.1:: ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +deleting revision 3\.3 +deleting revision 3\.2 +done" + dotest basica-o5 "${testcvs} admin -o ::1.1 ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +done" + dotest basica-o5a "${testcvs} -n admin -o 1.2::3.1 ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +deleting revision 2\.1100 +deleting revision 2\.1099 +deleting revision 2\.100 +deleting revision 2\.99 +deleting revision 2\.10 +deleting revision 2\.9 +deleting revision 2\.0 +deleting revision 1\.3 +done" + dotest basica-o6 "${testcvs} admin -o 1.2::3.1 ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +deleting revision 2\.1100 +deleting revision 2\.1099 +deleting revision 2\.100 +deleting revision 2\.99 +deleting revision 2\.10 +deleting revision 2\.9 +deleting revision 2\.0 +deleting revision 1\.3 +done" + dotest basica-o6a "${testcvs} admin -o 3.1.2: ssfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +deleting revision 3\.1\.2\.1 +done" + dotest basica-o7 "${testcvs} log -N ssfile" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +Working file: ssfile +head: 3\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 3\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +bump-it +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify-it +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +add-it +=============================================================================" + dotest basica-o8 "${testcvs} -q update -p -r 1.1 ./ssfile" "ssfile" + cd ../.. + + cd .. + + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r first-dir + ;; + + + + basicb) + # More basic tests, including non-branch tags and co -d. + mkdir 1; cd 1 + dotest basicb-0a "${testcvs} -q co -l ." '' + touch topfile + dotest basicb-0b "${testcvs} add topfile" \ +"${SPROG} add: scheduling file .topfile. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest basicb-0c "${testcvs} -q ci -m add-it topfile" \ +"$CVSROOT_DIRNAME/topfile,v <-- topfile +initial revision: 1\.1" + cd .. + rm -r 1 + mkdir 2; cd 2 + dotest basicb-0d "${testcvs} -q co -l ." "U topfile" + # Now test the ability to run checkout on an existing working + # directory without having it lose its mind. I don't know + # whether this is tested elsewhere in sanity.sh. A more elaborate + # test might also have modified files, make sure it works if + # the modules file was modified to add new directories to the + # module, and such. + dotest basicb-0d0 "${testcvs} -q co -l ." "" + mkdir first-dir + dotest basicb-0e "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd .. + rm -r 2 + + dotest basicb-1 "${testcvs} -q co first-dir" '' + + # The top-level CVS directory is not created by default. + # I'm leaving basicb-1a and basicb-1b untouched, mostly, in + # case we decide that the default should be reversed... + + dotest_fail basicb-1a "test -d CVS" '' + + dotest basicb-1c "cat first-dir/CVS/Repository" "first-dir" + + cd first-dir + # Note that the name Emptydir is chosen to test that CVS just + # treats it like any other directory name. It should be + # special only when it is directly in $CVSROOT/CVSROOT. + mkdir Emptydir sdir2 + dotest basicb-2 "${testcvs} add Emptydir sdir2" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/Emptydir added to the repository +Directory ${CVSROOT_DIRNAME}/first-dir/sdir2 added to the repository" + cd Emptydir + echo sfile1 starts >sfile1 + dotest basicb-2a10 "${testcvs} -n add sfile1" \ +"${SPROG} add: scheduling file .sfile1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest basicb-2a11 "${testcvs} status sfile1" \ +"${SPROG} status: use \`${SPROG} add' to create an entry for \`sfile1' +=================================================================== +File: sfile1 Status: Unknown + + Working revision: No entry for sfile1 + Repository revision: No revision control file" + dotest basicb-3 "${testcvs} add sfile1" \ +"${SPROG} add: scheduling file .sfile1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest basicb-3a1 "${testcvs} status sfile1" \ +"=================================================================== +File: sfile1 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + cd ../sdir2 + echo sfile2 starts >sfile2 + dotest basicb-4 "${testcvs} add sfile2" \ +"${SPROG} add: scheduling file .sfile2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest basicb-4a "${testcvs} -q ci CVS" \ +"${CPROG} commit: warning: directory CVS specified in argument +${CPROG} commit: but CVS uses CVS for its own purposes; skipping CVS directory" + cd .. + dotest basicb-5 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/Emptydir/sfile1,v <-- Emptydir/sfile1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/sdir2/sfile2,v <-- sdir2/sfile2 +initial revision: 1\.1" + echo sfile1 develops >Emptydir/sfile1 + dotest basicb-6 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/Emptydir/sfile1,v <-- Emptydir/sfile1 +new revision: 1\.2; previous revision: 1\.1" + dotest basicb-7 "${testcvs} -q tag release-1" 'T Emptydir/sfile1 +T sdir2/sfile2' + echo not in time for release-1 >sdir2/sfile2 + dotest basicb-8 "${testcvs} -q ci -m modify-2" \ +"$CVSROOT_DIRNAME/first-dir/sdir2/sfile2,v <-- sdir2/sfile2 +new revision: 1\.2; previous revision: 1\.1" + # See if CVS can correctly notice when an invalid numeric + # revision is specified. + # Commented out until we get around to fixing CVS +: dotest basicb-8a0 "${testcvs} diff -r 1.5 -r 1.7 sfile2" 'error msg' + cd .. + + # Test that we recurse into the correct directory when checking + # for existing files, even if co -d is in use. + touch first-dir/extra + dotest basicb-cod-1 "${testcvs} -q co -d first-dir1 first-dir" \ +'U first-dir1/Emptydir/sfile1 +U first-dir1/sdir2/sfile2' + rm -r first-dir1 + + rm -r first-dir + + # FIXME? basicb-9 used to check things out like this: + # U newdir/Emptydir/sfile1 + # U newdir/sdir2/sfile2 + # but that's difficult to do. The whole "shorten" thing + # is pretty bogus, because it will break on things + # like "cvs co foo/bar baz/quux". Unless there's some + # pretty detailed expansion and analysis of the command-line + # arguments, we shouldn't do "shorten" stuff at all. + + dotest basicb-9 \ +"${testcvs} -q co -d newdir -r release-1 first-dir/Emptydir first-dir/sdir2" \ +'U newdir/first-dir/Emptydir/sfile1 +U newdir/first-dir/sdir2/sfile2' + + # basicb-9a and basicb-9b: see note about basicb-1a + + dotest_fail basicb-9a "test -d CVS" '' + + dotest basicb-9c "cat newdir/CVS/Repository" "\." + dotest basicb-9d "cat newdir/first-dir/CVS/Repository" \ +"${CVSROOT_DIRNAME}/first-dir" \ +"first-dir" + dotest basicb-9e "cat newdir/first-dir/Emptydir/CVS/Repository" \ +"${CVSROOT_DIRNAME}/first-dir/Emptydir" \ +"first-dir/Emptydir" + dotest basicb-9f "cat newdir/first-dir/sdir2/CVS/Repository" \ +"${CVSROOT_DIRNAME}/first-dir/sdir2" \ +"first-dir/sdir2" + + dotest basicb-10 "cat newdir/first-dir/Emptydir/sfile1 newdir/first-dir/sdir2/sfile2" \ +"sfile1 develops +sfile2 starts" + + rm -r newdir + + # Hmm, this might be a case for CVSNULLREPOS, but CVS doesn't + # seem to deal with it... + if false; then + dotest basicb-11 "${testcvs} -q co -d sub1/sub2 first-dir" \ +"U sub1/sub2/Emptydir/sfile1 +U sub1/sub2/sdir2/sfile2" + cd sub1 + dotest basicb-12 "${testcvs} -q update ./." '' + touch xx + dotest basicb-13 "${testcvs} add xx" fixme + cd .. + rm -r sub1 + # to test: sub1/sub2/sub3 + fi # end of tests commented out. + + # Create a second directory. + mkdir 1 + cd 1 + dotest basicb-14 "${testcvs} -q co -l ." 'U topfile' + mkdir second-dir + dotest basicb-15 "${testcvs} add second-dir" \ +"Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" + cd second-dir + touch aa + dotest basicb-16 "${testcvs} add aa" \ +"${SPROG} add: scheduling file .aa. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest basicb-17 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/second-dir/aa,v <-- aa +initial revision: 1\.1" + cd .. + + # Try to remove all revisions in a file. + dotest_fail basicb-o1 "${testcvs} admin -o1.1 topfile" \ +"RCS file: ${CVSROOT_DIRNAME}/topfile,v +deleting revision 1\.1 +${SPROG} \[admin aborted\]: attempt to delete all revisions" + dotest basicb-o2 "${testcvs} -q update -d first-dir" \ +"U first-dir/Emptydir/sfile1 +U first-dir/sdir2/sfile2" + dotest_fail basicb-o3 \ +"${testcvs} admin -o1.1:1.2 first-dir/sdir2/sfile2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v +deleting revision 1\.2 +deleting revision 1\.1 +${SPROG} \[admin aborted\]: attempt to delete all revisions" + cd .. + rm -r 1 + + mkdir 1; cd 1 + # Note that -H is an invalid option. + # I suspect that the choice between "illegal" and "invalid" + # depends on the user's environment variables, the phase + # of the moon (weirdness with optind), and who knows what else. + # I've been seeing "illegal"... + # And I switched it to "invalid". -DRP + # POSIX 1003.2 specifies the format should be 'illegal option' + # many other folks are still using the older 'invalid option' + # lib/getopt.c will use POSIX when __posixly_correct + # otherwise the other, so accept both of them. -- mdb + dotest_fail basicb-21 "${testcvs} -q admin -H" \ +"admin: invalid option -- H +${CPROG} \[admin aborted\]: specify ${CPROG} -H admin for usage information" \ +"admin: illegal option -- H +${CPROG} \[admin aborted\]: specify ${CPROG} -H admin for usage information" + cd .. + rmdir 1 + + if $keep; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir + modify_repo rm -f $CVSROOT_DIRNAME/topfile,v + ;; + + + + basicc) + # More tests of basic/miscellaneous functionality. + mkdir 1; cd 1 + dotest_fail basicc-1 "$testcvs diff" \ +"$CPROG diff: in directory \.: +$CPROG \[diff aborted\]: there is no version here; run .$CPROG checkout. first" + dotest basicc-2 "$testcvs -q co -l ." + mkdir first-dir second-dir + dotest basicc-3 "${testcvs} add first-dir second-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" + # Old versions of CVS often didn't create this top-level CVS + # directory in the first place. I think that maybe the only + # way to get it to work currently is to let CVS create it, + # and then blow it away (don't complain if it does not + # exist). But that is perfectly valid; people who are used + # to the old behavior especially may be interested. + # FIXME: this test is intended for the TopLevelAdmin=yes case; + # should adjust/move it accordingly. + rm -rf CVS + dotest basicc-4 "echo *" "first-dir second-dir" + dotest basicc-5 "${testcvs} update" \ +"${SPROG} update: Updating first-dir +${SPROG} update: Updating second-dir" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating first-dir +${SPROG} update: Updating second-dir" + + cd first-dir + dotest basicc-6 "${testcvs} release -d" "" + dotest basicc-7 "test -d ../first-dir" "" + # The Linux 2.2 kernel lets you delete ".". That's OK either way, + # the point is that CVS must not mess with anything *outside* "." + # the way that CVS 1.10 and older tried to. + dotest basicc-8 "${testcvs} -Q release -d ." \ +"" "${CPROG} release: deletion of directory \. failed: .*" + dotest basicc-9 "test -d ../second-dir" "" + # For CVS to make a syntactic check for "." wouldn't suffice. + # On Linux 2.2 systems, the cwd may be gone, so we recreate it + # to allow basicc-11 to actually happen + if test ! -d ../first-dir; then + # Apparently `cd ..' doesn't work with Linux 2.2 & Bash 2.05b. + cd $TESTDIR/1 + mkdir ./first-dir + cd ./first-dir + fi + dotest basicc-11 "${testcvs} -Q release -d ./." \ +"" "${CPROG} release: deletion of directory \./\. failed: .*" + dotest basicc-11a "test -d ../second-dir" "" + + cd ../.. + + mkdir 2; cd 2 + dotest basicc-12 "${testcvs} -Q co ." "" + # actual entries can be in either Entries or Entries.log, do + # an update to get them consolidated into Entries + dotest basicc-12a "${testcvs} -Q up" "" + dotest basicc-12b "cat CVS/Entries" \ +"D/CVSROOT//// +D/first-dir//// +D/second-dir////" + dotest basicc-13 "echo *" "CVS CVSROOT first-dir second-dir" + dotest basicc-14 "${testcvs} -Q release first-dir second-dir" "" + # a normal release shouldn't affect the Entries file + dotest basicc-14b "cat CVS/Entries" \ +"D/CVSROOT//// +D/first-dir//// +D/second-dir////" + # FIXCVS: but release -d probably should + dotest basicc-15 "${testcvs} -Q release -d first-dir second-dir" "" + dotest basicc-16 "echo *" "CVS CVSROOT" + dotest basicc-17 "cat CVS/Entries" \ +"D/CVSROOT//// +D/first-dir//// +D/second-dir////" + # FIXCVS: if not, update should notice the missing directories + # and update Entries accordingly + dotest basicc-18 "${testcvs} -Q up" "" + dotest basicc-19 "cat CVS/Entries" \ +"D/CVSROOT//// +D/first-dir//// +D/second-dir////" + + cd .. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + basic1) + # first dive - add a files, first singly, then in a group. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir basic1; cd basic1 + # check out an empty directory + dotest basic1-1 "${testcvs} -q co first-dir" '' + + cd first-dir + echo file2 >file2 + echo file3 >file3 + echo file4 >file4 + echo file5 >file5 + + dotest basic1-14-add-add "${testcvs} add file2 file3 file4 file5" \ +"${SPROG} add: scheduling file \`file2' for addition +${SPROG} add: scheduling file \`file3' for addition +${SPROG} add: scheduling file \`file4' for addition +${SPROG} add: scheduling file \`file5' for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest basic1-15-add-add \ +"${testcvs} -q update file2 file3 file4 file5" \ +"A file2 +A file3 +A file4 +A file5" + dotest basic1-16-add-add "${testcvs} -q update" \ +"A file2 +A file3 +A file4 +A file5" + dotest basic1-17-add-add "${testcvs} -q status" \ +"=================================================================== +File: file2 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file4 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file5 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest basic1-18-add-add "${testcvs} -q log" \ +"${SPROG} log: file2 has been added, but not committed +${SPROG} log: file3 has been added, but not committed +${SPROG} log: file4 has been added, but not committed +${SPROG} log: file5 has been added, but not committed" + cd .. + dotest basic1-21-add-add "${testcvs} -q update" \ +"A first-dir/file2 +A first-dir/file3 +A first-dir/file4 +A first-dir/file5" + # FIXCVS? Shouldn't this read first-dir/file2 instead of file2? + dotest basic1-22-add-add "${testcvs} log first-dir" \ +"${SPROG} log: Logging first-dir +${SPROG} log: file2 has been added, but not committed +${SPROG} log: file3 has been added, but not committed +${SPROG} log: file4 has been added, but not committed +${SPROG} log: file5 has been added, but not committed" + dotest basic1-23-add-add "${testcvs} status first-dir" \ +"${SPROG} status: Examining first-dir +=================================================================== +File: file2 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file4 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file5 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest basic1-24-add-add "${testcvs} update first-dir" \ +"${SPROG} update: Updating first-dir +A first-dir/file2 +A first-dir/file3 +A first-dir/file4 +A first-dir/file5" + dotest basic1-27-add-add "${testcvs} co first-dir" \ +"${SPROG} checkout: Updating first-dir +A first-dir/file2 +A first-dir/file3 +A first-dir/file4 +A first-dir/file5" + cd first-dir + dotest basic1-14-add-ci \ +"$testcvs commit -m test file2 file3 file4 file5" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +initial revision: 1\.1" + dotest basic1-15-add-ci \ +"${testcvs} -q update file2 file3 file4 file5" '' + dotest basic1-16-add-ci "${testcvs} -q update" '' + dotest basic1-17-add-ci "${testcvs} -q status" \ +"=================================================================== +File: file2 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file3,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file4 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file4,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file5 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file5,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + # The "log" tests and friends probably already test the output + # from log quite adequately. + # Note: using dotest fails here. It seems to be related + # to the output being sufficiently large (Red Hat 4.1). + # dotest basic1-18-add-ci "${testcvs} log" "${DOTSTAR}" + if ${testcvs} -q log >>${LOGFILE}; then + pass basic1-18-add-ci + else + pass basic1-18-add-ci + fi + cd .. + dotest basic1-21-add-ci "${testcvs} -q update" '' + # See test basic1-18-add-ci for explanation of non-use of dotest. + if ${testcvs} -q log first-dir >>${LOGFILE}; then + pass basic1-22-add-ci + else + pass basic1-22-add-ci + fi + # At least for the moment I am going to consider 17-add-ci + # an adequate test of the output here. + # See test basic1-18-add-ci for explanation of non-use of dotest. + if ${testcvs} -q status first-dir >>${LOGFILE}; then + pass basic1-23-add-ci + else + pass basic1-23-add-ci + fi + dotest basic1-24-add-ci "${testcvs} -q update first-dir" '' + dotest basic1-27-add-ci "${testcvs} -q co first-dir" '' + + cd first-dir + rm file2 file3 file4 file5 + dotest basic1-14-rm-rm "${testcvs} rm file2 file3 file4 file5" \ +"${SPROG} remove: scheduling .file2. for removal +${SPROG} remove: scheduling .file3. for removal +${SPROG} remove: scheduling .file4. for removal +${SPROG} remove: scheduling .file5. for removal +${SPROG} remove: use .${SPROG} commit. to remove these files permanently" + # 15-rm-rm was commented out. Why? + dotest basic1-15-rm-rm \ +"${testcvs} -q update file2 file3 file4 file5" \ +"R file2 +R file3 +R file4 +R file5" + dotest basic1-16-rm-rm "${testcvs} -q update" \ +"R file2 +R file3 +R file4 +R file5" + dotest basic1-17-rm-rm "${testcvs} -q status" \ +"=================================================================== +File: no file file2 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file3 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file3,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file4 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file4,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file5 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file5,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + # Would be nice to test that real logs appear (with dead state + # and all), either here or someplace like log2 tests. + if ${testcvs} -q log >>${LOGFILE}; then + pass basic1-18-rm-rm + else + fail basic1-18-rm-rm + fi + cd .. + dotest basic1-21-rm-rm "${testcvs} -q update" \ +"R first-dir/file2 +R first-dir/file3 +R first-dir/file4 +R first-dir/file5" + if ${testcvs} -q log first-dir >>${LOGFILE}; then + pass basic1-22-rm-rm + else + fail basic1-22-rm-rm + fi + if ${testcvs} -q status first-dir >>${LOGFILE}; then + pass basic1-23-rm-rm + else + fail basic1-23-rm-rm + fi + dotest basic1-24-rm-rm "${testcvs} -q update first-dir" \ +"R first-dir/file2 +R first-dir/file3 +R first-dir/file4 +R first-dir/file5" + dotest basic1-27-rm-rm "${testcvs} -q co first-dir" \ +"R first-dir/file2 +R first-dir/file3 +R first-dir/file4 +R first-dir/file5" + cd first-dir + dotest basic1-14-rm-ci "${testcvs} -q commit -m test" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +new revision: delete; previous revision: 1\.1" + dotest basic1-15-rm-ci \ +"${testcvs} -q update file2 file3 file4 file5" '' + dotest basic1-16-rm-ci "${testcvs} -q update" '' + dotest basic1-17-rm-ci "${testcvs} -q status" '' + # Would be nice to test that real logs appear (with dead state + # and all), either here or someplace like log2 tests. + if ${testcvs} -q log >>${LOGFILE}; then + pass basic1-18-rm-ci + else + fail basic1-18-rm-ci + fi + cd .. + dotest basic1-21-rm-ci "${testcvs} -q update" '' + if ${testcvs} -q log first-dir >>${LOGFILE}; then + pass basic1-22-rm-ci + else + fail basic1-22-rm-ci + fi + if ${testcvs} -q status first-dir >>${LOGFILE}; then + pass basic1-23-rm-ci + else + fail basic1-23-rm-ci + fi + dotest basic1-24-rm-ci "${testcvs} -q update first-dir" '' + dotest basic1-27-rm-ci "${testcvs} -q co first-dir" '' + cd first-dir + # All the files are removed, so nothing gets tagged. + dotest basic1-28 "${testcvs} -q tag first-dive" '' + cd .. + cd .. + + if $keep; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + + rm -r basic1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + deep) + # Test the ability to operate on directories nested rather deeply. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest deep-1 "${testcvs} -q co first-dir" '' + cd first-dir + for i in dir1 dir2 dir3 dir4 dir5 dir6 dir7 dir8; do + mkdir $i + dotest deep-2-$i "${testcvs} add $i" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1[/dir0-9]* added to the repository" + cd $i + echo file1 >file1 + dotest deep-3-$i "${testcvs} add file1" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + done + cd ../../../../../../../../.. + dotest_lit deep-4 "$testcvs -q ci -m add-them first-dir" <<HERE +$CVSROOT_DIRNAME/first-dir/dir1/file1,v <-- first-dir/dir1/file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/file1,v <-- first-dir/dir1/dir2/file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/file1,v <-- first-dir/dir1/dir2/dir3/file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/file1,v <-- first-dir/dir1/dir2/dir3/dir4/file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/file1,v <-- first-dir/dir1/dir2/dir3/dir4/dir5/file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1,v <-- first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file1,v <-- first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v <-- first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1 +initial revision: 1.1 +HERE + + cd first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8 + rm file1 + dotest deep-4a0 "$testcvs rm file1" \ +"$SPROG remove: scheduling .file1. for removal +$SPROG remove: use .$SPROG commit. to remove this file permanently" + dotest deep-4a1 "$testcvs -q ci -m rm-it" \ +"$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v <-- file1 +new revision: delete; previous revision: 1\.1" + cd ../../.. + dotest deep-4a2 "${testcvs} -q update -P dir6/dir7" '' + # Should be using "test -e", but it's not portable enough - + # Solaris 2.5 does not have it. + dotest_fail deep-4a3 "test -d dir6/dir7/dir8" '' + + # Test that if we remove the working directory, CVS does not + # recreate it. (I realize that this behavior is what the + # users expect, but in the longer run we might want to + # re-think it. The corresponding behavior for a file is that + # CVS *will* recreate it, and we might want to make it so + # that "cvs release -d" is the way to delete the directory + # and have it stay gone -kingdon, Oct1996). + rm -r dir6 + dotest deep-4b0a "${testcvs} -q diff" + dotest deep-4b0b "${testcvs} -q ci" + dotest deep-4b1 "${testcvs} -q update" + dotest deep-4b2 "${testcvs} -q update -d -P" \ +'U dir6/file1 +U dir6/dir7/file1' + + # Test what happens if one uses -P when there are files removed + # but not committed. + cd dir6/dir7 + dotest deep-rm1 "${testcvs} rm -f file1" \ +"${SPROG} remove: scheduling .file1. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + cd .. + dotest deep-rm2 "${testcvs} -q update -d -P" 'R dir7/file1' + dotest deep-rm3 "test -d dir7" '' + dotest deep-rm4 "$testcvs -q ci -m rm-it" \ +"$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file1,v <-- dir7/file1 +new revision: delete; previous revision: 1\.1" + dotest deep-rm5 "${testcvs} -q update -d -P" '' + dotest_fail deep-rm6 "test -d dir7" '' + + # Test rm -f -R. + cd ../.. + dotest deep-rm7 "${testcvs} rm -f -R dir5" \ +"${SPROG} remove: Removing dir5 +${SPROG} remove: scheduling .dir5/file1. for removal +${SPROG} remove: Removing dir5/dir6 +${SPROG} remove: scheduling .dir5/dir6/file1. for removal +${SPROG} remove: use .${SPROG} commit. to remove these files permanently" + dotest deep-rm8 "${testcvs} -q ci -m rm-it" \ +"$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/file1,v <-- dir5/file1 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1,v <-- dir5/dir6/file1 +new revision: delete; previous revision: 1\.1" + dotest deep-rm9 "${testcvs} -q update -d -P" '' + dotest_fail deep-rm10 "test -d dir5" + + cd ../../../../.. + + if echo "yes" | $testcvs release -d first-dir >>$LOGFILE 2>&1; then + pass deep-5 + else + fail deep-5 + fi + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + basic2) + # Test rtag, import, history, various miscellaneous operations + + # NOTE: this section has reached the size and + # complexity where it is getting to be a good idea to + # add new tests to a new section rather than + # continuing to piggyback them onto the tests here. + + # First empty the history file + modify_repo rm -rf $CVSROOT_DIRNAME/CVSROOT/history + modify_repo touch $CVSROOT_DIRNAME/CVSROOT/history + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest basic2-1 "$testcvs -q co first-dir" + for i in first-dir dir1 dir2 ; do + if test ! -d $i ; then + mkdir $i + dotest basic2-2-$i "${testcvs} add $i" \ +"Directory ${CVSROOT_DIRNAME}/.*/$i added to the repository" + fi + + cd $i + + for j in file6 file7; do + echo $j > $j + done + + dotest basic2-3-$i "${testcvs} add file6 file7" \ +"${SPROG} add: scheduling file .file6. for addition +${SPROG} add: scheduling file .file7. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + + done + cd ../../.. + dotest basic2-4 "${testcvs} update first-dir" \ +"${SPROG} update: Updating first-dir +A first-dir/file6 +A first-dir/file7 +${SPROG} update: Updating first-dir/dir1 +A first-dir/dir1/file6 +A first-dir/dir1/file7 +${SPROG} update: Updating first-dir/dir1/dir2 +A first-dir/dir1/dir2/file6 +A first-dir/dir1/dir2/file7" + + # fixme: doesn't work right for added files. + dotest basic2-5 "${testcvs} log first-dir" \ +"${SPROG} log: Logging first-dir +${SPROG} log: file6 has been added, but not committed +${SPROG} log: file7 has been added, but not committed +${SPROG} log: Logging first-dir/dir1 +${SPROG} log: file6 has been added, but not committed +${SPROG} log: file7 has been added, but not committed +${SPROG} log: Logging first-dir/dir1/dir2 +${SPROG} log: file6 has been added, but not committed +${SPROG} log: file7 has been added, but not committed" + + dotest basic2-6 "${testcvs} status first-dir" \ +"${SPROG} status: Examining first-dir +=================================================================== +File: file6 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file7 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +${SPROG} status: Examining first-dir/dir1 +=================================================================== +File: file6 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file7 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +${SPROG} status: Examining first-dir/dir1/dir2 +=================================================================== +File: file6 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file7 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + +# XXX why is this commented out??? +# if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then +# pass 34 +# else +# fail 34 +# fi + + dotest basic2-8 "${testcvs} -q ci -m 'second dive' first-dir" \ +"$CVSROOT_DIRNAME/first-dir/file6,v <-- first-dir/file6 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file7,v <-- first-dir/file7 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir1/file6,v <-- first-dir/dir1/file6 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir1/file7,v <-- first-dir/dir1/file7 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/file6,v <-- first-dir/dir1/dir2/file6 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir1/dir2/file7,v <-- first-dir/dir1/dir2/file7 +initial revision: 1\.1" + + dotest basic2-9 "${testcvs} tag second-dive first-dir" \ +"${SPROG} tag: Tagging first-dir +T first-dir/file6 +T first-dir/file7 +${SPROG} tag: Tagging first-dir/dir1 +T first-dir/dir1/file6 +T first-dir/dir1/file7 +${SPROG} tag: Tagging first-dir/dir1/dir2 +T first-dir/dir1/dir2/file6 +T first-dir/dir1/dir2/file7" + + # third dive - in bunch o' directories, add bunch o' files, + # delete some, change some. + + for i in first-dir dir1 dir2 ; do + cd $i + + # modify a file + echo file6 >>file6 + + # delete a file + rm file7 + + dotest basic2-10-$i "${testcvs} rm file7" \ +"${SPROG} remove: scheduling .file7. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + + # and add a new file + echo file14 >file14 + + dotest basic2-11-$i "${testcvs} add file14" \ +"${SPROG} add: scheduling file .file14. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + done + + cd ../../.. + dotest basic2-12 "${testcvs} update first-dir" \ +"${SPROG} update: Updating first-dir +A first-dir/file14 +M first-dir/file6 +R first-dir/file7 +${SPROG} update: Updating first-dir/dir1 +A first-dir/dir1/file14 +M first-dir/dir1/file6 +R first-dir/dir1/file7 +${SPROG} update: Updating first-dir/dir1/dir2 +A first-dir/dir1/dir2/file14 +M first-dir/dir1/dir2/file6 +R first-dir/dir1/dir2/file7" + + # FIXME: doesn't work right for added files + dotest basic2-13 "${testcvs} log first-dir" \ +"${SPROG} log: Logging first-dir +${SPROG} log: file14 has been added, but not committed + +RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v +Working file: first-dir/file6 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +second dive +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v +Working file: first-dir/file7 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +second dive +============================================================================= +${SPROG} log: Logging first-dir/dir1 +${SPROG} log: file14 has been added, but not committed + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v +Working file: first-dir/dir1/file6 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +second dive +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v +Working file: first-dir/dir1/file7 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +second dive +============================================================================= +${SPROG} log: Logging first-dir/dir1/dir2 +${SPROG} log: file14 has been added, but not committed + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v +Working file: first-dir/dir1/dir2/file6 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +second dive +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v +Working file: first-dir/dir1/dir2/file7 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +second dive +=============================================================================" + + dotest basic2-14 "${testcvs} status first-dir" \ +"${SPROG} status: Examining first-dir +=================================================================== +File: file14 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file6 Status: Locally Modified + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file6,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file7 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file7,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +${SPROG} status: Examining first-dir/dir1 +=================================================================== +File: file14 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file6 Status: Locally Modified + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file7 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +${SPROG} status: Examining first-dir/dir1/dir2 +=================================================================== +File: file14 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file6 Status: Locally Modified + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file7 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)${DOTSTAR}" + +# XXX why is this commented out? +# if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then +# pass 42 +# else +# fail 42 +# fi + + dotest basic2-16 "${testcvs} ci -m 'third dive' first-dir" \ +"${CPROG} commit: Examining first-dir +${CPROG} commit: Examining first-dir/dir1 +${CPROG} commit: Examining first-dir/dir1/dir2 +${CVSROOT_DIRNAME}/first-dir/file14,v <-- first-dir/file14 +initial revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/file6,v <-- first-dir/file6 +new revision: 1\.2; previous revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/file7,v <-- first-dir/file7 +new revision: delete; previous revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/dir1/file14,v <-- first-dir/dir1/file14 +initial revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/dir1/file6,v <-- first-dir/dir1/file6 +new revision: 1\.2; previous revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/dir1/file7,v <-- first-dir/dir1/file7 +new revision: delete; previous revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file14,v <-- first-dir/dir1/dir2/file14 +initial revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v <-- first-dir/dir1/dir2/file6 +new revision: 1\.2; previous revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v <-- first-dir/dir1/dir2/file7 +new revision: delete; previous revision: 1\.1" + dotest basic2-17 "${testcvs} -q update first-dir" '' + + dotest basic2-18 "${testcvs} tag third-dive first-dir" \ +"${SPROG} tag: Tagging first-dir +T first-dir/file14 +T first-dir/file6 +${SPROG} tag: Tagging first-dir/dir1 +T first-dir/dir1/file14 +T first-dir/dir1/file6 +${SPROG} tag: Tagging first-dir/dir1/dir2 +T first-dir/dir1/dir2/file14 +T first-dir/dir1/dir2/file6" + + dotest basic2-19 "echo yes | ${testcvs} release -d first-dir" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .first-dir.: " + + # end of third dive + dotest_fail basic2-20 "test -d first-dir" "" + + # now try some rtags + + # rtag HEADS + dotest basic2-21 "${testcvs} rtag rtagged-by-head first-dir" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: Tagging first-dir/dir1 +${SPROG} rtag: Tagging first-dir/dir1/dir2" + + dotest basic2-21b "${testcvs} co -p -r rtagged-by-head first-dir/file6" \ +"=================================================================== +Checking out first-dir/file6 +RCS: $CVSROOT_DIRNAME/first-dir/file6,v +VERS: 1\.2 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +file6 +file6" + # see what happens when val-tags is removed + modify_repo mv $CVSROOT_DIRNAME/CVSROOT/val-tags \ + $CVSROOT_DIRNAME/CVSROOT/val-tags.save + # The output for this used to be something like: + # "${SPROG} checkout: cannot open CVS/Entries for reading: No such file or directory + # ${SPROG} \[checkout aborted\]: no such tag \`rtagged-by-head'" + + dotest basic2-21c \ +"${testcvs} co -p -r rtagged-by-head first-dir/file6" \ +"=================================================================== +Checking out first-dir/file6 +RCS: $CVSROOT_DIRNAME/first-dir/file6,v +VERS: 1\.2 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +file6 +file6" + modify_repo mv $CVSROOT_DIRNAME/CVSROOT/val-tags.save \ + $CVSROOT_DIRNAME/CVSROOT/val-tags + + # tag by tag + dotest basic2-22 "${testcvs} rtag -r rtagged-by-head rtagged-by-tag first-dir" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: Tagging first-dir/dir1 +${SPROG} rtag: Tagging first-dir/dir1/dir2" + + # tag by revision + dotest basic2-23 "${testcvs} rtag -r1.1 rtagged-by-revision first-dir" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: Tagging first-dir/dir1 +${SPROG} rtag: Tagging first-dir/dir1/dir2" + + # rdiff by revision + dotest basic2-24 "${testcvs} rdiff -r1.1 -rrtagged-by-head first-dir" \ +"${SPROG} rdiff: Diffing first-dir +Index: first-dir/file6 +diff -c first-dir/file6:1\.1 first-dir/file6:1\.2 +\*\*\* first-dir/file6:1\.1 ${DATE} +--- first-dir/file6 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + file6 +${PLUS} file6 +Index: first-dir/file7 +diff -c first-dir/file7:1\.1 first-dir/file7:removed +\*\*\* first-dir/file7:1.1 ${DATE} +--- first-dir/file7 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file7 +--- 0 ---- +${SPROG} rdiff: Diffing first-dir/dir1 +Index: first-dir/dir1/file6 +diff -c first-dir/dir1/file6:1\.1 first-dir/dir1/file6:1\.2 +\*\*\* first-dir/dir1/file6:1\.1 ${DATE} +--- first-dir/dir1/file6 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + file6 +${PLUS} file6 +Index: first-dir/dir1/file7 +diff -c first-dir/dir1/file7:1\.1 first-dir/dir1/file7:removed +\*\*\* first-dir/dir1/file7:1\.1 ${DATE} +--- first-dir/dir1/file7 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file7 +--- 0 ---- +${SPROG} rdiff: Diffing first-dir/dir1/dir2 +Index: first-dir/dir1/dir2/file6 +diff -c first-dir/dir1/dir2/file6:1\.1 first-dir/dir1/dir2/file6:1\.2 +\*\*\* first-dir/dir1/dir2/file6:1\.1 ${DATE} +--- first-dir/dir1/dir2/file6 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + file6 +${PLUS} file6 +Index: first-dir/dir1/dir2/file7 +diff -c first-dir/dir1/dir2/file7:1\.1 first-dir/dir1/dir2/file7:removed +\*\*\* first-dir/dir1/dir2/file7:1\.1 ${DATE} +--- first-dir/dir1/dir2/file7 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file7 +--- 0 ----" + dotest basic2-24a "${testcvs} rdiff -l -r1.1 -rrtagged-by-head first-dir" \ +"${SPROG} rdiff: Diffing first-dir +Index: first-dir/file6 +diff -c first-dir/file6:1\.1 first-dir/file6:1\.2 +\*\*\* first-dir/file6:1\.1 ${DATE} +--- first-dir/file6 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + file6 +${PLUS} file6 +Index: first-dir/file7 +diff -c first-dir/file7:1\.1 first-dir/file7:removed +\*\*\* first-dir/file7:1.1 ${DATE} +--- first-dir/file7 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file7 +--- 0 ----" + # now export by rtagged-by-head and rtagged-by-tag and compare. + dotest basic2-25 "${testcvs} export -r rtagged-by-head -d 1dir first-dir" \ +"${SPROG} export: Updating 1dir +U 1dir/file14 +U 1dir/file6 +${SPROG} export: Updating 1dir/dir1 +U 1dir/dir1/file14 +U 1dir/dir1/file6 +${SPROG} export: Updating 1dir/dir1/dir2 +U 1dir/dir1/dir2/file14 +U 1dir/dir1/dir2/file6" + dotest_fail basic2-25a "test -d 1dir/CVS" + dotest_fail basic2-25b "test -d 1dir/dir1/CVS" + dotest_fail basic2-25c "test -d 1dir/dir1/dir2/CVS" + + dotest basic2-26 "${testcvs} export -r rtagged-by-tag first-dir" \ +"${SPROG} export: Updating first-dir +U first-dir/file14 +U first-dir/file6 +${SPROG} export: Updating first-dir/dir1 +U first-dir/dir1/file14 +U first-dir/dir1/file6 +${SPROG} export: Updating first-dir/dir1/dir2 +U first-dir/dir1/dir2/file14 +U first-dir/dir1/dir2/file6" + dotest_fail basic2-26a "test -d first-dir/CVS" + dotest_fail basic2-26b "test -d first-dir/dir1/CVS" + dotest_fail basic2-26c "test -d first-dir/dir1/dir2/CVS" + + dotest basic2-27 "directory_cmp 1dir first-dir" + rm -r 1dir first-dir + + # checkout by revision vs export by rtagged-by-revision and compare. + mkdir export-dir + dotest basic2-28 "${testcvs} export -rrtagged-by-revision -d export-dir first-dir" \ +"${SPROG} export: Updating export-dir +U export-dir/file14 +U export-dir/file6 +U export-dir/file7 +${SPROG} export: Updating export-dir/dir1 +U export-dir/dir1/file14 +U export-dir/dir1/file6 +U export-dir/dir1/file7 +${SPROG} export: Updating export-dir/dir1/dir2 +U export-dir/dir1/dir2/file14 +U export-dir/dir1/dir2/file6 +U export-dir/dir1/dir2/file7" + dotest_fail basic2-28a "test -d export-dir/CVS" + dotest_fail basic2-28b "test -d export-dir/dir1/CVS" + dotest_fail basic2-28c "test -d export-dir/dir1/dir2/CVS" + + dotest basic2-29 "${testcvs} co -r1.1 first-dir" \ +"${SPROG} checkout: Updating first-dir +U first-dir/file14 +U first-dir/file6 +U first-dir/file7 +${SPROG} checkout: Updating first-dir/dir1 +U first-dir/dir1/file14 +U first-dir/dir1/file6 +U first-dir/dir1/file7 +${SPROG} checkout: Updating first-dir/dir1/dir2 +U first-dir/dir1/dir2/file14 +U first-dir/dir1/dir2/file6 +U first-dir/dir1/dir2/file7" + + # directory copies are done in an oblique way in order to avoid a bug in sun's tmp filesystem. + mkdir first-dir.cpy ; (cd first-dir ; tar cf - . | (cd ../first-dir.cpy ; tar xf -)) + + dotest basic2-30 "directory_cmp first-dir export-dir" + + # interrupt, while we've got a clean 1.1 here, let's import it + # into a couple of other modules. + cd export-dir + dotest_sort basic2-31 \ +"$testcvs import -m first-import second-dir first-immigration immigration1 immigration1_0" \ +" + +N second-dir/dir1/dir2/file14 +N second-dir/dir1/dir2/file6 +N second-dir/dir1/dir2/file7 +N second-dir/dir1/file14 +N second-dir/dir1/file6 +N second-dir/dir1/file7 +N second-dir/file14 +N second-dir/file6 +N second-dir/file7 +No conflicts created by this import +${SPROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1 +${SPROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1/dir2" + cd .. + + dotest basic2-32 "${testcvs} export -r HEAD second-dir" \ +"${SPROG} export: Updating second-dir +U second-dir/file14 +U second-dir/file6 +U second-dir/file7 +${SPROG} export: Updating second-dir/dir1 +U second-dir/dir1/file14 +U second-dir/dir1/file6 +U second-dir/dir1/file7 +${SPROG} export: Updating second-dir/dir1/dir2 +U second-dir/dir1/dir2/file14 +U second-dir/dir1/dir2/file6 +U second-dir/dir1/dir2/file7" + + dotest basic2-33 "directory_cmp first-dir second-dir" + + rm -r second-dir + + rm -r export-dir first-dir + mkdir first-dir + (cd first-dir.cpy ; tar cf - . | (cd ../first-dir ; tar xf -)) + + # update the top, cancelling sticky tags, retag, update other copy, compare. + cd first-dir + dotest basic2-34 "${testcvs} update -A -l *file*" \ +"[UP] file6 +${SPROG} update: \`file7' is no longer in the repository" + + # If we don't delete the tag first, cvs won't retag it. + # This would appear to be a feature. + dotest basic2-35 "${testcvs} tag -l -d rtagged-by-revision" \ +"${SPROG} tag: Untagging \. +D file14 +D file6" + dotest basic2-36 "${testcvs} tag -l rtagged-by-revision" \ +"${SPROG} tag: Tagging \. +T file14 +T file6" + + cd .. + mv first-dir 1dir + mv first-dir.cpy first-dir + cd first-dir + + dotest basic2-37 "${testcvs} -q diff -u" '' + + dotest basic2-38 "${testcvs} update" \ +"${SPROG} update: Updating . +${SPROG} update: Updating dir1 +${SPROG} update: Updating dir1/dir2" + + cd .. + + #### FIXME: is this expected to work??? Need to investigate + #### and fix or remove the test. +# dotest basic2-39 "directory_cmp 1dir first-dir" + + rm -r 1dir first-dir + + # Test the cvs history command. + # + # Just skip these in write proxy mode for now. We should only + # see write commands and maybe the last few reads in the + # secondary history file the way we currently sync, but I'm not + # going to try and test this yet. + if $proxy; then :; else + + # The reason that there are two patterns rather than using + # \(${TESTDIR}\|<remote>\) is that we are trying to + # make this portable. Perhaps at some point we should + # ditch that notion and require GNU expr (or dejagnu or....) + # since it seems to be so painful. + + dotest basic2-64 "${testcvs} his -x TOFWUPCGMAR -a" \ +"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= ${TESTDIR}/\* +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == ${TESTDIR} +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TESTDIR} +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == ${TESTDIR} +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == ${TESTDIR} +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == ${TESTDIR} +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == ${TESTDIR} +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == ${TESTDIR} +F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= ${TESTDIR}/\* +T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\] +T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\] +T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\] +O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= ${TESTDIR}/\* +U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TESTDIR}/first-dir +W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == ${TESTDIR}/first-dir" \ +"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= <remote>/\* +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == <remote> +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == <remote> +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == <remote> +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == <remote> +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == <remote> +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == <remote> +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == <remote> +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == <remote> +F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= <remote>/\* +T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\] +T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\] +T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\] +O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= <remote>/\* +P [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == <remote> +W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == <remote>" + fi + + dokeep + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + ls) + # Test the ls & rls commands. There are some tests of + # Interaction of ls, rls, and branches in branches2. + mkdir ls; cd ls + dotest ls-init-1 "$testcvs -Q co -dtop ." + cd top + dotest ls-1 "$testcvs ls CVSROOT" \ +"checkoutlist +commitinfo +config +cvswrappers +loginfo +modules +notify +postadmin +postproxy +posttag +postwatch +preproxy +rcsinfo +taginfo +verifymsg" + dotest ls-2 "$testcvs ls -R" \ +"\.: +CVSROOT + +CVSROOT: +checkoutlist +commitinfo +config +cvswrappers +loginfo +modules +notify +postadmin +postproxy +posttag +postwatch +preproxy +rcsinfo +taginfo +verifymsg" + # This used to cause a fatal error. + modify_repo mkdir $CVSROOT_DIRNAME/notcheckedout + dotest ls-3 "$testcvs ls -RP" \ +"\.: +CVSROOT +notcheckedout + +CVSROOT: +checkoutlist +commitinfo +config +cvswrappers +loginfo +modules +notify +postadmin +postproxy +posttag +postwatch +preproxy +rcsinfo +taginfo +verifymsg" + + # Make sure the previous command did not create the notcheckedout + # directory. + dotest_fail ls-4 "test -d notcheckedout" + + dotest ls-5 "$testcvs ls -R" \ +"\.: +CVSROOT +notcheckedout + +CVSROOT: +checkoutlist +commitinfo +config +cvswrappers +loginfo +modules +notify +postadmin +postproxy +posttag +postwatch +preproxy +rcsinfo +taginfo +verifymsg + +notcheckedout:" + dotest_fail ls-6 "test -d notcheckedout" + + # Several test for ls -d, which shows dead revisions + + # Set up the dead files + mkdir cemetery + dotest ls-d-init-1 "$testcvs -Q add cemetery" + cd cemetery + touch dead living + dotest ls-d-init-2 "$testcvs -Q add dead living" + dotest ls-d-init-3 "$testcvs -Q ci -mm dead living" + dotest ls-d-init-4 "$testcvs -Q tag -b branch" + dotest ls-d-init-5 "$testcvs -Q up -A" + rm dead + dotest ls-d-init-6 "$testcvs -Q rm dead" + dotest ls-d-init-7 "$testcvs -Q ci -mm dead" + dotest ls-d-init-8 "$testcvs -Q up -r branch" + rm dead + dotest ls-d-init-9 "$testcvs -Q rm dead" + dotest ls-d-init-10 "$testcvs -Q ci -mm dead" + + # Possible output + output_living="living" + output_dead="dead +living" + + # The basic test is to make sure that dead revisions are shown if and + # only if -d is speficified (and that live revisions are always + # shown). The following test cases cover all combinations of these + # factors: + # + # + Working directory is on branch or trunk + # + ls or rls + # + implicit branch, explicit trunk, or explicit branch + # + -d present or absent + + # Working directory on trunk + $testcvs -Q up -A + + ## ls + dotest ls-d-1 "$testcvs ls" "$output_living" + dotest ls-d-2 "$testcvs ls -d" "$output_dead" + + dotest ls-d-3 "$testcvs ls -rHEAD" "$output_living" + dotest ls-d-4 "$testcvs ls -drHEAD" "$output_dead" + + dotest ls-d-5 "$testcvs ls -rbranch" "$output_living" + dotest ls-d-6 "$testcvs ls -drbranch" "$output_dead" + + ## rls + dotest ls-d-7 "$testcvs rls cemetery" \ +"$SPROG rls: Listing module: \`cemetery' +$output_living" + dotest ls-d-8 "$testcvs rls -d cemetery" \ +"$SPROG rls: Listing module: \`cemetery' +$output_dead" + + dotest ls-d-9 "$testcvs -q rls -rHEAD cemetery" "$output_living" + dotest ls-d-10 "$testcvs -q rls -drHEAD cemetery" "$output_dead" + + dotest ls-d-11 "$testcvs -q rls -rbranch cemetery" "$output_living" + dotest ls-d-12 "$testcvs -q rls -drbranch cemetery" "$output_dead" + + # Working directory on branch + $testcvs -Q up -r branch + + ## ls + dotest ls-d-13 "$testcvs ls" "$output_living" + dotest ls-d-14 "$testcvs ls -d" "$output_dead" + + dotest ls-d-15 "$testcvs ls -r HEAD" "$output_living" + dotest ls-d-16 "$testcvs ls -d -r HEAD" "$output_dead" + + dotest ls-d-17 "$testcvs ls -r branch" "$output_living" + dotest ls-d-18 "$testcvs ls -d -r branch" "$output_dead" + + ## rls + dotest ls-d-19 "$testcvs -q rls cemetery" "$output_living" + dotest ls-d-20 "$testcvs -q rls -d cemetery" "$output_dead" + + dotest ls-d-21 "$testcvs -q rls -rHEAD cemetery" "$output_living" + dotest ls-d-22 "$testcvs -q rls -drHEAD cemetery" "$output_dead" + + dotest ls-d-23 "$testcvs -q rls -rbranch cemetery" "$output_living" + dotest ls-d-24 "$testcvs -q rls -drbranch cemetery" "$output_dead" + + # Some tests to cover specifying a file name as an option + # Combinations of factors: + # + # + file in CVS/Entries or not + # + current directory or subdirectory + # + file dead or not + + # Switch back to the trunk + $testcvs -Q up -A + + ## file in CVS/Entries + dotest ls-filename-1 "$testcvs ls dead" + + # ls'ing a file that already exists once caused an assertion failure. + dotest ls-filename-2 "$testcvs ls living" "living" + + cd .. + dotest ls-filename-3 "$testcvs ls cemetery/dead" + + # ls'ing a file that already exists once caused an assertion failure. + dotest ls-filename-4 "$testcvs ls cemetery/living" "cemetery/living" + cd cemetery + + ## file not in CVS/Entries + echo D > CVS/Entries + + dotest ls-filename-5 "$testcvs ls dead" + + # ls'ing a file that already exists once caused an assertion failure. + dotest ls-filename-6 "$testcvs ls living" "living" + + cd .. + dotest ls-filename-7 "$testcvs ls cemetery/dead" + + # ls'ing a file that already exists once caused an assertion failure. + dotest ls-filename-8 "$testcvs ls cemetery/living" "cemetery/living" + + cd cemetery + + # Test the -D date option to cvs ls + + # try and list a file before it's created, during an old revision, in + # a period when it was dead and in the future + time_prebirth=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 1 + touch dated + dotest ls-D-init-1 "$testcvs -Q add dated" + dotest ls-D-init-2 "$testcvs -Q ci -mm dated" + time_newborn=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 1 + echo mm >> dated + dotest ls-D-init-2 "$testcvs -Q ci -mm dated" + time_predeath=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 1 + rm dated + dotest ls-D-init-3 "$testcvs -Q rm dated" + dotest ls-D-init-4 "$testcvs -Q ci -mm dated" + time_postdeath=`date '+%Y-%m-%d %H:%M:%S'` + + dotest ls-D-1 "$testcvs ls -D '$time_prebirth' -e dated" + + # ls'ing a file that already exists once caused an assertion failure. + dotest ls-D-2 "$testcvs ls -D '$time_newborn' -e dated" \ +"/dated/1\.1/.*" + + # ls'ing a file that already exists once caused an assertion failure. + dotest ls-D-3 "$testcvs ls -D '$time_predeath' -e dated" \ +"/dated/1.2/.*" + + dotest ls-D-4 "$testcvs ls -D '$time_postdeath' -e dated" + + dokeep + cd ../../.. + rm -r ls + modify_repo rm -rf $CVSROOT_DIRNAME/notcheckedout \ + $CVSROOT_DIRNAME/cemetery + unset output_living output_dead + ;; + + + + parseroot) + mkdir 1; cd 1 + # Test odd cases involving CVSROOT. At the moment, that means we + # are testing roots with '/'s on the end, which CVS should parse off. + CVSROOT_save=${CVSROOT} + CVSROOT="${CVSROOT}/////" + dotest parseroot-1 "${testcvs} -q co CVSROOT/modules" \ +"U CVSROOT/modules" + dotest parseroot-2 "${testcvs} -q ci -fmnull-change CVSROOT/modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- CVSROOT/modules +new revision: 1\.2; previous revision: 1\.1 +$SPROG commit: Rebuilding administrative file database" + + if $remote; then + # I only test these when testing remote in case CVS was compiled + # without client support. + + # logout does not try to contact the server. + CVSROOT=":pserver;proxy=localhost;proxyport=8080:localhost/dev/null" + dotest parseroot-3r "$testcvs -d'$CVSROOT' logout" \ +"Logging out of :pserver:$username@localhost:2401/dev/null +$CPROG logout: warning: failed to open $HOME/\.cvspass for reading: No such file or directory +$CPROG logout: Entry not found." + CVSROOT=":pserver;proxyport=8080:localhost/dev/null" + dotest_fail parseroot-4r "$testcvs -d'$CVSROOT' logout" \ +"$CPROG logout: Proxy port specified in CVSROOT without proxy host\. +$CPROG \[logout aborted\]: Bad CVSROOT: \`:pserver;proxyport=8080:localhost/dev/null'\." + CVSROOT=":pserver;optionnoarg:localhost/dev/null" + dotest_fail parseroot-5r "$testcvs -d'$CVSROOT' logout" \ +"$CPROG logout: Option (\`optionnoarg') has no argument in CVSROOT\. +$CPROG \[logout aborted\]: Bad CVSROOT: \`:pserver;optionnoarg:localhost/dev/null'\." + CVSROOT=":pserver;notanoption=anything:localhost/dev/null" + dotest_fail parseroot-6r "$testcvs -d'$CVSROOT' logout" \ +"$CPROG logout: Unknown option (\`notanoption') in CVSROOT\. +$CPROG \[logout aborted\]: Bad CVSROOT: \`:pserver;notanoption=anything:localhost/dev/null'\." + CVSROOT=":local;proxy=localhost:/dev/null" + dotest_fail parseroot-7r "$testcvs -d'$CVSROOT' logout" \ +"$CPROG logout: CVSROOT proxy specification is only valid for gserver and +$CPROG logout: pserver connection methods\. +$CPROG \[logout aborted\]: Bad CVSROOT: \`:local;proxy=localhost:/dev/null'\." + CVSROOT="::pserver@anonymous@test.org:/cvs" + dotest_fail parseroot-8r "$testcvs -d'$CVSROOT' co test" \ +"$CPROG checkout: Unknown method (\`') in CVSROOT\. +$CPROG \[checkout aborted\]: Bad CVSROOT: \`$CVSROOT'\." + fi + + dokeep + + # Clean up + CVSROOT=$CVSROOT_save + cd .. + rm -r 1 + ;; + + + + files) + # Test of how we specify files on the command line + # (recurse.c and that sort of thing). Vaguely similar to + # tests like basic* and deep. See modules and such tests + # for what happens when we throw in modules and co -d, &c. + + # This particular test is fairly carefully crafted, to spot + # one particular issue with remote. + mkdir 1; cd 1 + dotest files-1 "${testcvs} -q co -l ." "" + mkdir first-dir + dotest files-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch tfile + dotest files-3 "${testcvs} add tfile" \ +"${SPROG} add: scheduling file .tfile. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest files-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/tfile,v <-- tfile +initial revision: 1\.1" + dotest files-5 "${testcvs} -q tag -b C" "T tfile" + dotest files-6 "${testcvs} -q update -r C" "" + mkdir dir + dotest files-7 "${testcvs} add dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository +--> Using per-directory sticky tag .C'" + cd dir + touch .file + dotest files-7b "${testcvs} add .file" \ +"${SPROG} add: scheduling file .\.file' for addition on branch .C. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + mkdir sdir + dotest files-7c "${testcvs} add sdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir added to the repository +--> Using per-directory sticky tag .C'" + cd sdir + mkdir ssdir + dotest files-8 "${testcvs} add ssdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir added to the repository +--> Using per-directory sticky tag .C'" + cd ssdir + touch .file + dotest files-9 "${testcvs} add .file" \ +"${SPROG} add: scheduling file .\.file' for addition on branch .C. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cd ../.. + dotest files-10 "${testcvs} -q ci -m test" \ +"$CVSROOT_DIRNAME/first-dir/dir/Attic/\.file,v <-- \.file +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- sdir/ssdir/\.file +new revision: 1\.1\.2\.1; previous revision: 1\.1" + dotest files-11 \ +"${testcvs} commit -m test -f ./.file ./sdir/ssdir/.file" \ +"${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 +${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \./sdir/ssdir/\.file +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + if $remote; then + # FIXCVS: + # This is a bug, looks like that toplevel_repos cruft in + # client.c is coming back to haunt us. + # May want to think about the whole issue, toplevel_repos + # has always been crufty and trying to patch it up again + # might be a mistake. + dotest files-12r \ +"$testcvs commit -f -m test ./sdir/ssdir/.file ./.file" \ +"$CVSROOT_DIRNAME/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \./sdir/ssdir/\.file +new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2" + + # Sync up the version numbers so that the rest of the + # tests don't need to expect different numbers based + # local or remote. + dotest files-12rworkaround \ +"$testcvs commit -f -m test .file" \ +"$CVSROOT_DIRNAME/first-dir/dir/Attic/\.file,v <-- \.file +new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2" + else + dotest files-12 \ +"${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \ +"${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \./sdir/ssdir/\.file +new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 +${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file +new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2" + fi + dotest files-13 \ +"${testcvs} commit -fmtest ./sdir/../sdir/ssdir/..///ssdir/.file" \ +"${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \./sdir/\.\./sdir/ssdir/\.\.///ssdir/\.file +new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3" + dotest files-14 \ +"${testcvs} commit -fmtest ../../first-dir/dir/.file" \ +"${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.\./\.\./first-dir/dir/\.file +new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3" + + dokeep + cd ../../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + spacefiles) + # More filename tests, in particular spaces in file names. + # (it might be better to just change a few of the names in + # basica or some other test instead, always good to keep the + # testsuite concise). + + mkdir 1; cd 1 + dotest spacefiles-1 "${testcvs} -q co -l ." "" + touch ./-c + dotest spacefiles-2 "${testcvs} add -- -c" \ +"${SPROG} add: scheduling file .-c. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest spacefiles-3 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/-c,v <-- -c +initial revision: 1\.1" + mkdir 'first dir' + dotest spacefiles-4 "${testcvs} add 'first dir'" \ +"Directory ${CVSROOT_DIRNAME}/first dir added to the repository" + mkdir ./-b + dotest spacefiles-5 "${testcvs} add -- -b" \ +"Directory ${CVSROOT_DIRNAME}/-b added to the repository" + cd 'first dir' + touch 'a file' + dotest spacefiles-6 "${testcvs} add 'a file'" \ +"${SPROG} add: scheduling file .a file. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest spacefiles-7 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first dir/a file,v <-- a file +initial revision: 1\.1" + dotest spacefiles-8 "${testcvs} -q tag new-tag" "T a file" + cd ../.. + + mkdir 2; cd 2 + dotest spacefiles-10 "${testcvs} co -- -b" \ +"${SPROG} checkout: Updating -b" + dotest spacefiles-11 "${testcvs} -q co -- -c" "U \./-c" + rm ./-c + dotest spacefiles-13 "${testcvs} -q co 'first dir'" \ +"U first dir/a file" + cd .. + + mkdir 3; cd 3 + dotest spacefiles-14 "${testcvs} -q co 'first dir/a file'" \ +"U first dir/a file" + cd .. + + rm -r 1 2 3 + modify_repo rm -rf "'$CVSROOT_DIRNAME/first dir'" \ + $CVSROOT_DIRNAME/-b $CVSROOT_DIRNAME/-c,v + ;; + + + + commit-readonly) + mkdir 1; cd 1 + module=x + + : > junk + dotest commit-readonly-1 "$testcvs -Q import -m . $module X Y" '' + dotest commit-readonly-2 "$testcvs -Q co $module" '' + cd $module + + file=m + + # Include an rcs keyword to be expanded. + echo '$Id''$' > $file + + dotest commit-readonly-3 "$testcvs add $file" \ +"$SPROG add: scheduling file .$file. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest commit-readonly-4 "$testcvs -Q ci -m . $file" + + echo line2 >> $file + # Make the file read-only. + chmod a-w $file + + dotest commit-readonly-5 "$testcvs -Q ci -m . $file" + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/"$module" + ;; + + + + status) + # This tests for a bug in the status command which failed to + # notice resolved conflicts. + mkdir status; cd status + dotest status-init-1 "$testcvs -q co -l ." + mkdir first-dir + dotest status-init-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo a line >tfile + dotest status-init-3 "${testcvs} add tfile" \ +"${SPROG} add: scheduling file .tfile. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest status-init-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/tfile,v <-- tfile +initial revision: 1\.1" + cd .. + dotest status-init-5 "${testcvs} -q co -dsecond-dir first-dir" \ +"U second-dir/tfile" + cd second-dir + echo some junk >>tfile + dotest status-init-6 "${testcvs} -q ci -maline" \ +"$CVSROOT_DIRNAME/first-dir/tfile,v <-- tfile +new revision: 1\.2; previous revision: 1\.1" + cd ../first-dir + echo force a conflict >>tfile + dotest status-init-7 "${testcvs} -q up" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into tfile +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in tfile +C tfile" + + # Now note our status + dotest status-1 "${testcvs} status tfile" \ +"=================================================================== +File: tfile Status: Unresolved Conflict + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + # touch the file, leaving conflict markers in place + # and note our status + touch tfile + dotest status-2 "${testcvs} status tfile" \ +"=================================================================== +File: tfile Status: File had conflicts on merge + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + # resolve the conflict + echo resolution >tfile + dotest status-3 "${testcvs} status tfile" \ +"=================================================================== +File: tfile Status: Locally Modified + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + # Check that there are no problems just using CVS/Root too. + save_CVSROOT=$CVSROOT + unset CVSROOT + dotest status-3a "${testcvs} status tfile" \ +"=================================================================== +File: tfile Status: Locally Modified + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + CVSROOT=$save_CVSROOT + export CVSROOT + + # FIXCVS: + # Update is supposed to re-Register() the file when it + # finds resolved conflicts: + dotest status-4 "grep 'Result of merge' CVS/Entries" \ +"/tfile/1\.2/Result of merge${PLUS}[a-zA-Z0-9 :]*//" + + cd .. + mkdir fourth-dir + dotest status-init-8 "$testcvs add fourth-dir" \ +"Directory $CVSROOT_DIRNAME/fourth-dir added to the repository" + cd fourth-dir + echo yet another line >t3file + dotest status-init-9 "$testcvs add t3file" \ +"$SPROG add: scheduling file .t3file. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest status-init-10 "$testcvs -q ci -m add" \ +"$CVSROOT_DIRNAME/fourth-dir/t3file,v <-- t3file +initial revision: 1\.1" + cd ../first-dir + mkdir third-dir + dotest status-init-11 "$testcvs add third-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir/third-dir added to the repository" + cd third-dir + echo another line >t2file + dotest status-init-12 "$testcvs add t2file" \ +"$SPROG add: scheduling file .t2file. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest status-init-13 "$testcvs -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/third-dir/t2file,v <-- t2file +initial revision: 1\.1" + dotest status-5 "$testcvs status ../tfile" \ +"=================================================================== +File: tfile Status: Locally Modified + + Working revision: 1\.2.* + Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/tfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest status-6 "$testcvs status ../../fourth-dir/t3file" \ +"=================================================================== +File: t3file Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/fourth-dir/t3file,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + dokeep + cd ../../.. + rm -rf status + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/fourth-dir + ;; + + + + commit-readonlyfs) + mkdir 1; cd 1 + module=x + : > junk + dotest commit-readonlyfs-1 "${testcvs} -Q import -m . $module X Y" '' + if $remote; then + dotest_fail commit-readonlyfs-2r1 "${testcvs} -Q -R co $module" \ +"${CPROG} \[checkout aborted\]: Read-only repository feature unavailable with remote roots (cvsroot = ${CVSROOT_DIRNAME})" + dotest commit-readonlyfs-2r2 "${testcvs} -Q co $module" '' + else + dotest commit-readonlyfs-2 "${testcvs} -Q -R co $module" '' + rm -rf $module + dotest commit-readonlyfs-2r3 "${testcvs} -q -R co $module" \ +"U $module/junk" + rm -rf $module + dotest commit-readonlyfs-2r4 "${testcvs} -R co $module" \ +"${SPROG}: WARNING: Read-only repository access mode selected via \`cvs -R'\. +Using this option to access a repository which some users write to may +cause intermittent sandbox corruption\. +${SPROG} checkout: Updating $module +U $module/junk" + fi + cd $module + echo test > junk + if $remote; then + dotest_fail commit-readonlyfs-3r "${testcvs} -Q -R ci -m. junk" \ +"${SPROG} \[commit aborted\]: Read-only repository feature unavailable with remote roots (cvsroot = ${CVSROOT_DIRNAME})" + else + dotest_fail commit-readonlyfs-3 "${testcvs} -Q -R ci -m. junk" \ +"${SPROG} commit: write lock failed\. +WARNING: Read-only repository access mode selected via \`cvs -R'\. +Attempting to write to a read-only filesystem is not allowed\. +${SPROG} \[commit aborted\]: lock failed - giving up" + fi + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/"$module" + ;; + + + + rdiff) + # Test rdiff + # XXX for now this is just the most essential test... + cd ${TESTDIR} + + mkdir testimport + cd testimport + echo '$''Id$' > foo + echo '$''Name$' >> foo + echo '$''Id$' > bar + echo '$''Name$' >> bar + dotest_sort rdiff-1 \ + "${testcvs} import -I ! -m test-import-with-keyword trdiff TRDIFF T1" \ +' + +N trdiff/bar +N trdiff/foo +No conflicts created by this import' + dotest rdiff-2 \ + "${testcvs} co -ko trdiff" \ +"${SPROG} checkout: Updating trdiff +U trdiff/bar +U trdiff/foo" + cd trdiff + echo something >> foo + dotest rdiff-3 \ + "${testcvs} ci -m added-something foo" \ +"${CVSROOT_DIRNAME}/trdiff/foo,v <-- foo +new revision: 1\.2; previous revision: 1\.1" + echo '#ident "@(#)trdiff:$''Name$:$''Id$"' > new + echo "new file" >> new + dotest rdiff-4 \ + "${testcvs} add -m new-file-description new" \ +"${SPROG} add: scheduling file \`new' for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest rdiff-5 \ + "${testcvs} commit -m added-new-file new" \ +"${CVSROOT_DIRNAME}/trdiff/new,v <-- new +initial revision: 1\.1" + dotest rdiff-6 \ + "${testcvs} tag local-v0" \ +"${SPROG} tag: Tagging . +T bar +T foo +T new" + dotest rdiff-7 \ + "${testcvs} status -v foo" \ +"=================================================================== +File: foo Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/trdiff/foo,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -ko + + Existing Tags: + local-v0 (revision: 1\.2) + T1 (revision: 1\.1\.1\.1) + TRDIFF (branch: 1\.1\.1)" + + cd .. + rm -r trdiff + + dotest rdiff-8 \ + "${testcvs} rdiff -r T1 -r local-v0 trdiff" \ +"${SPROG}"' rdiff: Diffing trdiff +Index: trdiff/foo +diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2 +\*\*\* trdiff/foo:1\.1\.1\.1 '"${DATE}"' +--- trdiff/foo '"${DATE}"' +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1,2 \*\*\*\* +! \$''Id: foo,v 1\.1\.1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$ +! \$''Name: T1 \$ +--- 1,3 ---- +! \$''Id: foo,v 1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$ +! \$''Name: local-v0 \$ +! something +Index: trdiff/new +diff -c /dev/null trdiff/new:1\.1 +\*\*\* /dev/null '"${DATE}"' +--- trdiff/new '"${DATE}"' +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1,2 ---- +'"${PLUS}"' #ident "@(#)trdiff:\$''Name: local-v0 \$:\$''Id: new,v 1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$" +'"${PLUS}"' new file' + + dokeep + cd .. + rm -r testimport + modify_repo rm -rf $CVSROOT_DIRNAME/trdiff + ;; + + + + rdiff-short) + # Test that the short patch behaves as expected + # 1) Added file. + # 2) Removed file. + # 3) Different revision number with no difference. + # 4) Different revision number with changes. + # 5) Against trunk. + # 6) Same revision number (no difference). + mkdir rdiff-short; cd rdiff-short + mkdir abc + dotest rdiff-short-init-1 \ +"${testcvs} -q import -I ! -m initial-import abc vendor initial" \ +' +No conflicts created by this import' + + dotest rdiff-short-init-2 "${testcvs} -q get abc" '' + cd abc + echo "abc" >file1.txt + dotest rdiff-short-init-3 "${testcvs} add file1.txt" \ +"${SPROG} add: scheduling file .file1\.txt' for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + dotest rdiff-short-init-4 \ +"${testcvs} commit -madd-file1 file1.txt" \ +"${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt +initial revision: 1\.1" + echo def >>file1.txt + dotest rdiff-short-init-5 \ +"${testcvs} commit -mchange-file1 file1.txt" \ +"${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt +new revision: 1\.2; previous revision: 1\.1" + echo "abc" >file1.txt + dotest rdiff-short-init-6 \ +"${testcvs} commit -mrestore-file1-rev1 file1.txt" \ +"${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt +new revision: 1\.3; previous revision: 1\.2" + dotest rdiff-short-init-7 \ +"${testcvs} tag -r 1.1 tag1 file1.txt" \ +"T file1\.txt" + dotest rdiff-short-init-8 \ +"${testcvs} tag -r 1.2 tag2 file1.txt" \ +"T file1\.txt" + dotest rdiff-short-init-9 \ +"${testcvs} tag -r 1.3 tag3 file1.txt" \ +"T file1\.txt" + echo "abc" >file2.txt + dotest rdiff-short-init-10 \ +"${testcvs} add file2.txt" \ +"${SPROG} add: scheduling file .file2\.txt' for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + dotest rdiff-add-remove-nodiff-init-11 \ +"${testcvs} commit -madd-file2 file2.txt" \ +"${CVSROOT_DIRNAME}/abc/file2\.txt,v <-- file2\.txt +initial revision: 1\.1" + dotest rdiff-short-init-12 \ +"${testcvs} tag -r 1.1 tag4 file2.txt" \ +"T file2\.txt" + dotest rdiff-short-init-13 \ +"${testcvs} tag -r 1.1 tag5 file2.txt" \ +"T file2\.txt" + cd ../.. + rm -fr rdiff-short + + # 3) Different revision number with no difference. + dotest rdiff-short-no-real-change \ +"${testcvs} -q rdiff -s -r tag1 -r tag3 abc" + + # 4) Different revision number with changes. + dotest rdiff-short-real-change \ +"${testcvs} -q rdiff -s -r tag1 -r tag2 abc" \ +'File abc/file1.txt changed from revision 1\.1 to 1\.2' + + # 1) Added file. + # 2) Removed file. + dotest_sort rdiff-short-remove-add \ +"${testcvs} -q rdiff -s -r tag2 -r tag4 abc" \ +'File abc/file1\.txt is removed; tag2 revision 1\.2 +File abc/file2\.txt is new; tag4 revision 1\.1' + + # 6) Same revision number (no difference). + dotest rdiff-short-no-change \ +"${testcvs} -q rdiff -s -r tag4 -r tag5 abc" + + # 5) Against trunk. + # Check that the messages change when we diff against the trunk + # rather than a tag or date. + dotest rdiff-short-against-trunk-1 \ +"${testcvs} -q rdiff -s -rtag4 abc" \ +"File abc/file1\.txt is new; current revision 1\.3" + + dotest rdiff-short-against-trunk-2 \ +"${testcvs} -q rdiff -s -rtag2 abc" \ +"File abc/file1\.txt changed from revision 1\.2 to 1\.3 +File abc/file2\.txt is new; current revision 1\.1" + + modify_repo rm -rf $CVSROOT_DIRNAME/abc + ;; + + + + rdiff2) + # Test for the segv problem reported by James Cribb + # Somewhere to work + mkdir rdiff2; cd rdiff2 + # Create a module "m" with files "foo" and "d/bar" + mkdir m; cd m + echo foo >foo + mkdir d + echo bar >d/bar + dotest_sort rdiff2-1 \ +"${testcvs} -q import -I ! -m initial-import m vendor initial" \ +' + +N m/d/bar +N m/foo +No conflicts created by this import' + + cd .. + rm -r m + + # Remove "foo" + dotest rdiff2-2 "${testcvs} get m" \ +"${SPROG} checkout: Updating m +U m/foo +${SPROG} checkout: Updating m/d +U m/d/bar" + cd m + dotest rdiff2-3 "${testcvs} rm -f foo" \ +"${SPROG} remove: scheduling .foo. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + + dotest rdiff2-4 "${testcvs} commit -m Removed foo" \ +"${CVSROOT_DIRNAME}/m/foo,v <-- foo +new revision: delete; previous revision: 1\.1\.1\.1" + + # Modify "d/bar" + echo foo >d/bar + dotest rdiff2-5 "${testcvs} commit -m Changed d/bar" \ +"${CVSROOT_DIRNAME}/m/d/bar,v <-- d/bar +new revision: 1\.2; previous revision: 1\.1" + + # Crash before showing d/bar diffs + dotest_fail rdiff2-6 "${testcvs} rdiff -t m" \ +"${SPROG} rdiff: Diffing m +${SPROG} rdiff: Diffing m/d +Index: m/d/bar +diff -c m/d/bar:1\.1\.1\.1 m/d/bar:1\.2 +\*\*\* m/d/bar:1\.1\.1\.1 ${DATE} +--- m/d/bar ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +! bar +--- 1 ---- +! foo" + + dokeep + cd ../.. + rm -rf rdiff2 + modify_repo rm -rf $CVSROOT_DIRNAME/m + ;; + + + + diff) + # Various tests specific to the "cvs diff" command. + # Related tests: + # death2: -N + # rcslib: cvs diff and $Name. + # rdiff: cvs rdiff. + # diffmerge*: nuts and bolts (stuff within diff library) + mkdir 1; cd 1 + dotest diff-1 "$testcvs -q co -l ." + mkdir first-dir + dotest diff-2 "$testcvs add first-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir added to the repository" + cd first-dir + + # diff is anomalous. Most CVS commands print the "nothing + # known" message (or worse yet, no message in some cases) but + # diff says "I know nothing". Shrug. + dotest_fail diff-3 "${testcvs} diff xyzpdq" \ +"${SPROG} diff: I know nothing about xyzpdq" + touch abc + dotest diff-4 "${testcvs} add abc" \ +"${SPROG} add: scheduling file .abc. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest diff-5 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/abc,v <-- abc +initial revision: 1\.1" + echo "extern int gethostname ();" >abc + dotest diff-6 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/abc,v <-- abc +new revision: 1\.2; previous revision: 1\.1" + echo "#include <winsock.h>" >abc + # check the behavior of the --ifdef=MACRO option + dotest_fail diff-7 "${testcvs} -q diff --ifdef=HAVE_WINSOCK_H" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.2 +diff --ifdef HAVE_WINSOCK_H -r1\.2 abc +#ifndef HAVE_WINSOCK_H +extern int gethostname (); +#else /\* HAVE_WINSOCK_H \*/ +#include <winsock\.h> +#endif /\* HAVE_WINSOCK_H \*/" + + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r 1 + ;; + + + + diffnl) + # Test handling of 'cvs diff' of files without newlines + mkdir 1; cd 1 + dotest diffnl-000 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest diffnl-001 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' </dev/null >abc + dotest diffnl-002 "${testcvs} add abc" \ +"${SPROG} add: scheduling file .abc. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest diffnl-003 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/abc,v <-- abc +initial revision: 1\.1" + + # change to line near EOF + ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nsix")}' </dev/null >abc + dotest_fail diffnl-100 "${testcvs} diff abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.1 +diff -r1\.1 abc +5d4 +< five" + dotest_fail diffnl-101 "${testcvs} diff -u abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.1 +diff -u -r1\.1 abc +--- abc ${RFCDATE} 1\.1 ++++ abc ${RFCDATE} +@@ -2,5 +2,4 @@ + two + three + four +-five + six +\\\\ No newline at end of file" + dotest diffnl-102 "${testcvs} -q ci -mtest abc" \ +"$CVSROOT_DIRNAME/first-dir/abc,v <-- abc +new revision: 1\.2; previous revision: 1\.1" + + # Change to last line + ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' </dev/null >abc + dotest_fail diffnl-200 "${testcvs} diff abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.2 +diff -r1\.2 abc +5c5 +< six +\\\\ No newline at end of file +--- +> seven +\\\\ No newline at end of file" + dotest_fail diffnl-201 "${testcvs} diff -u abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.2 +diff -u -r1\.2 abc +--- abc ${RFCDATE} 1\.2 ++++ abc ${RFCDATE} +@@ -2,4 +2,4 @@ + two + three + four +-six +\\\\ No newline at end of file ++seven +\\\\ No newline at end of file" + dotest diffnl-202 "${testcvs} ci -mtest abc" \ +"${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc +new revision: 1\.3; previous revision: 1\.2" + + # Addition of newline + echo "one +two +three +four +seven" > abc + dotest_fail diffnl-300 "${testcvs} diff abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.3 +diff -r1\.3 abc +5c5 +< seven +\\\\ No newline at end of file +--- +> seven" + dotest_fail diffnl-301 "${testcvs} diff -u abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.3 +diff -u -r1\.3 abc +--- abc ${RFCDATE} 1\.3 ++++ abc ${RFCDATE} +@@ -2,4 +2,4 @@ + two + three + four +-seven +\\\\ No newline at end of file ++seven" + dotest diffnl-302 "${testcvs} ci -mtest abc" \ +"${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc +new revision: 1\.4; previous revision: 1\.3" + + # Removal of newline + ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' </dev/null >abc + dotest_fail diffnl-400 "${testcvs} diff abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.4 +diff -r1\.4 abc +5c5 +< seven +--- +> seven +\\\\ No newline at end of file" + dotest_fail diffnl-401 "${testcvs} diff -u abc" \ +"Index: abc +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v +retrieving revision 1\.4 +diff -u -r1\.4 abc +--- abc ${RFCDATE} 1\.4 ++++ abc ${RFCDATE} +@@ -2,4 +2,4 @@ + two + three + four +-seven ++seven +\\\\ No newline at end of file" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + death) + # next dive. test death support. + + # NOTE: this section has reached the size and + # complexity where it is getting to be a good idea to + # add new death support tests to a new section rather + # than continuing to piggyback them onto the tests here. + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest death-init-1 "$testcvs -Q co first-dir" + + cd first-dir + + # Create a directory with only dead files, to make sure CVS + # doesn't get confused by it. + mkdir subdir + dotest 65a0 "${testcvs} add subdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" + cd subdir + echo file in subdir >sfile + dotest 65a1 "${testcvs} add sfile" \ +"${SPROG}"' add: scheduling file `sfile'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest 65a2 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/subdir/sfile,v <-- sfile +initial revision: 1\.1" + rm sfile + dotest 65a3 "${testcvs} rm sfile" \ +"${SPROG}"' remove: scheduling `sfile'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove this file permanently' + dotest 65a4 "${testcvs} -q ci -m remove-it" \ +"$CVSROOT_DIRNAME/first-dir/subdir/sfile,v <-- sfile +new revision: delete; previous revision: 1\.1" + cd .. + dotest 65a5 "${testcvs} -q update -P" '' + dotest_fail 65a6 "test -d subdir" '' + + # add a file. + touch file1 + if ${CVS} add file1 2>> ${LOGFILE}; then + pass 66 + else + fail 66 + fi + + # commit + if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then + pass 67 + else + fail 67 + fi + + # remove + rm file1 + if ${CVS} rm file1 2>> ${LOGFILE}; then + pass 68 + else + fail 68 + fi + + # commit + if ${CVS} ci -m test >>${LOGFILE} ; then + pass 69 + else + fail 69 + fi + + dotest_fail 69a0 "test -f file1" '' + # get the old contents of file1 back + if ${testcvs} update -p -r 1.1 file1 >file1 2>>${LOGFILE}; then + pass 69a1 + else + fail 69a1 + fi + dotest 69a2 "cat file1" '' + + # create second file + touch file2 + if ${CVS} add file1 file2 2>> ${LOGFILE}; then + pass 70 + else + fail 70 + fi + + # commit + if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then + pass 71 + else + fail 71 + fi + + # log + if ${CVS} log file1 >> ${LOGFILE}; then + pass 72 + else + fail 72 + fi + + # file4 will be dead at the time of branching and stay dead. + echo file4 > file4 + dotest death-file4-add "${testcvs} add file4" \ +"${SPROG}"' add: scheduling file `file4'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest death-file4-ciadd "${testcvs} -q ci -m add file4" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +initial revision: 1\.1" + rm file4 + dotest death-file4-rm "${testcvs} remove file4" \ +"${SPROG}"' remove: scheduling `file4'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove this file permanently' + dotest death-file4-cirm "${testcvs} -q ci -m remove file4" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.1" + + # Tag the branchpoint. + dotest death-72a "${testcvs} -q tag bp_branch1" 'T file1 +T file2' + + # branch1 + if ${CVS} tag -b branch1 ; then + pass 73 + else + fail 73 + fi + + # and move to the branch. + if ${CVS} update -r branch1 ; then + pass 74 + else + fail 74 + fi + + dotest_fail death-file4-3 "test -f file4" '' + + # add a file in the branch + echo line1 from branch1 >> file3 + if ${CVS} add file3 2>> ${LOGFILE}; then + pass 75 + else + fail 75 + fi + + # commit + if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then + pass 76 + else + fail 76 + fi + + dotest death-76a0 \ +"${testcvs} -q rdiff -r bp_branch1 -r branch1 first-dir" \ +"Index: first-dir/file3 +diff -c /dev/null first-dir/file3:1\.1\.2\.1 +\*\*\* /dev/null ${DATE} +--- first-dir/file3 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} line1 from branch1" + dotest death-76a1 \ +"${testcvs} -q rdiff -r branch1 -r bp_branch1 first-dir" \ +"Index: first-dir/file3 +diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed +\*\*\* first-dir/file3:1\.1\.2\.1 ${DATE} +--- first-dir/file3 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- line1 from branch1 +--- 0 ----" + + # remove + rm file3 + if ${CVS} rm file3 2>> ${LOGFILE}; then + pass 77 + else + fail 77 + fi + + # commit + if ${CVS} ci -m test >>${LOGFILE} ; then + pass 78 + else + fail 78 + fi + + # add again + echo line1 from branch1 >> file3 + if ${CVS} add file3 2>> ${LOGFILE}; then + pass 79 + else + fail 79 + fi + + # commit + if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then + pass 80 + else + fail 80 + fi + + # change the first file + echo line2 from branch1 >> file1 + + # commit + if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then + pass 81 + else + fail 81 + fi + + # remove the second + rm file2 + if ${CVS} rm file2 2>> ${LOGFILE}; then + pass 82 + else + fail 82 + fi + + # commit + if ${CVS} ci -m test >>${LOGFILE}; then + pass 83 + else + fail 83 + fi + + # back to the trunk. + if ${CVS} update -A 2>> ${LOGFILE}; then + pass 84 + else + fail 84 + fi + + dotest_fail death-file4-4 "test -f file4" '' + + if test -f file3 ; then + fail 85 + else + pass 85 + fi + + # join + dotest death-86 "$testcvs -q update -j branch1" \ +"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v +retrieving revision 1\.3 +retrieving revision 1\.3\.2\.1 +Merging differences between 1\.3 and 1\.3\.2\.1 into file1 +${SPROG} update: scheduling \`file2' for removal +U file3" + + dotest_fail death-file4-5 "test -f file4" '' + + if test -f file3 ; then + pass 87 + else + fail 87 + fi + + # Make sure that we joined the correct change to file1 + if echo line2 from branch1 | cmp - file1 >/dev/null; then + pass 87a + else + fail 87a + fi + + # update + if ${CVS} update ; then + pass 88 + else + fail 88 + fi + + # commit + dotest 89 "${testcvs} -q ci -m test" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +new revision: 1\.2; previous revision: 1\.1" + cd .. + mkdir 2 + cd 2 + dotest 89a "${testcvs} -q co first-dir" 'U first-dir/file1 +U first-dir/file3' + cd .. + rm -r 2 + cd first-dir + + # remove first file. + rm file1 + if ${CVS} rm file1 2>> ${LOGFILE}; then + pass 90 + else + fail 90 + fi + + # commit + if ${CVS} ci -m test >>${LOGFILE}; then + pass 91 + else + fail 91 + fi + + if test -f file1 ; then + fail 92 + else + pass 92 + fi + + # typo; try to get to the branch and fail + dotest_fail 92.1a "$testcvs update -r brnach1" \ + "$SPROG \[update aborted\]: no such tag \`brnach1'" + # Make sure we are still on the trunk + if test -f file1 ; then + fail 92.1b + else + pass 92.1b + fi + if test -f file3 ; then + pass 92.1c + else + fail 92.1c + fi + + # back to branch1 + if ${CVS} update -r branch1 2>> ${LOGFILE}; then + pass 93 + else + fail 93 + fi + + dotest_fail death-file4-6 "test -f file4" '' + + if test -f file1 ; then + pass 94 + else + fail 94 + fi + + # and join + dotest 95 "${testcvs} -q update -j HEAD" \ +"${SPROG}"' update: file file1 has been modified, but has been removed in revision HEAD +'"${SPROG}"' update: file file3 exists, but has been added in revision HEAD' + + dotest_fail death-file4-7 "test -f file4" '' + + # file2 should not have been recreated. It was + # deleted on the branch, and has not been modified on + # the trunk. That means that there have been no + # changes between the greatest common ancestor (the + # trunk version) and HEAD. + dotest_fail death-file2-1 "test -f file2" '' + + dokeep + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + death2) + # More tests of death support. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest death2-1 "$testcvs -q co first-dir" + + cd first-dir + + # Add two files on the trunk. + echo "first revision" > file1 + echo "file4 first revision" > file4 + dotest death2-2 "${testcvs} add file1 file4" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: scheduling file `file4'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + + dotest death2-3 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +initial revision: 1\.1" + + # Make a branch and a non-branch tag. + dotest death2-4 "${testcvs} -q tag -b branch" \ +'T file1 +T file4' + dotest death2-5 "${testcvs} -q tag tag" \ +'T file1 +T file4' + + # Switch over to the branch. + dotest death2-6 "${testcvs} -q update -r branch" '' + + # Delete the file on the branch. + rm file1 + dotest death2-7 "${testcvs} rm file1" \ +"${SPROG} remove: scheduling .file1. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + + # Test diff of the removed file before it is committed. + dotest_fail death2-diff-1 "${testcvs} -q diff file1" \ +"${SPROG} diff: file1 was removed, no comparison available" + + dotest_fail death2-diff-2 "${testcvs} -q diff -N -c file1" \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* file1 ${RFCDATE} [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- first revision +--- 0 ----" + + dotest death2-8 "${testcvs} -q ci -m removed" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.1" + + # Test diff of a dead file. + dotest_fail death2-diff-3 \ +"${testcvs} -q diff -r1.1 -rbranch -c file1" \ +"${SPROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\. +${SPROG} diff: No comparison available\. Pass .-N. to .${SPROG} diff.${QUESTION}" + # and in reverse + dotest_fail death2-diff-3a \ +"${testcvs} -q diff -rbranch -r1.1 -c file1" \ +"${SPROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\. +${SPROG} diff: No comparison available\. Pass .-N. to .${SPROG} diff.${QUESTION}" + + dotest_fail death2-diff-4 \ +"${testcvs} -q diff -r1.1 -rbranch -N -c file1" \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* file1 ${RFCDATE} [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- first revision +--- 0 ----" + # and in reverse + dotest_fail death2-diff-4a \ +"${testcvs} -q diff -rbranch -r1.1 -N -c file1" \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file1 ${RFCDATE} [0-9.]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- ++ first revision" + + + dotest_fail death2-diff-5 "${testcvs} -q diff -rtag -c ." \ +"${SPROG} diff: file1 no longer exists, no comparison available" + + dotest_fail death2-diff-6 "${testcvs} -q diff -rtag -N -c ." \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* file1 [-a-zA-Z0-9: ]* [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- first revision +--- 0 ----" + + # Test rdiff of a dead file. + dotest death2-rdiff-1 \ +"${testcvs} -q rtag -rbranch rdiff-tag first-dir" '' + + dotest death2-rdiff-2 "${testcvs} -q rdiff -rtag -rbranch first-dir" \ +"Index: first-dir/file1 +diff -c first-dir/file1:1\.1 first-dir/file1:removed +\*\*\* first-dir/file1:1\.1 [a-zA-Z0-9: ]* +--- first-dir/file1 [a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- first revision +--- 0 ----" + + # Readd the file to the branch. + echo "second revision" > file1 + dotest death2-9 "${testcvs} add file1" \ +"${SPROG} add: Re-adding file \`file1' on branch \`branch' after dead revision 1\.1\.2\.1\. +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + + # Test diff of the added file before it is committed. + dotest_fail death2-diff-7 "${testcvs} -q diff file1" \ +"${SPROG} diff: file1 is a new entry, no comparison available" + + dotest_fail death2-diff-8 "${testcvs} -q diff -N -c file1" \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file1 ${RFCDATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} second revision" + + dotest death2-10 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + + # Delete file4 from the branch + dotest death2-10a "${testcvs} rm -f file4" \ +"${SPROG} remove: scheduling .file4. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest death2-10b "${testcvs} -q ci -m removed" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.1" + + # Back to the trunk. + dotest death2-11 "${testcvs} -q update -A" \ +"[UP] file1 +U file4" + + # Add another file on the trunk. + echo "first revision" > file2 + dotest death2-12 "${testcvs} add file2" \ +"${SPROG}"' add: scheduling file `file2'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest death2-13 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + + # Modify file4 on the trunk. + echo "new file4 revision" > file4 + dotest death2-13a "${testcvs} -q commit -m mod" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.2; previous revision: 1\.1" + + # Back to the branch. + # The ``no longer in the repository'' message doesn't really + # look right to me, but that's what CVS currently prints for + # this case. + dotest death2-14 "${testcvs} -q update -r branch" \ +"[UP] file1 +${SPROG} update: \`file2' is no longer in the repository +${SPROG} update: \`file4' is no longer in the repository" + + # Add a file on the branch with the same name. + echo "branch revision" > file2 + dotest death2-15 "${testcvs} add file2" \ +"${SPROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest death2-16 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + + # Add a new file on the branch. + echo "first revision" > file3 + dotest death2-17 "${testcvs} add file3" \ +"${SPROG}"' add: scheduling file `file3'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest death2-18 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/Attic/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # Test diff of a nonexistent tag + dotest_fail death2-diff-9 "$testcvs -q diff -rtag -c file3" \ +"$SPROG diff: tag tag is not in file file3" + + dotest_fail death2-diff-10 "${testcvs} -q diff -rtag -N -c file3" \ +"Index: file3 +=================================================================== +RCS file: file3 +diff -N file3 +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file3 ${RFCDATE} [0-9.]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} first revision" + + dotest_fail death2-diff-11 "${testcvs} -q diff -rtag -c ." \ +"Index: file1 +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.2 +diff -c -r1\.1 -r1\.1\.2\.2 +\*\*\* file1 ${RFCDATE} [0-9.]* +--- file1 ${RFCDATE} [0-9.]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +! first revision +--- 1 ---- +! second revision +${SPROG} diff: tag tag is not in file file2 +${SPROG} diff: tag tag is not in file file3 +${SPROG} diff: file4 no longer exists, no comparison available" + + dotest_fail death2-diff-12 "${testcvs} -q diff -rtag -c -N ." \ +"Index: file1 +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.2 +diff -c -r1\.1 -r1\.1\.2\.2 +\*\*\* file1 ${RFCDATE} [0-9.]* +--- file1 ${RFCDATE} [0-9.]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +! first revision +--- 1 ---- +! second revision +Index: file2 +=================================================================== +RCS file: file2 +diff -N file2 +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file2 ${RFCDATE} [0-9.]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} branch revision +Index: file3 +=================================================================== +RCS file: file3 +diff -N file3 +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file3 ${RFCDATE} [0-9.]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} first revision +Index: file4 +=================================================================== +RCS file: file4 +diff -N file4 +\*\*\* file4 ${RFCDATE} [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file4 first revision +--- 0 ----" + + # Switch to the nonbranch tag. + dotest death2-19 "${testcvs} -q update -r tag" \ +"[UP] file1 +${SPROG} update: \`file2' is no longer in the repository +${SPROG} update: \`file3' is no longer in the repository +U file4" + + dotest_fail death2-20 "test -f file2" + + # Make sure diff only reports appropriate files. + dotest_fail death2-diff-13 "${testcvs} -q diff -r rdiff-tag" \ +"${SPROG} diff: Tag rdiff-tag refers to a dead (removed) revision in file .file1.\. +${SPROG} diff: No comparison available\. Pass .-N. to .${SPROG} diff.${QUESTION}" + + dotest_fail death2-diff-14 "${testcvs} -q diff -r rdiff-tag -c -N" \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file1 ${RFCDATE} [0-9.]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} first revision" + + # now back to the trunk + dotest death2-21 "${testcvs} -q update -A" \ +"U file2 +[UP] file4" + + # test merging with a dead file + dotest death2-22 "${testcvs} -q co first-dir" \ +"U first-dir/file1 +U first-dir/file2 +U first-dir/file4" + + cd first-dir + dotest death2-23 "${testcvs} rm -f file4" \ +"${SPROG} remove: scheduling .file4. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest death2-24 "${testcvs} -q ci -m removed file4" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.2" + cd .. + echo "new stuff" >file4 + dotest_fail death2-25 "${testcvs} up file4" \ +"${SPROG} update: conflict: \`file4' is modified but no longer in the repository +C file4" + + dokeep + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + rm-update-message) + # FIXME + # local CVS prints a warning message when update notices a missing + # file and client/server CVS doesn't. These should be identical. + mkdir rm-update-message; cd rm-update-message + modify_repo mkdir $CVSROOT_DIRNAME/rm-update-message + dotest rm-update-message-setup-1 "$testcvs -q co rm-update-message" '' + cd rm-update-message + file=x + echo >$file + dotest rm-update-message-setup-2 "$testcvs -q add $file" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest rm-update-message-setup-3 "$testcvs -q ci -mcreate $file" \ +"$CVSROOT_DIRNAME/rm-update-message/$file,v <-- $file +initial revision: 1\.1" + + rm $file + dotest rm-update-message-1 "$testcvs up $file" \ +"${SPROG} update: warning: \`$file' was lost +U $file" + + dokeep + cd ../.. + rm -r rm-update-message + modify_repo rm -rf $CVSROOT_DIRNAME/rm-update-message + ;; + + + + rmadd) + # More tests of adding and removing files. + # In particular ci -r. + # Other ci -r tests: + # * editor-9: checking in a modified file, + # where "ci -r" means a branch. + # * basica-8a1: checking in a modified file with numeric revision. + # * basica-8a2: likewise. + # * keywordlog-4: adding a new file with numeric revision. + mkdir 1; cd 1 + dotest rmadd-1 "$testcvs -q co -l ." + mkdir first-dir + dotest rmadd-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo first file1 >file1 + dotest rmadd-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + + dotest_fail rmadd-4 "${testcvs} -q ci -r 1.2.2.4 -m add" \ +"${SPROG} commit: cannot add file .file1' with revision .1\.2\.2\.4'; must be on trunk +${SPROG} \[commit aborted\]: correct above errors first!" + dotest_fail rmadd-5 "${testcvs} -q ci -r 1.2.2 -m add" \ +"${SPROG} commit: cannot add file .file1' with revision .1\.2\.2'; must be on trunk +${SPROG} \[commit aborted\]: correct above errors first!" + dotest_fail rmadd-6 "$testcvs -q ci -r mybranch -m add" \ +"$SPROG \[commit aborted\]: no such tag \`mybranch'" + + # The thing with the trailing periods strikes me as a very + # bizarre behavior, but it would seem to be intentional + # (see commit.c). It probably could go away.... + dotest rmadd-7 "${testcvs} -q ci -r 7.... -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 7\.1" + if $remote; then + # I guess remote doesn't set a sticky tag in this case. + # Kind of odd, in the sense that rmadd-24a does set one + # both local and remote. + dotest_fail rmadd-7a "test -f CVS/Tag" + echo T7 >CVS/Tag + else + dotest rmadd-7a "cat CVS/Tag" "T7" + fi + + dotest rmadd-8 "${testcvs} -q tag -b mybranch" "T file1" + dotest rmadd-9 "${testcvs} -q tag mynonbranch" "T file1" + + touch file2 + # The previous "cvs ci -r" set a sticky tag of '7'. Seems a + # bit odd, and I guess commit.c (findmaxrev) makes '7' sticky + # tags unnecessary (?). I kind of suspect that it should be + # saying "sticky tag is not a branch" like keywordlog-4b. + # Or something. + dotest rmadd-10 "${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition on branch .7' +${SPROG} add: use .${SPROG} commit. to add this file permanently" + # As in the previous example, CVS is confused.... + dotest rmadd-11 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 7\.1" + + dotest rmadd-12 "${testcvs} -q update -A" "" + touch file3 + dotest rmadd-13 "${testcvs} add file3" \ +"${SPROG} add: scheduling file .file3. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + # Huh? file2 is not up to date? Seems buggy to me.... + dotest_fail rmadd-14 "${testcvs} -q ci -r mybranch -m add" \ +"${SPROG} commit: Up-to-date check failed for .file2' +${SPROG} \[commit aborted\]: correct above errors first!" + # Whatever, let's not let file2 distract us.... + dotest rmadd-15 "${testcvs} -q ci -r mybranch -m add file3" \ +"$CVSROOT_DIRNAME/first-dir/Attic/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + touch file4 + dotest rmadd-16 "${testcvs} add file4" \ +"${SPROG} add: scheduling file .file4. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + # Prior to CVS 1.12.10, this would fail with a, "no such tag" message + # since val-tags used to be updated the first time the tag was used + # rather than when it was created. + + # Try to make CVS write val-tags. + if $proxy; then :; else + # First remove the tag. + grep -v mynonbranch $CVSROOT_DIRNAME/CVSROOT/val-tags \ + >$CVSROOT_DIRNAME/CVSROOT/val-tags-tmp + mv $CVSROOT_DIRNAME/CVSROOT/val-tags-tmp \ + $CVSROOT_DIRNAME/CVSROOT/val-tags + + dotest rmadd-18 "$testcvs -q update -p -r mynonbranch file1" \ +"first file1" + # Oops, -p suppresses writing val-tags (probably a questionable + # behavior). + dotest_fail rmadd-19 \ +"$testcvs -q ci -r mynonbranch -m add file4" \ +"$SPROG \[commit aborted\]: no such tag \`mynonbranch'" + # Now make CVS write val-tags for real. + dotest rmadd-20 "$testcvs -q update -r mynonbranch file1" + fi # !$proxy + + # Oops - CVS isn't distinguishing between a branch tag and + # a non-branch tag. + dotest rmadd-21 \ +"${testcvs} -q ci -r mynonbranch -m add file4" \ +"$CVSROOT_DIRNAME/first-dir/Attic/file4,v <-- file4 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # OK, we add this one in a vanilla way, but then check in + # a modification with ci -r and sniff around for sticky tags. + echo file5 >file5 + dotest rmadd-22 "${testcvs} add file5" \ +"${SPROG} add: scheduling file .file5. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + if $remote; then + # Interesting bug (or missing feature) here. findmaxrev + # gets the major revision from the Entries. Well, remote + # doesn't send the entries for files which are not involved. + dotest rmadd-23r "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +initial revision: 1\.1" + dotest rmadd-23-workaroundr \ +"${testcvs} -q ci -r 7 -m bump-it file5" \ +"$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +new revision: 7\.1; previous revision: 1\.1" + else + dotest rmadd-23 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +initial revision: 7\.1" + fi + echo change it >file5 + dotest_fail rmadd-24 "$testcvs -q ci -r 4.8 -m change file5" \ +"$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +$SPROG commit: $CVSROOT_DIRNAME/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1 +$SPROG commit: could not check in file5" + dotest rmadd-24a "${testcvs} -q ci -r 8.4 -m change file5" \ +"$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +new revision: 8\.4; previous revision: 7\.1" + # I'm not really sure that a sticky tag make sense here. + # It seems to be longstanding behavior for what that is worth. + dotest rmadd-25 "${testcvs} status file5" \ +"=================================================================== +File: file5 Status: Up-to-date + + Working revision: 8\.4.* + Repository revision: 8\.4 ${CVSROOT_DIRNAME}/first-dir/file5,v + Commit Identifier: ${commitid} + Sticky Tag: 8\.4 + Sticky Date: (none) + Sticky Options: (none)" + + # now try forced revision with recursion + mkdir sub + dotest rmadd-26 "${testcvs} -q add sub" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sub added to the repository" + echo hello >sub/subfile + dotest rmadd-27 "${testcvs} -q add sub/subfile" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + + dotest rmadd-28 "${testcvs} -q ci -m. sub" \ +"$CVSROOT_DIRNAME/first-dir/sub/subfile,v <-- sub/subfile +initial revision: 1\.1" + + # lose the branch + dotest rmadd-29 "${testcvs} -q up -A" \ +"${SPROG} update: \`file3' is no longer in the repository +${SPROG} update: \`file4' is no longer in the repository" + + # -f disables recursion + dotest rmadd-30 "${testcvs} -q ci -f -r9 -m." \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 9\.1; previous revision: 7\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 9\.1; previous revision: 7\.1 +$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +new revision: 9\.1; previous revision: 8\.4" + + # add -R to force recursion + dotest rmadd-31 "${testcvs} -q ci -f -r9 -R -m." \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 9\.2; previous revision: 9\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 9\.2; previous revision: 9\.1 +$CVSROOT_DIRNAME/first-dir/file5,v <-- file5 +new revision: 9\.2; previous revision: 9\.1 +$CVSROOT_DIRNAME/first-dir/sub/subfile,v <-- sub/subfile +new revision: 9\.1; previous revision: 1\.1" + + if $remote; then + # as noted above, remote doesn't set a sticky tag + : + else + dotest rmadd-32 "cat CVS/Tag" "T9" + dotest rmadd-33 "cat sub/CVS/Tag" "T9" + fi + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + rmadd2) + # Tests of undoing commits, including in the presence of + # adding and removing files. See join for a list of -j tests. + mkdir 1; cd 1 + dotest rmadd2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest rmadd2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo 'initial contents' >file1 + dotest rmadd2-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest rmadd2-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + dotest rmadd2-4a "${testcvs} -Q tag tagone" "" + dotest rmadd2-5 "${testcvs} rm -f file1" \ +"${SPROG} remove: scheduling .file1. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest rmadd2-6 "${testcvs} -q ci -m remove" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.1" + dotest rmadd2-7 "$testcvs -q update -j 1.2 -j 1.1 file1" "U file1" + dotest rmadd2-8 "${testcvs} -q ci -m readd" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + echo 'new contents' >file1 + dotest rmadd2-9 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3" + dotest rmadd2-10 "${testcvs} -q update -j 1.4 -j 1.3 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.4 +retrieving revision 1\.3 +Merging differences between 1\.4 and 1\.3 into file1" + dotest rmadd2-11 "${testcvs} -q ci -m undo" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4" + dotest rmadd2-12 "cat file1" "initial contents" + dotest rmadd2-13 "${testcvs} -q update -p -r 1.3" "initial contents" + + # Hmm, might be a bit odd that this works even if 1.3 is not + # the head. + dotest rmadd2-14 "${testcvs} -q update -j 1.3 -j 1.2 file1" \ +"${SPROG} update: scheduling \`file1' for removal" + + # Check that -p can get arbitrary revisions of a removed file + dotest rmadd2-14a "${testcvs} -q update -p" "initial contents" + dotest rmadd2-14b "${testcvs} -q update -p -r 1.5" "initial contents" + dotest rmadd2-14c "${testcvs} -q update -p -r 1.3" "initial contents" + + dotest rmadd2-15 "${testcvs} -q ci -m re-remove" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.5" + dotest rmadd2-16 "${testcvs} log -h file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +Working file: file1 +head: 1\.6 +branch: +locks: strict +access list: +symbolic names: + tagone: 1\.1 +keyword substitution: kv +total revisions: 6 +=============================================================================" + dotest rmadd2-17 "${testcvs} status -v file1" \ +"=================================================================== +File: no file file1 Status: Up-to-date + + Working revision: No entry for file1 + Repository revision: 1\.6 ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v + Commit Identifier: ${commitid} + + Existing Tags: + tagone (revision: 1.1)" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + rmadd3) + # This test demonstrates that CVS notices that file1 exists rather + # that deleting or writing over it after: + # + # cvs remove -f file1; touch file1; cvs add file1. + # + # According to the manual, this should work for: + # + # rm file1; cvs remove file1; cvs add file1 + # + # but in past version of CVS, new content in file1 would be + # erroneously deleted when file1 reappeared between the remove and + # the add. + # + # Later versions of CVS would refuse to perform the add, but still + # allow a subsequent local commit to erase the file from the + # workspace, possibly losing data. + mkdir 1; cd 1 + dotest rmadd3-init1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest rmadd3-init2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + echo initial content for file1 >file1 + dotest rmadd3-init3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file \`file1' for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + dotest rmadd3-init4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + # Here begins the guts of this test, as detailed above. + dotest rmadd3-1 "${testcvs} rm -f file1" \ +"${SPROG} remove: scheduling \`file1' for removal +${SPROG} remove: use \`${SPROG} commit' to remove this file permanently" + + # Now recreate the file: + echo desired future contents for file1 >file1 + + # And attempt to resurrect it at the same time: + dotest_fail rmadd3-2 "${testcvs} add file1" \ +"${SPROG} add: \`file1' should be removed and is still there (or is back again)" + + # Now prove that commit knows that it shouldn't erase files. + dotest_fail rmadd3-3 "${testcvs} -q ci -m." \ +"$CPROG commit: \`file1' should be removed and is still there (or is back again) +$CPROG \[commit aborted\]: correct above errors first!" + + # Then these should pass too: + dotest rmadd3-4 "test -f file1" + dotest rmadd3-5 "cat file1" "desired future contents for file1" + + if $keep; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + resurrection) + # This test tests a few file resurrection scenarios. + mkdir 1; cd 1 + dotest resurrection-init1 "$testcvs -q co -l ." '' + mkdir first-dir + dotest resurrection-init2 "$testcvs add first-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir added to the repository" + cd first-dir + + echo initial content for file1 >file1 + dotest resurrection-init3 "$testcvs add file1" \ +"$SPROG add: scheduling file \`file1' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + dotest resurrection-init4 "$testcvs -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + dotest resurrection-init5 "$testcvs -Q rm -f file1" + + # The first test is that `cvs add' will resurrect a file before its + # removal has been committed. + dotest_sort resurrection-1 "$testcvs add file1" \ +"U file1 +$SPROG add: \`file1', version 1\.1, resurrected" + dotest resurrection-2 "$testcvs -Q diff file1" "" + + dotest resurrection-init6 "$testcvs -Q tag -b resurrection" + dotest resurrection-init7 "$testcvs -Q rm -f file1" + dotest resurrection-init8 "$testcvs -Q ci -mrm" + + # The next test is that CVS will resurrect a committed removal. + dotest_sort resurrection-3 "$testcvs add file1" \ +"U file1 +$SPROG add: Re-adding file \`file1' after dead revision 1\.2\. +$SPROG add: Resurrecting file \`file1' from revision 1\.1\. +$SPROG add: use \`$SPROG commit' to add this file permanently" + dotest resurrection-4 "$testcvs -q diff -r1.1 file1" "" + dotest resurrection-5 "$testcvs -q ci -mreadd" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + + dotest resurrection-init9 "$testcvs -Q up -rresurrection" + dotest resurrection-init10 "$testcvs -Q rm -f file1" + dotest resurrection-init11 "$testcvs -Q ci -mrm-on-resurrection" + + # The next test is that CVS will resurrect a committed removal to a + # branch. + dotest_sort resurrection-6 "$testcvs -r add file1" \ +"U file1 +$SPROG add: Re-adding file \`file1' on branch \`resurrection' after dead revision 1\.1\.2\.1\. +$SPROG add: Resurrecting file \`file1' from revision 1\.1\. +$SPROG add: use \`$SPROG commit' to add this file permanently" + # If the file is modified, it had better be read-write + # regardless of what the user has requested with the CVSREAD + # environment variable or the global -r switch + dotest resurrection-6b 'test -w file1' '' + dotest resurrection-7 "$testcvs -Q diff -r1.1 file1" "" + dotest resurrection-8 "$testcvs -q ci -mreadd" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + + # The next few tests verify that an attempted resurrection of a file + # with no previous revision on the trunk fails. + touch file2 + dotest resurrection-9 "$testcvs -Q add file2" + dotest resurrection-10 "$testcvs -Q ci -mnew-file2" + dotest resurrection-11 "$testcvs -Q up -A" + + # This command once caused an assertion failure. + dotest resurrection-12 "$testcvs add file2" \ +"$SPROG add: File \`file2' has no previous revision to resurrect\." + + # Check what 'cvs -r add' does with resurrected files. + dotest resurrection-13 "$testcvs -Q rm -f file1" + dotest_sort resurrection-14 "$testcvs -r add file1" \ +"U file1 +$SPROG add: \`file1', version 1\.3, resurrected" + dotest_fail resurrection-15 'test -w file1' '' + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + dirs) + # Tests related to removing and adding directories. + # See also: + # conflicts (especially dir1 in conflicts-130): What happens if + # directory exists in repository and a non-CVS-controlled + # directory in the working directory? + # conflicts3-15. More cases, especially where CVS directory + # exists but without CVS/Repository and friends. + # conflicts3-22. Similar to conflicts-130 but there is a file + # in the directory. + # dirs2. Sort of similar to conflicts3-22 but somewhat different. + mkdir imp-dir; cd imp-dir + echo file1 >file1 + mkdir sdir + echo sfile >sdir/sfile + dotest_sort dirs-1 \ +"${testcvs} import -m import-it dir1 vend rel" " + +N dir1/file1 +N dir1/sdir/sfile +No conflicts created by this import +${SPROG} import: Importing ${CVSROOT_DIRNAME}/dir1/sdir" + cd .. + + mkdir 1; cd 1 + dotest dirs-2 "$testcvs -Q co dir1" "" + + # Various CVS administrators are in the habit of removing + # the repository directory for things they don't want any + # more. I've even been known to do it myself (on rare + # occasions). Not the usual recommended practice, but we want + # to try to come up with some kind of reasonable/documented/sensible + # behavior. + modify_repo rm -rf $CVSROOT_DIRNAME/dir1/sdir + + dotest dirs-3 "${testcvs} update" \ +"${SPROG} update: Updating dir1 +${SPROG} update: Updating dir1/sdir +${SPROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory +${SPROG} update: skipping directory dir1/sdir" + dotest dirs-3a "${testcvs} update -d" \ +"${SPROG} update: Updating dir1 +${SPROG} update: Updating dir1/sdir +${SPROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory +${SPROG} update: skipping directory dir1/sdir" + + # If we say "yes", then CVS gives errors about not being able to + # create lock files. + # The fact that it says "skipping directory " rather than + # "skipping directory dir1/sdir" is some kind of bug. + dotest dirs-4 "echo no | ${testcvs} release -d dir1/sdir" \ +"${SPROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory +${SPROG} update: skipping directory +You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .dir1/sdir': .. .release' aborted by user choice." + + # OK, if "cvs release" won't help, we'll try it the other way... + rm -r dir1/sdir + + dotest dirs-5 "cat dir1/CVS/Entries" \ +"/file1/1.1.1.1/[a-zA-Z0-9 :]*// +D/sdir////" + dotest dirs-6 "${testcvs} update" "${SPROG} update: Updating dir1" + dotest dirs-7 "cat dir1/CVS/Entries" \ +"/file1/1.1.1.1/[a-zA-Z0-9 :]*// +D/sdir////" + dotest dirs-8 "${testcvs} update -d dir1" \ +"${SPROG} update: Updating dir1" + + dokeep + cd .. + rm -r imp-dir 1 + modify_repo rm -rf $CVSROOT_DIRNAME/dir1 + ;; + + + + dirs2) + # See "dirs" for a list of tests involving adding and + # removing directories. + mkdir 1; cd 1 + dotest dirs2-1 "$testcvs -q co -l ." + mkdir first-dir + dotest dirs2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + mkdir sdir + dotest dirs2-3 "${testcvs} add sdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" + touch sdir/file1 + dotest dirs2-4 "${testcvs} add sdir/file1" \ +"${SPROG} add: scheduling file .sdir/file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest dirs2-5 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/sdir/file1,v <-- sdir/file1 +initial revision: 1\.1" + rm -r sdir/CVS + if $remote; then + # This is just like conflicts3-23 + dotest_fail dirs2-6r "${testcvs} update -d" \ +"${QUESTION} sdir +${SPROG} update: Updating \. +${SPROG} update: Updating sdir +${CPROG} update: move away \`sdir/file1'; it is in the way +C sdir/file1" + rm sdir/file1 + rm -r sdir/CVS + + # This is where things are not just like conflicts3-23 + dotest dirs2-7r "${testcvs} update -d" \ +"${QUESTION} sdir +${SPROG} update: Updating \. +${SPROG} update: Updating sdir +U sdir/file1" + else + dotest dirs2-6 "${testcvs} update -d" \ +"${CPROG} update: Updating \. +${QUESTION} sdir" + rm sdir/file1 + dotest dirs2-7 "${testcvs} update -d" \ +"${CPROG} update: Updating \. +${QUESTION} sdir" + fi + cd ../.. + + # Now, the same thing (more or less) on a branch. + mkdir 2; cd 2 + dotest dirs2-8 "${testcvs} -q co first-dir" 'U first-dir/sdir/file1' + cd first-dir + dotest dirs2-9 "${testcvs} -q tag -b br" "T sdir/file1" + rm -r sdir/CVS + + if $remote; then + # val-tags used to have a cute little quirk; if an update didn't + # recurse into the directories where the tag is defined, val-tags + # wouldn't get updated. This is no longer a problem as of 1.12.10. + dotest_fail dirs2-10-againr "$testcvs update -d -r br" \ +"$QUESTION sdir +$SPROG update: Updating \. +$SPROG update: Updating sdir +$CPROG update: move away \`sdir/file1'; it is in the way +C sdir/file1" + else + dotest dirs2-10 "${testcvs} update -d -r br" \ +"$SPROG update: Updating \. +$QUESTION sdir" +# This is what used to happen. I'm not sure why it changed with 1.12.10, but +# as near as I can tell from the comments in update_direntproc, the new +# behavior was the intended behavior. +#"$CPROG update: in directory \`sdir': +#$CPROG \[update aborted\]: there is no version here; do \`$CPROG checkout' first" + fi + cd ../.. + + # OK, the above tests make the situation somewhat harder + # than it might be, in the sense that they actually have a + # file which is alive on the branch we are updating. Let's + # try it where it is just a directory where all the files + # have been removed. + mkdir 3; cd 3 + dotest dirs2-11 "${testcvs} -q co -r br first-dir" \ +"U first-dir/sdir/file1" + cd first-dir + # Hmm, this doesn't mention the branch like add does. That's + # an odd non-orthogonality. + dotest dirs2-12 "${testcvs} rm -f sdir/file1" \ +"${SPROG} remove: scheduling .sdir/file1. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest dirs2-13 "${testcvs} -q ci -m remove" \ +"$CVSROOT_DIRNAME/first-dir/sdir/file1,v <-- sdir/file1 +new revision: delete; previous revision: 1\.1" + cd ../../2/first-dir + if $remote; then + dotest dirs2-14 "${testcvs} update -d -r br" \ +"${QUESTION} sdir/file1 +${SPROG} update: Updating \. +${SPROG} update: Updating sdir" + else + dotest dirs2-14 "${testcvs} update -d -r br" \ +"${CPROG} update: Updating \. +${QUESTION} sdir" + fi + + dokeep + cd ../.. + rm -r 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + branches) + # More branch tests, including branches off of branches + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest branches-1 "$testcvs -q co first-dir" + cd first-dir + echo 1:ancest >file1 + echo 2:ancest >file2 + echo 3:ancest >file3 + echo 4:trunk-1 >file4 + dotest branches-2 "${testcvs} add file1 file2 file3 file4" \ +"$SPROG add: scheduling file \`file1' for addition +$SPROG add: scheduling file \`file2' for addition +$SPROG add: scheduling file \`file3' for addition +$SPROG add: scheduling file \`file4' for addition +$SPROG add: use .$SPROG commit. to add these files permanently" + dotest branches-2a "$testcvs -n -q ci -m dont-commit" + dotest_lit branches-3 "$testcvs -q ci -m add-it" <<HERE +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1.1 +${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 +initial revision: 1.1 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 +initial revision: 1.1 +HERE + echo 4:trunk-2 >file4 + dotest branches-3.2 "${testcvs} -q ci -m trunk-before-branch" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.2; previous revision: 1\.1" + # The "cvs log file4" in test branches-14.3 will test that we + # didn't really add the tag. + dotest branches-3.3 "${testcvs} -qn tag dont-tag" \ +"T file1 +T file2 +T file3 +T file4" + # Modify this file before branching, to deal with the case where + # someone is hacking along, says "oops, I should be doing this on + # a branch", and only then creates the branch. + echo 1:br1 >file1 + dotest branches-4 "${testcvs} tag -b br1" "${SPROG}"' tag: Tagging \. +T file1 +T file2 +T file3 +T file4' + dotest branches-5 "${testcvs} update -r br1" \ +"${SPROG} update: Updating \. +M file1" + echo 2:br1 >file2 + echo 4:br1 >file4 + dotest branches-6 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.2\.2\.1; previous revision: 1\.2" + dotest branches-7 "${testcvs} -q tag -b brbr" 'T file1 +T file2 +T file3 +T file4' + dotest branches-8 "${testcvs} -q update -r brbr" '' + echo 1:brbr >file1 + echo 4:brbr >file4 + dotest branches-9 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1\.2\.1; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.2\.2\.1\.2\.1; previous revision: 1\.2\.2\.1" + dotest branches-10 "cat file1 file2 file3 file4" '1:brbr +2:br1 +3:ancest +4:brbr' + dotest branches-11 "${testcvs} -q update -r br1" \ +'[UP] file1 +[UP] file4' + dotest branches-12 "cat file1 file2 file3 file4" '1:br1 +2:br1 +3:ancest +4:br1' + echo 4:br1-2 >file4 + dotest branches-12.2 "${testcvs} -q ci -m change-on-br1" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1" + dotest branches-13 "${testcvs} -q update -A" '[UP] file1 +[UP] file2 +[UP] file4' + dotest branches-14 "cat file1 file2 file3 file4" '1:ancest +2:ancest +3:ancest +4:trunk-2' + echo 4:trunk-3 >file4 + dotest branches-14.2 \ + "${testcvs} -q ci -m trunk-change-after-branch" \ +"$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.3; previous revision: 1\.2" + dotest branches-14.3 "${testcvs} log file4" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v +Working file: file4 +head: 1\.3 +branch: +locks: strict +access list: +symbolic names: + brbr: 1\.2\.2\.1\.0\.2 + br1: 1\.2\.0\.2 +keyword substitution: kv +total revisions: 6; selected revisions: 6 +description: +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +trunk-change-after-branch +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +branches: 1\.2\.2; +trunk-before-branch +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +add-it +---------------------------- +revision 1\.2\.2\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +change-on-br1 +---------------------------- +revision 1\.2\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +branches: 1\.2\.2\.1\.2; +modify +---------------------------- +revision 1\.2\.2\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +modify +=============================================================================" + dotest_fail branches-14.4 \ + "${testcvs} diff -c -r 1.1 -r 1.3 file4" \ +"Index: file4 +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v +retrieving revision 1\.1 +retrieving revision 1\.3 +diff -c -r1\.1 -r1\.3 +\*\*\* file4 ${RFCDATE} 1\.1 +--- file4 ${RFCDATE} 1\.3 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +! 4:trunk-1 +--- 1 ---- +! 4:trunk-3" + dotest_fail branches-14.5 \ + "${testcvs} diff -c -r 1.1 -r 1.2.2.1 file4" \ +"Index: file4 +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v +retrieving revision 1\.1 +retrieving revision 1\.2\.2\.1 +diff -c -r1\.1 -r1\.2\.2\.1 +\*\*\* file4 ${RFCDATE} 1\.1 +--- file4 ${RFCDATE} 1\.2\.2\.1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +! 4:trunk-1 +--- 1 ---- +! 4:br1" + dotest branches-15 \ + "${testcvs} update -j 1.1.2.1 -j 1.1.2.1.2.1 file1" \ + "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1\.2\.1 +retrieving revision 1\.1\.2\.1\.2\.1 +Merging differences between 1\.1\.2\.1 and 1\.1\.2\.1\.2\.1 into file1 +rcsmerge: warning: conflicts during merge" + dotest branches-16 "cat file1" '<<<<<<< file1 +1:ancest +[=]====== +1:brbr +[>]>>>>>> 1\.1\.2\.1\.2\.1' + + dotest branches-o1 "${testcvs} -q admin -o ::brbr" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v +done" + + dokeep + cd .. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r first-dir + ;; + + + + branches2) + # More branch tests. + # Test that when updating a new subdirectory in a directory + # which was checked out on a branch, the new subdirectory is + # created on the appropriate branch. Test this when joining + # as well. + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir trunk; cd trunk + + # Create a file. + dotest branches2-1 "${testcvs} -q co first-dir" + cd first-dir + echo "file1 first revision" > file1 + dotest branches2-2 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest branches2-3 "${testcvs} commit -m add file1" \ +"${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + # Tag the file. + dotest branches2-4 "${testcvs} -q tag tag1" 'T file1' + + # Make two branches. + dotest branches2-5 "${testcvs} -q rtag -b -r tag1 b1 first-dir" '' + dotest branches2-6 "${testcvs} -q rtag -b -r tag1 b2 first-dir" '' + + # Create some files and a subdirectory on branch b1. + cd ../.. + mkdir b1; cd b1 + dotest branches2-7 "${testcvs} -q co -r b1 first-dir" \ +"U first-dir/file1" + cd first-dir + echo "file2 first revision" > file2 + dotest branches2-8 "${testcvs} add file2" \ +"${SPROG}"' add: scheduling file `file2'\'' for addition on branch `b1'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + mkdir dir1 + dotest branches2-9 "${testcvs} add dir1" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository +--> Using per-directory sticky tag "'`'"b1'" + echo "file3 first revision" > dir1/file3 + dotest branches2-10 "${testcvs} add dir1/file3" \ +"${SPROG}"' add: scheduling file `dir1/file3'\'' for addition on branch `b1'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest branches2-11 "${testcvs} -q ci -madd ." \ +"$CVSROOT_DIRNAME/first-dir/Attic/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir1/Attic/file3,v <-- dir1/file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # Check out the second branch, and update the working + # directory to the first branch, to make sure the right + # happens with dir1. + cd ../.. + mkdir b2; cd b2 + dotest branches2-12 "${testcvs} -q co -r b2 first-dir" \ +'U first-dir/file1' + cd first-dir + dotest branches2-13 "${testcvs} update -d -r b1 dir1" \ +"${SPROG} update: Updating dir1 +U dir1/file3" + dotest branches2-14 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: b2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v + Commit Identifier: ${commitid} + Sticky Tag: b1 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + + # Test some calls to rls here because we can. These should probably + # be somewhere else, but we already have some directories set up. + dotest branches2-14-rls-1 "$testcvs rls" \ +"$SPROG rls: Listing module: \`.' +CVSROOT +first-dir" + dotest branches2-14-rls-2 "$testcvs rls -R" \ +"$SPROG rls: Listing module: \`.' +\.: +CVSROOT +first-dir + +CVSROOT: +checkoutlist +commitinfo +config +cvswrappers +loginfo +modules +notify +postadmin +postproxy +posttag +postwatch +preproxy +rcsinfo +taginfo +verifymsg +Emptydir + +CVSROOT/Emptydir: + +first-dir: +file1 +dir1 + +first-dir/dir1:" + dotest branches2-14-rls-3 "$testcvs rls -l -R" \ +"$SPROG rls: Listing module: \`.' +\.: +d--- $ISO8601DATE CVSROOT +d--- $ISO8601DATE first-dir + +CVSROOT: +---- $ISO8601DATE 1\.[0-9][0-9]* checkoutlist +---- $ISO8601DATE 1\.[0-9][0-9]* commitinfo +---- $ISO8601DATE 1\.[0-9][0-9]* config +---- $ISO8601DATE 1\.[0-9][0-9]* cvswrappers +---- $ISO8601DATE 1\.[0-9][0-9]* loginfo +---- $ISO8601DATE 1\.[0-9][0-9]* modules +---- $ISO8601DATE 1\.[0-9][0-9]* notify +---- $ISO8601DATE 1\.[0-9][0-9]* postadmin +---- $ISO8601DATE 1\.[0-9][0-9]* postproxy +---- $ISO8601DATE 1\.[0-9][0-9]* posttag +---- $ISO8601DATE 1\.[0-9][0-9]* postwatch +---- $ISO8601DATE 1\.[0-9][0-9]* preproxy +---- $ISO8601DATE 1\.[0-9][0-9]* rcsinfo +---- $ISO8601DATE 1\.[0-9][0-9]* taginfo +---- $ISO8601DATE 1\.[0-9][0-9]* verifymsg +d--- $ISO8601DATE Emptydir + +CVSROOT/Emptydir: + +first-dir: +---- $ISO8601DATE 1\.1 file1 +d--- $ISO8601DATE dir1 + +first-dir/dir1:" + dotest branches2-14-rls-4 "$testcvs rls -eR" \ +"$SPROG rls: Listing module: \`.' +\.: +D/CVSROOT//// +D/first-dir//// + +CVSROOT: +/checkoutlist/1\.[0-9][0-9]*/$DATE// +/commitinfo/1\.[0-9][0-9]*/$DATE// +/config/1\.[0-9][0-9]*/$DATE// +/cvswrappers/1\.[0-9][0-9]*/$DATE// +/loginfo/1\.[0-9][0-9]*/$DATE// +/modules/1\.[0-9][0-9]*/$DATE// +/notify/1\.[0-9][0-9]*/$DATE// +/postadmin/1\.[0-9][0-9]*/$DATE// +/postproxy/1\.[0-9][0-9]*/$DATE// +/posttag/1\.[0-9][0-9]*/$DATE// +/postwatch/1\.[0-9][0-9]*/$DATE// +/preproxy/1\.[0-9][0-9]*/$DATE// +/rcsinfo/1\.[0-9][0-9]*/$DATE// +/taginfo/1\.[0-9][0-9]*/$DATE// +/verifymsg/1\.[0-9][0-9]*/$DATE// +D/Emptydir//// + +CVSROOT/Emptydir: + +first-dir: +/file1/1\.1/$DATE// +D/dir1//// + +first-dir/dir1:" + dotest branches2-14-rls-5 "$testcvs -q rls -R" \ +"\.: +CVSROOT +first-dir + +CVSROOT: +checkoutlist +commitinfo +config +cvswrappers +loginfo +modules +notify +postadmin +postproxy +posttag +postwatch +preproxy +rcsinfo +taginfo +verifymsg +Emptydir + +CVSROOT/Emptydir: + +first-dir: +file1 +dir1 + +first-dir/dir1:" + dotest branches2-14-rls-6 "$testcvs -q rls -lRrb1" \ +"\.: +d--- $ISO8601DATE CVSROOT +d--- $ISO8601DATE first-dir + +CVSROOT: +d--- $ISO8601DATE Emptydir + +CVSROOT/Emptydir: + +first-dir: +---- $ISO8601DATE 1\.1 file1 +---- $ISO8601DATE 1\.1\.2\.1 file2 +d--- $ISO8601DATE dir1 + +first-dir/dir1: +---- $ISO8601DATE 1\.1\.2\.1 file3" + dotest branches2-14-rls-7 "$testcvs -q rls -lRrb2" \ +"\.: +d--- $ISO8601DATE CVSROOT +d--- $ISO8601DATE first-dir + +CVSROOT: +d--- $ISO8601DATE Emptydir + +CVSROOT/Emptydir: + +first-dir: +---- $ISO8601DATE 1\.1 file1 +d--- $ISO8601DATE dir1 + +first-dir/dir1:" + + # Now some calls to ls. These are more appropriate here. + dotest branches2-14-ls-1 "$testcvs ls" \ +"file1 +dir1" + dotest branches2-14-ls-2 "$testcvs ls -e" \ +"/file1/1\.1/$DATE// +D/dir1////" + dotest branches2-14-ls-3 "$testcvs ls -R" \ +"\.: +file1 +dir1 + +dir1: +file3" + dotest branches2-14-ls-4 "$testcvs ls -eRrHEAD" \ +"\.: +/file1/1\.1/$DATE//THEAD +D/dir1//// + +dir1:" + dotest branches2-14-ls-5 "$testcvs ls -eRrb1" \ +"\.: +/file1/1\.1/$DATE//Tb1 +/file2/1\.1\.2\.1/$DATE//Tb1 +D/dir1//// + +dir1: +/file3/1\.1\.2\.1/$DATE//Tb1" + dotest branches2-14-ls-6 "$testcvs ls -eRrb2" \ +"\.: +/file1/1.1/$DATE//Tb2 +D/dir1//// + +dir1:" + # Nonexistant tags used to cause assertion failures. + dotest_fail branches2-14-ls-7 "$testcvs ls -eRrnosuchtag" \ +"$SPROG \[ls aborted\]: no such tag \`nosuchtag'" + + # FIXME: Just clobbering the directory like this is a bit + # tacky, although people generally expect it to work. Maybe + # we should release it instead. We do it a few other places + # below as well. + rm -r dir1 + dotest branches2-15 "${testcvs} update -d -j b1 dir1" \ +"${SPROG} update: Updating dir1 +U dir1/file3" + # FIXCVS: The `No revision control file' stuff seems to be + # CVS's way of telling us that we're adding the file on a + # branch, and the file is not on that branch yet. This + # should be nicer. + dotest branches2-16 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: b2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: b2 - MISSING from RCS file! + Sticky Date: (none) + Sticky Options: (none)" + + cd ../../trunk/first-dir + dotest branches2-17 "${testcvs} update -d -P dir1" \ +"${SPROG} update: Updating dir1" + dotest_fail branches2-18 "test -d dir1" + dotest branches2-19 "${testcvs} update -d -P -r b1 dir1" \ +"${SPROG} update: Updating dir1 +U dir1/file3" + dotest branches2-20 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v + Commit Identifier: ${commitid} + Sticky Tag: b1 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + + rm -r dir1 + dotest branches2-21 "${testcvs} update -d -P -j b1 dir1" \ +"${SPROG} update: Updating dir1 +U dir1/file3" + dotest branches2-22 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Locally Added + + Working revision: New file! + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + cd ../.. + rm -r b1 b2 + + # Check out branch b1 twice. Crate a new directory in one + # working directory, then do a cvs update in the other + # working directory and see if the tags are right. + mkdir b1a + mkdir b1b + cd b1b + dotest branches2-23 "${testcvs} -q co -r b1 first-dir" \ +'U first-dir/file1 +U first-dir/file2 +U first-dir/dir1/file3' + cd ../b1a + dotest branches2-24 "${testcvs} -q co -r b1 first-dir" \ +'U first-dir/file1 +U first-dir/file2 +U first-dir/dir1/file3' + cd first-dir + mkdir dir2 + dotest branches2-25 "${testcvs} add dir2" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository +--> Using per-directory sticky tag "'`'"b1'" + echo "file4 first revision" > dir2/file4 + dotest branches2-26 "${testcvs} add dir2/file4" \ +"${SPROG}"' add: scheduling file `dir2/file4'\'' for addition on branch `b1'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest branches2-27 "${testcvs} -q commit -madd" \ +"$CVSROOT_DIRNAME/first-dir/dir2/Attic/file4,v <-- dir2/file4 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + cd ../../b1b/first-dir + dotest branches2-28 "${testcvs} update -d dir2" \ +"${SPROG} update: Updating dir2 +U dir2/file4" + cd dir2 + dotest branches2-29 "${testcvs} -q status" \ +"=================================================================== +File: file4 Status: Up-to-date + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v + Commit Identifier: ${commitid} + Sticky Tag: b1 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + dotest branches2-30 "cat CVS/Tag" 'Tb1' + + # Test update -A on a subdirectory + cd .. + rm -r dir2 + dotest branches2-31 "${testcvs} update -A -d dir2" \ +"${SPROG} update: Updating dir2" + cd dir2 + dotest branches2-32 "${testcvs} -q status" '' + dotest_fail branches2-33 "test -f CVS/Tag" + + # Add a file on the trunk. + echo "file5 first revision" > file5 + dotest branches2-34 "${testcvs} add file5" \ +"${SPROG}"' add: scheduling file `file5'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest branches2-35 "${testcvs} -q commit -madd" \ +"$CVSROOT_DIRNAME/first-dir/dir2/file5,v <-- file5 +initial revision: 1\.1" + + cd ../../../trunk/first-dir + dotest branches2-36 "${testcvs} -q update -d dir2" 'U dir2/file5' + cd dir2 + dotest branches2-37 "${testcvs} -q status" \ +"=================================================================== +File: file5 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir2/file5,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest_fail branches2-38 "test -f CVS/status" + + dotest branches2-39 "$testcvs rls -rb1 -l -R first-dir" \ +"$SPROG rls: Listing module: \`first-dir' +first-dir: +---- $ISO8601DATE 1\.1 file1 +---- $ISO8601DATE 1\.1\.2\.1 file2 +d--- $ISO8601DATE dir1 +d--- $ISO8601DATE dir2 + +first-dir/dir1: +---- $ISO8601DATE 1\.1\.2\.1 file3 + +first-dir/dir2: +---- $ISO8601DATE 1\.1\.2\.1 file4" + + dokeep + cd ../../.. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r trunk b1a b1b + ;; + + + + branches3) + # test local branch number support + + # This test is skipped in $remotehost mode since the + # CVS_LOCAL_BRANCH_NUM is not inherited by the server process as it + # is with :fork:, for hopefully obvious reasons. + # + # FIXCVS? Is this correct? Should CVS_LOCAL_BRANCH_NUM be sent as + # a protocol extension or is it reasonable to only want this set on + # the server? + + if test -n "$remotehost"; then :;else + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir branches3; cd branches3 + + dotest branches3-1 "$testcvs -q co first-dir" + cd first-dir + echo "file1 first revision" > file1 + dotest branches3-2 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest branches3-3 "${testcvs} commit -m add file1" \ +"${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + # Tag the file using a CVS_LOCAL_BRANCH_NUM of 1000 + CVS_LOCAL_BRANCH_NUM=1000; export CVS_LOCAL_BRANCH_NUM + dotest branches3-4 "${testcvs} -q tag -b tag1" 'T file1' + unset CVS_LOCAL_BRANCH_NUM + dotest branches3-5 "${testcvs} -q log file1" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + tag1: 1\.1\.0\.1000 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +add +=============================================================================" + + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r branches3 + fi # !$remotehost + ;; + + + + branches4) + # test where a tag is a branch tag in some files and a revision + # tag in others + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir branches4; cd branches4 + + dotest branches4-1 "$testcvs -q co first-dir" + cd first-dir + mkdir branches mixed mixed2 versions + dotest branches4-2 "${testcvs} -q add branches mixed mixed2 versions" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/branches added to the repository +Directory ${CVSROOT_DIRNAME}/first-dir/mixed added to the repository +Directory ${CVSROOT_DIRNAME}/first-dir/mixed2 added to the repository +Directory ${CVSROOT_DIRNAME}/first-dir/versions added to the repository" + + echo file1 >branches/file1 + echo file2 >branches/file2 + echo file3 >branches/file3 + echo file4 >branches/file4 + cp branches/file* mixed + cp branches/file* mixed2 + cp branches/file* versions + + dotest branches4-3 "${testcvs} -q add */file*" \ +"${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest branches4-3a "${testcvs} -Q ci -m." + + dotest branches4-4 "${testcvs} -q tag xxx versions/file* mixed*/file1 mixed*/file3" \ +"T versions/file1 +T versions/file2 +T versions/file3 +T versions/file4 +T mixed/file1 +T mixed/file3 +T mixed2/file1 +T mixed2/file3" + + dotest branches4-5 "${testcvs} -q tag -b xxx branches/file* mixed*/file2 mixed*/file4" \ +"T branches/file1 +T branches/file2 +T branches/file3 +T branches/file4 +T mixed/file2 +T mixed/file4 +T mixed2/file2 +T mixed2/file4" + + # make sure we get the appropriate warnings when updating + dotest branches4-6 "${testcvs} update -r xxx" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating branches +${SPROG} update: Updating mixed +${SPROG} update: warning: xxx is a branch tag in some files and a revision tag in others\. +${SPROG} update: Updating mixed2 +${SPROG} update: warning: xxx is a branch tag in some files and a revision tag in others\. +${SPROG} update: Updating versions" + + # make sure we don't get warned in quiet modes + dotest branches4-7 "${testcvs} -q update -A" + dotest branches4-8 "${testcvs} -q update -r xxx" + dotest branches4-9 "${testcvs} -q update -A" + dotest branches4-10 "${testcvs} -Q update -r xxx" + + # make sure the Tag files are correct + dotest branches4-11 "cat branches/CVS/Tag" "Txxx" + dotest branches4-12 "cat mixed/CVS/Tag" "Nxxx" + dotest branches4-13 "cat mixed2/CVS/Tag" "Nxxx" + dotest branches4-14 "cat versions/CVS/Tag" "Nxxx" + + # We only warn if there's mixed usage in a single directory. + # We may want to consider changing that in the future. + dotest branches4-15 "${testcvs} update -r xxx branches versions" \ +"${SPROG} update: Updating branches +${SPROG} update: Updating versions" + + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r branches4 + ;; + + + + tagc) + # Test the tag -c option. + mkdir 1; cd 1 + dotest tagc-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest tagc-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch file1 file2 + dotest tagc-3 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest tagc-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + dotest tagc-5 "${testcvs} -q tag -c tag1" \ +"T file1 +T file2" + touch file1 file2 + dotest tagc-6 "${testcvs} -q tag -c tag2" \ +"T file1 +T file2" + # Avoid timestamp granularity bugs (FIXME: CVS should be + # doing the sleep, right?). + sleep 1 + echo myedit >>file1 + dotest tagc-6a "${testcvs} rm -f file2" \ +"${SPROG} remove: scheduling .file2. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + touch file3 + dotest tagc-6b "${testcvs} add file3" \ +"${SPROG} add: scheduling file .file3. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest_fail tagc-7 "${testcvs} -q tag -c tag3" \ +"${SPROG} tag: file1 is locally modified +${SPROG} tag: file2 is locally modified +${SPROG} tag: file3 is locally modified +${SPROG} \[tag aborted\]: correct the above errors first!" + cd ../.. + mkdir 2 + cd 2 + dotest tagc-8 "${testcvs} -q co first-dir" \ +"U first-dir/file1 +U first-dir/file2" + cd ../1/first-dir + dotest tagc-9 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +initial revision: 1\.1" + cd ../../2/first-dir + dotest tagc-10 "${testcvs} -q tag -c tag4" \ +"${SPROG} tag: \`file2' is no longer in the repository +T file1 +T file2" + + dokeep + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + update-p) + # Make sure `cvs update -p -rT FILE' works from a branch when + # FILE is already on the trunk and is being added to that branch. + + mkdir 1; cd 1 + module=x + + echo > unused-file + + # Create the module. + dotest update-p-1 \ + "$testcvs -Q import -m. $module X Y" '' + + file=F + # Check it out and tag it. + dotest update-p-2 "$testcvs -Q co $module" '' + cd $module + dotest update-p-3 "$testcvs -Q tag -b B" '' + echo v1 > $file + dotest update-p-4 "$testcvs -Q add $file" '' + dotest update-p-5 "$testcvs -Q ci -m. $file" + dotest update-p-6 "$testcvs -Q tag T $file" '' + dotest update-p-7 "$testcvs -Q update -rB" '' + + # This merge effectively adds file F on branch B. + dotest update-p-8 "$testcvs -Q update -jT" '' + + # Before the fix that prompted the addition of this test, + # the following command would fail with this diagnostic: + # cvs update: conflict: F created independently by second party + dotest update-p-9 "$testcvs update -p -rT $file" \ +"=================================================================== +Checking out $file +RCS: ${CVSROOT_DIRNAME}/$module/$file,v +VERS: 1\.1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +v1" + + # Repeat the above, but with $file removed. + # This exercises a slightly different code path. + rm $file + # Before the fix that prompted the addition of this test, + # the following command would fail with this diagnostic: + # cvs update: warning: new-born \`F' has disappeared + dotest update-p-10 "$testcvs update -p -rT $file" \ +"=================================================================== +Checking out $file +RCS: ${CVSROOT_DIRNAME}/$module/$file,v +VERS: 1\.1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +v1" + + # Exercise yet another code path: + # the one that involves reviving a `dead' file. + # And a little more, for good measure... + touch new + dotest update-p-a1 "$testcvs -Q add new" '' + dotest update-p-a2 "$testcvs -Q update -p new" '' + dotest update-p-a3 "$testcvs -Q rm -f new" '' + + # Both an update -A, *and* the following update are required + # to return to the state of being on the trunk with a $file + # that we can then remove. + dotest update-p-undead-0 "$testcvs update -A" \ +"${SPROG} update: Updating \. +${SPROG} update: warning: new-born \`$file' has disappeared" + dotest update-p-undead-1 "$testcvs update" \ +"${SPROG} update: Updating \. +U $file" + dotest update-p-undead-2 "$testcvs -Q update -p -rT $file" v1 + dotest update-p-undead-3 "$testcvs -Q rm -f $file" '' + dotest update-p-undead-4 "$testcvs -Q update -p -rT $file" v1 + dotest update-p-undead-5 "$testcvs -Q ci -m. $file" + dotest update-p-undead-6 "$testcvs -Q update -p -rT $file" v1 + echo v2 > $file + dotest update-p-undead-7 "$testcvs -Q update -p -rT $file" v1 + dotest update-p-undead-8 "$testcvs add $file" \ +"$SPROG add: Re-adding file .$file. after dead revision 1\.2\. +$SPROG add: use \`$SPROG commit' to add this file permanently" + + dotest update-p-undead-9 "$testcvs -Q update -p -rT $file" v1 + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + tagf) + # More tagging tests, including using tag -F -B to convert a + # branch tag to a regular tag and recovering thereof. + + # Setup; check in first-dir/file1 + mkdir 1; cd 1 + dotest tagf-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest tagf-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch file1 file2 + dotest tagf-3 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest tagf-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + + # Now create a branch and commit a revision there. + dotest tagf-5 "${testcvs} -q tag -b br" "T file1 +T file2" + dotest tagf-6 "${testcvs} -q update -r br" "" + echo brmod >> file1 + echo brmod >> file2 + dotest tagf-7 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + # Here we try to make it a non-branch tag, but will + # succeed in getting only warnings, even with -F + # because converting a branch tag to non-branch + # is potentially catastrophic. + dotest tagf-8a "${testcvs} -q tag -F br" \ +"${SPROG} tag: file1: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\\.2\.1\. +${SPROG} tag: file2: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\.2\.1\." + # however, if we *really* are sure we want to move a branch tag, + # "-F -B" will do the trick + dotest tagf-8 "${testcvs} -q tag -F -B br" "T file1 +T file2" + echo moremod >> file1 + echo moremod >> file2 + dotest tagf-9 "${testcvs} -q status -v file1" \ +"=================================================================== +File: file1 Status: Locally Modified + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br (revision: 1\.1\.2\.1) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + br (revision: 1\.1\.2\.1)" + + # Now, how do we recover? + dotest tagf-10 "${testcvs} -q tag -d br" "D file1 +D file2" + # This creates a new branch, 1.1.4. See the code in RCS_magicrev + # which will notice that there is a (non-magic) 1.1.2 and thus + # skip that number. + dotest tagf-11 "${testcvs} -q tag -r 1.1 -b br file1" "T file1" + # Fix it with admin -n (cf admin-18, admin-26-4). + dotest tagf-12 "${testcvs} -q admin -nbr:1.1.2 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + # Another variation on the file2 test would be to use two working + # directories so that the update -r br would need to + # a merge to get from 1.1.2.1 to the head of the 1.1.2 branch. + dotest tagf-13 "${testcvs} -q update -r br" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1\.2\.1 +retrieving revision 1\.1 +Merging differences between 1\.1\.2\.1 and 1\.1 into file1 +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in file1 +C file1 +M file2" + # CVS is giving a conflict because we are trying to get back to + # 1.1.4. I'm not sure why it is a conflict rather than just + # "M file1". + dotest tagf-14 "cat file1" \ +"<<<<<<< file1 +brmod +moremod +[=]====== +[>]>>>>>> 1\.1" + echo resolve >file1 + dotest tagf-15 "${testcvs} -q ci -m recovered" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.4\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + # try accidentally deleting branch tag, "tag -d" + dotest_fail tagf-16 "${testcvs} tag -d br" \ +"${SPROG} tag: Untagging \. +${SPROG} tag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\. +${SPROG} tag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\." + # try accidentally deleting branch tag, "rtag -d" + dotest_fail tagf-17 "${testcvs} rtag -d br first-dir" \ +"${SPROG} rtag: Untagging first-dir +${SPROG} rtag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\. +${SPROG} rtag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\." + # try accidentally converting branch tag to non-branch tag "tag -F" + dotest tagf-18 "${testcvs} tag -r1.1 -F br file1" \ +"${SPROG} tag: file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\." + # try accidentally converting branch tag to non-branch tag "rtag -F" + dotest tagf-19 "${testcvs} rtag -r1.1 -F br first-dir" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: first-dir/file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\. +${SPROG} rtag: first-dir/file2: Not moving branch tag .br. from 1\.1\.2\.2 to 1\.1\." + # create a non-branch tag + dotest tagf-20 "${testcvs} rtag regulartag first-dir" \ +"${SPROG} rtag: Tagging first-dir" + # try accidentally converting non-branch tag to branch tag (tag -F -B -b) + dotest tagf-21 "${testcvs} tag -F -B -b regulartag file1" \ +"${SPROG} tag: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1\.0\.2 due to .-B. option\." + # try accidentally converting non-branch tag to branch rtag (rtag -F -B -b) + dotest tagf-22 "${testcvs} rtag -F -B -b regulartag first-dir" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.6 due to .-B. option\. +${SPROG} rtag: first-dir/file2: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.4 due to .-B. option\." + # Try accidentally deleting non-branch: (tag -d -B) + dotest_fail tagf-23 "${testcvs} tag -d -B regulartag file1" \ +"${SPROG} tag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\." + # Try accidentally deleting non-branch: (rtag -d -B) + dotest_fail tagf-24 \ + "${testcvs} rtag -d -B regulartag first-dir" \ +"${SPROG} rtag: Untagging first-dir +${SPROG} rtag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\. +${SPROG} rtag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file2,v. due to .-B. option\." + + # the following tests (throught the next commit) keep moving the same + # tag back and forth between 1.1.6 & 1.1.8 in file1 and between + # 1.1.4 and 1.1.6 in file2 since nothing was checked in on some of + # these branches and CVS only tracks branches via tags unless they contain data. + + # try intentionally converting non-branch tag to branch tag (tag -F -b) + dotest tagf-25a "${testcvs} tag -F -b regulartag file1" "T file1" + # try intentionally moving a branch tag to a newly created branch (tag -F -b -B) + dotest tagf-25b "${testcvs} tag -F -B -b -r1.1 regulartag file1" \ +"T file1" + # try intentionally converting mixed tags to branch tags (rtag -F -b) + dotest tagf-26a "${testcvs} rtag -F -b regulartag first-dir" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: first-dir/file1: Not moving branch tag .regulartag. from 1\.1 to 1\.1\.0\.8\." + # try intentionally converting a branch to a new branch tag (rtag -F -b -B) + dotest tagf-26b "${testcvs} rtag -F -B -b -r1.1 regulartag first-dir" \ +"${SPROG} rtag: Tagging first-dir" + # update to our new branch + dotest tagf-27 "${testcvs} update -r regulartag" \ +"${SPROG} update: Updating \. +U file1 +U file2" + # commit some changes and see that all rev numbers look right + echo changes >> file1 + echo changes >> file2 + dotest tagf-28 "${testcvs} ci -m changes" \ +"${CPROG} commit: Examining \. +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +new revision: 1\.1\.8\.1; previous revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 +new revision: 1\.1\.6\.1; previous revision: 1\.1" + # try intentional branch to non-branch (tag -F -B) + dotest tagf-29 "${testcvs} tag -F -B -r1.1 regulartag file1" \ +"T file1" + # try non-branch to non-branch (tag -F -B) + dotest tagf-29a "${testcvs} tag -F -B -r br regulartag file1" \ +"${SPROG} tag: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\." + # try mixed-branch to non-branch (rtag -F -B ) + dotest tagf-29b "${testcvs} rtag -F -B -r br regulartag first-dir" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\." + # at this point, regulartag is a regular tag within + # file1 and file2 + + # try intentional branch to non-branch (rtag -F -B) + dotest tagf-30 "${testcvs} rtag -F -B -r1.1 br first-dir" \ +"${SPROG} rtag: Tagging first-dir" + # create a branch tag so we can try to delete it. + dotest tagf-31 "${testcvs} rtag -b brtag first-dir" \ +"${SPROG} rtag: Tagging first-dir" + + # try intentinal deletion of branch tag (tag -d -B) + dotest tagf-32 "${testcvs} tag -d -B brtag file1" "D file1" + # try intentinal deletion of branch tag (rtag -d -B) + dotest tagf-33 "${testcvs} rtag -d -B brtag first-dir" \ +"${SPROG} rtag: Untagging first-dir" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + tag-space) + # Test tags with spaces in the names. + # + # Prior to releases 1.11.18 & 1.12.10, some commands used with + # tags with spaces in the names could hang CVS. + + # Setup; check in first-dir/file1 + mkdir 1; cd 1 + dotest tag-space-init-1 "$testcvs -q co -l ." + mkdir first-dir + dotest tag-space-init-2 "$testcvs add first-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir added to the repository" + cd first-dir + touch file1 + dotest tag-space-init-3 "$testcvs add file1" \ +"$SPROG add: scheduling file \`file1' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + dotest tag-space-init-4 "$testcvs -Q ci -m add" + + # Reportedly, the following two tags make it past WinCVS. + dotest_fail tag-space-1 "$testcvs tag ' spacetag '" \ +"$SPROG \[tag aborted\]: tag \` spacetag ' must start with a letter" + dotest_fail tag-space-2 "$testcvs tag 'spacetag '" \ +"$SPROG \[tag aborted\]: tag \`spacetag ' has non-visible graphic characters" + + if $remote; then + # Verify that this isn't a client check. + dotest tag-space-3 "$testcvs server" \ +"E $SPROG \[tag aborted\]: tag \` spacetag ' must start with a letter +error " <<EOF +Root $CVSROOT_DIRNAME +UseUnchanged +Argument -- +Argument spacetag +Directory . +$CVSROOT_DIRNAME/first-dir +Entry /file1/1.1/// +Unchanged file1 +tag +EOF + + dotest tag-space-4 "$testcvs server" \ +"E $SPROG \[tag aborted\]: tag \`spacetag ' has non-visible graphic characters +error " <<EOF +Root $CVSROOT_DIRNAME +UseUnchanged +Argument -- +Argument spacetag +Directory . +$CVSROOT_DIRNAME/first-dir +Entry /file1/1.1/// +Unchanged file1 +tag +EOF + fi # $remote + + # Any number of normal tags and branches were handled correctly. + dotest tag-space-5 "$testcvs -Q tag t1" + dotest tag-space-5b "$testcvs -Q tag t2" + dotest tag-space-5c "$testcvs -Q tag -b b1" + + cd ../.. + mkdir 2; cd 2 + + # But once a vendor branch exists, it's all over. + mkdir project; cd project + touch file1 + dotest tag-space-init-4 \ +"$testcvs -Q import -mimport second-dir VENDOR RELEASE" + + cd .. + + dotest_fail tag-space-6 "$testcvs -Q co -r ' spacetag ' first-dir" \ +"$SPROG \[checkout aborted\]: tag \` spacetag ' must start with a letter" + + # But when any files were imported, this test hung prior to CVS + # versions 1.11.18 & 1.12.10. + dotest_fail tag-space-7 "$testcvs -Q co -r ' spacetag ' second-dir" \ +"$SPROG \[checkout aborted\]: tag \` spacetag ' must start with a letter" + + if $remote; then + # I based the client input in the next two tests on actual input + # from WinCVS 1.2. + dotest tag-space-8 "$testcvs server" \ +"E $SPROG \[checkout aborted\]: tag \` spacetag ' must start with a letter +error " <<EOF +Root $CVSROOT_DIRNAME +Argument -P +Argument -r +Argument spacetag +Argument first-dir +Directory . +$CVSROOT_DIRNAME +co +EOF + + # Verify the test is not on the client side. + dotest tag-space-9 "$testcvs server" \ +"E $SPROG \[checkout aborted\]: tag \` spacetag ' must start with a letter +error " <<EOF +Root $CVSROOT_DIRNAME +Argument -P +Argument -r +Argument spacetag +Argument second-dir +Directory . +$CVSROOT_DIRNAME +co +EOF + fi # $remote + + dotest tag-space-10 "$testcvs -Q co second-dir" + cd second-dir + + # This test would also hang. + dotest_fail tag-space-11 "$testcvs -Q up -r ' spacetag '" \ +"$SPROG \[update aborted\]: tag \` spacetag ' must start with a letter" + + if $remote; then + dotest tag-space-12 "$testcvs server" \ +"E $SPROG \[update aborted\]: tag \` spacetag ' must start with a letter +error " <<EOF +Root $CVSROOT_DIRNAME +Argument -r +Argument spacetag +Argument -u +Argument -- +Directory . +$CVSROOT_DIRNAME +Unchanged file1 +update +EOF + fi # $remote + + # I'm skipping tests for other commands that may have had the same + # problem. Hopefully, if a new issue arises, one of the above tests + # will catch the problem. + + if $keep; then + echo Keeping $TESTDIR and exiting due to --keep + exit 0 + fi + + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + rcslib) + # Test librarification of RCS. + # First: test whether `cvs diff' handles $Name expansion + # correctly. We diff two revisions with their symbolic tags; + # neither tag should be expanded in the output. Also diff + # one revision with the working copy. + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest rcsdiff-1 "${testcvs} -q co first-dir" '' + cd first-dir + echo "I am the first foo, and my name is $""Name$." > foo.c + dotest rcsdiff-2 "${testcvs} add -m new-file foo.c" \ +"${SPROG} add: scheduling file .foo\.c. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest rcsdiff-3 "${testcvs} commit -m rev1 foo.c" \ +"${CVSROOT_DIRNAME}/first-dir/foo.c,v <-- foo\.c +initial revision: 1\.1" + dotest rcsdiff-4 "${testcvs} tag first foo.c" "T foo\.c" + dotest rcsdiff-5 "${testcvs} update -p -r first foo.c" \ +"=================================================================== +Checking out foo\.c +RCS: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v +VERS: 1\.1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +I am the first foo, and my name is \$""Name: first \$\." + + echo "I am the second foo, and my name is $""Name$." > foo.c + dotest rcsdiff-6 "${testcvs} commit -m rev2 foo.c" \ +"${CVSROOT_DIRNAME}/first-dir/foo\.c,v <-- foo\.c +new revision: 1\.2; previous revision: 1\.1" + dotest rcsdiff-7 "${testcvs} tag second foo.c" "T foo\.c" + dotest rcsdiff-8 "${testcvs} update -p -r second foo.c" \ +"=================================================================== +Checking out foo\.c +RCS: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v +VERS: 1\.2 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +I am the second foo, and my name is \$""Name: second \$\." + + dotest_fail rcsdiff-9 "${testcvs} diff -r first -r second" \ +"${SPROG} diff: Diffing \. +Index: foo\.c +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v +retrieving revision 1\.1 +retrieving revision 1\.2 +diff -r1\.1 -r1\.2 +1c1 +< I am the first foo, and my name is \$""Name: \$\. +--- +> I am the second foo, and my name is \$""Name: \$\." + + echo "I am the once and future foo, and my name is $""Name$." > foo.c + dotest_fail rcsdiff-10 "${testcvs} diff -r first" \ +"${SPROG} diff: Diffing \. +Index: foo\.c +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v +retrieving revision 1\.1 +diff -r1\.1 foo\.c +1c1 +< I am the first foo, and my name is \$""Name: \$\. +--- +> I am the once and future foo, and my name is \$""Name\$\." + + # Test handling of libdiff options. diff gets quite enough + # of a workout elsewhere in sanity.sh, so we assume that it's + # mostly working properly if it passes all the other tests. + # The main one we want to try is regex handling, since we are + # using CVS's regex matcher and not diff's. + + cat >rgx.c <<EOF +test_regex (whiz, bang) +{ +foo; +bar; +baz; +grumble; +} +EOF + + dotest rcslib-diffrgx-1 "${testcvs} -q add -m '' rgx.c" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest rcslib-diffrgx-2 "${testcvs} -q ci -m '' rgx.c" \ +"$CVSROOT_DIRNAME/first-dir/rgx\.c,v <-- rgx\.c +initial revision: 1\.1" + cat >rgx.c <<EOF +test_regex (whiz, bang) +{ +foo; +bar; +baz; +mumble; +} +EOF + # Use dotest_fail because exit status from `cvs diff' must be 1. + # + # Incidentally test that CVS no longer splits diff arguments on + # spaces. + dotest_fail rcslib-diffrgx-3 "$testcvs diff -c -F'.* (' rgx.c" \ +"Index: rgx\.c +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/rgx\.c,v +retrieving revision 1\.1 +diff -c -F '\.\* (' -r1\.1 rgx\.c +\*\*\* rgx\.c ${RFCDATE} 1\.1 +--- rgx\.c ${RFCDATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* test_regex (whiz, bang) +\*\*\* 3,7 \*\*\*\* + foo; + bar; + baz; +! grumble; + } +--- 3,7 ---- + foo; + bar; + baz; +! mumble; + }" + + # Tests of rcsmerge/diff3. Merge operations get a good general + # workout elsewhere; we want to make sure that options are still + # handled properly. Try merging two branches with -kv, to test + # both -j and -k switches. + + cd .. + + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r first-dir + + mkdir 1; cd 1 + dotest rcslib-merge-1 "$testcvs -q co -l ." + mkdir first-dir + dotest rcslib-merge-2 "$testcvs -q add first-dir" \ +"Directory $CVSROOT_DIRNAME.*/first-dir added to the repository" + cd ..; rm -r 1 + + dotest rcslib-merge-3 "$testcvs -q co first-dir" "" + cd first-dir + + echo '$''Revision$' > file1 + echo '2' >> file1 + echo '3' >> file1 + dotest rcslib-merge-4 "${testcvs} -q add file1" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest rcslib-merge-5 "${testcvs} -q commit -m '' file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + sed -e 's/2/two/' file1 > f; mv f file1 + dotest rcslib-merge-6 "${testcvs} -q commit -m '' file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + dotest rcslib-merge-7 "${testcvs} -q tag -b -r 1.1 patch1" "T file1" + dotest rcslib-merge-8 "${testcvs} -q update -r patch1" "[UP] file1" + dotest rcslib-merge-9 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: patch1 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + dotest rcslib-merge-10 "cat file1" \ +'$''Revision: 1\.1 $ +2 +3' + sed -e 's/3/three/' file1 > f; mv f file1 + dotest rcslib-merge-11 "${testcvs} -q commit -m '' file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + dotest rcslib-merge-12 "${testcvs} -q update -kv -j1.2" \ +"U file1 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into file1 +rcsmerge: warning: conflicts during merge" + dotest rcslib-merge-13 "cat file1" \ +"<<<<<<< file1 +1\.1\.2\.1 +2 +three +[=]====== +1\.2 +two +3 +[>]>>>>>> 1\.2" + + # Test behavior of symlinks in the repository. + if test -n "$remotehost"; then + # Create the link on the remote system. This is because Cygwin's + # Windows support creates *.lnk files for Windows. When creating + # these in an SMB share from UNIX, these links won't work from the + # UNIX side. + modify_repo $CVS_RSH $remotehost "'ln -s file1,v $CVSROOT_DIRNAME/first-dir/file2,v'" + else + modify_repo ln -s file1,v $CVSROOT_DIRNAME/first-dir/file2,v + fi + dotest rcslib-symlink-2 "$testcvs update file2" "U file2" + echo "This is a change" >> file2 + dotest rcslib-symlink-3 "$testcvs ci -m because file2" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file2 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + + # Switch as for rcslib-symlink-1 + if test -n "$remotehost"; then + dotest rcslib-symlink-4 "$CVS_RSH $remotehost 'ls -l $CVSROOT_DIRNAME/first-dir/file2,v'" \ +".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" + else + dotest rcslib-symlink-4 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \ +".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" + fi + + # CVS was failing to check both the symlink and the file + # for timestamp changes for a while. Test that. + rm file1 + dotest rcslib-symlink-3a "${testcvs} -q up file1" \ +"${SPROG} update: warning: \`file1' was lost +U file1" + echo "This is a change" >> file1 + dotest rcslib-symlink-3b "${testcvs} ci -m because file1" \ +"${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.[0-9]*; previous revision: 1\.1\.2\.[0-9]*" + dotest rcslib-symlink-3c "${testcvs} update file2" "[UP] file2" + + echo some new text >file3 + dotest rcslib-symlink-3d "${testcvs} -Q add file3" '' + dotest rcslib-symlink-3e "$testcvs -Q ci -mtest file3" + + rm -f ${CVSROOT_DIRNAME}/first-dir/file2,v + # As for rcslib-symlink-1 + if test -n "$remotehost"; then + modify_repo "$CVS_RSH $remotehost 'ln -s Attic/file3,v $CVSROOT_DIRNAME/first-dir/file2,v'" + else + modify_repo ln -s Attic/file3,v $CVSROOT_DIRNAME/first-dir/file2,v + fi + + dotest rcslib-symlink-3g "$testcvs update file2" "U file2" + + # restore the link to file1 for the following tests + dotest rcslib-symlink-3i "$testcvs -Q rm -f file3" '' + dotest rcslib-symlink-3j "$testcvs -Q ci -mwhatever file3" + rm -f $CVSROOT_DIRNAME/first-dir/file2,v + rm -f $CVSROOT_DIRNAME/first-dir/Attic/file3,v + # As for rcslib-symlink-1 + if test -n "$remotehost"; then + modify_repo "$CVS_RSH $remotehost 'ln -s file1,v $CVSROOT_DIRNAME/first-dir/file2,v'" + else + modify_repo ln -s file1,v $CVSROOT_DIRNAME/first-dir/file2,v + fi + + # Test 5 reveals a problem with having symlinks in the + # repository. CVS will try to tag both of the files + # separately. After processing one, it will do the same + # operation to the other, which is actually the same file, + # so the tag will already be there. FIXME: do we bother + # changing operations to notice cases like this? This + # strikes me as a difficult problem. -Noel + dotest rcslib-symlink-5 "$testcvs tag the_tag" \ +"$SPROG tag: Tagging . +T file1 +W file2 : the_tag already exists on version 1.1.2.3 : NOT MOVING tag to version 1.1.2.1" + # As for rcslib-symlink-1 + if test -n "$remotehost"; then + dotest rcslib-symlink-6 "$CVS_RSH $remotehost 'ls -l $CVSROOT_DIRNAME/first-dir/file2,v'" \ +".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" + else + dotest rcslib-symlink-6 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \ +".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" + fi + + # Symlinks tend to interact poorly with the Attic. + cd .. + mkdir 2; cd 2 + dotest rcslib-symlink-7 "$testcvs -q co first-dir" \ +"U first-dir/file1 +U first-dir/file2" + cd first-dir + dotest rcslib-symlink-8 "$testcvs rm -f file2" \ +"$SPROG remove: scheduling .file2. for removal +$SPROG remove: use .$SPROG commit. to remove this file permanently" + dotest rcslib-symlink-9 "$testcvs -q ci -m rm-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file2 +new revision: delete; previous revision: 1\.2" + # OK, why this message happens twice is relatively clear + # (the check_* and rtag_* calls to start_recursion). + # Why it happens a third time I didn't try to find out. + # + # DRP: One of the error messages disappeared while I was making + # proxy modifications. Until I detect a deeper issue, I'm not + # going to stress over it. + # + # DRP: Both messages disappear starting with glibc 2.3.3 due to a bug + # in the glob function which causes it to fail to return broken + # symlinks. I'm submitting a bug fix to glibc which will hopefully + # be released with glibc 2.3.6. Once it is released and versions + # 2.3.3-2.3.5 of glibc become uncommon, the first, empty case below + # should be removed again. + dotest rcslib-symlink-10 \ +"$testcvs -q rtag -b -r the_tag brtag first-dir" "" \ +"$SPROG rtag: could not read RCS file for first-dir/file2 +$SPROG rtag: could not read RCS file for first-dir/file2" + + # Restore file1 for the next test. + dotest rcslib-long-symlink-init-1 "$testcvs -Q up -A" + dotest rcslib-long-symlink-init-2 "$testcvs -Q add file1" + dotest rcslib-long-symlink-init-3 "$testcvs -Q ci -mback" + + cd ../.. # $TESTDIR + + # CVS has a hard-coded default link path size of 127 characters. + # Make sure it knows how to exceed that. + longpath=$CVSROOT_DIRNAME + count=0 + while test $count -lt 10; do + # 10 * 30 characters + len $CVSROOT_DIRNAME + count=`expr $count + 1` + longpath=$longpath/123456789012345678901234567890 + modify_repo mkdir $longpath + done + modify_repo cp $CVSROOT_DIRNAME/first-dir/file1,v $longpath + modify_repo mkdir $CVSROOT_DIRNAME/second-dir + + # Switch as for rcslib-symlink-1 + if test -n "$remotehost"; then + modify_repo $CVS_RSH $remotehost \ + 'ln -s $longpath/file1,v $CVSROOT_DIRNAME/second-dir/fileX,v' + else + modify_repo ln -s $longpath/file1,v \ + $CVSROOT_DIRNAME/second-dir/fileX,v + fi + + dotest rcslib-long-symlink-2 "$testcvs co second-dir" \ +"$SPROG checkout: Updating second-dir +U second-dir/fileX" + + cd second-dir + echo change-it >>fileX + + # Writes actually cause symlinks to be resolved. + dotest rcslib-long-symlink-3 "$testcvs -q ci -mwrite-it" \ +"$CVSROOT_DIRNAME/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/file1,v <-- fileX +new revision: 1\.5; previous revision: 1\.4" + + dokeep + cd .. + + # Must remove the symlink first. Samba doesn't appear to show + # broken symlink across the SMB share, and rm -rf by itself + # will remove file1,v first and leave file2,v a broken link and the + # rm -rf will fail since it doesn't find file2,v and it still gets + # directory not empty errors removing cvsroot/first-dir. + # + # I'm not sure why I need to do this on $remotehost. The rm above + # rcslib-symlink-3j works fine, but the next one doesn't unless run + # remotely under Cygwin and using a TESTDIR on a Samba share. + if test -n "$remotehost"; then + $CVS_RSH $remotehost \ +"rm -f $CVSROOT_DIRNAME/first-dir/file2,v $CVSROOT_DIRNAME/second-dir/fileX,v" + fi + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir \ + $CVSROOT_DIRNAME/123456789012345678901234567890 + rm -r first-dir second-dir 2 + ;; + + + + multibranch) + # Test the ability to have several branchpoints coming off the + # same revision. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest multibranch-1 "${testcvs} -q co first-dir" '' + cd first-dir + echo 1:trunk-1 >file1 + dotest multibranch-2 "${testcvs} add file1" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest_lit multibranch-3 "${testcvs} -q ci -m add-it" <<HERE +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1.1 +HERE + dotest multibranch-4 "${testcvs} tag -b br1" \ +"${SPROG} tag: Tagging \. +T file1" + dotest multibranch-5 "${testcvs} tag -b br2" \ +"${SPROG} tag: Tagging \. +T file1" + dotest multibranch-6 "${testcvs} -q update -r br1" '' + echo on-br1 >file1 + dotest multibranch-7 "${testcvs} -q ci -m modify-on-br1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + dotest multibranch-8 "${testcvs} -q update -r br2" '[UP] file1' + echo br2 adds a line >>file1 + dotest multibranch-9 "${testcvs} -q ci -m modify-on-br2" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.4\.1; previous revision: 1\.1" + dotest multibranch-10 "${testcvs} -q update -r br1" '[UP] file1' + dotest multibranch-11 "cat file1" 'on-br1' + dotest multibranch-12 "${testcvs} -q update -r br2" '[UP] file1' + dotest multibranch-13 "cat file1" '1:trunk-1 +br2 adds a line' + + dotest multibranch-14 "${testcvs} log file1" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + br2: 1\.1\.0\.4 + br1: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; 1\.1\.4; +add-it +---------------------------- +revision 1\.1\.4\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify-on-br2 +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +modify-on-br1 +=============================================================================" + + dokeep + cd .. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r first-dir + ;; + + + + import) # test death after import + # Tests of "cvs import": + # basic2 + # rdiff -- imports with keywords + # import -- more tests of imports with keywords + # importb -- -b option. + # importc -- bunch o' files in bunch o' directories + # importX -- -X option. + # importX2 -- CVSROOT/config ImportNewFilesToVendorBranchOnly + # flag + # modules3 + # mflag -- various -m messages + # ignore -- import and cvsignore + # binwrap -- import and -k wrappers + # info -- imports which are rejected by verifymsg + # head -- intended to test vendor branches and HEAD, + # although it doesn't really do it yet. + # import-CVS -- refuse to import directories named "CVS". + # import-quirks -- short tests of import quirks. + + # import + mkdir import-dir ; cd import-dir + + for i in 1 2 3 4 ; do + echo imported file"$i" > imported-f"$i" + done + + # This directory should be on the default ignore list, + # so it shouldn't get imported. + mkdir RCS + echo ignore.me >RCS/ignore.me + + echo 'import should not expand $''Id$' >>imported-f2 + cp imported-f2 ../imported-f2-orig.tmp + + dotest_sort import-96 \ +"${testcvs} import -m first-import first-dir vendor-branch junk-1_0" \ +" + +I first-dir/RCS +N first-dir/imported-f1 +N first-dir/imported-f2 +N first-dir/imported-f3 +N first-dir/imported-f4 +No conflicts created by this import" + + dotest import-96.5 "cmp ../imported-f2-orig.tmp imported-f2" '' + + cd .. + + # co + dotest import-97 "${testcvs} -q co first-dir" \ +"U first-dir/imported-f1 +U first-dir/imported-f2 +U first-dir/imported-f3 +U first-dir/imported-f4" + + cd first-dir + + for i in 1 2 3 4 ; do + dotest import-98-$i "test -f imported-f$i" '' + done + dotest_fail import-98.5 "test -d RCS" '' + + # remove + rm imported-f1 + dotest import-99 "${testcvs} rm imported-f1" \ +"${SPROG}"' remove: scheduling `imported-f1'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove this file permanently' + + # change + echo local-change >> imported-f2 + + # commit + dotest import-100 "${testcvs} ci -m local-changes" \ +"${CPROG} commit: Examining . +${CVSROOT_DIRNAME}/first-dir/imported-f1,v <-- imported-f1 +new revision: delete; previous revision: 1\.1\.1\.1 +${CVSROOT_DIRNAME}/first-dir/imported-f2,v <-- imported-f2 +new revision: 1\.2; previous revision: 1\.1" + + # log + dotest import-101 "${testcvs} log imported-f1" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/imported-f1,v +Working file: imported-f1 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + junk-1_0: 1\.1\.1\.1 + vendor-branch: 1\.1\.1 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: dead; lines: ${PLUS}0 -0; commitid: ${commitid}; +local-changes +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.1; +Initial revision +---------------------------- +revision 1\.1\.1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +first-import +=============================================================================" + + # update into the vendor branch. + dotest import-102 "${testcvs} update -rvendor-branch" \ +"${SPROG} update: Updating . +[UP] imported-f1 +[UP] imported-f2" + + # remove file4 on the vendor branch + rm imported-f4 + dotest import-103 "${testcvs} rm imported-f4" \ +"${SPROG}"' remove: scheduling `imported-f4'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove this file permanently' + + # commit + dotest import-104 \ +"${testcvs} ci -m vendor-removed imported-f4" \ +"${CVSROOT_DIRNAME}/first-dir/imported-f4,v <-- imported-f4 +new revision: delete; previous revision: 1\.1\.1\.1" + + # update to main line + dotest import-105 "${testcvs} -q update -A" \ +"${SPROG} update: \`imported-f1' is no longer in the repository +[UP] imported-f2" + + # second import - file4 deliberately unchanged + cd ../import-dir + for i in 1 2 3 ; do + echo rev 2 of file $i >> imported-f"$i" + done + cp imported-f2 ../imported-f2-orig.tmp + + dotest_sort import-106 \ +"${testcvs} import -m second-import first-dir vendor-branch junk-2_0" \ +" + + + ${CPROG} checkout -j<prev_rel_tag> -jjunk-2_0 first-dir +2 conflicts created by this import. +C first-dir/imported-f1 +C first-dir/imported-f2 +I first-dir/RCS +U first-dir/imported-f3 +U first-dir/imported-f4 +Use the following command to help the merge:" + + dotest import-106.5 "cmp ../imported-f2-orig.tmp imported-f2" \ +'' + + cd .. + + rm imported-f2-orig.tmp + + # co + dotest import-107 "${testcvs} co first-dir" \ +"${SPROG} checkout: Updating first-dir +[UP] first-dir/imported-f3 +[UP] first-dir/imported-f4" + + cd first-dir + + dotest_fail import-108 "test -f imported-f1" '' + + for i in 2 3 ; do + dotest import-109-$i "test -f imported-f$i" '' + done + + # check vendor branch for file4 + dotest import-110 "${testcvs} -q update -rvendor-branch" \ +"[UP] imported-f1 +[UP] imported-f2" + + dotest import-111 "test -f imported-f4" '' + + # update to main line + dotest import-112 "${testcvs} -q update -A" \ +"${SPROG} update: \`imported-f1' is no longer in the repository +[UP] imported-f2" + + cd .. + + dotest import-113 \ +"${testcvs} -q co -jjunk-1_0 -jjunk-2_0 first-dir" \ +"${SPROG} checkout: file first-dir/imported-f1 does not exist, but is present in revision junk-2_0 +RCS file: ${CVSROOT_DIRNAME}/first-dir/imported-f2,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.2 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into imported-f2 +rcsmerge: warning: conflicts during merge +first-dir/imported-f3 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.2 +first-dir/imported-f4 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.3" + + cd first-dir + + dotest_fail import-114 "test -f imported-f1" '' + + for i in 2 3 ; do + dotest import-115-$i "test -f imported-f$i" '' + done + + dotest import-116 'cat imported-f2' \ +'imported file2 +[<]<<<<<< imported-f2 +import should not expand \$''Id: imported-f2,v 1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$ +local-change +[=]====== +import should not expand \$''Id: imported-f2,v 1\.1\.1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$ +rev 2 of file 2 +[>]>>>>>> 1\.1\.1\.2' + + dokeep + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r import-dir + ;; + + + + importb) + # More cvs import tests, especially -b option. + + # OK, first we get some sources from the NetMunger project, and + # import them into the 1.1.1 vendor branch. + mkdir imp-dir + cd imp-dir + echo 'OpenMunger sources' >file1 + echo 'OpenMunger sources' >file2 + dotest_sort importb-1 \ +"${testcvs} import -m add first-dir openmunger openmunger-1_0" \ +" + +N first-dir/file1 +N first-dir/file2 +No conflicts created by this import" + cd .. + rm -r imp-dir + + # Now we put the sources we get from FreeMunger into 1.1.3 + mkdir imp-dir + cd imp-dir + echo 'FreeMunger sources' >file1 + echo 'FreeMunger sources' >file2 + # Not completely sure how the conflict detection is supposed to + # be working here (haven't really thought about it). + # We use an explicit -d option to test that it is reflected + # in the suggested checkout. + dotest_sort importb-2 \ +"$testcvs -d '$CVSROOT' import -m add -b 1.1.3 \ + first-dir freemunger freemunger-1_0" \ +" + + + ${CPROG} -d ${CVSROOT} checkout -j<prev_rel_tag> -jfreemunger-1_0 first-dir +2 conflicts created by this import. +C first-dir/file1 +C first-dir/file2 +Use the following command to help the merge:" + cd .. + rm -r imp-dir + + # Now a test of main branch import (into second-dir, not first-dir). + mkdir imp-dir + cd imp-dir + echo 'my own stuff' >mine1.c + echo 'my own stuff' >mine2.c + dotest_fail importb-3 \ +"${testcvs} import -m add -b 1 second-dir dummy really_dumb_y" \ +"$CPROG \[import aborted\]: Only numeric branch specifications with two dots are +supported by import, not \`1'\. For example: \`1\.1\.1'\." + : when we implement main-branch import, should be \ +"N second-dir/mine1\.c +N second-dir/mine2\.c + +No conflicts created by this import" + cd .. + rm -r imp-dir + + mkdir 1 + cd 1 + # when we implement main branch import, will want to + # add "second-dir" here. + dotest importb-4 "${testcvs} -q co first-dir" \ +"U first-dir/file1 +U first-dir/file2" + cd first-dir + dotest importb-5 "${testcvs} -q log file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: 1\.1\.1 +locks: strict +access list: +symbolic names: + freemunger-1_0: 1\.1\.3\.1 + freemunger: 1\.1\.3 + openmunger-1_0: 1\.1\.1\.1 + openmunger: 1\.1\.1 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.1; 1\.1\.3; +Initial revision +---------------------------- +revision 1\.1\.3\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +add +---------------------------- +revision 1\.1\.1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +add +=============================================================================" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + importc) + # Test importing a bunch o' files in a bunch o' directories. + # Also the -d option. + + # Set a predictable time zone for these tests. + save_TZ=$TZ + TZ=UTC0; export TZ + + mkdir 1; cd 1 + mkdir adir bdir cdir + mkdir adir/sub1 adir/sub2 + mkdir adir/sub1/ssdir + mkdir bdir/subdir + touch adir/sub1/file1 adir/sub2/file2 adir/sub1/ssdir/ssfile + touch -t ${TOUCH1971} bdir/subdir/file1 + touch -t ${TOUCH2034} cdir/cfile + dotest_sort importc-1 \ +"${testcvs} import -d -m import-it first-dir vendor release" \ +" + +N first-dir/adir/sub1/file1 +N first-dir/adir/sub1/ssdir/ssfile +N first-dir/adir/sub2/file2 +N first-dir/bdir/subdir/file1 +N first-dir/cdir/cfile +No conflicts created by this import +${SPROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir +${SPROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1 +${SPROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1/ssdir +${SPROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub2 +${SPROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/bdir +${SPROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/bdir/subdir +${SPROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/cdir" + cd .. + mkdir 2; cd 2 + dotest importc-2 "${testcvs} -q co first-dir" \ +"U first-dir/adir/sub1/file1 +U first-dir/adir/sub1/ssdir/ssfile +U first-dir/adir/sub2/file2 +U first-dir/bdir/subdir/file1 +U first-dir/cdir/cfile" + cd first-dir + dotest importc-3 "${testcvs} update adir/sub1" \ +"${SPROG} update: Updating adir/sub1 +${SPROG} update: Updating adir/sub1/ssdir" + dotest importc-4 "${testcvs} update adir/sub1 bdir/subdir" \ +"${SPROG} update: Updating adir/sub1 +${SPROG} update: Updating adir/sub1/ssdir +${SPROG} update: Updating bdir/subdir" + + echo modify >>cdir/cfile + dotest importc-5 \ +"${testcvs} -q rtag -b -r release wip_test first-dir" "" + dotest importc-6 "${testcvs} -q update -r wip_test" "M cdir/cfile" + + # This used to fail in local mode + dotest importc-7 "${testcvs} -q ci -m modify -r wip_test" \ +"$CVSROOT_DIRNAME/first-dir/cdir/cfile,v <-- cdir/cfile +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1" + + # TODO: should also be testing "import -d" when we update + # an existing file. + dotest importc-8 "${testcvs} -q log cdir/cfile" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v +Working file: cdir/cfile +head: 1\.1 +branch: 1\.1\.1 +locks: strict +access list: +symbolic names: + wip_test: 1\.1\.1\.1\.0\.2 + release: 1\.1\.1\.1 + vendor: 1\.1\.1 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE2034}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.1; +Initial revision +---------------------------- +revision 1\.1\.1\.1 +date: ${ISO8601DATE2034}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +branches: 1\.1\.1\.1\.2; +import-it +---------------------------- +revision 1\.1\.1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify +=============================================================================" + + dotest importc-9 "${testcvs} -q log bdir/subdir/file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/bdir/subdir/file1,v +Working file: bdir/subdir/file1 +head: 1\.1 +branch: 1\.1\.1 +locks: strict +access list: +symbolic names: + wip_test: 1\.1\.1\.1\.0\.2 + release: 1\.1\.1\.1 + vendor: 1\.1\.1 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE1971}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.1; +Initial revision +---------------------------- +revision 1\.1\.1\.1 +date: ${ISO8601DATE1971}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +import-it +=============================================================================" + cd .. + + # Now tests of absolute pathnames and .. as repository directory. + cd ../1 + dotest_fail importc-10 \ +"${testcvs} import -m imp ../other vendor release2" \ +"${CPROG} \[import aborted\]: directory \.\./other not relative within the repository" + dotest_fail importc-11 \ +"${testcvs} import -m imp ${TESTDIR}/other vendor release3" \ +"${CPROG} \[import aborted\]: directory ${TESTDIR}/other not relative within the repository" + dotest_fail importc-12 "test -d ${TESTDIR}/other" "" + + dokeep + TZ=$save_TZ + cd .. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + importX) + # More cvs import tests, especially -X option. + + # OK, first we get some sources from the Munger version 0.9, + # and import them into the 1.1.1 vendor branch (w/o -X). (This + # will be used to test subsequent imports of the same file + # with -X.) + mkdir imp-dir + cd imp-dir + echo 'Munger sources 0.9' >file0 + dotest_sort importX-1 \ +"${testcvs} import -m add first-dir munger munger-0_9" \ +" + +N first-dir/file0 +No conflicts created by this import" + cd .. + rm -r imp-dir + + # Now we put the sources we get from Munger version 1.0 on + # to the 1.1.1 vendor branch using -X. (This imports a new + # version of file0, and imports all-new files file1 and file2.) + mkdir imp-dir + cd imp-dir + echo 'Munger sources' >file0 + echo 'Munger sources' >file1 + echo 'Munger sources' >file2 + dotest_sort importX-2 \ +"${testcvs} import -X -m add first-dir munger munger-1_0" \ +" + + + ${CPROG} checkout -j<prev_rel_tag> -jmunger-1_0 first-dir +N first-dir/file1 +N first-dir/file2 +No conflicts created by this import. +U first-dir/file0 +Use the following command to help the merge:" + cd .. + rm -r imp-dir + + # Now we put the sources we get from Munger version 1.1 on + # to the 1.1.1 vendor branch using -X. (This imports unchanged + # versions of file0 and file2, a changed version of file1, and + # an all-new file3.) + mkdir imp-dir + cd imp-dir + echo 'Munger sources' >file0 + echo 'Munger sources 1.1' >file1 + echo 'Munger sources' >file2 + echo 'Munger sources 1.1' >file3 + dotest_sort importX-3 \ +"$testcvs -d '$CVSROOT' import -X -m add first-dir munger munger-1_1" \ +" + + + ${CPROG} -d ${CVSROOT} checkout -j<prev_rel_tag> -jmunger-1_1 first-dir +1 conflicts created by this import. +C first-dir/file1 +N first-dir/file3 +U first-dir/file0 +U first-dir/file2 +Use the following command to help the merge:" + cd .. + rm -r imp-dir + + mkdir 1 + cd 1 + # only file0 should be checked out + dotest importX-4 "${testcvs} -q co first-dir" \ +"U first-dir/file0" + cd first-dir + + dotest importX-5 "${testcvs} -q log file0" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file0,v +Working file: file0 +head: 1\.1 +branch: 1\.1\.1 +locks: strict +access list: +symbolic names: + munger-1_1: 1\.1\.1\.2 + munger-1_0: 1\.1\.1\.2 + munger-0_9: 1\.1\.1\.1 + munger: 1\.1\.1 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.1; +Initial revision +---------------------------- +revision 1\.1\.1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +add +---------------------------- +revision 1\.1\.1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +add +=============================================================================" + + dotest importX-6 "${testcvs} -q log file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +Working file: file1 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + munger-1_1: 1\.1\.1\.2 + munger-1_0: 1\.1\.1\.1 + munger: 1\.1\.1 +keyword substitution: kv +total revisions: 4; selected revisions: 4 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: dead; lines: ${PLUS}0 -0; commitid: ${commitid}; +Revision 1\.1 was added on the vendor branch\. +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.1; +Initial revision +---------------------------- +revision 1\.1\.1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +add +---------------------------- +revision 1\.1\.1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +add +=============================================================================" + + cd ../.. + rm -r 1 + modify_repo rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + + + + importX2) + # Test ImportNewFilesToVendorBranchOnly config file option. + + # On Windows, we can't check out CVSROOT, because the case + # insensitivity means that this conflicts with cvsroot. + mkdir wnt + cd wnt + + dotest importX2-1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" + cd CVSROOT + echo "ImportNewFilesToVendorBranchOnly=yes" >> config + + dotest importX2-2 "$testcvs -q ci -m force-cvs-import-X" \ +"$TESTDIR/cvsroot/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd ../.. + + # Import a sources file, but do NOT specify -X. The new file + # should be killed, anyway (because of the config option). + mkdir imp-dir + cd imp-dir + echo 'source' >file1 + dotest_sort importX2-3 \ +"${testcvs} import -m add first-dir source source-1_0" \ +" + + + ${CPROG} checkout -j<prev_rel_tag> -jsource-1_0 first-dir +N first-dir/file1 +No conflicts created by this import. +Use the following command to help the merge:" + cd .. + rm -r imp-dir + + mkdir 1 + cd 1 + # **nothing** should be checked out** + dotest importX2-4 "${testcvs} -q co first-dir" "" + + cd first-dir + dotest importX2-5 "${testcvs} -q log file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +Working file: file1 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + source-1_0: 1\.1\.1\.1 + source: 1\.1\.1 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: dead; lines: ${PLUS}0 -0; commitid: ${commitid}; +Revision 1\.1 was added on the vendor branch\. +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.1; +Initial revision +---------------------------- +revision 1\.1\.1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +add +=============================================================================" + + dokeep + cd ../.. + restore_adm + rm -r 1 + rm -r wnt + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + import-CVS) + mkdir import-CVS + cd import-CVS + touch file1 file2 file3 + dotest_fail import-CVS-1 "$testcvs import CVS vtag rtag" \ +"$CPROG import: The word \`CVS' is reserved by CVS and may not be used +$CPROG \[import aborted\]: as a directory in a path or as a file name\." + mkdir sdir + mkdir sdir/CVS + touch sdir/CVS/file4 sdir/CVS/file5 sdir/file6 sdir/file7 + # Calling the imported directory import-CVS is dual purpose in the + # following test. It makes sure the path test which matched above + # wasn't too strict. + dotest_sort import-CVS-2 \ +"$testcvs import -I! -mimport import-CVS vtag rtag" \ +" + +I import-CVS/sdir/CVS +N import-CVS/file1 +N import-CVS/file2 +N import-CVS/file3 +N import-CVS/sdir/file6 +N import-CVS/sdir/file7 +No conflicts created by this import +$SPROG import: Importing $CVSROOT_DIRNAME/import-CVS/sdir" + + dokeep + cd .. + rm -r import-CVS + modify_repo rm -rf $CVSROOT_DIRNAME/import-CVS + ;; + + + + import-quirks) + # Short tests of quirky import behavior. + # + # For a list of other import tests with short descriptions, see the + # comment header of the "import" test. + mkdir import-quirks + cd import-quirks + touch file1 file2 file3 + + # CVS prior to 1.11.18 and 1.12.10 used to happily import to + # "branch 1.1", creating RCS archives with revisions like, + # "1.1..1". That double-dot is *not* a typo. + dotest_fail import-quirks-1 \ +"$testcvs import -b1.1. -mbad-bad-bad import-quirks VB RT" \ +"$CPROG \[import aborted\]: Only numeric branch specifications with two dots are +supported by import, not \`1\.1\.'\. For example: \`1\.1\.1'\." + + dotest_fail import-quirks-2 \ +"$testcvs import -b1.1.1.. -mbad-bad-bad import-quirks VB RT" \ +"$CPROG \[import aborted\]: Only numeric branch specifications with two dots are +supported by import, not \`1\.1\.1\.\.'\. For example: \`1\.1\.1'\." + + # Try a few odd numbers. This is hardly comprehensive. + dotest_sort import-quirks-2 \ +"$testcvs import -b10.10.101 -mthis-ones-ok import-quirks-2 VB RT" \ +" + +N import-quirks-2/file1 +N import-quirks-2/file2 +N import-quirks-2/file3 +No conflicts created by this import" + + dotest_sort import-quirks-3 \ +"$testcvs import -b2345678901.2345678901.2345678901 -mthis-ones-ok import-quirks-3 VB RT" \ +" + +N import-quirks-3/file1 +N import-quirks-3/file2 +N import-quirks-3/file3 +No conflicts created by this import" + + dotest_sort import-quirks-4 \ +"$testcvs import -b1.1.2 -mthis-ones-ok import-quirks-4 VB RT" \ +" + +N import-quirks-4/file1 +N import-quirks-4/file2 +N import-quirks-4/file3 +No conflicts created by this import" + + dokeep + cd .. + rm -r import-quirks + rm -rf $CVSROOT_DIRNAME/import-quirks-2 \ + $CVSROOT_DIRNAME/import-quirks-3 \ + $CVSROOT_DIRNAME/import-quirks-4 + ;; + + + + import-after-initial) + # Properly handle the case in which the first version of a + # file is created by a regular cvs add and commit, and there + # is a subsequent cvs import of the same file. cvs update with + # a date tag must resort to searching the vendor branch only if + # the initial version of the file was created at the same time + # as the initial version on the vendor branch. + + mkdir 1; cd 1 + module=x + + echo > unused-file + + # Create the module. + dotest import-after-initial-1 \ + "$testcvs -Q import -m. $module X Y" '' + + file=m + # Check it out and add a file. + dotest import-after-initial-2 "$testcvs -Q co $module" '' + cd $module + echo original > $file + dotest import-after-initial-3 "${testcvs} -Q add $file" "" + dotest import-after-initial-4 "$testcvs -Q ci -m. $file" + + # Delay a little so the following import isn't done in the same + # second as the preceding commit. + sleep 2 + + # Do the first import of $file *after* $file already has an + # initial version. + mkdir sub + cd sub + echo newer-via-import > $file + dotest import-after-initial-5 \ + "$testcvs -Q import -m. $module X Y2" '' + cd .. + + # Sleep a second so we're sure to be after the second of the import. + sleep 1 + + dotest import-after-initial-6 \ + "$testcvs -Q update -p -D now $file" 'original' + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + branch-after-import) + # Test branching after an import via both cvs tag -b and + # cvs add to verify that the HEAD remains at 1.1.1.1 + # This was a FreeBSD bug documented at the URL: + # http://www.freebsd.org/cgi/query-pr.cgi?pr=4033 + + mkdir branch-after-import + cd branch-after-import + + # OK, first we get some sources from the NetMunger project, + # and import them into the 1.1.1 vendor branch. + mkdir imp-dir + cd imp-dir + echo 'OpenMunger sources' >file1 + echo 'OpenMunger sources' >file2 + dotest_sort branch-after-import-1 \ +"${testcvs} import -m add first-dir openmunger openmunger-1_0" \ +' + +N first-dir/file1 +N first-dir/file2 +No conflicts created by this import' + cd .. + + # Next checkout the new module + dotest branch-after-import-2 \ +"${testcvs} -q co first-dir" \ +'U first-dir/file1 +U first-dir/file2' + cd first-dir + # Branch tag the file1 and cvs add file2, + # the branch should remain the same in both cases + # such that a new import will not require a conflict + # resolution. + dotest branch-after-import-3 \ +"${testcvs} tag -b TESTTOTRON file1" \ +'T file1' + dotest branch-after-import-4 \ +"${testcvs} -q update -r TESTTOTRON" \ +"${SPROG} update: \`file2' is no longer in the repository" + + cp ../imp-dir/file2 . + dotest branch-after-import-5 \ +"${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition on branch .TESTTOTRON. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + + dotest branch-after-import-6 \ +"$testcvs commit -m cvs-add file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.1\.1\.2\.2; previous revision: 1\.1\.1\.1\.2\.1" + + dokeep + cd ../.. + rm -r branch-after-import + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + join) + # Test doing joins which involve adding and removing files. + # Variety of scenarios (see list below), in the context of: + # * merge changes from T1 to T2 into the main line + # * merge changes from branch 'branch' into the main line + # * merge changes from branch 'branch' into branch 'br2'. + # See also binfile2, which does similar things with binary files. + # See also join2, which tests joining (and update -A) on only + # a single file, rather than a directory. + # See also rmadd2, which tests -j cases not involving branches + # (e.g. undoing a commit) + # See also join3, which tests some cases involving the greatest + # common ancestor. Here is a list of tests according to branch + # topology: + # + # --->bp---->trunk too many to mention + # \----->branch + # + # /----->branch1 + # --->bp---->trunk multibranch, multibranch2 + # \----->branch2 + # + # --->bp1----->bp2---->trunk join3 + # \->br1 \->br2 + # + # --->bp1----->trunk + # \----bp2---->branch branches + # \------>branch-of-branch + + # We check merging changes from T1 to T2 into the main line. + # Here are the interesting cases I can think of: + # 1) File added between T1 and T2, not on main line. + # File should be marked for addition. + # 2) File added between T1 and T2, also added on main line. + # Conflict. + # 3) File removed between T1 and T2, unchanged on main line. + # File should be marked for removal. + # 4) File removed between T1 and T2, modified on main line. + # If mod checked in, file should be marked for removal. + # If mod still in working directory, conflict. + # 5) File removed between T1 and T2, was never on main line. + # Nothing should happen. + # 6) File removed between T1 and T2, also removed on main line. + # Nothing should happen. + # 7) File not added between T1 and T2, added on main line. + # Nothing should happen. + # 8) File not modified between T1 and T2, removed on main line. + # Nothing should happen. + # 9) File modified between T1 and T2, removed on main line. + # Conflict. + # 10) File was never on branch, removed on main line. + # Nothing should happen. + + # We also check merging changes from a branch into the main + # line. Here are the interesting cases: + # 1) File added on branch, not on main line. + # File should be marked for addition. + # 2) File added on branch, also added on main line. + # Conflict. + # 3) File removed on branch, unchanged on main line. + # File should be marked for removal. + # 4) File removed on branch, modified on main line. + # Conflict. + # 5) File removed on branch, was never on main line. + # Nothing should happen. + # 6) File removed on branch, also removed on main line. + # Nothing should happen. + # 7) File added on main line, not added on branch. + # Nothing should happen. + # 8) File removed on main line, not modified on branch. + # Nothing should happen. + # 9) File modified on branch, removed on main line. + # Conflict. + # 10) File was never on branch, removed on main line. + # Nothing should happen. + + # In the tests below, fileN represents case N in the above + # lists. + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1 + cd 1 + dotest join-1 "$testcvs -q co first-dir" + + cd first-dir + + # Add two files. + echo 'first revision of file3' > file3 + echo 'first revision of file4' > file4 + echo 'first revision of file6' > file6 + echo 'first revision of file8' > file8 + echo 'first revision of file9' > file9 + dotest join-2 "${testcvs} add file3 file4 file6 file8 file9" \ +"${SPROG}"' add: scheduling file `file3'\'' for addition +'"${SPROG}"' add: scheduling file `file4'\'' for addition +'"${SPROG}"' add: scheduling file `file6'\'' for addition +'"${SPROG}"' add: scheduling file `file8'\'' for addition +'"${SPROG}"' add: scheduling file `file9'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + + dotest join-3 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file6,v <-- file6 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file8,v <-- file8 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file9,v <-- file9 +initial revision: 1\.1" + + # Make a branch. + dotest join-4 "${testcvs} -q tag -b branch ." \ +'T file3 +T file4 +T file6 +T file8 +T file9' + + # Add file2, file7, and file10, modify file4, and remove + # file6, file8, and file9. + echo 'first revision of file2' > file2 + echo 'second revision of file4' > file4 + echo 'first revision of file7' > file7 + rm file6 file8 file9 + echo 'first revision of file10' > file10 + dotest join-5 "${testcvs} add file2 file7 file10" \ +"${SPROG}"' add: scheduling file `file2'\'' for addition +'"${SPROG}"' add: scheduling file `file7'\'' for addition +'"${SPROG}"' add: scheduling file `file10'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + dotest join-6 "${testcvs} rm file6 file8 file9" \ +"${SPROG}"' remove: scheduling `file6'\'' for removal +'"${SPROG}"' remove: scheduling `file8'\'' for removal +'"${SPROG}"' remove: scheduling `file9'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove these files permanently' + dotest join-7 "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/file10,v <-- file10 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file6,v <-- file6 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file7,v <-- file7 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file8,v <-- file8 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file9,v <-- file9 +new revision: delete; previous revision: 1\.1" + + # Remove file10 + dotest join-7a "${testcvs} rm -f file10" \ +"${SPROG}"' remove: scheduling `file10'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove this file permanently' + dotest join-7b "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/file10,v <-- file10 +new revision: delete; previous revision: 1\.1" + + # Check out the branch. + cd ../.. + mkdir 2 + cd 2 + dotest join-8 "${testcvs} -q co -r branch first-dir" \ +'U first-dir/file3 +U first-dir/file4 +U first-dir/file6 +U first-dir/file8 +U first-dir/file9' + + cd first-dir + + # Modify the files on the branch, so that T1 is not an + # ancestor of the main line, and add file5 + echo 'first branch revision of file3' > file3 + echo 'first branch revision of file4' > file4 + echo 'first branch revision of file5' > file5 + echo 'first branch revision of file6' > file6 + echo 'first branch revision of file9' > file9 + dotest join-9 "${testcvs} add file5" \ +"${SPROG}"' add: scheduling file `file5'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest join-10 "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file5,v <-- file5 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file6,v <-- file6 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file9,v <-- file9 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # Tag the current revisions on the branch. + dotest join-11 "${testcvs} -q tag T1 ." \ +'T file3 +T file4 +T file5 +T file6 +T file8 +T file9' + + # Add file1 and file2, modify file9, and remove the other files. + echo 'first branch revision of file1' > file1 + echo 'first branch revision of file2' > file2 + echo 'second branch revision of file9' > file9 + rm file3 file4 file5 file6 + dotest join-12 "${testcvs} add file1 file2" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + dotest join-13 "${testcvs} rm file3 file4 file5 file6" \ +"${SPROG}"' remove: scheduling `file3'\'' for removal +'"${SPROG}"' remove: scheduling `file4'\'' for removal +'"${SPROG}"' remove: scheduling `file5'\'' for removal +'"${SPROG}"' remove: scheduling `file6'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove these files permanently' + dotest join-14 "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/Attic/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file5,v <-- file5 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file6,v <-- file6 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file9,v <-- file9 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + + # Tag the current revisions on the branch. + dotest join-15 "${testcvs} -q tag T2 ." \ +'T file1 +T file2 +T file8 +T file9' + + # Do a checkout with a merge. + cd ../.. + mkdir 3 + cd 3 + dotest join-16 "${testcvs} -q co -jT1 -jT2 first-dir" \ +"U first-dir/file1 +U first-dir/file2 +${SPROG} checkout: file first-dir/file2 exists, but has been added in revision T2 +U first-dir/file3 +${SPROG} checkout: scheduling \`first-dir/file3' for removal +U first-dir/file4 +${SPROG} checkout: scheduling \`first-dir/file4' for removal +U first-dir/file7 +${SPROG} checkout: file first-dir/file9 does not exist, but is present in revision T2" + + # Verify that the right changes have been scheduled. + cd first-dir + dotest join-17 "${testcvs} -q update" \ +'A file1 +R file3 +R file4' + + # Modify file4 locally, and do an update with a merge. + cd ../../1/first-dir + echo 'third revision of file4' > file4 + dotest join-18 "${testcvs} -q update -jT1 -jT2 ." \ +"U file1 +$SPROG update: file file2 exists, but has been added in revision T2 +$SPROG update: scheduling \`file3' for removal +M file4 +$SPROG update: file file4 is locally modified, but has been removed in revision T2 +$SPROG update: file file9 does not exist, but is present in revision T2" + + # Verify that the right changes have been scheduled. + dotest join-19 "${testcvs} -q update" \ +'A file1 +R file3 +M file4' + + # Do a checkout with a merge from a single revision. + + # FIXME: CVS currently gets this wrong. file2 has been + # added on both the branch and the main line, and so should + # be regarded as a conflict. However, given the way that + # CVS sets up the RCS file, there is no way to distinguish + # this case from the case of file2 having existed before the + # branch was made. This could be fixed by reserving + # a revision somewhere, perhaps 1.1, as an always dead + # revision which can be used as the source for files added + # on branches. + cd ../../3 + rm -r first-dir + dotest join-20 "${testcvs} -q co -jbranch first-dir" \ +"U first-dir/file1 +U first-dir/file2 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.2 +Merging differences between 1\.1 and 1\.1\.2\.2 into file2 +U first-dir/file3 +${SPROG} checkout: scheduling \`first-dir/file3' for removal +U first-dir/file4 +${SPROG} checkout: file first-dir/file4 has been modified, but has been removed in revision branch +U first-dir/file7 +${SPROG} checkout: file first-dir/file9 does not exist, but is present in revision branch" + + # Verify that the right changes have been scheduled. + # The M file2 line is a bug; see above join-20. + cd first-dir + dotest join-21 "${testcvs} -q update" \ +'A file1 +M file2 +R file3' + + # Checkout the main line again. + cd ../../1 + rm -r first-dir + dotest join-22 "${testcvs} -q co first-dir" \ +'U first-dir/file2 +U first-dir/file3 +U first-dir/file4 +U first-dir/file7' + + # Modify file4 locally, and do an update with a merge from a + # single revision. + # The file2 handling is a bug; see above join-20. + cd first-dir + echo 'third revision of file4' > file4 + dotest join-23 "${testcvs} -q update -jbranch ." \ +"U file1 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.2 +Merging differences between 1\.1 and 1\.1\.2\.2 into file2 +${SPROG} update: scheduling \`file3' for removal +M file4 +${SPROG} update: file file4 is locally modified, but has been removed in revision branch +${SPROG} update: file file9 does not exist, but is present in revision branch" + + # Verify that the right changes have been scheduled. + # The M file2 line is a bug; see above join-20 + dotest join-24 "${testcvs} -q update" \ +'A file1 +M file2 +R file3 +M file4' + + cd .. + + # Checkout the main line again and make a new branch which we + # merge to. + rm -r first-dir + dotest join-25 "${testcvs} -q co first-dir" \ +'U first-dir/file2 +U first-dir/file3 +U first-dir/file4 +U first-dir/file7' + cd first-dir + dotest join-26 "${testcvs} -q tag -b br2" \ +"T file2 +T file3 +T file4 +T file7" + dotest join-27 "${testcvs} -q update -r br2" "" + # The handling of file8 and file9 here look fishy to me. I don't + # see why it should be different from the case where we merge to + # the trunk (e.g. join-23). + dotest join-28 "${testcvs} -q update -j branch" \ +"U file1 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +retrieving revision 1.1 +retrieving revision 1.1.2.2 +Merging differences between 1.1 and 1.1.2.2 into file2 +${SPROG} update: scheduling \`file3' for removal +${SPROG} update: file file4 has been modified, but has been removed in revision branch +U file8 +U file9" + # Verify that the right changes have been scheduled. + dotest join-29 "${testcvs} -q update" \ +"A file1 +M file2 +R file3 +A file8 +A file9" + + # Checkout the mainline again to try updating and merging between two + # branches in the same step + # this seems a likely scenario - the user finishes up on branch and + # updates to br2 and merges in the same step - and there was a bug + # once that if the file was removed in the update then it wouldn't be + # readded in the merge + cd .. + rm -r first-dir + dotest join-twobranch-1 "${testcvs} -q co -rbranch first-dir" \ +'U first-dir/file1 +U first-dir/file2 +U first-dir/file8 +U first-dir/file9' + cd first-dir + dotest join-twobranch-2 "${testcvs} -q update -rbr2 -jbranch" \ +"${SPROG} update: \`file1' is no longer in the repository +U file1 +U file2 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.2 +Merging differences between 1\.1 and 1\.1\.2\.2 into file2 +U file3 +${SPROG} update: scheduling \`file3' for removal +U file4 +${SPROG} update: file file4 has been modified, but has been removed in revision branch +U file7 +${SPROG} update: \`file8' is no longer in the repository +U file8 +${SPROG} update: \`file9' is no longer in the repository +U file9" + # Verify that the right changes have been scheduled. + dotest join-twobranch-3 "${testcvs} -q update" \ +"A file1 +M file2 +R file3 +A file8 +A file9" + + # Checkout the mainline again to try merging from the trunk + # to a branch. + cd .. + rm -r first-dir + dotest join-30 "${testcvs} -q co first-dir" \ +'U first-dir/file2 +U first-dir/file3 +U first-dir/file4 +U first-dir/file7' + cd first-dir + + # Tag the current revisions on the trunk. + dotest join-31 "${testcvs} -q tag T3 ." \ +'T file2 +T file3 +T file4 +T file7' + + # Modify file7. + echo 'second revision of file7' > file7 + dotest join-32 "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/file7,v <-- file7 +new revision: 1\.2; previous revision: 1\.1" + + # And Tag again. + dotest join-33 "${testcvs} -q tag T4 ." \ +'T file2 +T file3 +T file4 +T file7' + + # Now update branch to T3. + cd ../../2/first-dir + dotest join-34 "${testcvs} -q up -jT3" \ +"${SPROG} update: file file4 does not exist, but is present in revision T3 +U file7" + + # Verify that the right changes have been scheduled. + dotest join-35 "${testcvs} -q update" \ +'A file7' + + # Now update to T4. + # This is probably a bug, although in this particular case it just + # happens to do the right thing; see above join-20. + dotest join-36 "${testcvs} -q up -j T3 -j T4" \ +"A file7 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into file7" + + # Verify that the right changes have been scheduled. + dotest join-37 "${testcvs} -q update" \ +'A file7' + + dokeep + cd ../.. + rm -r 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + join2) + # More joining tests. + + # First the usual setup; create a directory first-dir, a file + # first-dir/file1, and a branch br1. + mkdir 1; cd 1 + dotest join2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest join2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo 'initial contents of file1' >file1 + dotest join2-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest join2-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + dotest join2-5 "${testcvs} -q tag -b br1" "T file1" + dotest join2-6 "${testcvs} -q update -r br1" "" + echo 'modify on branch' >>file1 + touch bradd + dotest join2-6a "${testcvs} add bradd" \ +"${SPROG} add: scheduling file .bradd. for addition on branch .br1. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest join2-7 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/Attic/bradd,v <-- bradd +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # Here is the unusual/pathological part. We switch back to + # the trunk *for file1 only*, not for the whole directory. + dotest join2-8 "${testcvs} -q update -A file1" '[UP] file1' + dotest join2-9 "${testcvs} -q status file1" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest join2-10 "cat CVS/Tag" "Tbr1" + + dotest join2-11 "${testcvs} -q update -j br1 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file1" + dotest join2-12 "cat file1" "initial contents of file1 +modify on branch" + # We should have no sticky tag on file1 + dotest join2-13 "${testcvs} -q status file1" \ +"=================================================================== +File: file1 Status: Locally Modified + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest join2-14 "cat CVS/Tag" "Tbr1" + # And the checkin should go to the trunk + dotest join2-15 "${testcvs} -q ci -m modify file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + + # OK, the above is all well and good and has worked for some + # time. Now try the case where the file had been added on + # the branch. + dotest join2-16 "${testcvs} -q update -r br1" "[UP] file1" + # The workaround is to update the whole directory. + # The non-circumvented version won't work. The reason is that + # update removes the entry from CVS/Entries, so of course we get + # the tag from CVS/Tag and not Entries. I suppose maybe + # we could invent some new format in Entries which would handle + # this, but doing so, and handling it properly throughout + # CVS, would be a lot of work and I'm not sure this case justifies + # it. + dotest join2-17-circumvent "${testcvs} -q update -A" \ +"${SPROG} update: \`bradd' is no longer in the repository +[UP] file1" +: dotest join2-17 "${testcvs} -q update -A bradd" \ +"${SPROG} update: warning: \`bradd' is not (any longer) pertinent" + dotest join2-18 "${testcvs} -q update -j br1 bradd" "U bradd" + dotest join2-19 "${testcvs} -q status bradd" \ +"=================================================================== +File: bradd Status: Locally Added + + Working revision: New file! + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest join2-20 "${testcvs} -q ci -m modify bradd" \ +"$CVSROOT_DIRNAME/first-dir/bradd,v <-- bradd +new revision: 1\.2; previous revision: 1\.1" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + join3) + # See "join" for a list of other joining/branching tests. + # First the usual setup; create a directory first-dir, a file + # first-dir/file1, and a branch br1. + mkdir 1; cd 1 + dotest join3-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest join3-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo 'initial contents of file1' >file1 + dotest join3-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest join3-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + dotest join3-5 "${testcvs} -q tag -b br1" "T file1" + dotest join3-6 "${testcvs} -q update -r br1" "" + echo 'br1:line1' >>file1 + dotest join3-7 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # Now back to the trunk for: + # another revision and another branch for file1. + # add file2, which will exist on trunk and br2 but not br1. + dotest join3-8 "${testcvs} -q update -A" "[UP] file1" + echo 'trunk:line1' > file2 + dotest join3-8a "${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + echo 'trunk:line1' >>file1 + dotest join3-9 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + dotest join3-10 "${testcvs} -q tag -b br2" "T file1 +T file2" + + # Before we actually have any revision on br2, let's try a join + dotest join3-11 "${testcvs} -q update -r br1" "[UP] file1 +${SPROG} update: \`file2' is no longer in the repository" + dotest join3-12 "${testcvs} -q update -j br2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into file1 +rcsmerge: warning: conflicts during merge +U file2" + dotest join3-13 "cat file1" \ +"initial contents of file1 +[<]<<<<<< file1 +br1:line1 +[=]====== +trunk:line1 +[>]>>>>>> 1\.2" + rm file1 + + # OK, we'll try the same thing with a revision on br2. + dotest join3-14 "${testcvs} -q update -r br2 file1" \ +"${SPROG} update: warning: \`file1' was lost +U file1" "U file1" + echo 'br2:line1' >>file1 + dotest join3-15 "${testcvs} -q ci -m modify file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2\.2\.1; previous revision: 1\.2" + + # OK, now we can join br2 to br1 + dotest join3-16 "${testcvs} -q update -r br1 file1" "[UP] file1" + # It may seem odd, to merge a higher branch into a lower + # branch, but in fact CVS defines the ancestor as 1.1 + # and so it merges both the 1.1->1.2 and 1.2->1.2.2.1 changes. + # This seems like a reasonably plausible behavior. + dotest join3-17 "${testcvs} -q update -j br2 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.2\.2\.1 +Merging differences between 1\.1 and 1\.2\.2\.1 into file1 +rcsmerge: warning: conflicts during merge" + dotest join3-18 "cat file1" \ +"initial contents of file1 +[<]<<<<<< file1 +br1:line1 +[=]====== +trunk:line1 +br2:line1 +[>]>>>>>> 1\.2\.2\.1" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + join4) + # Like join, but with local (uncommitted) modifications. + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1 + cd 1 + dotest join4-1 "${testcvs} -q co first-dir" '' + + cd first-dir + + # Add two files. + echo 'first revision of file3' > file3 + echo 'first revision of file4' > file4 + echo 'first revision of file6' > file6 + echo 'first revision of file8' > file8 + echo 'first revision of file9' > file9 + dotest join4-2 "${testcvs} add file3 file4 file6 file8 file9" \ +"${SPROG}"' add: scheduling file `file3'\'' for addition +'"${SPROG}"' add: scheduling file `file4'\'' for addition +'"${SPROG}"' add: scheduling file `file6'\'' for addition +'"${SPROG}"' add: scheduling file `file8'\'' for addition +'"${SPROG}"' add: scheduling file `file9'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + + dotest join4-3 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file6,v <-- file6 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file8,v <-- file8 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file9,v <-- file9 +initial revision: 1\.1" + + # Make a branch. + dotest join4-4 "${testcvs} -q tag -b branch ." \ +'T file3 +T file4 +T file6 +T file8 +T file9' + + # Add file10 + echo 'first revision of file10' > file10 + dotest join4-7a "${testcvs} add file10" \ +"${SPROG}"' add: scheduling file `file10'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest join4-7b "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/file10,v <-- file10 +initial revision: 1\.1" + + # Add file2 and file7, modify file4, and remove + # file6, file8, file9, and file10. + echo 'first revision of file2' > file2 + echo 'second revision of file4' > file4 + echo 'first revision of file7' > file7 + rm file6 file8 file9 file10 + dotest join4-5 "${testcvs} add file2 file7" \ +"${SPROG}"' add: scheduling file `file2'\'' for addition +'"${SPROG}"' add: scheduling file `file7'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + dotest join4-6 "${testcvs} rm file6 file8 file9 file10" \ +"${SPROG}"' remove: scheduling `file6'\'' for removal +'"${SPROG}"' remove: scheduling `file8'\'' for removal +'"${SPROG}"' remove: scheduling `file9'\'' for removal +'"${SPROG}"' remove: scheduling `file10'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove these files permanently' + + # Check out the branch. + cd ../.. + mkdir 2 + cd 2 + dotest join4-8 "${testcvs} -q co -r branch first-dir" \ +'U first-dir/file3 +U first-dir/file4 +U first-dir/file6 +U first-dir/file8 +U first-dir/file9' + + cd first-dir + + # Modify the files on the branch, so that T1 is not an + # ancestor of the main line, and add file5 + echo 'first branch revision of file3' > file3 + echo 'first branch revision of file4' > file4 + echo 'first branch revision of file5' > file5 + echo 'first branch revision of file6' > file6 + echo 'first branch revision of file9' > file9 + dotest join4-9 "${testcvs} add file5" \ +"${SPROG}"' add: scheduling file `file5'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest join4-10 "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file5,v <-- file5 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file6,v <-- file6 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file9,v <-- file9 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # Tag the current revisions on the branch. + dotest join4-11 "${testcvs} -q tag T1 ." \ +'T file3 +T file4 +T file5 +T file6 +T file8 +T file9' + + # Add file1 and file2, modify file9, and remove the other files. + echo 'first branch revision of file1' > file1 + echo 'first branch revision of file2' > file2 + echo 'second branch revision of file9' > file9 + rm file3 file4 file5 file6 + dotest join4-12 "${testcvs} add file1 file2" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\'' +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + dotest join4-13 "${testcvs} rm file3 file4 file5 file6" \ +"${SPROG}"' remove: scheduling `file3'\'' for removal +'"${SPROG}"' remove: scheduling `file4'\'' for removal +'"${SPROG}"' remove: scheduling `file5'\'' for removal +'"${SPROG}"' remove: scheduling `file6'\'' for removal +'"${SPROG}"' remove: use .'"${SPROG}"' commit. to remove these files permanently' + dotest join4-14 "${testcvs} -q ci -mx ." \ +"$CVSROOT_DIRNAME/first-dir/Attic/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file3,v <-- file3 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file5,v <-- file5 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/file6,v <-- file6 +new revision: delete; previous revision: 1\.1\.2\.1 +$CVSROOT_DIRNAME/first-dir/file9,v <-- file9 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + + # Tag the current revisions on the branch. + dotest join4-15 "${testcvs} -q tag T2 ." \ +'T file1 +T file2 +T file8 +T file9' + + # Modify file4 locally, and do an update with a merge. + cd ../../1/first-dir + echo 'third revision of file4' > file4 + dotest join4-18 "${testcvs} -q update -jT1 -jT2 ." \ +"U file1 +R file10 +A file2 +${SPROG} update: file file2 exists, but has been added in revision T2 +${SPROG} update: scheduling \`file3' for removal +M file4 +${SPROG} update: file file4 is locally modified, but has been removed in revision T2 +R file6 +A file7 +R file8 +R file9 +${SPROG} update: file file9 does not exist, but is present in revision T2" + + # Verify that the right changes have been scheduled. + dotest join4-19 "${testcvs} -q update" \ +'A file1 +R file10 +A file2 +R file3 +M file4 +R file6 +A file7 +R file8 +R file9' + + dokeep + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + join5) + # This test verifies that CVS can handle filenames starting with a + # dash (`-') properly. What used to happen was that CVS handled it + # just fine, until it went to pass them as arguments to the diff + # library, at which point it neglected to pass `--' before the file + # list, causing the diff library to attempt to interpret the file + # name as an argument. + mkdir join5; cd join5 + mkdir 1; cd 1 + dotest join5-init-1 "${testcvs} -Q co -l ." + mkdir join5 + dotest join5-init-2 "${testcvs} -Q add join5" + cd join5 + echo "there once was a file from harrisburg" >-file + echo "who's existance it seems was quiteabsurd" >>-file + dotest join5-init-3 "${testcvs} -Q add -- -file" + dotest join5-init-4 "${testcvs} -q ci -minitial" \ +"$CVSROOT_DIRNAME/join5/-file,v <-- -file +initial revision: 1\.1" + cd ../.. + + mkdir 2; cd 2 + dotest join5-init-5 "${testcvs} -Q co join5" + cd join5 + echo "it tested for free" >>-file + echo "when paid it should be" >>-file + dotest join5-init-4 "${testcvs} -q ci -msecond" \ +"$CVSROOT_DIRNAME/join5/-file,v <-- -file +new revision: 1\.2; previous revision: 1\.1" + cd ../.. + + cd 1/join5 + echo "but maybe it could charge bytheword" >>-file + # This is the test that used to spew complaints from diff3: + dotest join5 "${testcvs} up" \ +"${SPROG} update: Updating \. +RCS file: ${CVSROOT_DIRNAME}/join5/-file,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into -file +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in -file +C -file" + + dokeep + cd ../../.. + rm -r join5 + modify_repo rm -rf $CVSROOT_DIRNAME/join5 + ;; + + + + join6) + mkdir join6; cd join6 + mkdir 1; cd 1 + dotest join6-init-1 "${testcvs} -Q co -l ." + mkdir join6 + dotest join6-init-2 "${testcvs} -Q add join6" + cd join6 + echo aaa >temp.txt + echo bbb >>temp.txt + echo ccc >>temp.txt + dotest join6-1 "${testcvs} -Q add temp.txt" + dotest join6-2 "${testcvs} -q commit -minitial temp.txt" \ +"$CVSROOT_DIRNAME/join6/temp\.txt,v <-- temp\.txt +initial revision: 1\.1" + cp temp.txt temp2.txt + echo ddd >>temp.txt + dotest join6-3 "${testcvs} -q commit -madd temp.txt" \ +"$CVSROOT_DIRNAME/join6/temp.txt,v <-- temp\.txt +new revision: 1\.2; previous revision: 1\.1" + + # The case where the merge target is up-to-date and its base revision + # matches the second argument to -j: CVS doesn't bother attempting + # the merge since it already knows that the target contains the + # change. + dotest join6-3.3 "${testcvs} update -j1.1 -j1.2 temp.txt" \ +"temp\.txt already contains the differences between 1\.1 and 1\.2" + dotest join6-3.4 "${testcvs} diff temp.txt" "" + + # The case where the merge target is modified but already contains + # the change. + echo bbb >temp.txt + echo ccc >>temp.txt + echo ddd >>temp.txt + dotest join6-3.5 "${testcvs} update -j1.1 -j1.2 temp.txt" \ +"M temp\.txt +RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into temp\.txt +temp\.txt already contains the differences between 1\.1 and 1\.2" + dotest_fail join6-3.6 "${testcvs} diff temp.txt" \ +"Index: temp\.txt +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v +retrieving revision 1\.2 +diff -r1\.2 temp.txt +1d0 +< aaa" + + cp temp2.txt temp.txt + dotest_fail join6-4 "${testcvs} diff temp.txt" \ +"Index: temp.txt +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v +retrieving revision 1\.2 +diff -r1\.2 temp\.txt +4d3 +< ddd" + + dotest join6-5 "${testcvs} update -j1.1 -j1.2 temp.txt" \ +"M temp\.txt +RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into temp\.txt" + dotest join6-6 "${testcvs} diff temp.txt" "" + mv temp.txt temp3.txt + dotest join6-7 "sed 's/ddd/dddd/' < temp3.txt > temp.txt" "" + dotest join6-8 "${testcvs} update -j1.1 -j1.2 temp.txt" \ +"M temp\.txt +RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into temp\.txt +rcsmerge: warning: conflicts during merge" + dotest_fail join6-9 "${testcvs} diff temp.txt" \ +"Index: temp\.txt +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v +retrieving revision 1\.2 +diff -r1\.2 temp\.txt +3a4,6 +> <<<<<<< temp\.txt +> dddd +> ======= +4a8 +> >>>>>>> 1\.2" + cp temp2.txt temp.txt + dotest join6-10 "${testcvs} -q ci -m del temp.txt" \ +"$CVSROOT_DIRNAME/join6/temp.txt,v <-- temp\.txt +new revision: 1\.3; previous revision: 1\.2" + cp temp3.txt temp.txt + dotest_fail join6-11 "${testcvs} diff temp.txt" \ +"Index: temp\.txt +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v +retrieving revision 1\.3 +diff -r1\.3 temp\.txt +3a4 +> ddd" + dotest join6-12 "${testcvs} update -j1.2 -j1.3 temp.txt" \ +"M temp\.txt +RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v +retrieving revision 1\.2 +retrieving revision 1\.3 +Merging differences between 1\.2 and 1\.3 into temp\.txt" + dotest join6-13 "${testcvs} diff temp.txt" "" + + # The case where the merge target wasn't created until after the + # first tag was applied + rm temp2.txt temp3.txt + dotest join6-20 "${testcvs} -q tag -r1.1 t1" \ +"T temp.txt" + echo xxx >temp2.txt + dotest join6-21 "${testcvs} -Q add temp2.txt" + dotest join6-22 "${testcvs} -q ci -m." \ +"$CVSROOT_DIRNAME/join6/temp2\.txt,v <-- temp2\.txt +initial revision: 1\.1" + dotest join6-23 "${testcvs} -q tag t2" \ +"T temp.txt +T temp2.txt" + echo xxx >>temp.txt + dotest join6-24 "${testcvs} -q ci -m." \ +"$CVSROOT_DIRNAME/join6/temp.txt,v <-- temp\.txt +new revision: 1\.4; previous revision: 1\.3" + dotest join6-25 "${testcvs} -q up -jt1 -jt2" \ +"RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v +retrieving revision 1\.1 +retrieving revision 1\.3 +Merging differences between 1\.1 and 1\.3 into temp.txt +temp.txt already contains the differences between 1\.1 and 1\.3 +temp2.txt already contains the differences between creation and 1\.1" + + # Now for my next trick: delete the file, recreate it, and + # try to merge + dotest join6-30 "${testcvs} -q rm -f temp2.txt" \ +"${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest join6-31 "${testcvs} -q ci -m. temp2.txt" \ +"$CVSROOT_DIRNAME/join6/temp2\.txt,v <-- temp2\.txt +new revision: delete; previous revision: 1\.1" + echo new >temp2.txt + # FIXCVS: Local and remote really shouldn't be different and there + # really shouldn't be two different status lines for temp2.txt + if $remote; then + dotest_fail join6-32 "${testcvs} -q up -jt1 -jt2" \ +"? temp2\.txt +RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v +retrieving revision 1\.1 +retrieving revision 1\.3 +Merging differences between 1\.1 and 1\.3 into temp.txt +temp.txt already contains the differences between 1\.1 and 1\.3 +$CPROG update: move away .\./temp2\.txt.; it is in the way +C temp2\.txt" + else + dotest join6-32 "${testcvs} -q up -jt1 -jt2" \ +"RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v +retrieving revision 1\.1 +retrieving revision 1\.3 +Merging differences between 1\.1 and 1\.3 into temp.txt +temp.txt already contains the differences between 1\.1 and 1\.3 +${SPROG} update: use .${SPROG} add. to create an entry for .temp2\.txt. +U temp2\.txt +? temp2\.txt" + fi + + dokeep + cd ../../.. + rm -r join6 + modify_repo rm -rf $CVSROOT_DIRNAME/join6 + ;; + + + + join7) + # This test deals with joins that happen with the -n switch + mkdir join7; cd join7 + mkdir impdir; cd impdir + echo aaa >temp.txt + echo bbb >>temp.txt + echo ccc >>temp.txt + dotest join7-1 \ +"${testcvs} -Q import -minitial join7 vendor vers-1" \ +"" + cd .. + dotest join7-2 "${testcvs} -Q co join7" "" + cd join7 + echo ddd >> temp.txt + dotest join7-3 "${testcvs} -Q ci -madded-line temp.txt" "" + cd ../impdir + echo aaaa >temp.txt + echo bbbb >>temp.txt + echo ccc >>temp.txt + echo eee >>temp.txt + dotest join7-4 \ +"${testcvs} -Q import -minitial join7 vendor vers-2" \ +"" + cd ../join7 + dotest join7-5 \ +"${testcvs} -n update -jvers-1 -jvers-2 temp.txt" \ +"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.2 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt +rcsmerge: warning: conflicts during merge" + touch temp.txt + dotest join7-6 "${testcvs} -n update -jvers-1 -jvers-2 temp.txt" \ +"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.2 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt +rcsmerge: warning: conflicts during merge" \ +"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.2 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt +rcsmerge: warning: conflicts during merge" + + dokeep + cd ../.. + rm -r join7 + modify_repo rm -rf $CVSROOT_DIRNAME/join7 + ;; + + + + join-readonly-conflict) + # Previously, only tests 1 & 11 were being tested. I added the + # intermediate dotest's to try and diagnose a different failure + # + # Demonstrate that cvs-1.9.29 can fail on 2nd and subsequent + # conflict-evoking join attempts. + # Even with that version of CVS, This test failed only in + # client-server mode, and would have been noticed in normal + # operation only for files that were read-only (either due to + # use of cvs' global -r option, setting the CVSREAD envvar, + # or use of watch lists). + mkdir join-readonly-conflict; cd join-readonly-conflict + dotest join-readonly-conflict-1 "$testcvs -q co -l ." '' + module=join-readonly-conflict + mkdir $module + $testcvs -q add $module >>$LOGFILE 2>&1 + cd $module + + file=m + echo trunk > $file + dotest join-readonly-conflict-2 "$testcvs -Q add $file" '' + + dotest join-readonly-conflict-3 "$testcvs -q ci -m . $file" \ +"$CVSROOT_DIRNAME/$module/$file,v <-- $file +initial revision: 1\.1" + + dotest join-readonly-conflict-4 "$testcvs tag -b B $file" "T $file" + dotest join-readonly-conflict-5 "$testcvs -q update -rB $file" '' + echo branch B > $file + dotest join-readonly-conflict-6 "$testcvs -q ci -m . $file" \ +"$CVSROOT_DIRNAME/$module/$file,v <-- $file +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + rm $file + dotest join-readonly-conflict-7 "$testcvs -Q update -A $file" '' + # Make sure $file is read-only. This can happen more realistically + # via patch -- which could be used to apply a delta, yet would + # preserve a file's read-only permissions. + echo conflict > $file; chmod u-w $file + dotest join-readonly-conflict-8 "$testcvs update -r B $file" \ +"RCS file: $CVSROOT_DIRNAME/$module/$file,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into $file +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in $file +C $file" + + # restore to the trunk + rm -f $file + dotest join-readonly-conflict-9 "$testcvs -Q update -A $file" '' + + # This one would fail because cvs couldn't open the existing + # (and read-only) .# file for writing. + echo conflict > $file + + # verify that the backup file is not writable + if test -w ".#$file.1.1"; then + fail "join-readonly-conflict-10 : .#$file.1.1 is writable" + else + pass "join-readonly-conflict-10" + fi + dotest join-readonly-conflict-11 "$testcvs update -r B $file" \ +"RCS file: $CVSROOT_DIRNAME/$module/$file,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into $file +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in $file +C m" + + dokeep + cd ../.. + rm -r join-readonly-conflict + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + join-admin) + mkdir 1; cd 1 + dotest join-admin-0-1 "$testcvs -q co -l ." + module=x + mkdir $module + dotest join-admin-0-2 "$testcvs -q add $module" \ +"Directory $CVSROOT_DIRNAME/$module added to the repository" + cd $module + + # Create a file so applying the first tag works. + echo foo > a + dotest join-admin-0-3 "$testcvs -Q add a" '' + dotest join-admin-0-4 "$testcvs -Q ci -m. a" '' + + dotest join-admin-0-5 "$testcvs -Q tag -b B" '' + dotest join-admin-0-6 "$testcvs -Q tag -b M1" '' + echo '$''Id$' > b + dotest join-admin-0-7 "$testcvs -Q add b" '' + dotest join-admin-0-8 "$testcvs -Q ci -m. b" '' + dotest join-admin-0-9 "$testcvs -Q tag -b M2" '' + + dotest join-admin-0-10 "$testcvs -Q update -r B" '' + dotest join-admin-0-11 "$testcvs -Q update -kk -jM1 -jM2" '' + dotest join-admin-0-12 "$testcvs -Q ci -m. b" '' + + dotest join-admin-0-13 "$testcvs -Q update -A" '' + + # Verify that the -kk flag from the update did not + # propagate to the repository. + dotest join-admin-1 "$testcvs status b" \ +"=================================================================== +File: b Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/x/b,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + join-admin-2) + # Show that when a merge (via update -kk -jtag1 -jtag2) first + # removes a file, then modifies another containing an $Id...$ line, + # the resulting file contains the unexpanded `$Id.$' string, as + # -kk requires. + mkdir 1; cd 1 + dotest join-admin-2-1 "$testcvs -q co -l ." '' + module=x + mkdir $module + dotest join-admin-2-2 "$testcvs -q add $module" \ +"Directory ${CVSROOT_DIRNAME}/x added to the repository" + cd $module + + # Create a file so applying the first tag works. + echo '$''Id$' > e0 + cp e0 e + dotest join-admin-2-3 "$testcvs -Q add e" + dotest join-admin-2-4 "$testcvs -Q ci -m. e" + + dotest join-admin-2-5 "$testcvs -Q tag -b T" '' "${QUESTION} e0" + dotest join-admin-2-6 "$testcvs -Q update -r T" '' "${QUESTION} e0" + cp e0 e + dotest join-admin-2-7 "$testcvs -Q ci -m. e" + + dotest join-admin-2-8 "$testcvs -Q update -A" '' "${QUESTION} e0" + dotest join-admin-2-9 "$testcvs -Q tag -b M1" '' "${QUESTION} e0" + + echo '$''Id$' > b + dotest join-admin-2-10 "$testcvs -Q add b" '' + cp e0 e + dotest join-admin-2-11 "$testcvs -Q ci -m. b e" + + dotest join-admin-2-12 "$testcvs -Q tag -b M2" '' "${QUESTION} e0" + + dotest join-admin-2-13 "$testcvs -Q update -r T" '' "${QUESTION} e0" + dotest join-admin-2-14 "$testcvs update -kk -jM1 -jM2" \ +"${SPROG} update: Updating . +U b +U e +RCS file: ${CVSROOT_DIRNAME}/x/e,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into e +e already contains the differences between 1\.1 and 1\.2 +${QUESTION} e0" \ +"${QUESTION} e0 +${SPROG} update: Updating . +U b +U e +RCS file: ${CVSROOT_DIRNAME}/x/e,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into e +e already contains the differences between 1\.1 and 1\.2" + + # Verify that the $Id.$ string is not expanded. + dotest join-admin-2-15 "cat e" '$''Id$' + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + join-rm) + # This first half of this test checks that a single-argument merge + # from a branch is capable of removing files. + # + # The second half verifies that an update to another location with an + # uncommitted removal will transfer the destination branch of the + # removal. + + module=join-rm + mkdir $module; cd $module + + dotest join-rm-init-1 "$testcvs -q co -l ." '' + mkdir $module + dotest join-rm-init-2 "$testcvs -q add $module" \ +"Directory $CVSROOT_DIRNAME/$module added to the repository" + cd $module + + # add some files. + touch a b c d e f g + dotest join-rm-init-3 "$testcvs -Q add a b c d e f g" + dotest join-rm-init-4 "$testcvs -Q ci -m add-em" + + # create the branch and update to it + dotest join-rm-init-5 "$testcvs -Q tag -b br" + dotest join-rm-init-6 "$testcvs -Q up -rbr" + + # remove a few files from the branch + dotest join-rm-init-7 "$testcvs -Q rm -f b d g" + dotest join-rm-init-8 "$testcvs -Q ci -mrm" + + # update to the trunk + dotest join-rm-init-9 "$testcvs -Q up -A" + + # now for the test - try and merge the removals. + dotest join-rm-1 "$testcvs -q up -jbr" \ +"$SPROG update: scheduling \`b' for removal +$SPROG update: scheduling \`d' for removal +$SPROG update: scheduling \`g' for removal" + + # And make sure the merge took + dotest join-rm-2 "$testcvs -qn up" \ +"R b +R d +R g" + + dotest join-rm-3 "$testcvs -q ci -m 'save the merge'" \ +"$CVSROOT_DIRNAME/join-rm/b,v <-- b +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/join-rm/d,v <-- d +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/join-rm/g,v <-- g +new revision: delete; previous revision: 1\.1" + + # and verify that it was the head revision which was removed. + dotest join-rm-4 "$testcvs -q log b" " +RCS file: $CVSROOT_DIRNAME/join-rm/Attic/b,v +Working file: b +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + br: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: $username; state: dead; lines: ${PLUS}0 -0; commitid: ${commitid}; +save the merge +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +branches: 1.1.2; +add-em +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: $username; state: dead; lines: ${PLUS}0 -0; commitid: ${commitid}; +rm +=============================================================================" + + # go back to the branch to set up for the second set of tests + dotest join-rm-init-10 "$testcvs -Q up -rbr" + dotest join-rm-init-11 "$testcvs -Q rm -f a" + dotest join-rm-init-12 "$testcvs -Q ci -m rma" + + # now the test: update to the trunk + # + # FIXCVS: This update should merge the removal to the trunk. It does + # not. + dotest join-rm-5 "$testcvs -q up -A" "U a" + + # and verify that there is no sticky tag + dotest join-rm-6 "$testcvs status a" \ +"=================================================================== +File: a Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/join-rm/a,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/$module + rm -r $module + ;; + + + + new) # look for stray "no longer pertinent" messages. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest new-init-1 "$testcvs -Q co first-dir" + + cd first-dir + touch a + + dotest new-1 "$testcvs -Q add a" + + dotest new-2 "$testcvs -Q ci -m added" + rm a + + dotest new-3 "$testcvs -Q rm a" + dotest new-4 "$testcvs -Q ci -m removed" + dotest new-5 "$testcvs -Q update -A" + dotest new-6 "$testcvs -Q update -rHEAD" + + dokeep + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + newb) + # Test removing a file on a branch and then checking it out. + + # We call this "newb" only because it, like the "new" tests, + # has something to do with "no longer pertinent" messages. + # Not necessarily the most brilliant nomenclature. + + # Create file 'a'. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest newb-123a "${testcvs} -q co first-dir" '' + cd first-dir + touch a + dotest newb-123b "${testcvs} add a" \ +"${SPROG} add: scheduling file .a. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest newb-123c "${testcvs} -q ci -m added" \ +"$CVSROOT_DIRNAME/first-dir/a,v <-- a +initial revision: 1\.1" + + # Make a branch. + dotest newb-123d "${testcvs} -q tag -b branch" "T a" + + # Check out the branch. + cd .. + rm -r first-dir + mkdir 1 + cd 1 + dotest newb-123e "${testcvs} -q co -r branch first-dir" \ +"U first-dir/a" + + # Remove 'a' on another copy of the branch. + cd .. + mkdir 2 + cd 2 + dotest newb-123f "${testcvs} -q co -r branch first-dir" \ +"U first-dir/a" + cd first-dir + rm a + dotest newb-123g "${testcvs} rm a" \ +"${SPROG} remove: scheduling .a. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest newb-123h "${testcvs} -q ci -m removed" \ +"$CVSROOT_DIRNAME/first-dir/a,v <-- a +new revision: delete; previous revision: 1\.1" + + # Check out the file on the branch. This should report + # that the file is not pertinent, but it should not + # say anything else. + cd .. + rm -r first-dir + dotest newb-123i "${testcvs} -q co -r branch first-dir/a" \ +"${SPROG} checkout: warning: \`first-dir/a' is not (any longer) pertinent" + + # Update the other copy, and make sure that a is removed. + cd ../1/first-dir + # "Entry Invalid" is a rather strange output here. Something like + # "Removed in Repository" would make more sense. + dotest newb-123j0 "${testcvs} status a" \ +"${SPROG} status: \`a' is no longer in the repository +=================================================================== +File: a Status: Entry Invalid + + Working revision: 1\.1.* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/a,v + Commit Identifier: ${commitid} + Sticky Tag: branch (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)${DOTSTAR}" + dotest newb-123j "${testcvs} -q update" \ +"${SPROG} update: \`a' is no longer in the repository" + + if test -f a; then + fail newb-123k + else + pass newb-123k + fi + + dokeep + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + conflicts) + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + + mkdir 1 + cd 1 + + dotest conflicts-124 "${testcvs} -q co first-dir" '' + + cd first-dir + touch a + + dotest conflicts-125 "${testcvs} add a" \ +"${SPROG} add: scheduling file .a. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest conflicts-126 "${testcvs} -q ci -m added" \ +"$CVSROOT_DIRNAME/first-dir/a,v <-- a +initial revision: 1\.1" + + cd ../.. + mkdir 2 + cd 2 + + dotest conflicts-126.5 "${testcvs} co -p first-dir" \ +"${SPROG} checkout: Updating first-dir +=================================================================== +Checking out first-dir/a +RCS: ${CVSROOT_DIRNAME}/first-dir/a,v +VERS: 1\.1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*" + dotest conflicts-127 "${testcvs} -Q co first-dir" '' + cd first-dir + dotest conflicts-127a "test -f a" '' + + cd ../../1/first-dir + echo add a line >>a + mkdir dir1 + dotest conflicts-127b "${testcvs} add dir1" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" + dotest conflicts-128 "${testcvs} -q ci -m changed" \ +"$CVSROOT_DIRNAME/first-dir/a,v <-- a +new revision: 1\.2; previous revision: 1\.1" + cd ../.. + + # Similar to conflicts-126.5, but now the file has nonempty + # contents. + mkdir 3 + cd 3 + dotest conflicts-128.5 "${testcvs} co -p -l first-dir" \ +"${SPROG} checkout: Updating first-dir +=================================================================== +Checking out first-dir/a +RCS: ${CVSROOT_DIRNAME}/first-dir/a,v +VERS: 1\.2 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +add a line" + cd .. + rmdir 3 + + # Now go over the to the other working directory and + # start testing conflicts + cd 2/first-dir + echo add a conflicting line >>a + dotest_fail conflicts-129 "${testcvs} -q ci -m changed" \ +"${SPROG}"' commit: Up-to-date check failed for `a'\'' +'"${SPROG}"' \[commit aborted\]: correct above errors first!' + mkdir dir1 + mkdir sdir + dotest conflicts-status-0 "${testcvs} status a" \ +"=================================================================== +File: a Status: Needs Merge + + Working revision: 1\.1.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest conflicts-129a "${testcvs} -nq update a" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into a +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in a +C a" + dotest conflicts-130 "${testcvs} -q update" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into a +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in a +C a +${QUESTION} dir1 +${QUESTION} sdir" \ +"${QUESTION} dir1 +${QUESTION} sdir +RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into a +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in a +C a" + rmdir dir1 sdir + + dotest conflicts-status-1 "${testcvs} status a" \ +"=================================================================== +File: a Status: Unresolved Conflict + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest_fail conflicts-131 "${testcvs} -q ci -m try" \ +"${SPROG} commit: file .a. had a conflict and has not been modified +${SPROG} \[commit aborted\]: correct above errors first!" + + # Try to check in the file with the conflict markers in it. + # Make sure we detect any one of the three conflict markers + mv a aa + grep '^<<<<<<<' aa >a + dotest conflicts-status-2 "${testcvs} -nq ci -m try a" \ +"${SPROG} commit: warning: file .a. seems to still contain conflict indicators" + + grep '^=======' aa >a + dotest conflicts-status-3 "${testcvs} -nq ci -m try a" \ +"${SPROG} commit: warning: file .a. seems to still contain conflict indicators" + + grep '^>>>>>>>' aa >a + dotest conflicts-status-4 "${testcvs} -qn ci -m try a" \ +"${SPROG} commit: warning: file .a. seems to still contain conflict indicators" + + mv aa a + echo lame attempt at resolving it >>a + dotest conflicts-status-5 "${testcvs} status a" \ +"=================================================================== +File: a Status: File had conflicts on merge + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest conflicts-132 "$testcvs -q ci -m try" \ +"$SPROG commit: warning: file .a. seems to still contain conflict indicators +$CVSROOT_DIRNAME/first-dir/a,v <-- a +new revision: 1\.3; previous revision: 1\.2" + + # OK, the user saw the warning (good user), and now + # resolves it for real. + echo resolve conflict >a + dotest conflicts-status-6 "${testcvs} status a" \ +"=================================================================== +File: a Status: Locally Modified + + Working revision: 1\.3.* + Repository revision: 1\.3 ${CVSROOT_DIRNAME}/first-dir/a,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest conflicts-133 "${testcvs} -q ci -m resolved" \ +"$CVSROOT_DIRNAME/first-dir/a,v <-- a +new revision: 1\.4; previous revision: 1\.3" + dotest conflicts-status-7 "${testcvs} status a" \ +"=================================================================== +File: a Status: Up-to-date + + Working revision: 1\.4.* + Repository revision: 1\.4 ${CVSROOT_DIRNAME}/first-dir/a,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + # Now test that we can add a file in one working directory + # and have an update in another get it. + cd ../../1/first-dir + echo abc >abc + if ${testcvs} add abc >>${LOGFILE} 2>&1; then + pass 134 + else + fail 134 + fi + if ${testcvs} ci -m 'add abc' abc >>${LOGFILE} 2>&1; then + pass 135 + else + fail 135 + fi + cd ../../2 + mkdir first-dir/dir1 first-dir/sdir + dotest conflicts-136 "${testcvs} -q update first-dir" \ +'[UP] first-dir/abc +'"${QUESTION}"' first-dir/dir1 +'"${QUESTION}"' first-dir/sdir' \ +''"${QUESTION}"' first-dir/dir1 +'"${QUESTION}"' first-dir/sdir +[UP] first-dir/abc' + dotest conflicts-137 'test -f first-dir/abc' '' + rmdir first-dir/dir1 first-dir/sdir + + # Now test something similar, but in which the parent directory + # (not the directory in question) has the Entries.Static flag + # set. + cd ../1/first-dir + mkdir subdir + dotest conflicts-138 "${testcvs} add subdir" "${DOTSTAR}" + cd ../.. + mkdir 3 + cd 3 + dotest conflicts-139 \ +"${testcvs} -q co first-dir/abc first-dir/subdir" "${DOTSTAR}" + cd ../1/first-dir/subdir + echo sss >sss + dotest conflicts-140 "${testcvs} add sss" "${DOTSTAR}" + dotest conflicts-140a "${testcvs} ci -m adding sss" \ +"${DOTSTAR}" + cd ../../../3/first-dir + dotest conflicts-141 "${testcvs} -q update" "${DOTSTAR}" + dotest conflicts-142 "test -f subdir/sss" + + dokeep + cd ../.. + rm -r 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + restore_adm + ;; + + + + conflicts2) + # More conflicts tests; separate from conflicts to keep each + # test a manageable size. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + + mkdir 1 + cd 1 + + dotest conflicts2-142a1 "${testcvs} -q co first-dir" '' + + cd first-dir + touch a abc + + dotest conflicts2-142a2 "${testcvs} add a abc" \ +"${SPROG} add: scheduling file .a. for addition +${SPROG} add: scheduling file .abc. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest conflicts2-142a3 "${testcvs} -q ci -m added" \ +"$CVSROOT_DIRNAME/first-dir/a,v <-- a +initial revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc +initial revision: 1\.1" + + cd ../.. + mkdir 2 + cd 2 + + dotest conflicts2-142a4 "${testcvs} -q co first-dir" 'U first-dir/a +U first-dir/abc' + cd .. + + # BEGIN TESTS USING THE FILE A + # FIXME: would be cleaner to separate them out into their own + # tests; conflicts2 is getting long. + # Now test that if one person modifies and commits a + # file and a second person removes it, it is a + # conflict + cd 1/first-dir + echo modify a >>a + dotest conflicts2-142b2 "${testcvs} -q ci -m modify-a" \ +"$CVSROOT_DIRNAME/first-dir/a,v <-- a +new revision: 1\.2; previous revision: 1\.1" + cd ../../2/first-dir + rm a + dotest conflicts2-142b3 "${testcvs} rm a" \ +"${SPROG} remove: scheduling .a. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest_fail conflicts2-142b4 "${testcvs} -q update" \ +"${SPROG} update: conflict: removed \`a' was modified by second party +C a" + # Resolve the conflict by deciding not to remove the file + # after all. + dotest_sort conflicts2-142b5 "$testcvs add a" "U a +${SPROG} add: \`a', version 1\.1, resurrected" + dotest conflicts2-142b5b1 "$testcvs status a" \ +"=================================================================== +File: a Status: Needs Patch + + Working revision: 1\.1.* + Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/a,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest conflicts2-142b6 "$testcvs -q update" 'U a' + + # Now one level up. + cd .. + dotest conflicts2-142b7 "${testcvs} rm -f first-dir/a" \ +"${SPROG} remove: scheduling \`first-dir/a' for removal +${SPROG} remove: use \`${SPROG} commit' to remove this file permanently" + + if $remote; then + # Haven't investigated this one. + dotest_fail conflicts2-142b8r "$testcvs add first-dir/a" \ +"${CPROG} add: in directory \`\.': +${CPROG} \[add aborted\]: there is no version here; do \`${CPROG} checkout' first" + cd first-dir + else + dotest conflicts2-142b8 "${testcvs} add first-dir/a" \ +"U first-dir/a +$SPROG add: \`first-dir/a', version 1\.2, resurrected" + cd first-dir + # Now recover from the damage that the 142b8 test did. + dotest conflicts2-142b9 "${testcvs} rm -f a" \ +"${SPROG} remove: scheduling \`a' for removal +${SPROG} remove: use \`${SPROG} commit' to remove this file permanently" + fi + + # As before, 1.2 instead of 1.1 is a bug. + dotest_sort conflicts2-142b10 "$testcvs add a" "U a +${SPROG} add: \`a', version 1\.2, resurrected" + # As with conflicts2-142b6, check that things are normal again. + dotest conflicts2-142b11 "${testcvs} -q update" '' + cd ../.. + # END TESTS USING THE FILE A + + # Now test that if one person removes a file and + # commits it, and a second person removes it, is it + # not a conflict. + cd 1/first-dir + rm abc + dotest conflicts2-142c0 "${testcvs} rm abc" \ +"${SPROG} remove: scheduling \`abc' for removal +${SPROG} remove: use \`${SPROG} commit' to remove this file permanently" + dotest conflicts2-142c1 "${testcvs} -q ci -m remove-abc" \ +"$CVSROOT_DIRNAME/first-dir/abc,v <-- abc +new revision: delete; previous revision: 1\.1" + cd ../../2/first-dir + rm abc + dotest conflicts2-142c2 "${testcvs} rm abc" \ +"${SPROG} remove: scheduling \`abc' for removal +${SPROG} remove: use \`${SPROG} commit' to remove this file permanently" + dotest conflicts2-142c3 "${testcvs} update" \ +"${SPROG} update: Updating \." + cd ../.. + + # conflicts2-142d*: test that if one party adds a file, and another + # party has a file of the same name, cvs notices + cd 1/first-dir + touch aa.c + echo 'contents unchanged' >same.c + dotest conflicts2-142d0 "${testcvs} add aa.c same.c" \ +"${SPROG} add: scheduling file .aa\.c. for addition +${SPROG} add: scheduling file .same\.c. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest conflicts2-142d1 "${testcvs} -q ci -m added" \ +"$CVSROOT_DIRNAME/first-dir/aa\.c,v <-- aa\.c +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/same\.c,v <-- same\.c +initial revision: 1\.1" + + # Test the case where the second user manages the add before the + # first commits + touch bb.c + dotest conflicts2-142d1a "$testcvs add bb.c" \ +"$SPROG add: scheduling file .bb\.c. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + cd ../../2/first-dir + echo "don't you dare obliterate this text" >bb.c + dotest conflicts2-142d1b "$testcvs add bb.c" \ +"$SPROG add: scheduling file .bb\.c. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + cd ../../1/first-dir + dotest conflicts2-142d1c "$testcvs -q ci -m added" \ +"$CVSROOT_DIRNAME/first-dir/bb\.c,v <-- bb\.c +initial revision: 1\.1" + + cd ../../2/first-dir + echo "don't you dare obliterate this text either" >aa.c + echo 'contents unchanged' >same.c + # Note the discrepancy between local and remote in the handling + # of same.c. I kind + # of suspect that the local CVS behavior is the more useful one + # although I do sort of wonder whether we should make people run + # cvs add just to get them in that habit (also, trying to implement + # the local CVS behavior for remote without the cvs add seems + # pretty difficult). + if $remote; then + dotest_fail conflicts2-142d2r "${testcvs} -q update" \ +"${QUESTION} aa\.c +${QUESTION} same\.c +${CPROG} update: move away \`\./aa\.c'; it is in the way +C aa\.c +${SPROG} update: conflict: \`bb\.c' created independently by second party +C bb\.c +${CPROG} update: move away \`\./same\.c'; it is in the way +C same\.c" + else + dotest_fail conflicts2-142d2 "${testcvs} -q update" \ +"${CPROG} update: move away \`aa\.c'; it is in the way +C aa\.c +${CPROG} update: conflict: \`bb\.c' created independently by second party +C bb\.c +U same\.c" + fi + dotest conflicts2-142d3 "${testcvs} -q status aa.c" \ +"${SPROG} status: move away \`aa\.c'; it is in the way +=================================================================== +File: aa\.c Status: Unresolved Conflict + + Working revision: No entry for aa\.c + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/aa\.c,v + Commit Identifier: ${commitid}" + dotest conflicts2-142d3a "${testcvs} -q status bb.c" \ +"${SPROG} status: conflict: \`bb\.c' created independently by second party +=================================================================== +File: bb\.c Status: Unresolved Conflict + + Working revision: New file! + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/bb\.c,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + # FIXCVS + # This message seems somewhat bogus. I mean, parallel development + # means that we get to work in parallel if we choose, right? And + # then at commit time it would be a conflict. + # + # Well, the status is "Unresolved conflict" before _and_ after + # the update/merge (when conflicts happen, not at commit time). + # It is possible that this message could be changed to something + # more infomrative to novice users, like "File of same name exists + # in repository", or "File of same name committed independantly by + # second party", but these two messages look too long for the Status + # field and the move away & added independantly error messages _are_ + # displayed. Still, we get a lot of questions about this on the + # email lists. Somehow we need to get more information to users + # via these messages and the ones generated by update. -DRP + dotest_fail conflicts2-142d4 "${testcvs} -q add aa.c" \ +"${SPROG} add: \`aa.c' added independently by second party" + + # The user might want to see just what the conflict is. + # Don't bother, diff seems to kind of lose its mind, with or + # without -N. This is a CVS bug(s). + #dotest conflicts2-142d5 \ + #"${testcvs} -q diff -r HEAD -N aa.c" FIXCVS THEN FIXME + + # Now: "how can the user resolve this conflict", I hear you cry. + # Well, one way is to forget about the file in the working + # directory. + # Since it didn't let us do the add in conflicts2-142d4, there + # is no need to run cvs rm here. + #dotest conflicts2-142d6 "${testcvs} -q rm -f aa.c" fixme + dotest conflicts2-142d6 "rm aa.c" '' + dotest conflicts2-142d7 "${testcvs} -q update aa.c" "U aa\.c" + dotest conflicts2-142d8 "cat aa.c" '' + + # The other way is to use the version from the working directory + # instead of the version from the repository. Unfortunately, + # there doesn't seem to be any particularly clear way to do + # this (?). + + dokeep + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + conflicts3) + # More tests of conflicts and/or multiple working directories + # in general. + + mkdir 1; cd 1 + dotest conflicts3-1 "$testcvs -q co -l ." + mkdir first-dir + dotest conflicts3-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd .. + mkdir 2; cd 2 + dotest conflicts3-3 "${testcvs} -q co -l first-dir" '' + cd ../1/first-dir + touch file1 file2 + dotest conflicts3-4 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest conflicts3-5 "${testcvs} -q ci -m add-them" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + cd ../../2/first-dir + # Check that -n doesn't make CVS lose its mind as it creates + # (or rather, doesn't) a new file. + dotest conflicts3-6 "${testcvs} -nq update" \ +"U file1 +U file2" + dotest_fail conflicts3-7 "test -f file1" '' + dotest conflicts3-8 "${testcvs} -q update" \ +"U file1 +U file2" + dotest conflicts3-9 "test -f file2" '' + + # OK, now remove two files at once + dotest conflicts3-10 "${testcvs} rm -f file1 file2" \ +"${SPROG} remove: scheduling .file1. for removal +${SPROG} remove: scheduling .file2. for removal +${SPROG} remove: use .${SPROG} commit. to remove these files permanently" + dotest conflicts3-11 "${testcvs} -q ci -m remove-them" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: delete; previous revision: 1\.1" + cd ../../1/first-dir + dotest conflicts3-12 "${testcvs} -n -q update" \ +"${SPROG} update: \`file1' is no longer in the repository +${SPROG} update: \`file2' is no longer in the repository" + dotest conflicts3-13 "${testcvs} -q update" \ +"${SPROG} update: \`file1' is no longer in the repository +${SPROG} update: \`file2' is no longer in the repository" + + # OK, now add a directory to both working directories + # and see that CVS doesn't lose its mind. + mkdir sdir + dotest conflicts3-14 "${testcvs} add sdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" + touch sdir/sfile + dotest conflicts3-14a "${testcvs} add sdir/sfile" \ +"${SPROG} add: scheduling file .sdir/sfile. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest conflicts3-14b "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/sdir/sfile,v <-- sdir/sfile +initial revision: 1\.1" + + cd ../../2/first-dir + + # Create a CVS directory without the proper administrative + # files in it. This can happen for example if you hit ^C + # in the middle of a checkout. + mkdir sdir + mkdir sdir/CVS + # OK, in the local case CVS sees that the directory exists + # in the repository and recurses into it. In the remote case + # CVS can't see the repository and has no way of knowing + # that sdir is even a directory (stat'ing everything would be + # too slow). The remote behavior makes more sense to me (but + # would this affect other cases?). + if $remote; then + dotest conflicts3-15 "${testcvs} -q update" \ +"${QUESTION} sdir" + else + dotest conflicts3-15 "${testcvs} -q update" \ +"${QUESTION} sdir +${SPROG} update: ignoring sdir (CVS/Repository missing)" + touch sdir/CVS/Repository + dotest conflicts3-16 "${testcvs} -q update" \ +"${QUESTION} sdir +${SPROG} update: ignoring sdir (CVS/Entries missing)" + cd .. + dotest conflicts3-16a "${testcvs} -q update first-dir" \ +"${QUESTION} first-dir/sdir +${SPROG} update: ignoring first-dir/sdir (CVS/Entries missing)" + cd first-dir + fi + rm -r sdir + + # OK, now the same thing, but the directory doesn't exist + # in the repository. + mkdir newdir + mkdir newdir/CVS + dotest conflicts3-17 "${testcvs} -q update" "${QUESTION} newdir" + echo "D/newdir////" >> CVS/Entries + dotest conflicts3-18 "${testcvs} -q update" \ +"${CPROG} update: ignoring newdir (CVS/Repository missing)" + touch newdir/CVS/Repository + dotest conflicts3-19 "${testcvs} -q update" \ +"${CPROG} update: ignoring newdir (CVS/Entries missing)" + cd .. + dotest conflicts3-20 "${testcvs} -q update first-dir" \ +"${CPROG} update: ignoring first-dir/newdir (CVS/Entries missing)" + cd first-dir + rm -r newdir + + # The previous tests have left CVS/Entries in something of a mess. + # While we "should" be able to deal with that (maybe), for now + # we just start over. + cd .. + rm -r first-dir + dotest conflicts3-20a "${testcvs} -q co -l first-dir" '' + cd first-dir + + dotest conflicts3-21 "${testcvs} -q update -d sdir" "U sdir/sfile" + rm -r sdir/CVS + dotest conflicts3-22 "${testcvs} -q update" "${QUESTION} sdir" + if $remote; then + dotest_fail conflicts3-23 "${testcvs} -q update -PdA" \ +"${QUESTION} sdir +${CPROG} update: move away \`sdir/sfile'; it is in the way +C sdir/sfile" + else + dotest conflicts3-23 "${testcvs} -q update -PdA" \ +"${QUESTION} sdir" + fi + + # Not that it should really affect much, but let's do the case + # where sfile has been removed. For example, suppose that sdir + # had been a CVS-controlled directory which was then removed + # by removing each file (and using update -P or some such). Then + # suppose that the build process creates an sdir directory which + # is not supposed to be under CVS. + rm -r sdir + dotest conflicts3-24 "${testcvs} -q update -d sdir" "U sdir/sfile" + rm sdir/sfile + dotest conflicts3-25 "${testcvs} rm sdir/sfile" \ +"${SPROG} remove: scheduling .sdir/sfile. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest conflicts3-26 "${testcvs} ci -m remove sdir/sfile" \ +"${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v <-- sdir/sfile +new revision: delete; previous revision: 1\.1" + rm -r sdir/CVS + dotest conflicts3-27 "${testcvs} -q update" "${QUESTION} sdir" + dotest conflicts3-28 "${testcvs} -q update -PdA" \ +"${QUESTION} sdir" + + dokeep + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + clean) + # Test update -C (overwrite local mods w/ repository copies) + mkdir 1; cd 1 + dotest clean-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest clean-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo "The usual boring test text." > cleanme.txt + dotest clean-3 "${testcvs} add cleanme.txt" \ +"${SPROG} add: scheduling file .cleanme\.txt. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest clean-4 "${testcvs} -q ci -m clean-3" \ +"$CVSROOT_DIRNAME/first-dir/cleanme\.txt,v <-- cleanme\.txt +initial revision: 1\.1" + # Okay, preparation is done, now test. + # Check that updating an unmodified copy works. + dotest clean-5 "${testcvs} -q update" '' + # Check that updating -C an unmodified copy works. + dotest clean-6 "${testcvs} -q update -C" '' + # Check that updating a modified copy works. + echo "fish" >> cleanme.txt + dotest clean-7 "${testcvs} -q update" 'M cleanme\.txt' + # Check that updating -C a modified copy works. + dotest clean-8 "${testcvs} -q update -C" \ +"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1) +U cleanme\.txt" + # And check that the backup copy really was made. + dotest clean-9 "cat .#cleanme.txt.1.1" \ +"The usual boring test text\. +fish" + + # Do it all again, this time naming the file explicitly. + rm .#cleanme.txt.1.1 + dotest clean-10 "${testcvs} -q update cleanme.txt" '' + dotest clean-11 "${testcvs} -q update -C cleanme.txt" '' + echo "bluegill" >> cleanme.txt + dotest clean-12 "${testcvs} -q update cleanme.txt" 'M cleanme\.txt' + dotest clean-13 "${testcvs} -q update -C cleanme.txt" \ +"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1) +U cleanme\.txt" + # And check that the backup copy really was made. + dotest clean-14 "cat .#cleanme.txt.1.1" \ +"The usual boring test text\. +bluegill" + + # Now try with conflicts + cd .. + dotest clean-15 "${testcvs} -q co -d second-dir first-dir" \ +'U second-dir/cleanme\.txt' + cd second-dir + echo "conflict test" >> cleanme.txt + dotest clean-16 "${testcvs} -q ci -m." \ +"$CVSROOT_DIRNAME/first-dir/cleanme\.txt,v <-- cleanme\.txt +new revision: 1\.2; previous revision: 1\.1" + cd ../first-dir + echo "fish" >> cleanme.txt + dotest clean-17 "${testcvs} -nq update" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into cleanme\.txt +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in cleanme\.txt +C cleanme\.txt" + dotest clean-18 "${testcvs} -q update -C" \ +"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1) +U cleanme\.txt" + dotest clean-19 "cat .#cleanme.txt.1.1" \ +"The usual boring test text\. +fish" + + # Done. Clean up. + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + keywordexpand) + # Tests of the original *BSD tag= and keywordexpand= features + # are done via the LocalKeyword= and KeywordExpand features. + + # Skip this in noredirect mode because it is too easy for the primary + # and secondary error messages to get out of sync when the + # CVSROOT/config files are broken. This is intentional, since it is + # possible and even likely that an administrator might want to set up + # different configurations on the two servers and the paths to the + # config files on the secondary and primary were intentionally left + # intact even though they might be different. + if $noredirect; then + notnoredirect keywordexpand + continue + fi + + mkdir keywordexpand; cd keywordexpand + + dotest keywordexpand-1 "${testcvs} -q co CVSROOT" \ +'U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg' + cd CVSROOT + echo LocalKeyword=MyBSD=CVSHeader >> config + # First do not expand any keywords + echo KeywordExpand=i >> config + dotest keywordexpand-2 "${testcvs} -Q ci -mkeywordexpand config" + + cd .. + + mkdir testimport; cd testimport + echo '$''Author$' > file1 + echo '$''Date$' >> file1 + echo '$''CVSHeader$' >> file1 + echo '$''Header$' >> file1 + echo '$''Id$' >> file1 + echo '$''Locker$' >> file1 + echo '$''Log$' >> file1 + echo '$''Name$' >> file1 + echo '$''RCSfile$' >> file1 + echo '$''Revision$' >> file1 + echo '$''Source$' >> file1 + echo '$''State$' >> file1 + echo '$''MyBSD$' >> file1 + dotest keywordexpand-3 \ +"${testcvs} -Q import -I ! -m test-import-with-bsd-keyword keywordexpand vendor v1" \ +'' + cd .. + + dotest keywordexpand-4 "${testcvs} -Q checkout keywordexpand" '' + cd keywordexpand + dotest keywordexpand-5 "cat file1" \ +"\$""Author\$ +\$""Date\$ +\$""CVSHeader\$ +\$""Header\$ +\$""Id\$ +\$""Locker\$ +\$""Log\$ +\$""Name\$ +\$""RCSfile\$ +\$""Revision\$ +\$""Source\$ +\$""State\$ +\$MyBSD\$" + cd ../CVSROOT + # Now expand just the MyBSD and Id keywords + mv config config.old + sed -e 's/KeywordExpand=i/KeywordExpand=iMyBSD,Id/' < config.old > config + rm -f config.old + dotest keywordexpand-6 "${testcvs} -Q ci -mkeywordexpand config" + cd ../keywordexpand + echo 'a change' >> file1 + dotest keywordexpand-7 "${testcvs} -Q ci -madd" + dotest keywordexpand-8 "cat file1" \ +"\$""Author\$ +\$""Date\$ +\$""CVSHeader\$ +\$""Header\$ +\$""Id: file1,v 1\.2 [0-9/]* [0-9:]* ${username} Exp \$ +\$""Locker\$ +\$""Log\$ +\$""Name\$ +\$""RCSfile\$ +\$""Revision\$ +\$""Source\$ +\$""State\$ +\$MyBSD: keywordexpand/file1,v 1\.2 [0-9/]* [0-9:]* ${username} Exp \$ +a change" + + cd ../CVSROOT + mv config config.old + sed -e 's/LocalKeyword=MyBSD/LocalKeyword=My_BSD/' \ + <config.old >config + dotest keywordexpand-9 "$testcvs -Q ci -minvalidlocalkeyword config" + dotest keywordexpand-10 "$testcvs -Q update config" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Bad character \`_' in key \`My_BSD'" + cp config.old config + dotest keywordexpand-11 "$testcvs -Q ci -mfixit config" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Bad character \`_' in key \`My_BSD'" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Bad character \`_' in key \`My_BSD' +$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Bad character \`_' in key \`My_BSD'" + dotest keywordexpand-12 "$testcvs -Q update config" + sed -e 's/LocalKeyword=MyBSD=CVSHeader/LocalKeyword=MyBSD=Name/' \ + <config.old >config + dotest keywordexpand-13 \ +"$testcvs -Q ci -minvalidlocalkeyword2 config" + dotest keywordexpand-14 "$testcvs -Q update config" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Unknown LocalId mode: \`Name'" + cp config.old config + dotest keywordexpand-15 "$testcvs -Q ci -mfixit2 config" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Unknown LocalId mode: \`Name'" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Unknown LocalId mode: \`Name' +$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: LocalKeyword ignored: Unknown LocalId mode: \`Name'" + dotest keywordexpand-16 "$testcvs -Q update config" + + dokeep + # Done. Clean up. + cd ../.. + rm -rf $TESTDIR/keywordexpand + modify_repo rm -rf $CVSROOT_DIRNAME/keywordexpand + restore_adm + ;; + + + + modules) + # Tests of various ways to define and use modules. + # Roadmap to various modules tests: + # -a: + # error on incorrect placement: modules + # error combining with other options: modules2-a* + # infinite loops: modules148a1.1 - modules148a1.2 + # use to specify a file more than once: modules3 + # use with ! feature: modules4 + # regular modules: modules, modules2, cvsadm + # ampersand modules: modules2 + # -s: modules. + # -d: modules, modules3, cvsadm + # -i, -o, -u, -e, -t: modules5 + # slashes in module names: modules3 + # invalid module definitions: modules6 + + ############################################################ + # These tests are to make sure that administrative files get + # rebuilt, regardless of how and where files are checked + # out. + ############################################################ + # Check out the whole repository + mkdir 1; cd 1 + dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg' + echo "# made a change" >>CVSROOT/modules + dotest modules-1d "${testcvs} -q ci -m add-modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- CVSROOT/modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + rm -rf 1 + + ############################################################ + # Check out CVSROOT + mkdir 1; cd 1 + dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg' + echo "# made a change" >>CVSROOT/modules + dotest modules-2d "${testcvs} -q ci -m add-modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- CVSROOT/modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + rm -rf 1 + + ############################################################ + # Check out CVSROOT in some other directory + modify_repo mkdir $CVSROOT_DIRNAME/somedir + mkdir 1; cd 1 + dotest modules-3 "${testcvs} -q co somedir" '' + cd somedir + dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg' + echo "# made a change" >>CVSROOT/modules + dotest modules-3g "${testcvs} -q ci -m add-modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- CVSROOT/modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/somedir + ############################################################ + # end rebuild tests + ############################################################ + + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + + mkdir 1 + cd 1 + + dotest modules-143 "${testcvs} -q co first-dir" "" + + cd first-dir + mkdir subdir + dotest modules-143a "${testcvs} add subdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" + + cd subdir + mkdir ssdir + dotest modules-143b "${testcvs} add ssdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir added to the repository" + + touch a b + + dotest modules-144 "${testcvs} add a b" \ +"${SPROG} add: scheduling file .a. for addition +${SPROG} add: scheduling file .b. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + + dotest modules-145 "$testcvs ci -m added" \ +"$CPROG commit: Examining . +$CPROG commit: Examining ssdir +$CVSROOT_DIRNAME/first-dir/subdir/a,v <-- a +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/subdir/b,v <-- b +initial revision: 1\.1" + + cd .. + dotest modules-146 "$testcvs -q co CVSROOT" \ +"U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg" + + # Here we test that CVS can deal with CVSROOT (whose repository + # is at top level) in the same directory as subdir (whose repository + # is a subdirectory of first-dir). TODO: Might want to check that + # files can actually get updated in this state. + dotest modules-147 "$testcvs -q update" + + cat >CVSROOT/modules <<EOF +realmodule first-dir/subdir a +dirmodule first-dir/subdir +namedmodule -d nameddir first-dir/subdir +aliasmodule -a first-dir/subdir/a +aliasnested -a first-dir/subdir/ssdir +topfiles -a first-dir/file1 first-dir/file2 +world -a . +statusmod -s Mungeable +# Check for ability to block infinite loops. +infinitealias -a infinitealias +# Prior to 1.11.12 & 1.12.6, the infinite alias loop check didn't strip +# slashes or work if a module called a module which then called itself +# (A -> A was blocked, but not A -> B -> A or deeper). +infinitealias2 -a infinitealias2/ +infinitealias3 -a infinitealias4/ +infinitealias4 -a aliasmodule infinitealias5 +infinitealias5 -a infinitealias3/ +# Options must come before arguments. It is possible this should +# be relaxed at some point (though the result would be bizarre for +# -a); for now test the current behavior. +bogusalias first-dir/subdir/a -a +EOF + dotest modules-148 "$testcvs ci -m 'add modules' CVSROOT/modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- CVSROOT/modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd .. + # The "statusmod" module contains an error; trying to use it + # will produce "modules file missing directory" I think. + # However, that shouldn't affect the ability of "cvs co -c" or + # "cvs co -s" to do something reasonable with it. + dotest modules-148a0 "$testcvs co -c" \ +'aliasmodule -a first-dir/subdir/a +aliasnested -a first-dir/subdir/ssdir +bogusalias first-dir/subdir/a -a +dirmodule first-dir/subdir +infinitealias -a infinitealias +infinitealias2 -a infinitealias2/ +infinitealias3 -a infinitealias4/ +infinitealias4 -a aliasmodule infinitealias5 +infinitealias5 -a infinitealias3/ +namedmodule -d nameddir first-dir/subdir +realmodule first-dir/subdir a +statusmod -s Mungeable +topfiles -a first-dir/file1 first-dir/file2 +world -a \.' + # There is code in modules.c:save_d which explicitly skips + # modules defined with -a, which is why aliasmodule is not + # listed. + dotest modules-148a1 "${testcvs} co -s" \ +'statusmod Mungeable +bogusalias NONE first-dir/subdir/a -a +dirmodule NONE first-dir/subdir +namedmodule NONE first-dir/subdir +realmodule NONE first-dir/subdir a' + + # Check that infinite loops are avoided + dotest modules-148a1.1 "${testcvs} co infinitealias" \ +"$CPROG checkout: module \`infinitealias' in modules file contains infinite loop" \ +"$SPROG server: module \`infinitealias' in modules file contains infinite loop +$SPROG checkout: module \`infinitealias' in modules file contains infinite loop" + # Prior to 1.11.12 & 1.12.6, the inifinte alias loop check did not + # strip slashes. + dotest modules-148a1.2 "${testcvs} co infinitealias2" \ +"$CPROG checkout: module \`infinitealias2' in modules file contains infinite loop" \ +"$SPROG server: module \`infinitealias2' in modules file contains infinite loop +$SPROG checkout: module \`infinitealias2' in modules file contains infinite loop" + # Prior to 1.11.12 & 1.12.6, the inifinte alias loop check did not + # notice when A -> B -> A, it only noticed A -> A. + dotest modules-148a1.3 "${testcvs} co infinitealias3/" \ +"$CPROG checkout: module \`infinitealias3' in modules file contains infinite loop" \ +"$SPROG server: module \`infinitealias3' in modules file contains infinite loop +$SPROG checkout: module \`infinitealias3' in modules file contains infinite loop" + + # Test that real modules check out to realmodule/a, not subdir/a. + dotest modules-149a1 "${testcvs} co realmodule" "U realmodule/a" + dotest modules-149a2 "test -d realmodule && test -f realmodule/a" "" + dotest_fail modules-149a3 "test -f realmodule/b" "" + dotest modules-149a4 "${testcvs} -q co realmodule" "" + dotest modules-149a5 "echo yes | ${testcvs} release -d realmodule" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .realmodule.: " + + dotest_fail modules-149b1 "${testcvs} co realmodule/a" \ +"${SPROG}"' checkout: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \ +"${SPROG}"' server: module `realmodule/a'\'' is a request for a file in a module which is not a directory +'"${CPROG}"' \[checkout aborted\]: cannot expand modules' + + # Now test the ability to check out a single file from a directory + dotest modules-150c "${testcvs} co dirmodule/a" "U dirmodule/a" + dotest modules-150d "test -d dirmodule && test -f dirmodule/a" "" + dotest_fail modules-150e "test -f dirmodule/b" "" + dotest modules-150f "echo yes | ${testcvs} release -d dirmodule" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .dirmodule.: " + # Now test the ability to correctly reject a non-existent filename. + # For maximum studliness we would check that an error message is + # being output. + # We accept a zero exit status because it is what CVS does + # (Dec 95). Probably the exit status should be nonzero, + # however. + dotest modules-150g1 "${testcvs} co dirmodule/nonexist" \ +"${SPROG} checkout: warning: new-born \`dirmodule/nonexist' has disappeared" + # We tolerate the creation of the dirmodule directory, since that + # is what CVS does, not because we view that as preferable to not + # creating it. + dotest_fail modules-150g2 "test -f dirmodule/a || test -f dirmodule/b" "" + rm -r dirmodule + + # Now test that a module using -d checks out to the specified + # directory. + dotest modules-150h1 "${testcvs} -q co namedmodule" \ +'U nameddir/a +U nameddir/b' + dotest modules-150h2 "test -f nameddir/a && test -f nameddir/b" "" + echo add line >>nameddir/a + dotest modules-150h3 "${testcvs} -q co namedmodule" 'M nameddir/a' + rm nameddir/a + dotest modules-150h4 "${testcvs} -q co namedmodule" 'U nameddir/a' + dotest modules-150h99 "echo yes | ${testcvs} release -d nameddir" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .nameddir.: " + + # Now test that alias modules check out to subdir/a, not + # aliasmodule/a. + dotest modules-151 "${testcvs} co aliasmodule" "" + dotest_fail modules-152 "test -d aliasmodule" "" + echo abc >>first-dir/subdir/a + dotest modules-153 "${testcvs} -q co aliasmodule" "M first-dir/subdir/a" + + cd .. + rm -r 1 + + mkdir 2 + cd 2 + dotest modules-155a0 "${testcvs} co aliasnested" \ +"${SPROG} checkout: Updating first-dir/subdir/ssdir" + dotest modules-155a1 "test -d first-dir" '' + dotest modules-155a2 "test -d first-dir/subdir" '' + dotest modules-155a3 "test -d first-dir/subdir/ssdir" '' + # Test that nothing extraneous got created. + dotest modules-155a4 "ls" "first-dir" \ +"CVS +first-dir" + cd .. + rm -r 2 + + # Test checking out everything. + mkdir 1 + cd 1 + dotest modules-155b "${testcvs} -q co world" \ +"U CVSROOT/${DOTSTAR} +U first-dir/subdir/a +U first-dir/subdir/b" + cd .. + rm -r 1 + + # Test checking out a module which lists at least two + # specific files twice. At one time, this failed over + # remote CVS. + mkdir 1 + cd 1 + dotest modules-155c1 "${testcvs} -q co first-dir" \ +"U first-dir/subdir/a +U first-dir/subdir/b" + + cd first-dir + echo 'first revision' > file1 + echo 'first revision' > file2 + dotest modules-155c2 "${testcvs} add file1 file2" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: scheduling file `file2'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add these files permanently' + dotest modules-155c3 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + + cd .. + rm -r first-dir + dotest modules-155c4 "${testcvs} -q co topfiles" \ +"U first-dir/file1 +U first-dir/file2" + dotest modules-155c5 "${testcvs} -q co topfiles" "" + + # Make sure the right thing happens if we remove a file. + cd first-dir + dotest modules-155c6 "${testcvs} -q rm -f file1" \ +"${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest modules-155c7 "${testcvs} -q ci -m remove-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.1" + cd .. + rm -r first-dir + dotest modules-155c8 "${testcvs} -q co topfiles" \ +"${SPROG} checkout: warning: \`first-dir/file1' is not (any longer) pertinent +U first-dir/file2" + + dokeep + cd .. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + modules2) + # More tests of modules, in particular the & feature. + mkdir 1; cd 1 + dotest modules2-setup-1 "${testcvs} -q co -l ." '' + mkdir first-dir second-dir third-dir + dotest modules2-setup-2 \ +"${testcvs} add first-dir second-dir third-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository +Directory ${CVSROOT_DIRNAME}/third-dir added to the repository" + cd third-dir + touch file3 + dotest modules2-setup-3 "${testcvs} add file3" \ +"${SPROG} add: scheduling file .file3. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest modules2-setup-4 "${testcvs} -q ci -m add file3" \ +"$CVSROOT_DIRNAME/third-dir/file3,v <-- file3 +initial revision: 1\.1" + cd ../.. + rm -r 1 + + mkdir 1 + cd 1 + + dotest modules2-1 "${testcvs} -q co CVSROOT/modules" \ +'U CVSROOT/modules' + cd CVSROOT + cat >> modules << EOF +ampermodule &first-dir &second-dir +combmodule third-dir file3 &first-dir +ampdirmod -d newdir &first-dir &second-dir +badmod -d newdir +messymod first-dir &messymodchild +messymodchild -d sdir/child second-dir +EOF + # Depending on whether the user also ran the modules test + # we will be checking in revision 1.2 or 1.3. + dotest modules2-2 "${testcvs} -q ci -m add-modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd .. + + dotest modules2-3 "${testcvs} -q co ampermodule" '' + dotest modules2-4 "test -d ampermodule/first-dir" '' + dotest modules2-5 "test -d ampermodule/second-dir" '' + + # Test ability of cvs release to handle multiple arguments + # See comment at "release" for list of other cvs release tests. + cd ampermodule + if ${testcvs} release -d first-dir second-dir <<EOF >>${LOGFILE} +yes +yes +EOF + then + pass modules2-6 + else + fail modules2-6 + fi + dotest_fail modules2-7 "test -d first-dir" '' + dotest_fail modules2-8 "test -d second-dir" '' + + cd .. + + # There used to be a nasty-hack that made CVS skip creation of the + # module dir (in this case ampermodule) when -n was specified + dotest modules2-ampermod-1 "${testcvs} -q co -n ampermodule" '' + dotest modules2-ampermod-2 "test -d ampermodule/first-dir" '' + dotest modules2-ampermod-3 "test -d ampermodule/second-dir" '' + + # Test release of a module + if echo yes |${testcvs} release -d ampermodule >>${LOGFILE}; then + pass modules2-ampermod-release-1 + else + fail modules2-ampermod-release-1 + fi + dotest_fail modules2-ampermod-release-2 "test -d ampermodule" '' + + # and the '-n' test again, but in conjunction with '-d' + dotest modules2-ampermod-4 "${testcvs} -q co -n -d newname ampermodule" '' + dotest modules2-ampermod-5 "test -d newname/first-dir" '' + dotest modules2-ampermod-6 "test -d newname/second-dir" '' + rm -rf newname + + # Now we create another directory named first-dir and make + # sure that CVS doesn't get them mixed up. + mkdir first-dir + # Note that this message should say "Updating ampermodule/first-dir" + # I suspect. This is a long-standing behavior/bug.... + dotest modules2-9 "${testcvs} co ampermodule" \ +"${SPROG} checkout: Updating first-dir +${SPROG} checkout: Updating second-dir" + touch ampermodule/first-dir/amper1 + cd ampermodule + dotest modules2-10 "${testcvs} add first-dir/amper1" \ +"${SPROG} add: scheduling file .first-dir/amper1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cd .. + + # As with the "Updating xxx" message, the "U first-dir/amper1" + # message (instead of "U ampermodule/first-dir/amper1") is + # rather fishy. + dotest modules2-12 "${testcvs} co ampermodule" \ +"${SPROG} checkout: Updating first-dir +A first-dir/amper1 +${SPROG} checkout: Updating second-dir" + + if $remote; then + dotest modules2-13r "$testcvs -q ci -m add-it ampermodule" \ +"$CVSROOT_DIRNAME/first-dir/amper1,v <-- ampermodule/first-dir/amper1 +initial revision: 1\.1" + else + # Trying this as above led to a "protocol error" message. + # Work around this bug. + cd ampermodule + dotest modules2-13 "$testcvs -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/amper1,v <-- first-dir/amper1 +initial revision: 1\.1" + cd .. + fi + cd .. + rm -r 1 + + # Now test the "combmodule" module (combining regular modules + # and ampersand modules in the same module definition). + mkdir 1; cd 1 + dotest modules2-14 "${testcvs} co combmodule" \ +"U combmodule/file3 +${SPROG} checkout: Updating first-dir +U first-dir/amper1" + dotest modules2-15 "test -f combmodule/file3" "" + dotest modules2-16 "test -f combmodule/first-dir/amper1" "" + cd combmodule + rm -r first-dir + # At least for now there is no way to tell CVS that + # some files/subdirectories come from one repository directory, + # and others from another. + # This seems like a pretty sensible behavior to me, in the + # sense that first-dir doesn't "really" exist within + # third-dir, so CVS just acts as if there is nothing there + # to do. + dotest modules2-17 "${testcvs} update -d" \ +"${SPROG} update: Updating \." + + cd .. + dotest modules2-18 "${testcvs} -q co combmodule" \ +"U first-dir/amper1" + dotest modules2-19 "test -f combmodule/first-dir/amper1" "" + cd .. + rm -r 1 + + # Now test the "ampdirmod" and "badmod" modules to be sure that + # options work with ampersand modules but don't prevent the + # "missing directory" error message. + mkdir 1; cd 1 + dotest modules2-20 "${testcvs} co ampdirmod" \ +"${SPROG} checkout: Updating first-dir +U first-dir/amper1 +${SPROG} checkout: Updating second-dir" + dotest modules2-21 "test -f newdir/first-dir/amper1" "" + dotest modules2-22 "test -d newdir/second-dir" "" + dotest_fail modules2-23 "${testcvs} co badmod" \ +"${SPROG} checkout: modules file missing directory for module badmod" \ +"${SPROG} server: modules file missing directory for module badmod +${CPROG} \[checkout aborted\]: cannot expand modules" + cd .. + rm -r 1 + + # Confirm that a rename with added depth nested in an ampersand + # module works. + mkdir 1; cd 1 + dotest modules2-nestedrename-1 "${testcvs} -q co messymod" \ +"U messymod/amper1" + dotest modules2-nestedrename-2 "test -d messymod/sdir" '' + dotest modules2-nestedrename-3 "test -d messymod/sdir/CVS" '' + dotest modules2-nestedrename-4 "test -d messymod/sdir/child" '' + dotest modules2-nestedrename-5 "test -d messymod/sdir/child/CVS" '' + cd ..; rm -r 1 + + # FIXME: client/server has a bug. It should be working like a local + # repository in this case, but fails to check out the second module + # in the list when a branch is specified. + mkdir 1; cd 1 + dotest modules2-ampertag-setup-1 \ +"${testcvs} -Q rtag tag first-dir second-dir third-dir" \ +'' + dotest modules2-ampertag-1 "${testcvs} -q co -rtag ampermodule" \ +"U first-dir/amper1" + if $remote; then + dotest_fail modules2-ampertag-2 "test -d ampermodule/second-dir" '' + dotest_fail modules2-ampertag-3 "test -d ampermodule/second-dir/CVS" '' + else + dotest modules2-ampertag-2 "test -d ampermodule/second-dir" '' + dotest modules2-ampertag-3 "test -d ampermodule/second-dir/CVS" '' + fi + cd ..; rm -r 1 + + # Test for tag files when an ampermod is renamed with more path + # elements than it started with. + # + # FIXME: This is currently broken in the remote case, possibly only + # because the messymodchild isn't being checked out at all. + mkdir 1; cd 1 +# dotest modules2-tagfiles-setup-1 \ +#"${testcvs} -Q rtag -b branch first-dir second-dir" \ +#'' + dotest modules2-tagfiles-1 "${testcvs} -q co -rtag messymod" \ +"U messymod/amper1" + if $remote; then + dotest_fail modules2-tagfiles-2r "test -d messymod/sdir" '' + else + dotest modules2-tagfiles-2 "cat messymod/sdir/CVS/Tag" 'Ttag' + fi + cd ..; rm -r 1 + + # Test that CVS gives an error if one combines -a with + # other options. + # Probably would be better to break this out into a separate + # test. Although it is short, it shares no files/state with + # the rest of the modules2 tests. + mkdir 1; cd 1 + dotest modules2-a0.5 "${testcvs} -q co CVSROOT/modules" \ +'U CVSROOT/modules' + cd CVSROOT + echo 'aliasopt -a -d onedir first-dir' >modules + dotest modules2-a0 "${testcvs} -q ci -m add-modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + dotest_fail modules2-a1 "${testcvs} -q co aliasopt" \ +"${SPROG} checkout: -a cannot be specified in the modules file along with other options" \ +"${SPROG} server: -a cannot be specified in the modules file along with other options +${CPROG} \[checkout aborted\]: cannot expand modules" + cd ..; rm -r 1 + + # Clean up. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir \ + $CVSROOT_DIRNAME/third-dir + ;; + + + + modules3) + # More tests of modules, in particular what happens if several + # modules point to the same file. + + # First just set up a directory first-dir and a file file1 in it. + mkdir 1; cd 1 + + dotest modules3-0 "$testcvs -q co -l ." + mkdir first-dir + dotest modules3-1 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + + cd first-dir + echo file1 >file1 + dotest modules3-2 "${testcvs} add file1" \ +"${SPROG} add: scheduling file \`file1' for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + dotest modules3-3 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + cd .. + + dotest modules3-4 "${testcvs} -q update -d CVSROOT" \ +"U CVSROOT${DOTSTAR}" + cd CVSROOT + cat >modules <<EOF +mod1 -a first-dir/file1 +bigmod -a mod1 first-dir/file1 +namednest -d src/sub/dir first-dir +nestdeeper -d src/sub1/sub2/sub3/dir first-dir +nestshallow -d src/dir second-dir/suba/subb +path/in/modules &mod1 +another/path/test -d another/path/test first-dir +EOF + dotest modules3-5 "${testcvs} -q ci -m add-modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + + dotest modules3-6 "${testcvs} -q co bigmod" '' + rm -r first-dir + dotest modules3-7 "${testcvs} -q co bigmod" 'U first-dir/file1' + cd .. + rm -r 1 + + mkdir 1; cd 1 + mkdir suba + mkdir suba/subb + # This fails to work remote (it doesn't notice the directories, + # I suppose because they contain no files). Bummer, especially + # considering this is a documented technique and everything. + dotest modules3-7a \ +"${testcvs} import -m add-dirs second-dir tag1 tag2" \ +"${SPROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/suba +${SPROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/suba/subb + +No conflicts created by this import" " +No conflicts created by this import" + cd ..; rm -r 1 + mkdir 1; cd 1 + dotest modules3-7b "${testcvs} co second-dir" \ +"${SPROG} checkout: Updating second-dir +${SPROG} checkout: Updating second-dir/suba +${SPROG} checkout: Updating second-dir/suba/subb" \ +"${SPROG} checkout: Updating second-dir" + + if $remote; then + cd second-dir + mkdir suba + dotest modules3-7-workaround1 "${testcvs} add suba" \ +"Directory ${CVSROOT_DIRNAME}/second-dir/suba added to the repository" + cd suba + mkdir subb + dotest modules3-7-workaround2 "${testcvs} add subb" \ +"Directory ${CVSROOT_DIRNAME}/second-dir/suba/subb added to the repository" + cd ../.. + fi + + cd second-dir/suba/subb + touch fileb + dotest modules3-7c "${testcvs} add fileb" \ +"${SPROG} add: scheduling file .fileb. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest modules3-7d "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/second-dir/suba/subb/fileb,v <-- fileb +initial revision: 1\.1" + cd ../../.. + cd ..; rm -r 1 + + mkdir 1 + cd 1 + dotest modules3-8 "${testcvs} -q co namednest" \ +'U src/sub/dir/file1' + dotest modules3-9 "test -f src/sub/dir/file1" '' + cd .. + rm -r 1 + + # Try the same thing, but with the directories nested even + # deeper (deeply enough so they are nested more deeply than + # the number of directories from / to ${TESTDIR}). + mkdir 1 + cd 1 + dotest modules3-10 "${testcvs} -q co nestdeeper" \ +'U src/sub1/sub2/sub3/dir/file1' + dotest modules3-11 "test -f src/sub1/sub2/sub3/dir/file1" '' + + # While we are doing things like twisted uses of '/' (e.g. + # modules3-12), try this one. + if $remote; then + dotest_fail modules3-11b \ +"${testcvs} -q update ${TESTDIR}/1/src/sub1/sub2/sub3/dir/file1" \ +"absolute pathnames invalid for server (specified .${TESTDIR}/1/src/sub1/sub2/sub3/dir.)" + fi # end of remote-only tests + + cd .. + rm -r 1 + + # This one is almost too twisted for words. The pathname output + # in the message from "co" doesn't include the "path/in/modules", + # but those directories do get created (with no CVSADM except + # in "modules" which has a CVSNULLREPOS). + # I'm not sure anyone is relying on this nonsense or whether we + # need to keep doing it, but it is what CVS currently does... + # Skip it for remote; the remote code has the good sense to + # not deal with it (on the minus side it gives + # "internal error: repository string too short." (CVS 1.9) or + # "warning: server is not creating directories one at a time" (now) + # instead of a real error). + # I'm tempted to just make it a fatal error to have '/' in a + # module name. But see comments at modules3-16. + if $remote; then :; else + mkdir 1; cd 1 + dotest modules3-12 "${testcvs} -q co path/in/modules" \ +"U first-dir/file1" + dotest modules3-13 "test -f path/in/modules/first-dir/file1" '' + cd ..; rm -r 1 + fi # end of tests skipped for remote + + # Now here is where it used to get seriously bogus. + mkdir 1; cd 1 + dotest modules3-14 \ +"${testcvs} -q rtag tag1 path/in/modules" '' + # CVS used to create this even though rtag should *never* affect + # the directory current when it is called! + dotest_fail modules3-15 "test -d path/in/modules" '' + # Just for trivia's sake, rdiff was not similarly vulnerable + # because it passed 0 for run_module_prog to do_module. + cd ..; rm -r 1 + + # Some people seem to want this to work. I still suspect there + # are dark corners in slashes in module names. This probably wants + # more thought before we start hacking on CVS (one way or the other) + # or documenting this. + mkdir 2; cd 2 + dotest modules3-16 "${testcvs} -q co another/path/test" \ +"U another/path/test/file1" + dotest modules3-17 "cat another/path/test/file1" 'file1' + + dokeep + cd ..; rm -r 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + modules4) + # Some tests using the modules file with aliases that + # exclude particular directories. + + mkdir 1; cd 1 + + dotest modules4-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest modules4-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + + cd first-dir + mkdir subdir subdir_long + dotest modules4-3 "${testcvs} add subdir subdir_long" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository +Directory ${CVSROOT_DIRNAME}/first-dir/subdir_long added to the repository" + + echo file1 > file1 + dotest modules4-4 "${testcvs} add file1" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + + echo file2 > subdir/file2 + dotest modules4-5 "${testcvs} add subdir/file2" \ +"${SPROG}"' add: scheduling file `subdir/file2'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + + echo file3 > subdir_long/file3 + dotest modules4-6 "${testcvs} add subdir_long/file3" \ +"${SPROG}"' add: scheduling file `subdir_long/file3'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + + dotest modules4-7 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/subdir/file2,v <-- subdir/file2 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/subdir_long/file3,v <-- subdir_long/file3 +initial revision: 1\.1" + + cd .. + + dotest modules4-8 "${testcvs} -q update -d CVSROOT" \ +"U CVSROOT${DOTSTAR}" + cd CVSROOT + cat >modules <<EOF +all -a first-dir +some -a !first-dir/subdir first-dir +other -a !first-dir/subdir !first-dir/subdir_long first-dir +somewhat -a first-dir !first-dir/subdir +EOF + dotest modules4-9 "${testcvs} -q ci -m add-modules" \ +"$CVSROOT_DIRNAME/CVSROOT/modules,v <-- modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + + cd .. + mkdir 2; cd 2 + + dotest modules4-10 "${testcvs} -q co all" \ +"U first-dir/file1 +U first-dir/subdir/file2 +U first-dir/subdir_long/file3" + rm -r first-dir + + dotest modules4-11 "${testcvs} -q co some" \ +"U first-dir/file1 +U first-dir/subdir_long/file3" + dotest_fail modules4-12 "test -d first-dir/subdir" '' + dotest modules4-13 "test -d first-dir/subdir_long" '' + rm -r first-dir + + if $remote; then + # But remote seems to do it the other way. + dotest modules4-14r-1 "${testcvs} -q co somewhat" \ +"U first-dir/file1 +U first-dir/subdir_long/file3" + dotest_fail modules4-14r-2 "test -d first-dir/subdir" '' + dotest modules4-14r-3 "test -d first-dir/subdir_long" '' + else + # This is strange behavior, in that the order of the + # "!first-dir/subdir" and "first-dir" matter, and it isn't + # clear that they should. I suspect it is long-standing + # strange behavior but I haven't verified that. + dotest modules4-14-1 "${testcvs} -q co somewhat" \ +"U first-dir/file1 +U first-dir/subdir/file2 +U first-dir/subdir_long/file3" + dotest modules4-14-2 "test -d first-dir/subdir" '' + dotest modules4-14-3 "test -d first-dir/subdir_long" '' + fi + rm -r first-dir + + dotest modules4-15 "${testcvs} -q co other" \ +"U first-dir/file1" + dotest_fail modules4-16 "test -d first-dir/subdir" '' + dotest_fail modules4-17 "test -d first-dir/subdir_long" '' + rm -r first-dir + + cd .. + rm -r 2 + + dotest modules4-18 "${testcvs} rtag tag some" \ +"${SPROG} rtag: Tagging first-dir +${SPROG} rtag: Ignoring first-dir/subdir +${SPROG} rtag: Tagging first-dir/subdir_long" + + cd 1/first-dir/subdir + dotest modules4-19 "${testcvs} log file2" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/file2,v +Working file: file2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +add-it +=============================================================================" + + dokeep + cd ../../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + modules5) + # Test module programs + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1 + cd 1 + dotest modules5-1 "$testcvs -q co first-dir" + cd first-dir + mkdir subdir + dotest modules5-2 "${testcvs} add subdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" + cd subdir + mkdir ssdir + dotest modules5-3 "${testcvs} add ssdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir added to the repository" + touch a b + dotest modules5-4 "${testcvs} add a b" \ +"${SPROG} add: scheduling file .a. for addition +${SPROG} add: scheduling file .b. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + + dotest modules5-5 "${testcvs} ci -m added" \ +"${CPROG} commit: Examining . +${CPROG} commit: Examining ssdir +${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a +initial revision: 1\.1 +${CVSROOT_DIRNAME}/first-dir/subdir/b,v <-- b +initial revision: 1\.1" + + cd .. + dotest modules5-6 "${testcvs} -q co CVSROOT" \ +"U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg" + + # FIXCVS: The sleep in the following script helps avoid out of + # order messages, but we really need to figure out how to fix + # cvs to prevent them in the first place. + for i in checkout export tag; do + cat >> ${CVSROOT_DIRNAME}/$i.sh <<EOF +#! $TESTSHELL +sleep 1 +echo "$i script invoked in \`pwd\`" +echo "args: \$@" +EOF + # Cygwin doesn't set premissions correctly over the Samba share. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x ${CVSROOT_DIRNAME}/$i.sh" + else + chmod +x ${CVSROOT_DIRNAME}/$i.sh + fi + done + + OPTS="-o${CVSROOT_DIRNAME}/checkout.sh -e ${CVSROOT_DIRNAME}/export.sh -t${CVSROOT_DIRNAME}/tag.sh" + cat >CVSROOT/modules <<EOF +realmodule ${OPTS} first-dir/subdir a +dirmodule ${OPTS} first-dir/subdir +namedmodule -d nameddir ${OPTS} first-dir/subdir +EOF + + dotest modules5-7 "$testcvs -Q ci -m 'add modules' CVSROOT/modules" + + cd .. + rm -rf first-dir + + # Test that real modules check out to realmodule/a, not subdir/a. + if $remote; then + # FIXCVS? + # Mac OSX 10.3 (Darwin ppc-osx1 5.5) fails here when $TMPDIR + # contains a symlink (it does not fail the local modules5-8). + # Since no other platforms are exhibiting the same problem, I + # suspect an issue with OSX and fork() or the like dereferencing + # the symlink, but it is possible it is something that could be + # fixed or worked around in CVS. + dotest modules5-8r "$testcvs co realmodule" \ +"U realmodule/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule.. +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: realmodule" + else + dotest modules5-8 "${testcvs} co realmodule" \ +"U realmodule/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule.. +checkout script invoked in ${TESTDIR}/1 +args: realmodule" + fi + dotest modules5-9 "test -d realmodule && test -f realmodule/a" "" + dotest_fail modules5-10 "test -f realmodule/b" "" + if $remote; then + dotest modules5-11 "${testcvs} -q co realmodule" \ +"checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: realmodule" + dotest modules5-12 "${testcvs} -q update" '' + echo "change" >>realmodule/a + dotest modules5-13 "${testcvs} -q ci -m." \ +"$CVSROOT_DIRNAME/first-dir/subdir/a,v <-- realmodule/a +new revision: 1\.2; previous revision: 1\.1" + else + dotest modules5-11 "${testcvs} -q co realmodule" \ +"checkout script invoked in ${TESTDIR}/1 +args: realmodule" + dotest modules5-12 "${testcvs} -q update" '' + echo "change" >>realmodule/a + dotest modules5-13 "${testcvs} -q ci -m." \ +"$CVSROOT_DIRNAME/first-dir/subdir/a,v <-- realmodule/a +new revision: 1\.2; previous revision: 1\.1" + fi + dotest modules5-14 "echo yes | ${testcvs} release -d realmodule" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .realmodule.: " + dotest modules5-15 "${testcvs} -q rtag -Dnow MYTAG realmodule" \ +"tag script invoked in ${TESTDIR}/1 +args: realmodule MYTAG" \ +"tag script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: realmodule MYTAG" + if $remote; then + dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \ +"U realmodule/a +export script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: realmodule" + else + dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \ +"U realmodule/a +export script invoked in ${TESTDIR}/1 +args: realmodule" + fi + rm -r realmodule + + dotest_fail modules5-17 "${testcvs} co realmodule/a" \ +"${SPROG}"' checkout: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \ +"${SPROG}"' server: module `realmodule/a'\'' is a request for a file in a module which is not a directory +'"${CPROG}"' \[checkout aborted\]: cannot expand modules' + + # Now test the ability to check out a single file from a directory + if $remote; then + dotest modules5-18 "${testcvs} co dirmodule/a" \ +"U dirmodule/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: dirmodule" + else + dotest modules5-18 "${testcvs} co dirmodule/a" \ +"U dirmodule/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. +checkout script invoked in ${TESTDIR}/1 +args: dirmodule" + fi + dotest modules5-19 "test -d dirmodule && test -f dirmodule/a" "" + dotest_fail modules5-20 "test -f dirmodule/b" "" + dotest modules5-21 "echo yes | ${testcvs} release -d dirmodule" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .dirmodule.: " + + # Now test the ability to correctly reject a non-existent filename. + # For maximum studliness we would check that an error message is + # being output. + # We accept a zero exit status because it is what CVS does + # (Dec 95). Probably the exit status should be nonzero, + # however. + if $remote; then + dotest modules5-22 "${testcvs} co dirmodule/nonexist" \ +"${SPROG} checkout: warning: new-born \`dirmodule/nonexist' has disappeared +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: dirmodule" + else + dotest modules5-22 "${testcvs} co dirmodule/nonexist" \ +"${SPROG} checkout: warning: new-born \`dirmodule/nonexist' has disappeared +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. +checkout script invoked in ${TESTDIR}/1 +args: dirmodule" + fi + # We tolerate the creation of the dirmodule directory, since that + # is what CVS does, not because we view that as preferable to not + # creating it. + dotest_fail modules5-23 "test -f dirmodule/a || test -f dirmodule/b" "" + rm -r dirmodule + + # Now test that a module using -d checks out to the specified + # directory. + if $remote; then + dotest modules5-24 "${testcvs} -q co namedmodule" \ +"U nameddir/a +U nameddir/b +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: nameddir" + else + dotest modules5-24 "${testcvs} -q co namedmodule" \ +"U nameddir/a +U nameddir/b +checkout script invoked in ${TESTDIR}/1 +args: nameddir" + fi + dotest modules5-25 "test -f nameddir/a && test -f nameddir/b" "" + echo add line >>nameddir/a + # This seems suspicious: when we checkout an existing directory, + # the checkout script gets executed in addition to the update + # script. Is that by design or accident? + if $remote; then + dotest modules5-26 "${testcvs} -q co namedmodule" \ +"M nameddir/a +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: nameddir" + else + dotest modules5-26 "${testcvs} -q co namedmodule" \ +"M nameddir/a +checkout script invoked in ${TESTDIR}/1 +args: nameddir" + fi + rm nameddir/a + + if $remote; then + dotest modules5-27 "${testcvs} -q co namedmodule" \ +"U nameddir/a +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: nameddir" + else + dotest modules5-27 "${testcvs} -q co namedmodule" \ +"U nameddir/a +checkout script invoked in ${TESTDIR}/1 +args: nameddir" + fi + dotest modules5-28 "echo yes | ${testcvs} release -d nameddir" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .nameddir.: " + + # Now try the same tests with -d on command line + # FIXCVS? The manual says the modules programs get the module name, + # but they really get the directory name. + if $remote; then + dotest modules5-29 "${testcvs} co -d mydir realmodule" \ +"U mydir/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + else + dotest modules5-29 "${testcvs} co -d mydir realmodule" \ +"U mydir/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. +checkout script invoked in ${TESTDIR}/1 +args: mydir" + fi + dotest modules5-30 "test -d mydir && test -f mydir/a" "" + dotest_fail modules5-31 "test -d realmodule || test -f mydir/b" "" + if $remote; then + dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \ +"checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + dotest modules5-33 "${testcvs} -q update" '' + echo "change" >>mydir/a + dotest modules5-34 "${testcvs} -q ci -m." \ +"$CVSROOT_DIRNAME/first-dir/subdir/a,v <-- mydir/a +new revision: 1\.3; previous revision: 1\.2" + else + dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \ +"checkout script invoked in ${TESTDIR}/1 +args: mydir" + dotest modules5-33 "${testcvs} -q update" '' + echo "change" >>mydir/a + dotest modules5-34 "${testcvs} -q ci -m." \ +"$CVSROOT_DIRNAME/first-dir/subdir/a,v <-- mydir/a +new revision: 1\.3; previous revision: 1\.2" + fi + dotest modules5-35 "echo yes | ${testcvs} release -d mydir" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .mydir.: " + if $remote; then + dotest modules5-36 "${testcvs} -q rtag -Dnow MYTAG2 realmodule" \ +"tag script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: realmodule MYTAG2" + dotest modules5-37 "${testcvs} -q export -r MYTAG2 -d mydir realmodule" \ +"U mydir/a +export script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + else + dotest modules5-36 "${testcvs} -q rtag -Dnow MYTAG2 realmodule" \ +"tag script invoked in ${TESTDIR}/1 +args: realmodule MYTAG2" + dotest modules5-37 "${testcvs} -q export -r MYTAG2 -d mydir realmodule" \ +"U mydir/a +export script invoked in ${TESTDIR}/1 +args: mydir" + fi + rm -r mydir + + # Now test the ability to check out a single file from a directory + if $remote; then + dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \ +"U mydir/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + else + dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \ +"U mydir/a +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. +checkout script invoked in ${TESTDIR}/1 +args: mydir" + fi + dotest modules5-39 "test -d mydir && test -f mydir/a" "" + dotest_fail modules5-40 "test -d dirmodule || test -f mydir/b" "" + dotest modules5-41 "echo yes | ${testcvs} release -d mydir" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .mydir.: " + + # Now test the ability to correctly reject a non-existent filename. + # For maximum studliness we would check that an error message is + # being output. + # We accept a zero exit status because it is what CVS does + # (Dec 95). Probably the exit status should be nonzero, + # however. + if $remote; then + dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \ +"${SPROG} checkout: warning: new-born \`mydir/nonexist' has disappeared +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + else + dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \ +"${SPROG} checkout: warning: new-born \`mydir/nonexist' has disappeared +${SPROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. +checkout script invoked in ${TESTDIR}/1 +args: mydir" + fi + # We tolerate the creation of the mydir directory, since that + # is what CVS does, not because we view that as preferable to not + # creating it. + dotest_fail modules5-43 "test -f mydir/a || test -f mydir/b" "" + rm -r mydir + + if $remote; then + dotest modules5-44 "${testcvs} -q co -d mydir namedmodule" \ +"U mydir/a +U mydir/b +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + else + dotest modules5-44 "${testcvs} -q co -d mydir namedmodule" \ +"U mydir/a +U mydir/b +checkout script invoked in ${TESTDIR}/1 +args: mydir" + fi + dotest modules5-45 "test -f mydir/a && test -f mydir/b" "" + dotest_fail modules5-46 "test -d namedir" + echo add line >>mydir/a + # This seems suspicious: when we checkout an existing directory, + # the checkout script gets executed in addition to the update + # script. Is that by design or accident? + if $remote; then + dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \ +"M mydir/a +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + else + dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \ +"M mydir/a +checkout script invoked in ${TESTDIR}/1 +args: mydir" + fi + rm mydir/a + + if $remote; then + dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \ +"U mydir/a +checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* +args: mydir" + else + dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \ +"U mydir/a +checkout script invoked in ${TESTDIR}/1 +args: mydir" + fi + dotest modules5-49 "echo yes | ${testcvs} release -d mydir" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .mydir.: " + + dokeep + cd .. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/*.sh + ;; + + + + modules6) + # + # Test invalid module definitions + # + # See the header comment for the `modules' test for an index of + # the complete suite of modules tests. + # + + # + # There was a bug in CVS through 1.11.1p1 where a bad module name + # would cause the previous line to be parsed as the module + # definition. This test proves this doesn't happen anymore. + # + mkdir modules6 + cd modules6 + dotest module6-setup-1 "${testcvs} -Q co CVSROOT" "" + cd CVSROOT + echo "longmodulename who cares" >modules + echo "badname" >>modules + # This test almost isn't setup since it generates the error message + # we are looking for if `-Q' isn't specified, but I want to test the + # filename in the message later. + dotest modules6-setup-2 "$testcvs -Q ci -mbad-modules" + + # Here's where CVS would report not being able to find `lename' + cd .. + dotest_fail modules6-1 "${testcvs} -q co badname" \ +"${SPROG} checkout: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules. +${SPROG} checkout: cannot find module .badname. - ignored" \ +"${SPROG} server: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules. +${SPROG} server: cannot find module .badname. - ignored +${CPROG} \[checkout aborted\]: cannot expand modules" + + dokeep + restore_adm + cd .. + rm -r modules6 + ;; + + + + modules7) + # + # Test tag problems vs an empty CVSROOT/val-tags file + # + # See the header comment for the `modules' test for an index of + # the complete suite of modules tests. + # + mkdir modules7 + cd modules7 + dotest modules7-1 "$testcvs -Q co -d top ." + cd top + mkdir zero one + dotest modules7-2 "$testcvs -Q add zero one" + cd one + echo 'file1 contents' > file1 + dotest modules7-2 "$testcvs -Q add file1" + dotest modules7-3 "$testcvs -Q ci -mnew file1" + dotest modules7-4 "$testcvs -Q tag mytag file1" + cd ../CVSROOT + echo 'all -a zero one' > modules + dotest modules7-5 "$testcvs -Q ci -mall-module" + cd ../.. + mkdir myexport + cd myexport + + # This failed prior to CVS version 1.12.10. + dotest modules7-7 "$testcvs export -rmytag all" \ +"$SPROG export: Updating zero +$SPROG export: Updating one +U one/file1" + dotest modules7-8 'cat one/file1' 'file1 contents' + + dokeep + + # cleanup + restore_adm + cd ../.. + rm -fr modules7 + rm -rf $CVSROOT_DIRNAME/zero $CVSROOT_DIRNAME/one + ;; + + + + mkmodules) + # When a file listed in checkoutlist doesn't exist, cvs-1.10.4 + # would fail to remove the CVSROOT/.#[0-9]* temporary file it + # creates while mkmodules is in the process of trying to check + # out the missing file. + + mkdir 1; cd 1 + dotest mkmodules-temp-file-removal-1 "${testcvs} -Q co CVSROOT" '' + cd CVSROOT + echo no-such-file >> checkoutlist + dotest mkmodules-temp-file-removal-2 "$testcvs -Q ci -m. checkoutlist" + + dotest mkmodules-temp-file-removal-3 \ +"echo $CVSROOT_DIRNAME/CVSROOT/.#[0-9]*" \ +"$CVSROOT_DIRNAME/CVSROOT/\.#\[0-9\]\*" + + # Versions 1.11.6 & 1.12.1 and earlier of CVS printed most of the + # white space included before error messages in checkoutlist. + echo "no-such-file Failed to update no-such-file." >checkoutlist + dotest mkmodules-error-message-1 "$testcvs -Q ci -m. checkoutlist" \ +"$SPROG commit: Failed to update no-such-file\." + + # Versions 1.11.6 & 1.12.1 and earlier of CVS used the error string + # from the checkoutlist file as the format string passed to error()'s + # printf. Check that this is no longer the case by verifying that + # printf format patterns remain unchanged. + echo "no-such-file Failed to update %s %lx times because %s happened %d times." >checkoutlist + dotest mkmodules-error-message-2 "$testcvs -Q ci -m. checkoutlist" \ +"$SPROG commit: Failed to update %s %lx times because %s happened %d times\." + + dotest mkmodules-cleanup-1 \ +"$testcvs -Q up -pr1.1 checkoutlist >checkoutlist" + dotest mkmodules-cleanup-2 "$testcvs -Q ci -m. checkoutlist" + + dokeep + cd ../.. + rm -r 1 + ;; + + + + co-d) + # Some tests of various permutations of co-d when directories exist + # and checkouts lengthen. + # + # Interestingly enough, these same tests pass when the directory + # lengthening happens via the modules file. Go figure. + module=co-d + mkdir $module; cd $module + mkdir top; cd top + dotest co-d-init-1 "$testcvs -Q co -l ." + mkdir $module + dotest co-d-init-2 "$testcvs -Q add $module" + cd $module + echo content >file1 + echo different content >file2 + dotest co-d-init-3 "$testcvs -Q add file1 file2" + dotest co-d-init-4 "$testcvs -Q ci -madd-em" + cd ../.. + + mkdir 2; cd 2 + dotest co-d-1 "$testcvs -q co -d dir $module" \ +"U dir/file1 +U dir/file2" + dotest co-d-1.2 "cat dir/CVS/Repository" "$module" + + dotest co-d-2 "$testcvs -q co -d dir2/sdir $module" \ +"U dir2/sdir/file1 +U dir2/sdir/file2" + dotest co-d-2.2 "cat dir2/CVS/Repository" "." + dotest co-d-2.3 "cat dir2/sdir/CVS/Repository" "$module" + + dotest co-d-2.4 "$testcvs -q co -d dir2.4/sdir/sdir2 $module" \ +"U dir2.4/sdir/sdir2/file1 +U dir2.4/sdir/sdir2/file2" + dotest co-d-2.4.2 "cat dir2.4/CVS/Repository" "CVSROOT/Emptydir" + dotest co-d-2.4.3 "cat dir2.4/sdir/CVS/Repository" "." + dotest co-d-2.4.3 "cat dir2.4/sdir/sdir2/CVS/Repository" "$module" + + mkdir dir3 + dotest co-d-3 "$testcvs -q co -d dir3 $module" \ +"U dir3/file1 +U dir3/file2" + dotest co-d-3.2 "cat dir3/CVS/Repository" "$module" + + mkdir dir4 + dotest co-d-4 "$testcvs -q co -d dir4/sdir $module" \ +"U dir4/sdir/file1 +U dir4/sdir/file2" + + # CVS is only supposed to create administration directories in + # directories it also creates, and in the directory specified by + # the last portion of the path passed to -d regardless. This is + # + # FIXCVS: + # This is broken in client/server mode because the server does not + # know the client's directory structure and has to create + # everything. + if $remote; then + dotest co-d-4.2r "cat dir4/CVS/Repository" "." + else + dotest_fail co-d-4.2 "test -d dir4/CVS" + fi + + dotest co-d-4.3 "cat dir4/sdir/CVS/Repository" "$module" + + mkdir dir5 + mkdir dir5/sdir + dotest co-d-5 "$testcvs -q co -d dir5/sdir $module" \ +"U dir5/sdir/file1 +U dir5/sdir/file2" + # FIXCVS as for co-d-4.2r. + if $remote; then + dotest co-d-5.2 "cat dir5/CVS/Repository" "." + else + dotest_fail co-d-5.2 "test -d dir5/CVS" + fi + + dotest co-d-5.3 "cat dir5/sdir/CVS/Repository" "$module" + + # clean up + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/$module + rm -r $module + ;; + + + + cvsadm) + # These test check the content of CVS' administrative + # files as they are checked out in various configurations. + # (As a side note, I'm not using the "-q" flag in any of + # this code, which should provide some extra checking for + # those messages which don't seem to be checked thoroughly + # anywhere else.) To do a thorough test, we need to make + # a bunch of modules in various configurations. + # + # <1mod> is a directory at the top level of cvsroot + # ``foo bar'' + # <2mod> is a directory at the second level of cvsroot + # ``foo bar/baz'' + # <1d1mod> is a directory at the top level which is + # checked out into another directory + # ``foo -d bar baz'' + # <1d2mod> is a directory at the second level which is + # checked out into another directory + # ``foo -d bar baz/quux'' + # <2d1mod> is a directory at the top level which is + # checked out into a directory that is two deep + # ``foo -d bar/baz quux'' + # <2d2mod> is a directory at the second level which is + # checked out into a directory that is two deep + # ``foo -d bar/baz quux'' + # + # The tests do each of these types separately and in twos. + # We also repeat each test -d flag for 1-deep and 2-deep + # directories. + # + # Each test should check the output for the Repository + # file, since that is the one which varies depending on + # the directory and how it was checked out. + # + # Yes, this is verbose, but at least it's very thorough. + + # convenience variables + REP=${CVSROOT} + + # First, set TopLevelAdmin=yes so we're sure to get + # top-level CVS directories. + mkdir 1; cd 1 + dotest cvsadm-setup-1 "${testcvs} -q co CVSROOT/config" \ +"U CVSROOT/config" + cd CVSROOT + echo "TopLevelAdmin=yes" >>config + dotest cvsadm-setup-2 "${testcvs} -q ci -m yes-top-level" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../.. + rm -r 1 + + # Second, check out the modules file and edit it. + mkdir 1; cd 1 + dotest cvsadm-1 "${testcvs} co CVSROOT/modules" \ +"U CVSROOT/modules" + + # Test CVS/Root once. Since there is only one part of + # the code which writes CVS/Root files (Create_Admin), + # there is no point in testing this every time. + dotest cvsadm-1a "cat CVS/Root" ${REP} + dotest cvsadm-1b "cat CVS/Repository" "\." + dotest cvsadm-1c "cat CVSROOT/CVS/Root" ${REP} + dotest cvsadm-1d "cat CVSROOT/CVS/Repository" "CVSROOT" + # All of the defined module names begin with a number. + # All of the top-level directory names begin with "dir". + # All of the subdirectory names begin with "sub". + # All of the top-level modules begin with "mod". + echo "# Module defs for cvsadm tests" > CVSROOT/modules + echo "1mod mod1" >> CVSROOT/modules + echo "1mod-2 mod1-2" >> CVSROOT/modules + echo "2mod mod2/sub2" >> CVSROOT/modules + echo "2mod-2 mod2-2/sub2-2" >> CVSROOT/modules + echo "1d1mod -d dir1d1 mod1" >> CVSROOT/modules + echo "1d1mod-2 -d dir1d1-2 mod1-2" >> CVSROOT/modules + echo "1d2mod -d dir1d2 mod2/sub2" >> CVSROOT/modules + echo "1d2mod-2 -d dir1d2-2 mod2-2/sub2-2" >> CVSROOT/modules + echo "2d1mod -d dir2d1/sub2d1 mod1" >> CVSROOT/modules + echo "2d1mod-2 -d dir2d1-2/sub2d1-2 mod1-2" >> CVSROOT/modules + echo "2d2mod -d dir2d2/sub2d2 mod2/sub2" >> CVSROOT/modules + echo "2d2mod-2 -d dir2d2-2/sub2d2-2 mod2-2/sub2-2" >> CVSROOT/modules + dotest cvsadm-1e "${testcvs} ci -m add-modules" \ +"${CPROG} commit: Examining . +${CPROG} commit: Examining CVSROOT +${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- CVSROOT/modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +${SPROG} commit: Rebuilding administrative file database" \ +"${CPROG} commit: Examining . +${CPROG} commit: Examining CVSROOT" + rm -rf CVS CVSROOT; + + # Create the various modules + dotest cvsadm-2 "${testcvs} -q co -l ." '' + mkdir mod1 + mkdir mod1-2 + mkdir mod2 + mkdir mod2/sub2 + mkdir mod2-2 + mkdir mod2-2/sub2-2 + dotest cvsadm-2a "${testcvs} add mod1 mod1-2 mod2 mod2/sub2 mod2-2 mod2-2/sub2-2" \ +"Directory ${CVSROOT_DIRNAME}/mod1 added to the repository +Directory ${CVSROOT_DIRNAME}/mod1-2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2/sub2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2-2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2-2/sub2-2 added to the repository" + + # Populate the directories for the halibut + echo "file1" > mod1/file1 + echo "file1-2" > mod1-2/file1-2 + echo "file2" > mod2/sub2/file2 + echo "file2-2" > mod2-2/sub2-2/file2-2 + dotest cvsadm-2aa "${testcvs} add mod1/file1 mod1-2/file1-2 mod2/sub2/file2 mod2-2/sub2-2/file2-2" \ +"${SPROG} add: scheduling file .mod1/file1. for addition +${SPROG} add: scheduling file .mod1-2/file1-2. for addition +${SPROG} add: scheduling file .mod2/sub2/file2. for addition +${SPROG} add: scheduling file .mod2-2/sub2-2/file2-2. for addition +${SPROG} add: use \`${SPROG} commit' to add these files permanently" + + dotest cvsadm-2b "${testcvs} ci -m yup mod1 mod1-2 mod2 mod2-2" \ +"${CPROG} commit: Examining mod1 +${CPROG} commit: Examining mod1-2 +${CPROG} commit: Examining mod2 +${CPROG} commit: Examining mod2/sub2 +${CPROG} commit: Examining mod2-2 +${CPROG} commit: Examining mod2-2/sub2-2 +${CVSROOT_DIRNAME}/mod1/file1,v <-- mod1/file1 +initial revision: 1.1 +${CVSROOT_DIRNAME}/mod1-2/file1-2,v <-- mod1-2/file1-2 +initial revision: 1.1 +${CVSROOT_DIRNAME}/mod2/sub2/file2,v <-- mod2/sub2/file2 +initial revision: 1.1 +${CVSROOT_DIRNAME}/mod2-2/sub2-2/file2-2,v <-- mod2-2/sub2-2/file2-2 +initial revision: 1.1" + # Finished creating the modules -- clean up. + rm -rf CVS mod1 mod1-2 mod2 mod2-2 + # Done. + + ################################################## + ## Start the dizzying array of possibilities. + ## Begin with each module type separately. + ################################################## + + # Pattern -- after each checkout, first check the top-level + # CVS directory. Then, check the directories in numerical + # order. + + dotest cvsadm-3 "${testcvs} co 1mod" \ +"${SPROG} checkout: Updating 1mod +U 1mod/file1" + dotest cvsadm-3b "cat CVS/Repository" "\." + dotest cvsadm-3d "cat 1mod/CVS/Repository" "mod1" + rm -rf CVS 1mod + + dotest cvsadm-4 "${testcvs} co 2mod" \ +"${SPROG} checkout: Updating 2mod +U 2mod/file2" + dotest cvsadm-4b "cat CVS/Repository" "\." + dotest cvsadm-4d "cat 2mod/CVS/Repository" "mod2/sub2" + rm -rf CVS 2mod + + dotest cvsadm-5 "${testcvs} co 1d1mod" \ +"${SPROG} checkout: Updating dir1d1 +U dir1d1/file1" + dotest cvsadm-5b "cat CVS/Repository" "\." + dotest cvsadm-5d "cat dir1d1/CVS/Repository" "mod1" + rm -rf CVS dir1d1 + + dotest cvsadm-6 "${testcvs} co 1d2mod" \ +"${SPROG} checkout: Updating dir1d2 +U dir1d2/file2" + dotest cvsadm-6b "cat CVS/Repository" "\." + dotest cvsadm-6d "cat dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir1d2 + + dotest cvsadm-7 "${testcvs} co 2d1mod" \ +"${SPROG} checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + dotest cvsadm-7b "cat CVS/Repository" "\." + dotest cvsadm-7d "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-7f "cat dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir2d1 + + dotest cvsadm-8 "${testcvs} co 2d2mod" \ +"${SPROG} checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + dotest cvsadm-8b "cat CVS/Repository" "\." + dotest cvsadm-8d "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-8f "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir2d2 + + ################################################## + ## You are in a shell script of twisted little + ## module combination statements, all alike. + ################################################## + + ### 1mod + + dotest cvsadm-9 "${testcvs} co 1mod 1mod-2" \ +"${SPROG} checkout: Updating 1mod +U 1mod/file1 +${SPROG} checkout: Updating 1mod-2 +U 1mod-2/file1-2" + # the usual for the top level + dotest cvsadm-9b "cat CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-9d "cat 1mod/CVS/Repository" "mod1" + # the usual for 1mod copy + dotest cvsadm-9f "cat 1mod-2/CVS/Repository" "mod1-2" + rm -rf CVS 1mod 1mod-2 + + # 1mod 2mod redmod bluemod + dotest cvsadm-10 "${testcvs} co 1mod 2mod" \ +"${SPROG} checkout: Updating 1mod +U 1mod/file1 +${SPROG} checkout: Updating 2mod +U 2mod/file2" + # the usual for the top level + dotest cvsadm-10b "cat CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-10d "cat 1mod/CVS/Repository" "mod1" + # the usual for 2dmod + dotest cvsadm-10f "cat 2mod/CVS/Repository" "mod2/sub2" + rm -rf CVS 1mod 2mod + + dotest cvsadm-11 "${testcvs} co 1mod 1d1mod" \ +"${SPROG} checkout: Updating 1mod +U 1mod/file1 +${SPROG} checkout: Updating dir1d1 +U dir1d1/file1" + # the usual for the top level + dotest cvsadm-11b "cat CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-11d "cat 1mod/CVS/Repository" "mod1" + # the usual for 1d1mod + dotest cvsadm-11f "cat dir1d1/CVS/Repository" "mod1" + rm -rf CVS 1mod dir1d1 + + dotest cvsadm-12 "${testcvs} co 1mod 1d2mod" \ +"${SPROG} checkout: Updating 1mod +U 1mod/file1 +${SPROG} checkout: Updating dir1d2 +U dir1d2/file2" + # the usual for the top level + dotest cvsadm-12b "cat CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-12d "cat 1mod/CVS/Repository" "mod1" + # the usual for 1d2mod + dotest cvsadm-12f "cat dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS 1mod dir1d2 + + dotest cvsadm-13 "${testcvs} co 1mod 2d1mod" \ +"${SPROG} checkout: Updating 1mod +U 1mod/file1 +${SPROG} checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-13b "cat CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-13d "cat 1mod/CVS/Repository" "mod1" + # the usual for 2d1mod + dotest cvsadm-13f "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-13h "cat dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS 1mod dir2d1 + + dotest cvsadm-14 "${testcvs} co 1mod 2d2mod" \ +"${SPROG} checkout: Updating 1mod +U 1mod/file1 +${SPROG} checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-14b "cat CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-14d "cat 1mod/CVS/Repository" "mod1" + # the usual for 2d2mod + dotest cvsadm-14f "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-14h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS 1mod dir2d2 + + + ### 2mod + + dotest cvsadm-15 "${testcvs} co 2mod 2mod-2" \ +"${SPROG} checkout: Updating 2mod +U 2mod/file2 +${SPROG} checkout: Updating 2mod-2 +U 2mod-2/file2-2" + # the usual for the top level + dotest cvsadm-15b "cat CVS/Repository" "\." + # the usual for 2mod + dotest cvsadm-15d "cat 2mod/CVS/Repository" "mod2/sub2" + # the usual for 2mod copy + dotest cvsadm-15f "cat 2mod-2/CVS/Repository" "mod2-2/sub2-2" + rm -rf CVS 2mod 2mod-2 + + + dotest cvsadm-16 "${testcvs} co 2mod 1d1mod" \ +"${SPROG} checkout: Updating 2mod +U 2mod/file2 +${SPROG} checkout: Updating dir1d1 +U dir1d1/file1" + # the usual for the top level + dotest cvsadm-16b "cat CVS/Repository" "\." + # the usual for 2mod + dotest cvsadm-16d "cat 2mod/CVS/Repository" "mod2/sub2" + # the usual for 1d1mod + dotest cvsadm-16f "cat dir1d1/CVS/Repository" "mod1" + rm -rf CVS 2mod dir1d1 + + dotest cvsadm-17 "${testcvs} co 2mod 1d2mod" \ +"${SPROG} checkout: Updating 2mod +U 2mod/file2 +${SPROG} checkout: Updating dir1d2 +U dir1d2/file2" + # the usual for the top level + dotest cvsadm-17b "cat CVS/Repository" "\." + # the usual for 2mod + dotest cvsadm-17d "cat 2mod/CVS/Repository" "mod2/sub2" + # the usual for 1d2mod + dotest cvsadm-17f "cat dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS 2mod dir1d2 + + dotest cvsadm-18 "${testcvs} co 2mod 2d1mod" \ +"${SPROG} checkout: Updating 2mod +U 2mod/file2 +${SPROG} checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-18b "cat CVS/Repository" "\." + # the usual for 2mod + dotest cvsadm-18d "cat 2mod/CVS/Repository" "mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-18f "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-18h "cat dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS 2mod dir2d1 + + dotest cvsadm-19 "${testcvs} co 2mod 2d2mod" \ +"${SPROG} checkout: Updating 2mod +U 2mod/file2 +${SPROG} checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-19b "cat CVS/Repository" "\." + # the usual for 2mod + dotest cvsadm-19d "cat 2mod/CVS/Repository" "mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-19f "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-19h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS 2mod dir2d2 + + + ### 1d1mod + + dotest cvsadm-20 "${testcvs} co 1d1mod 1d1mod-2" \ +"${SPROG} checkout: Updating dir1d1 +U dir1d1/file1 +${SPROG} checkout: Updating dir1d1-2 +U dir1d1-2/file1-2" + # the usual for the top level + dotest cvsadm-20b "cat CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-20d "cat dir1d1/CVS/Repository" "mod1" + # the usual for 1d1mod copy + dotest cvsadm-20f "cat dir1d1-2/CVS/Repository" "mod1-2" + rm -rf CVS dir1d1 dir1d1-2 + + dotest cvsadm-21 "${testcvs} co 1d1mod 1d2mod" \ +"${SPROG} checkout: Updating dir1d1 +U dir1d1/file1 +${SPROG} checkout: Updating dir1d2 +U dir1d2/file2" + # the usual for the top level + dotest cvsadm-21b "cat CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-21d "cat dir1d1/CVS/Repository" "mod1" + # the usual for 1d2mod + dotest cvsadm-21f "cat dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir1d1 dir1d2 + + dotest cvsadm-22 "${testcvs} co 1d1mod 2d1mod" \ +"${SPROG} checkout: Updating dir1d1 +U dir1d1/file1 +${SPROG} checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-22b "cat CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-22d "cat dir1d1/CVS/Repository" "mod1" + # the usual for 2d1mod + dotest cvsadm-22f "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-22h "cat dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir1d1 dir2d1 + + dotest cvsadm-23 "${testcvs} co 1d1mod 2d2mod" \ +"${SPROG} checkout: Updating dir1d1 +U dir1d1/file1 +${SPROG} checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-23b "cat CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-23d "cat dir1d1/CVS/Repository" "mod1" + # the usual for 2d2mod + dotest cvsadm-23f "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-23h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir1d1 dir2d2 + + + ### 1d2mod + + dotest cvsadm-24 "${testcvs} co 1d2mod 1d2mod-2" \ +"${SPROG} checkout: Updating dir1d2 +U dir1d2/file2 +${SPROG} checkout: Updating dir1d2-2 +U dir1d2-2/file2-2" + # the usual for the top level + dotest cvsadm-24b "cat CVS/Repository" "\." + # the usual for 1d2mod + dotest cvsadm-24d "cat dir1d2/CVS/Repository" "mod2/sub2" + # the usual for 1d2mod copy + dotest cvsadm-24f "cat dir1d2-2/CVS/Repository" "mod2-2/sub2-2" + rm -rf CVS dir1d2 dir1d2-2 + + dotest cvsadm-25 "${testcvs} co 1d2mod 2d1mod" \ +"${SPROG} checkout: Updating dir1d2 +U dir1d2/file2 +${SPROG} checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-25b "cat CVS/Repository" "\." + # the usual for 1d2mod + dotest cvsadm-25d "cat dir1d2/CVS/Repository" "mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-25f "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-25h "cat dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir1d2 dir2d1 + + dotest cvsadm-26 "${testcvs} co 1d2mod 2d2mod" \ +"${SPROG} checkout: Updating dir1d2 +U dir1d2/file2 +${SPROG} checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-26b "cat CVS/Repository" "\." + # the usual for 1d2mod + dotest cvsadm-26d "cat dir1d2/CVS/Repository" "mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-26f "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-26h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir1d2 dir2d2 + + + # 2d1mod + + dotest cvsadm-27 "${testcvs} co 2d1mod 2d1mod-2" \ +"${SPROG} checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1 +${SPROG} checkout: Updating dir2d1-2/sub2d1-2 +U dir2d1-2/sub2d1-2/file1-2" + # the usual for the top level + dotest cvsadm-27b "cat CVS/Repository" "\." + # the usual for 2d1mod + dotest cvsadm-27d "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-27f "cat dir2d1/sub2d1/CVS/Repository" "mod1" + # the usual for 2d1mod + dotest cvsadm-27h "cat dir2d1-2/CVS/Repository" "\." + dotest cvsadm-27j "cat dir2d1-2/sub2d1-2/CVS/Repository" "mod1-2" + rm -rf CVS dir2d1 dir2d1-2 + + dotest cvsadm-28 "${testcvs} co 2d1mod 2d2mod" \ +"${SPROG} checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1 +${SPROG} checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-28b "cat CVS/Repository" "\." + # the usual for 2d1mod + dotest cvsadm-28d "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-28f "cat dir2d1/sub2d1/CVS/Repository" "mod1" + # the usual for 2d2mod + dotest cvsadm-28h "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-28j "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir2d1 dir2d2 + + + # 2d2mod + + dotest cvsadm-29 "${testcvs} co 2d2mod 2d2mod-2" \ +"${SPROG} checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2 +${SPROG} checkout: Updating dir2d2-2/sub2d2-2 +U dir2d2-2/sub2d2-2/file2-2" + # the usual for the top level + dotest cvsadm-29b "cat CVS/Repository" "\." + # the usual for 2d2mod + dotest cvsadm-29d "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-29f "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-29h "cat dir2d2-2/CVS/Repository" "mod2-2" + dotest cvsadm-29j "cat dir2d2-2/sub2d2-2/CVS/Repository" \ +"mod2-2/sub2-2" + rm -rf CVS dir2d2 dir2d2-2 + + ################################################## + ## And now, all of that again using the "-d" flag + ## on the command line. + ################################################## + + dotest cvsadm-1d3 "${testcvs} co -d dir 1mod" \ +"${SPROG} checkout: Updating dir +U dir/file1" + dotest cvsadm-1d3b "cat CVS/Repository" "\." + dotest cvsadm-1d3d "cat dir/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d4 "${testcvs} co -d dir 2mod" \ +"${SPROG} checkout: Updating dir +U dir/file2" + dotest cvsadm-1d4b "cat CVS/Repository" "\." + dotest cvsadm-1d4d "cat dir/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d5 "${testcvs} co -d dir 1d1mod" \ +"${SPROG} checkout: Updating dir +U dir/file1" + dotest cvsadm-1d5b "cat CVS/Repository" "\." + dotest cvsadm-1d5d "cat dir/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d6 "${testcvs} co -d dir 1d2mod" \ +"${SPROG} checkout: Updating dir +U dir/file2" + dotest cvsadm-1d6b "cat CVS/Repository" "\." + dotest cvsadm-1d6d "cat dir/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d7 "${testcvs} co -d dir 2d1mod" \ +"${SPROG} checkout: Updating dir +U dir/file1" + dotest cvsadm-1d7b "cat CVS/Repository" "\." + dotest cvsadm-1d7d "cat dir/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d8 "${testcvs} co -d dir 2d2mod" \ +"${SPROG} checkout: Updating dir +U dir/file2" + dotest cvsadm-1d8b "cat CVS/Repository" "\." + dotest cvsadm-1d8d "cat dir/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + ################################################## + ## Los Combonaciones + ################################################## + + ### 1mod + + dotest cvsadm-1d9 "${testcvs} co -d dir 1mod 1mod-2" \ +"${SPROG} checkout: Updating dir/1mod +U dir/1mod/file1 +${SPROG} checkout: Updating dir/1mod-2 +U dir/1mod-2/file1-2" + # the usual for the top level + dotest cvsadm-1d9b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d9d "cat dir/CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-1d9f "cat dir/1mod/CVS/Repository" "mod1" + # the usual for 1mod copy + dotest cvsadm-1d9h "cat dir/1mod-2/CVS/Repository" "mod1-2" + rm -rf CVS dir + + # 1mod 2mod redmod bluemod + dotest cvsadm-1d10 "${testcvs} co -d dir 1mod 2mod" \ +"${SPROG} checkout: Updating dir/1mod +U dir/1mod/file1 +${SPROG} checkout: Updating dir/2mod +U dir/2mod/file2" + dotest cvsadm-1d10b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d10d "cat dir/CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-1d10f "cat dir/1mod/CVS/Repository" "mod1" + # the usual for 2dmod + dotest cvsadm-1d10h "cat dir/2mod/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d11 "${testcvs} co -d dir 1mod 1d1mod" \ +"${SPROG} checkout: Updating dir/1mod +U dir/1mod/file1 +${SPROG} checkout: Updating dir/dir1d1 +U dir/dir1d1/file1" + dotest cvsadm-1d11b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d11d "cat dir/CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-1d11f "cat dir/1mod/CVS/Repository" "mod1" + # the usual for 1d1mod + dotest cvsadm-1d11h "cat dir/dir1d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d12 "${testcvs} co -d dir 1mod 1d2mod" \ +"${SPROG} checkout: Updating dir/1mod +U dir/1mod/file1 +${SPROG} checkout: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-1d12b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d12d "cat dir/CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-1d12f "cat dir/1mod/CVS/Repository" "mod1" + # the usual for 1d2mod + dotest cvsadm-1d12h "cat dir/dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d13 "${testcvs} co -d dir 1mod 2d1mod" \ +"${SPROG} checkout: Updating dir/1mod +U dir/1mod/file1 +${SPROG} checkout: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d13b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d13d "cat dir/CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-1d13f "cat dir/1mod/CVS/Repository" "mod1" + # the usual for 2d1mod + dotest cvsadm-1d13h "cat dir/dir2d1/CVS/Repository" "\." + dotest cvsadm-1d13j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d14 "${testcvs} co -d dir 1mod 2d2mod" \ +"${SPROG} checkout: Updating dir/1mod +U dir/1mod/file1 +${SPROG} checkout: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d14b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d14d "cat dir/CVS/Repository" "\." + # the usual for 1mod + dotest cvsadm-1d14f "cat dir/1mod/CVS/Repository" "mod1" + # the usual for 2d2mod + dotest cvsadm-1d14h "cat dir/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-1d14j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + + ### 2mod + + dotest cvsadm-1d15 "${testcvs} co -d dir 2mod 2mod-2" \ +"${SPROG} checkout: Updating dir/2mod +U dir/2mod/file2 +${SPROG} checkout: Updating dir/2mod-2 +U dir/2mod-2/file2-2" + dotest cvsadm-1d15b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d15d "cat dir/CVS/Repository" "mod2" + # the usual for 2mod + dotest cvsadm-1d15f "cat dir/2mod/CVS/Repository" "mod2/sub2" + # the usual for 2mod copy + dotest cvsadm-1d15h "cat dir/2mod-2/CVS/Repository" "mod2-2/sub2-2" + rm -rf CVS dir + + dotest cvsadm-1d16 "${testcvs} co -d dir 2mod 1d1mod" \ +"${SPROG} checkout: Updating dir/2mod +U dir/2mod/file2 +${SPROG} checkout: Updating dir/dir1d1 +U dir/dir1d1/file1" + dotest cvsadm-1d16b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d16d "cat dir/CVS/Repository" "mod2" + # the usual for 2mod + dotest cvsadm-1d16f "cat dir/2mod/CVS/Repository" "mod2/sub2" + # the usual for 1d1mod + dotest cvsadm-1d16h "cat dir/dir1d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d17 "${testcvs} co -d dir 2mod 1d2mod" \ +"${SPROG} checkout: Updating dir/2mod +U dir/2mod/file2 +${SPROG} checkout: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-1d17b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d17d "cat dir/CVS/Repository" "mod2" + # the usual for 2mod + dotest cvsadm-1d17f "cat dir/2mod/CVS/Repository" "mod2/sub2" + # the usual for 1d2mod + dotest cvsadm-1d17h "cat dir/dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d18 "${testcvs} co -d dir 2mod 2d1mod" \ +"${SPROG} checkout: Updating dir/2mod +U dir/2mod/file2 +${SPROG} checkout: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d18b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d18d "cat dir/CVS/Repository" "mod2" + # the usual for 2mod + dotest cvsadm-1d18f "cat dir/2mod/CVS/Repository" "mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-1d18h "cat dir/dir2d1/CVS/Repository" "\." + dotest cvsadm-1d18j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d19 "${testcvs} co -d dir 2mod 2d2mod" \ +"${SPROG} checkout: Updating dir/2mod +U dir/2mod/file2 +${SPROG} checkout: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d19b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d19d "cat dir/CVS/Repository" "mod2" + # the usual for 2mod + dotest cvsadm-1d19f "cat dir/2mod/CVS/Repository" "mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-1d19h "cat dir/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-1d19j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + + ### 1d1mod + + dotest cvsadm-1d20 "${testcvs} co -d dir 1d1mod 1d1mod-2" \ +"${SPROG} checkout: Updating dir/dir1d1 +U dir/dir1d1/file1 +${SPROG} checkout: Updating dir/dir1d1-2 +U dir/dir1d1-2/file1-2" + dotest cvsadm-1d20b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d20d "cat dir/CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-1d20f "cat dir/dir1d1/CVS/Repository" "mod1" + # the usual for 1d1mod copy + dotest cvsadm-1d20h "cat dir/dir1d1-2/CVS/Repository" "mod1-2" + rm -rf CVS dir + + dotest cvsadm-1d21 "${testcvs} co -d dir 1d1mod 1d2mod" \ +"${SPROG} checkout: Updating dir/dir1d1 +U dir/dir1d1/file1 +${SPROG} checkout: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-1d21b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d21d "cat dir/CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-1d21f "cat dir/dir1d1/CVS/Repository" "mod1" + # the usual for 1d2mod + dotest cvsadm-1d21h "cat dir/dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d22 "${testcvs} co -d dir 1d1mod 2d1mod" \ +"${SPROG} checkout: Updating dir/dir1d1 +U dir/dir1d1/file1 +${SPROG} checkout: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d22b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d22d "cat dir/CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-1d22f "cat dir/dir1d1/CVS/Repository" "mod1" + # the usual for 2d1mod + dotest cvsadm-1d22h "cat dir/dir2d1/CVS/Repository" "\." + dotest cvsadm-1d22j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d23 "${testcvs} co -d dir 1d1mod 2d2mod" \ +"${SPROG} checkout: Updating dir/dir1d1 +U dir/dir1d1/file1 +${SPROG} checkout: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d23b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d23d "cat dir/CVS/Repository" "\." + # the usual for 1d1mod + dotest cvsadm-1d23f "cat dir/dir1d1/CVS/Repository" "mod1" + # the usual for 2d2mod + dotest cvsadm-1d23h "cat dir/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-1d23j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + + ### 1d2mod + + dotest cvsadm-1d24 "${testcvs} co -d dir 1d2mod 1d2mod-2" \ +"${SPROG} checkout: Updating dir/dir1d2 +U dir/dir1d2/file2 +${SPROG} checkout: Updating dir/dir1d2-2 +U dir/dir1d2-2/file2-2" + dotest cvsadm-1d24b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d24d "cat dir/CVS/Repository" "mod2" + # the usual for 1d2mod + dotest cvsadm-1d24f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" + # the usual for 1d2mod copy + dotest cvsadm-1d24h "cat dir/dir1d2-2/CVS/Repository" "mod2-2/sub2-2" + rm -rf CVS dir + + dotest cvsadm-1d25 "${testcvs} co -d dir 1d2mod 2d1mod" \ +"${SPROG} checkout: Updating dir/dir1d2 +U dir/dir1d2/file2 +${SPROG} checkout: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d25b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d25d "cat dir/CVS/Repository" "mod2" + # the usual for 1d2mod + dotest cvsadm-1d25f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-1d25h "cat dir/dir2d1/CVS/Repository" "\." + dotest cvsadm-1d25j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-1d26 "${testcvs} co -d dir 1d2mod 2d2mod" \ +"${SPROG} checkout: Updating dir/dir1d2 +U dir/dir1d2/file2 +${SPROG} checkout: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d26b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d26d "cat dir/CVS/Repository" "mod2" + # the usual for 1d2mod + dotest cvsadm-1d26f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-1d26h "cat dir/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-1d26j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + + # 2d1mod + + dotest cvsadm-1d27 "${testcvs} co -d dir 2d1mod 2d1mod-2" \ +"${SPROG} checkout: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1 +${SPROG} checkout: Updating dir/dir2d1-2/sub2d1-2 +U dir/dir2d1-2/sub2d1-2/file1-2" + dotest cvsadm-1d27b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d27d "cat dir/CVS/Repository" "CVSROOT/Emptydir" + # the usual for 2d1mod + dotest cvsadm-1d27f "cat dir/dir2d1/CVS/Repository" "\." + dotest cvsadm-1d27h "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" + # the usual for 2d1mod + dotest cvsadm-1d27j "cat dir/dir2d1-2/CVS/Repository" "\." + dotest cvsadm-1d27l "cat dir/dir2d1-2/sub2d1-2/CVS/Repository" \ +"mod1-2" + rm -rf CVS dir + + dotest cvsadm-1d28 "${testcvs} co -d dir 2d1mod 2d2mod" \ +"${SPROG} checkout: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1 +${SPROG} checkout: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d28b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d28d "cat dir/CVS/Repository" "CVSROOT/Emptydir" + # the usual for 2d1mod + dotest cvsadm-1d28f "cat dir/dir2d1/CVS/Repository" "\." + dotest cvsadm-1d28h "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" + # the usual for 2d2mod + dotest cvsadm-1d28j "cat dir/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-1d28l "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + + # 2d2mod + + dotest cvsadm-1d29 "${testcvs} co -d dir 2d2mod 2d2mod-2" \ +"${SPROG} checkout: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2 +${SPROG} checkout: Updating dir/dir2d2-2/sub2d2-2 +U dir/dir2d2-2/sub2d2-2/file2-2" + dotest cvsadm-1d29b "cat CVS/Repository" "\." + # the usual for the dir level + dotest cvsadm-1d29d "cat dir/CVS/Repository" "\." + # the usual for 2d2mod + dotest cvsadm-1d29f "cat dir/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-1d29h "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-1d29j "cat dir/dir2d2-2/CVS/Repository" "mod2-2" + dotest cvsadm-1d29l "cat dir/dir2d2-2/sub2d2-2/CVS/Repository" \ +"mod2-2/sub2-2" + rm -rf CVS dir + + ################################################## + ## And now, some of that again using the "-d" flag + ## on the command line, but use a longer path. + ################################################## + + dotest cvsadm-2d3-1 "$testcvs co -d dir/dir2 1mod" \ +"$SPROG checkout: Updating dir/dir2 +U dir/dir2/file1" + + # Remote couldn't handle this, even with the "mkdir dir", before + # CVS 1.11.14. + dotest cvsadm-2d3b "cat CVS/Repository" "\." + dotest cvsadm-2d3d "cat dir/CVS/Repository" "." + dotest cvsadm-2d3f "cat dir/dir2/CVS/Repository" "mod1" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-2d4 "$testcvs co -d dir/dir2 2mod" \ +"$SPROG checkout: Updating dir/dir2 +U dir/dir2/file2" + dotest cvsadm-2d4b "cat CVS/Repository" "\." + dotest cvsadm-2d4f "cat dir/dir2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-2d5 "$testcvs co -d dir/dir2 1d1mod" \ +"$SPROG checkout: Updating dir/dir2 +U dir/dir2/file1" + dotest cvsadm-2d5b "cat CVS/Repository" "\." + dotest cvsadm-2d5f "cat dir/dir2/CVS/Repository" "mod1" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-2d6 "$testcvs co -d dir/dir2 1d2mod" \ +"$SPROG checkout: Updating dir/dir2 +U dir/dir2/file2" + dotest cvsadm-2d6b "cat CVS/Repository" "\." + dotest cvsadm-2d6f "cat dir/dir2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-2d7 "$testcvs co -d dir/dir2 2d1mod" \ +"$SPROG checkout: Updating dir/dir2 +U dir/dir2/file1" + dotest cvsadm-2d7b "cat CVS/Repository" "\." + dotest cvsadm-2d7f "cat dir/dir2/CVS/Repository" "mod1" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-2d8 "$testcvs co -d dir/dir2 2d2mod" \ +"$SPROG checkout: Updating dir/dir2 +U dir/dir2/file2" + dotest cvsadm-2d8b "cat CVS/Repository" "\." + dotest cvsadm-2d8f "cat dir/dir2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + ################################################## + ## And now, a few of those tests revisited to + ## test the behavior of the -N flag. + ################################################## + + dotest cvsadm-N3 "$testcvs co -N 1mod" \ +"$SPROG checkout: Updating 1mod +U 1mod/file1" + dotest cvsadm-N3b "cat CVS/Repository" "\." + dotest cvsadm-N3d "cat 1mod/CVS/Repository" "mod1" + rm -rf CVS 1mod + + dotest cvsadm-N4 "$testcvs co -N 2mod" \ +"$SPROG checkout: Updating 2mod +U 2mod/file2" + dotest cvsadm-N4b "cat CVS/Repository" "\." + dotest cvsadm-N4d "cat 2mod/CVS/Repository" "mod2/sub2" + rm -rf CVS 2mod + + dotest cvsadm-N5 "$testcvs co -N 1d1mod" \ +"$SPROG checkout: Updating dir1d1 +U dir1d1/file1" + dotest cvsadm-N5b "cat CVS/Repository" "\." + dotest cvsadm-N5d "cat dir1d1/CVS/Repository" "mod1" + rm -rf CVS dir1d1 + + dotest cvsadm-N6 "$testcvs co -N 1d2mod" \ +"$SPROG checkout: Updating dir1d2 +U dir1d2/file2" + dotest cvsadm-N6b "cat CVS/Repository" "\." + dotest cvsadm-N6d "cat dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir1d2 + + dotest cvsadm-N7 "$testcvs co -N 2d1mod" \ +"$SPROG checkout: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + dotest cvsadm-N7b "cat CVS/Repository" "\." + dotest cvsadm-N7d "cat dir2d1/CVS/Repository" "\." + dotest cvsadm-N7f "cat dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir2d1 + + dotest cvsadm-N8 "$testcvs co -N 2d2mod" \ +"$SPROG checkout: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + dotest cvsadm-N8b "cat CVS/Repository" "\." + dotest cvsadm-N8d "cat dir2d2/CVS/Repository" "mod2" + dotest cvsadm-N8f "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir2d2 + + ## the ones in one-deep directories + + dotest cvsadm-N1d3 "$testcvs co -N -d dir 1mod" \ +"$SPROG checkout: Updating dir/1mod +U dir/1mod/file1" + dotest cvsadm-N1d3b "cat CVS/Repository" "\." + dotest cvsadm-N1d3d "cat dir/CVS/Repository" "\." + dotest cvsadm-N1d3f "cat dir/1mod/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-N1d4 "$testcvs co -N -d dir 2mod" \ +"$SPROG checkout: Updating dir/2mod +U dir/2mod/file2" + dotest cvsadm-N1d4b "cat CVS/Repository" "\." + dotest cvsadm-N1d4d "cat dir/CVS/Repository" "mod2" + dotest cvsadm-N1d4f "cat dir/2mod/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-N1d5 "$testcvs co -N -d dir 1d1mod" \ +"$SPROG checkout: Updating dir/dir1d1 +U dir/dir1d1/file1" + dotest cvsadm-N1d5b "cat CVS/Repository" "\." + dotest cvsadm-N1d5d "cat dir/CVS/Repository" "\." + dotest cvsadm-N1d5d "cat dir/dir1d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-N1d6 "$testcvs co -N -d dir 1d2mod" \ +"$SPROG checkout: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-N1d6b "cat CVS/Repository" "\." + dotest cvsadm-N1d6d "cat dir/CVS/Repository" "mod2" + dotest cvsadm-N1d6f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-N1d7 "$testcvs co -N -d dir 2d1mod" \ +"$SPROG checkout: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-N1d7b "cat CVS/Repository" "\." + dotest cvsadm-N1d7d "cat dir/CVS/Repository" "CVSROOT/Emptydir" + dotest cvsadm-N1d7f "cat dir/dir2d1/CVS/Repository" "\." + dotest cvsadm-N1d7h "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" + rm -rf CVS dir + + dotest cvsadm-N1d8 "$testcvs co -N -d dir 2d2mod" \ +"$SPROG checkout: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-N1d8b "cat CVS/Repository" "\." + dotest cvsadm-N1d8d "cat dir/CVS/Repository" "\." + dotest cvsadm-N1d8d "cat dir/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-N1d8d "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"mod2/sub2" + rm -rf CVS dir + + ## the ones in two-deep directories + + mkdir dir + dotest cvsadm-N2d3 "$testcvs co -N -d dir/dir2 1mod" \ +"$SPROG checkout: Updating dir/dir2/1mod +U dir/dir2/1mod/file1" + dotest cvsadm-N2d3b "cat CVS/Repository" "\." + dotest cvsadm-N2d3f "cat dir/dir2/CVS/Repository" "\." + dotest cvsadm-N2d3h "cat dir/dir2/1mod/CVS/Repository" "mod1" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-N2d4 "$testcvs co -N -d dir/dir2 2mod" \ +"$SPROG checkout: Updating dir/dir2/2mod +U dir/dir2/2mod/file2" + dotest cvsadm-N2d4b "cat CVS/Repository" "\." + dotest cvsadm-N2d4f "cat dir/dir2/CVS/Repository" "mod2" + dotest cvsadm-N2d4h "cat dir/dir2/2mod/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-N2d5 "$testcvs co -N -d dir/dir2 1d1mod" \ +"$SPROG checkout: Updating dir/dir2/dir1d1 +U dir/dir2/dir1d1/file1" + dotest cvsadm-N2d5b "cat CVS/Repository" "\." + dotest cvsadm-N2d5f "cat dir/dir2/CVS/Repository" "\." + dotest cvsadm-N2d5h "cat dir/dir2/dir1d1/CVS/Repository" "mod1" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-N2d6 "$testcvs co -N -d dir/dir2 1d2mod" \ +"$SPROG checkout: Updating dir/dir2/dir1d2 +U dir/dir2/dir1d2/file2" + dotest cvsadm-N2d6b "cat CVS/Repository" "\." + dotest cvsadm-N2d6f "cat dir/dir2/CVS/Repository" "mod2" + dotest cvsadm-N2d6h "cat dir/dir2/dir1d2/CVS/Repository" "mod2/sub2" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-N2d7 "$testcvs co -N -d dir/dir2 2d1mod" \ +"$SPROG checkout: Updating dir/dir2/dir2d1/sub2d1 +U dir/dir2/dir2d1/sub2d1/file1" + dotest cvsadm-N2d7b "cat CVS/Repository" "\." + dotest cvsadm-N2d7f "cat dir/dir2/CVS/Repository" "CVSROOT/Emptydir" + dotest cvsadm-N2d7g "cat dir/dir2/dir2d1/CVS/Repository" "\." + dotest cvsadm-N2d7h "cat dir/dir2/dir2d1/sub2d1/CVS/Repository" \ +"mod1" + rm -rf CVS dir + + mkdir dir + dotest cvsadm-N2d8 "$testcvs co -N -d dir/dir2 2d2mod" \ +"$SPROG checkout: Updating dir/dir2/dir2d2/sub2d2 +U dir/dir2/dir2d2/sub2d2/file2" + dotest cvsadm-N2d8b "cat CVS/Repository" "\." + dotest cvsadm-N2d8f "cat dir/dir2/CVS/Repository" "\." + dotest cvsadm-N2d8h "cat dir/dir2/dir2d2/CVS/Repository" "mod2" + dotest cvsadm-N2d8j "cat dir/dir2/dir2d2/sub2d2/CVS/Repository" \ +"mod2/sub2" + rm -rf CVS dir + # End of test that didn't work for remote prior to CVS 1.11.14. + + ################################################## + ## That's enough of that, thank you very much. + ################################################## + + dokeep + restore_adm + + # remove our junk + cd .. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/1mod $CVSROOT_DIRNAME/1mod-2 \ + $CVSROOT_DIRNAME/2mod $CVSROOT_DIRNAME/2mod-2 \ + $CVSROOT_DIRNAME/mod1 $CVSROOT_DIRNAME/mod1-2 \ + $CVSROOT_DIRNAME/mod2 $CVSROOT_DIRNAME/mod2-2 + ;; + + + + emptydir) + # Various tests of the Emptydir (CVSNULLREPOS) code. See also: + # cvsadm: tests of Emptydir in various module definitions + # basicb: Test that "Emptydir" is non-special in ordinary contexts + + mkdir 1; cd 1 + dotest emptydir-1 "${testcvs} co CVSROOT/modules" \ +"U CVSROOT/modules" + echo "# Module defs for emptydir tests" > CVSROOT/modules + echo "2d1mod -d dir2d1/sub/sub2d1 mod1" >> CVSROOT/modules + echo "2d1moda -d dir2d1/suba moda/modasub" >> CVSROOT/modules + echo "2d1modb -d dir2d1/suba mod1" >> CVSROOT/modules + echo "comb -a 2d1modb 2d1moda" >> CVSROOT/modules + + dotest emptydir-2 "${testcvs} ci -m add-modules" \ +"${CPROG} commit: Examining CVSROOT +${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- CVSROOT/modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +${SPROG} commit: Rebuilding administrative file database" \ +"${CPROG} commit: Examining CVSROOT" + rm -rf CVS CVSROOT + + modify_repo mkdir $CVSROOT_DIRNAME/mod1 $CVSROOT_DIRNAME/moda + # Populate. Not sure we really need to do this. + dotest emptydir-3 "$testcvs -q co -l ." + dotest emptydir-3a "${testcvs} co mod1 moda" \ +"${SPROG} checkout: Updating mod1 +${SPROG} checkout: Updating moda" + echo "file1" > mod1/file1 + mkdir moda/modasub + dotest emptydir-3b "${testcvs} add moda/modasub" \ +"Directory ${CVSROOT_DIRNAME}/moda/modasub added to the repository" + echo "filea" > moda/modasub/filea + dotest emptydir-4 "${testcvs} add mod1/file1 moda/modasub/filea" \ +"${SPROG} add: scheduling file .mod1/file1. for addition +${SPROG} add: scheduling file .moda/modasub/filea. for addition +${SPROG} add: use \`${SPROG} commit' to add these files permanently" + dotest emptydir-5 "${testcvs} -q ci -m yup" \ +"$CVSROOT_DIRNAME/mod1/file1,v <-- mod1/file1 +initial revision: 1\.1 +${CVSROOT_DIRNAME}/moda/modasub/filea,v <-- moda/modasub/filea +initial revision: 1\.1" + rm -rf mod1 moda CVS + # End Populate. + + dotest emptydir-6 "${testcvs} co 2d1mod" \ +"${SPROG} checkout: Updating dir2d1/sub/sub2d1 +U dir2d1/sub/sub2d1/file1" + cd dir2d1 + touch emptyfile + # It doesn't make any sense to add a file (or do much of anything + # else) in Emptydir; Emptydir is a placeholder indicating that + # the working directory doesn't correspond to anything in + # the repository. + dotest_fail emptydir-7 "${testcvs} add emptyfile" \ +"${SPROG} \[add aborted]: cannot add to \`${CVSROOT_DIRNAME}/CVSROOT/Emptydir'" + mkdir emptydir + dotest_fail emptydir-8 "${testcvs} add emptydir" \ +"${CPROG} \[add aborted]: cannot add to \`${CVSROOT_DIRNAME}/CVSROOT/Emptydir'" + cd .. + rm -rf CVS dir2d1 + + # OK, while we have an Emptydir around, test a few obscure + # things about it. + mkdir edir; cd edir + dotest emptydir-9 "${testcvs} -q co -l CVSROOT" \ +"U CVSROOT${DOTSTAR}" + cd CVSROOT + dotest_fail emptydir-10 "test -d Emptydir" '' + # This tests the code in find_dirs which skips Emptydir. + dotest emptydir-11 "${testcvs} -q -n update -d -P" '' + cd ../.. + rm -r edir + cd .. + + # Now start playing with moda. + mkdir 2; cd 2 + dotest emptydir-12 "${testcvs} -q co 2d1moda" \ +"U dir2d1/suba/filea" + # OK, this is the crux of the matter. This used to show "Emptydir", + # but everyone seemed to think it should show "moda". This + # usually works better, but not always as shown by the following + # test. + dotest emptydir-13 "cat dir2d1/CVS/Repository" "moda" + dotest_fail emptydir-14 "${testcvs} co comb" \ +"${SPROG} checkout: existing repository ${CVSROOT_DIRNAME}/moda/modasub does not match ${CVSROOT_DIRNAME}/mod1 +${SPROG} checkout: ignoring module 2d1modb +${SPROG} checkout: Updating dir2d1/suba" + dotest emptydir-15 "cat dir2d1/CVS/Repository" "moda" + cd .. + + # Test the effect of a non-cvs directory already existing with the + # same name as one in the modules file. + mkdir 3; cd 3 + mkdir dir2d1 + dotest emptydir-16 "${testcvs} co 2d1mod" \ +"${SPROG} checkout: Updating dir2d1/sub/sub2d1 +U dir2d1/sub/sub2d1/file1" + + if $remote; then + dotest emptydir-17 "cat dir2d1/CVS/Repository" "CVSROOT/Emptydir" + else + dotest_fail emptydir-17 "test -d dir2d1/CVS" + fi + + dokeep + cd .. + rm -r 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/mod1 $CVSROOT_DIRNAME/moda + # I guess for the moment the convention is going to be + # that we don't need to remove $CVSROOT_DIRNAME/CVSROOT/Emptydir + ;; + + + + abspath) + + # These tests test the thituations thin thwitch thoo theck + # things thout twith thabsolute thaths. Threally. + + # + # CHECKOUTS + # + + # Create a few modules to use + modify_repo mkdir $CVSROOT_DIRNAME/mod1 $CVSROOT_DIRNAME/mod2 + dotest abspath-1a "${testcvs} co mod1 mod2" \ +"${SPROG} checkout: Updating mod1 +${SPROG} checkout: Updating mod2" + + # Populate the module + echo "file1" > mod1/file1 + echo "file2" > mod2/file2 + cd mod1 + dotest abspath-1ba "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + cd .. + cd mod2 + dotest abspath-1bb "${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + cd .. + + dotest abspath-1c "${testcvs} ci -m yup mod1 mod2" \ +"${CPROG} commit: Examining mod1 +${CPROG} commit: Examining mod2 +${CVSROOT_DIRNAME}/mod1/file1,v <-- mod1/file1 +initial revision: 1.1 +${CVSROOT_DIRNAME}/mod2/file2,v <-- mod2/file2 +initial revision: 1.1" + # Finished creating the module -- clean up. + rm -rf CVS mod1 mod2 + # Done. + + # Try checking out the module in a local directory + if $remote; then + dotest_fail abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ +"${SPROG} \[checkout aborted\]: absolute pathnames invalid for server (specified .${TESTDIR}/1.)" + dotest abspath-2a-try2 "${testcvs} co -d 1 mod1" \ +"${SPROG} checkout: Updating 1 +U 1/file1" + else + dotest abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ +"${SPROG} checkout: Updating ${TESTDIR}/1 +U ${TESTDIR}/1/file1" + fi # remote workaround + + dotest abspath-2b "cat ${TESTDIR}/1/CVS/Repository" "mod1" + + # Done. Clean up. + rm -r $TESTDIR/1 + + + # Now try in a subdirectory. We're not covering any more + # code here, but we might catch a future error if someone + # changes the checkout code. + + # Since CVS 1.11.14, CVS will create leading directories specified + # via co -d. + # I am unsure that this wasn't the behavior prior to CVS 1.9, but the + # comment that used to be here leads me to believe it was not. + if $remote; then :; else + dotest abspath-3.1 "$testcvs -q co -d $TESTDIR/1/2 mod1" \ +"U $TESTDIR/1/2/file1" + rm -r $TESTDIR/1 + fi + dotest abspath-3.2 "$testcvs -q co -d 1/2 mod1" \ +"U 1/2/file1" + rm -r 1 + + # We don't to mess with an existing directory just to traverse it, + # for example by creating a CVS directory, but currently we can't + # avoid this in client/server mode. + mkdir 1 + if $remote; then + dotest abspath-3ar "$testcvs co -d 1/2 mod1" \ +"$SPROG checkout: Updating 1/2 +U 1/2/file1" + dotest abspath-3br "cat 1/CVS/Repository" . + else + dotest abspath-3a "$testcvs co -d $TESTDIR/1/2 mod1" \ +"$SPROG checkout: Updating $TESTDIR/1/2 +U $TESTDIR/1/2/file1" + dotest_fail abspath-3b "test -d ${TESTDIR}/1/CVS" + fi + + dotest abspath-3c "cat ${TESTDIR}/1/2/CVS/Repository" mod1 + + + # Done. Clean up. + rm -rf ${TESTDIR}/1 + + + # Now try someplace where we don't have permission. + mkdir ${TESTDIR}/barf + chmod -w ${TESTDIR}/barf + dotest_fail abspath-4r "${testcvs} co -d ${TESTDIR}/barf/sub mod1" \ +"${SPROG} \[checkout aborted\]: cannot make directory sub: Permission denied" \ +"${SPROG} \[checkout aborted\]: absolute pathnames invalid for server (specified .${TESTDIR}/barf/sub.)" + chmod +w ${TESTDIR}/barf + rmdir ${TESTDIR}/barf + # Done. Nothing to clean up. + + + # Try checking out two modules into the same directory. + if $remote; then + dotest abspath-5ar "${testcvs} co -d 1 mod1 mod2" \ +"${SPROG} checkout: Updating 1/mod1 +U 1/mod1/file1 +${SPROG} checkout: Updating 1/mod2 +U 1/mod2/file2" + else + dotest abspath-5a "${testcvs} co -d ${TESTDIR}/1 mod1 mod2" \ +"${SPROG} checkout: Updating ${TESTDIR}/1/mod1 +U ${TESTDIR}/1/mod1/file1 +${SPROG} checkout: Updating ${TESTDIR}/1/mod2 +U ${TESTDIR}/1/mod2/file2" + fi # end remote workaround + dotest abspath-5b "cat ${TESTDIR}/1/CVS/Repository" "\." + dotest abspath-5c "cat ${TESTDIR}/1/mod1/CVS/Repository" "mod1" + dotest abspath-5d "cat ${TESTDIR}/1/mod2/CVS/Repository" "mod2" + # Done. Clean up. + rm -rf $TESTDIR/1 + + + # Try checking out the top-level module. + if $remote; then + dotest abspath-6ar "$testcvs co -d 1 ." \ +"$SPROG checkout: Updating 1 +$SPROG checkout: Updating 1/CVSROOT +$DOTSTAR +$SPROG checkout: Updating 1/mod1 +U 1/mod1/file1 +$SPROG checkout: Updating 1/mod2 +U 1/mod2/file2" + else + dotest abspath-6a "${testcvs} co -d ${TESTDIR}/1 ." \ +"${SPROG} checkout: Updating ${TESTDIR}/1 +${SPROG} checkout: Updating ${TESTDIR}/1/CVSROOT +${DOTSTAR} +${SPROG} checkout: Updating ${TESTDIR}/1/mod1 +U ${TESTDIR}/1/mod1/file1 +${SPROG} checkout: Updating ${TESTDIR}/1/mod2 +U ${TESTDIR}/1/mod2/file2" + fi # end of remote workaround + dotest abspath-6b "cat ${TESTDIR}/1/CVS/Repository" "\." + dotest abspath-6c "cat ${TESTDIR}/1/CVSROOT/CVS/Repository" "CVSROOT" + dotest abspath-6c "cat ${TESTDIR}/1/mod1/CVS/Repository" "mod1" + dotest abspath-6d "cat ${TESTDIR}/1/mod2/CVS/Repository" "mod2" + # Done. Clean up. + rm -rf ${TESTDIR}/1 + + # Test that an absolute pathname to some other directory + # doesn't mess with the current working directory. + mkdir 1 + cd 1 + if $remote; then + dotest_fail abspath-7ar "${testcvs} -q co -d ../2 mod2" \ +"${SPROG} checkout: protocol error: .\.\./2. contains more leading \.\. +${SPROG} \[checkout aborted\]: than the 0 which Max-dotdot specified" + cd .. + dotest abspath-7a-try2r "${testcvs} -q co -d 2 mod2" \ +"U 2/file2" + cd 1 + else + dotest abspath-7a "${testcvs} -q co -d ${TESTDIR}/2 mod2" \ +"U ${TESTDIR}/2/file2" + fi # remote workaround + dotest abspath-7b "ls" "" + dotest abspath-7c "${testcvs} -q co mod1" \ +"U mod1/file1" + cd mod1 + if $remote; then + cd ../.. + dotest abspath-7dr "${testcvs} -q co -d 3 mod2" \ +"U 3/file2" + cd 1/mod1 + else + dotest abspath-7d "${testcvs} -q co -d ${TESTDIR}/3 mod2" \ +"U ${TESTDIR}/3/file2" + fi # remote workaround + dotest abspath-7e "${testcvs} -q update -d" + + # + # FIXME: do other functions here (e.g. update /tmp/foo) + # + + # Finished with all tests. Cleanup. + dokeep + cd ../.. + rm -r 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/mod1 $CVSROOT_DIRNAME/mod2 + ;; + + + + abspath2) + # More absolute path checks. The following used to attempt to create + # directories in /: + # + # $ cvs -d:fork:/cvsroot co /foo + # cvs checkout: warning: cannot make directory CVS in /: Permission denied + # cvs [checkout aborted]: cannot make directory /foo: Permission denied + # $ + # + # The -z9 in this test also checks for an old server bug where the + # server would block indefinitely attempting to read an EOF from the + # client in the compression buffer shutdown routine. + dotest_fail abspath2-1 "$testcvs -z9 co /foo" \ +"$CPROG \[checkout aborted\]: Absolute module reference invalid: \`/foo'" \ +"$SPROG \[server aborted\]: Absolute module reference invalid: \`/foo' +$CPROG \[checkout aborted\]: end of file from server (consult above messages if any)" + ;; + + + + toplevel) + # test the feature that cvs creates a CVS subdir also for + # the toplevel directory + + # First set the TopLevelAdmin setting. + mkdir 1; cd 1 + dotest toplevel-1a "${testcvs} -q co CVSROOT/config" \ +"U CVSROOT/config" + cd CVSROOT + echo "TopLevelAdmin=yes" >>config + dotest toplevel-1b "${testcvs} -q ci -m yes-top-level" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../.. + rm -r 1 + + mkdir 1; cd 1 + dotest toplevel-1 "${testcvs} -q co -l ." '' + mkdir top-dir second-dir + dotest toplevel-2 "${testcvs} add top-dir second-dir" \ +"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" + cd top-dir + + touch file1 + dotest toplevel-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest toplevel-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/top-dir/file1,v <-- file1 +initial revision: 1\.1" + cd .. + + cd second-dir + touch file2 + dotest toplevel-3s "${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest toplevel-4s "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/second-dir/file2,v <-- file2 +initial revision: 1\.1" + + cd ../.. + rm -r 1; mkdir 1; cd 1 + dotest toplevel-5 "${testcvs} co top-dir" \ +"${SPROG} checkout: Updating top-dir +U top-dir/file1" + + dotest toplevel-6 "${testcvs} update top-dir" \ +"${SPROG} update: Updating top-dir" + dotest toplevel-7 "${testcvs} update" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating top-dir" + + dotest toplevel-8 "${testcvs} update -d top-dir" \ +"${SPROG} update: Updating top-dir" + # There is some sentiment that + # "${SPROG} update: Updating \. + # ${SPROG} update: Updating top-dir" + # is correct but it isn't clear why that would be correct instead + # of the remote CVS behavior (which also updates CVSROOT). + # + # The DOTSTAR matches of a bunch of lines like + # "U CVSROOT/checkoutlist". Trying to match them more precisely + # seemed to cause trouble. For example CVSROOT/cvsignore will + # be present or absent depending on whether we ran the "ignore" + # test or not. + dotest toplevel-9 "${testcvs} update -d" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating CVSROOT +${DOTSTAR} +${SPROG} update: Updating top-dir" + + cd .. + rm -r 1; mkdir 1; cd 1 + dotest toplevel-10 "${testcvs} co top-dir" \ +"${SPROG} checkout: Updating top-dir +U top-dir/file1" + + # This tests more or less the same thing, in a particularly + # "real life" example. + dotest toplevel-11 "${testcvs} -q update -d second-dir" \ +"U second-dir/file2" + + # Now remove the CVS directory (people may do this manually, + # especially if they formed their habits with CVS + # 1.9 and older, which didn't create it. Or perhaps the working + # directory itself was created with 1.9 or older). + rm -r CVS + # Now set the permissions so we can't recreate it. + if test -n "$remotehost"; then + # Cygwin again. + $CVS_RSH $remotehost "chmod -w $TESTDIR/1" + else + chmod -w ../1 + fi + # Now see whether CVS has trouble because it can't create CVS. + # First string is for local, second is for remote. + dotest toplevel-12 "${testcvs} co top-dir" \ +"${SPROG} checkout: warning: cannot make directory CVS in \.: Permission denied +${SPROG} checkout: Updating top-dir" \ +"${CPROG} checkout: warning: cannot make directory CVS in \.: Permission denied +${CPROG} checkout: in directory \.: +${CPROG} checkout: cannot open CVS/Entries for reading: No such file or directory +${SPROG} checkout: Updating top-dir" + + chmod +w ../1 + + dokeep + restore_adm + cd .. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/top-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + toplevel2) + # Similar to toplevel, but test the case where TopLevelAdmin=no. + + # First set the TopLevelAdmin setting. + mkdir 1; cd 1 + dotest toplevel2-1a "${testcvs} -q co CVSROOT/config" \ +"U CVSROOT/config" + cd CVSROOT + echo "TopLevelAdmin=no" >>config + dotest toplevel2-1b "$testcvs -q ci -m no-top-level" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../.. + rm -r 1 + + # Now set up some directories and subdirectories + mkdir 1; cd 1 + dotest toplevel2-1 "${testcvs} -q co -l ." '' + mkdir top-dir second-dir + dotest toplevel2-2 "${testcvs} add top-dir second-dir" \ +"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" + cd top-dir + + touch file1 + dotest toplevel2-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest toplevel2-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/top-dir/file1,v <-- file1 +initial revision: 1\.1" + cd .. + + cd second-dir + touch file2 + dotest toplevel2-3s "${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest toplevel2-4s "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/second-dir/file2,v <-- file2 +initial revision: 1\.1" + + cd ../.. + rm -r 1; mkdir 1; cd 1 + dotest toplevel2-5 "${testcvs} co top-dir" \ +"${SPROG} checkout: Updating top-dir +U top-dir/file1" + + dotest toplevel2-6 "${testcvs} update top-dir" \ +"${SPROG} update: Updating top-dir" + dotest toplevel2-7 "${testcvs} update" \ +"${SPROG} update: Updating top-dir" + + dotest toplevel2-8 "${testcvs} update -d top-dir" \ +"${SPROG} update: Updating top-dir" + # Contrast this with toplevel-9, which has TopLevelAdmin=yes. + dotest toplevel2-9 "${testcvs} update -d" \ +"${SPROG} update: Updating top-dir" + + cd .. + rm -r 1; mkdir 1; cd 1 + dotest toplevel2-10 "${testcvs} co top-dir" \ +"${SPROG} checkout: Updating top-dir +U top-dir/file1" + # This tests more or less the same thing, in a particularly + # "real life" example. With TopLevelAdmin=yes, this command + # would give us second-dir and CVSROOT directories too. + dotest toplevel2-11 "${testcvs} -q update -d" "" + + dokeep + cd .. + restore_adm + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/top-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + rstar-toplevel) + # This test used to confirm a bug that existed in the r* commands + # run against the top-level project prior to CVS 1.11.18 & 1.12.10. + # + # The assertion failure was something like: + # do_recursion: Assertion \`strstr (repository, \"/\./\") == ((void \*)0)' failed\..*" + dotest rstar-toplevel-1 "$testcvs -q rlog ." \ +" +RCS file: $CVSROOT_DIRNAME/CVSROOT$DOTSTAR" + + dokeep + ;; + + + + trailingslashes) + # Some tests of CVS's reactions to path specifications containing + # trailing slashes. + mkdir trailingslashes; cd trailingslashes + dotest trailingslashes-init-1 "$testcvs -Q co -ldt ." + dotest trailingslashes-init-2 "$testcvs -Q co -dt2 ." + cd t + echo "Ahh'll be baaack." >topfile + dotest trailingslashes-init-3 "$testcvs -Q add topfile" + dotest trailingslashes-init-4 "$testcvs -Q ci -mto-top" + + # First, demonstrate the usual case. + cd ../t2 + dotest trailingslashes-1 "$testcvs -q up CVSROOT" + dotest_fail trailingslashes-1a "test -f topfile" + + # FIXCVS: + # Now the one that fails in remote mode. + # This highlights one of the failure cases mentioned in TODO item + # #205. + if $remote; then + dotest trailingslashes-2 "$testcvs -q up CVSROOT/" \ +"U topfile" + dotest trailingslashes-2a "test -f topfile" + else + dotest trailingslashes-2 "$testcvs -q up CVSROOT/" + dotest_fail trailingslashes-2a "test -f topfile" + fi + + dokeep + cd ../.. + rm -rf trailingslashes + modify_repo rm -rf $CVSROOT_DIRNAME/topfile,v + ;; + + + + checkout_repository) + dotest_fail checkout_repository-1 \ +"${testcvs} co -d ${CVSROOT_DIRNAME} CVSROOT" \ +"${CPROG} \[checkout aborted\]: Cannot check out files into the repository itself" \ +"${SPROG} \[checkout aborted\]: absolute pathnames invalid for server (specified \`${CVSROOT_DIRNAME}')" + + # The behavior of the client/server test below should be correct. + # The CVS client currently has no way of knowing that the client and + # server are the same machine and thus skips the $CVSROOT checks. + # I think checking for this case in CVS would be bloat since this + # should be a fairly rare occurance. + cd ${CVSROOT_DIRNAME} + dotest_fail checkout_repository-2 "${testcvs} co CVSROOT" \ +"${CPROG} \[checkout aborted\]: Cannot check out files into the repository itself" \ +"${SPROG} checkout: Updating CVSROOT +${CPROG} checkout: move away \`CVSROOT/checkoutlist'; it is in the way +C CVSROOT/checkoutlist +${CPROG} checkout: move away \`CVSROOT/commitinfo'; it is in the way +C CVSROOT/commitinfo +${CPROG} checkout: move away \`CVSROOT/config'; it is in the way +C CVSROOT/config +${CPROG} checkout: move away \`CVSROOT/cvswrappers'; it is in the way +C CVSROOT/cvswrappers +${CPROG} checkout: move away \`CVSROOT/loginfo'; it is in the way +C CVSROOT/loginfo +${CPROG} checkout: move away \`CVSROOT/modules'; it is in the way +C CVSROOT/modules +${CPROG} checkout: move away \`CVSROOT/notify'; it is in the way +C CVSROOT/notify +${CPROG} checkout: move away \`CVSROOT/postadmin'; it is in the way +C CVSROOT/postadmin +${CPROG} checkout: move away \`CVSROOT/postproxy'; it is in the way +C CVSROOT/postproxy +${CPROG} checkout: move away \`CVSROOT/posttag'; it is in the way +C CVSROOT/posttag +${CPROG} checkout: move away \`CVSROOT/postwatch'; it is in the way +C CVSROOT/postwatch +${CPROG} checkout: move away \`CVSROOT/preproxy'; it is in the way +C CVSROOT/preproxy +${CPROG} checkout: move away \`CVSROOT/rcsinfo'; it is in the way +C CVSROOT/rcsinfo +${CPROG} checkout: move away \`CVSROOT/taginfo'; it is in the way +C CVSROOT/taginfo +${CPROG} checkout: move away \`CVSROOT/verifymsg'; it is in the way +C CVSROOT/verifymsg" + + dotest checkout_repository-3 \ +"${testcvs} co -p CVSROOT/modules >/dev/null" \ +"=================================================================== +Checking out CVSROOT/modules +RCS: ${CVSROOT_DIRNAME}/CVSROOT/modules,v +VERS: 1\.[0-9]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*" + + dokeep + cd $TESTDIR + ;; + + + + mflag) + for message in '' ' ' ' + ' ' test' ; do + # Set up + mkdir a-dir; cd a-dir + # Test handling of -m during import + echo testa >>test + if ${testcvs} import -m "$message" a-dir A A1 >>${LOGFILE} 2>&1;then + pass 156 + else + fail 156 + fi + # Must import twice since the first time uses inline code that + # avoids RCS call. + echo testb >>test + if ${testcvs} import -m "$message" a-dir A A2 >>${LOGFILE} 2>&1;then + pass 157 + else + fail 157 + fi + # Test handling of -m during ci + cd ..; rm -r a-dir + if ${testcvs} co a-dir >>${LOGFILE} 2>&1; then + pass 158 + else + fail 158 + fi + cd a-dir + echo testc >>test + if ${testcvs} ci -m "$message" >>${LOGFILE} 2>&1; then + pass 159 + else + fail 159 + fi + # Test handling of -m during rm/ci + rm test; + if ${testcvs} rm test >>${LOGFILE} 2>&1; then + pass 160 + else + fail 160 + fi + if ${testcvs} ci -m "$message" >>${LOGFILE} 2>&1; then + pass 161 + else + fail 161 + fi + + dokeep + # Clean up + cd .. + rm -r a-dir + modify_repo rm -rf $CVSROOT_DIRNAME/a-dir + done + ;; + + + + editor) + # More tests of log messages, in this case the ability to + # run an external editor. + # TODO: + # * also test $EDITOR, $CVSEDITOR, &c. + # * test what happens if up-to-date check fails. + + # Our "editor" puts "x" at the start of each line, so we + # can see the "CVS:" lines. + cat >${TESTDIR}/editme <<EOF +#!${TESTSHELL} +sleep 1 +sed <\$1 -e 's/^/x/' >${TESTDIR}/edit.new +mv ${TESTDIR}/edit.new \$1 +exit 0 +EOF + chmod +x ${TESTDIR}/editme + + mkdir 1; cd 1 + dotest editor-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest editor-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch file1 file2 + dotest editor-3 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest editor-4 "${testcvs} -e ${TESTDIR}/editme -q ci" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + dotest editor-5 "${testcvs} -q tag -b br" "T file1 +T file2" + dotest editor-6 "${testcvs} -q update -r br" '' + echo modify >>file1 + dotest editor-7 "${testcvs} -e ${TESTDIR}/editme -q ci" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + # OK, now we want to make sure "ci -r" puts in the branch + # where appropriate. Note that we can check in on the branch + # without being on the branch, because there is not a revision + # already on the branch. If there were a revision on the branch, + # CVS would correctly give an up-to-date check failed. + dotest editor-8 "${testcvs} -q update -A" "U file1" + echo add a line >>file2 + dotest editor-9 "${testcvs} -q -e ${TESTDIR}/editme ci -rbr file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + dotest editor-log-file1 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +xCVS: ---------------------------------------------------------------------- +xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically +xCVS: +xCVS: Committing in . +xCVS: +xCVS: Added Files: +xCVS: file1 file2 +xCVS: ---------------------------------------------------------------------- +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +xCVS: ---------------------------------------------------------------------- +xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically +xCVS: +xCVS: Committing in . +xCVS: +xCVS: Modified Files: +xCVS: Tag: br +xCVS: file1 +xCVS: ---------------------------------------------------------------------- +=============================================================================" + + # The only difference between the two expect strings is the + # presence or absence of "Committing in ." for 1.1.2.1. + dotest editor-log-file2 "${testcvs} log -N file2" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +xCVS: ---------------------------------------------------------------------- +xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically +xCVS: +xCVS: Committing in . +xCVS: +xCVS: Added Files: +xCVS: file1 file2 +xCVS: ---------------------------------------------------------------------- +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +xCVS: ---------------------------------------------------------------------- +xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically +xCVS: +xCVS: Modified Files: +xCVS: Tag: br +xCVS: file2 +xCVS: ---------------------------------------------------------------------- +=============================================================================" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +xCVS: ---------------------------------------------------------------------- +xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically +xCVS: +xCVS: Committing in . +xCVS: +xCVS: Added Files: +xCVS: file1 file2 +xCVS: ---------------------------------------------------------------------- +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +xCVS: ---------------------------------------------------------------------- +xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically +xCVS: +xCVS: Committing in . +xCVS: +xCVS: Modified Files: +xCVS: Tag: br +xCVS: file2 +xCVS: ---------------------------------------------------------------------- +=============================================================================" + + # Test CVS's response to an unchanged log message + cat >${TESTDIR}/editme <<EOF +#!${TESTSHELL} +sleep 1 +exit 0 +EOF + chmod +x ${TESTDIR}/editme + dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ +" +Log message unchanged or not specified +a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs +Action: (continue) ${CPROG} \[commit aborted\]: aborted by user" + + # Test CVS's response to an empty log message + cat >${TESTDIR}/editme <<EOF +#!${TESTSHELL} +sleep 1 +cat /dev/null >\$1 +exit 0 +EOF + chmod +x ${TESTDIR}/editme + dotest_fail editor-emptylog-1a "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ +" +Log message unchanged or not specified +a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs +Action: (continue) ${CPROG} \[commit aborted\]: aborted by user" + + # Test CVS's response to a log message with one blank line + cat >${TESTDIR}/editme <<EOF +#!${TESTSHELL} +sleep 1 +echo >\$1 +exit 0 +EOF + chmod +x ${TESTDIR}/editme + dotest_fail editor-emptylog-1b "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ +" +Log message unchanged or not specified +a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs +Action: (continue) ${CPROG} \[commit aborted\]: aborted by user" + + # Test CVS's response to a log message with only comments + cat >${TESTDIR}/editme <<EOF +#!${TESTSHELL} +sleep 1 +cat \$1 >${TESTDIR}/edit.new +mv ${TESTDIR}/edit.new \$1 +exit 0 +EOF + chmod +x ${TESTDIR}/editme + dotest_fail editor-emptylog-1c "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ +" +Log message unchanged or not specified +a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs +Action: (continue) ${CPROG} \[commit aborted\]: aborted by user" + + # Test CVS's response to a log message that is zero bytes + # in length. This caused core dumps in cvs 1.11.5 on Solaris + # hosts. + cd .. + dotest editor-emptylog-continue-1 "${testcvs} -q co CVSROOT/loginfo" \ +"U CVSROOT/loginfo" + + cd CVSROOT + cat <<\EOF >>loginfo +DEFAULT (echo Start-Log;cat;echo End-Log) >> $CVSROOT/CVSROOT/commitlog +EOF + dotest editor-emptylog-continue-2 "$testcvs -Q ci -mloggem" + + cd ../first-dir + cat >${TESTDIR}/editme <<EOF +#!${TESTSHELL} +sleep 1 +cp /dev/null \$1 +exit 1 +EOF + chmod +x ${TESTDIR}/editme + dotest editor-emptylog-continue-3 "echo c |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ +"${CPROG} commit: warning: editor session failed + +Log message unchanged or not specified +a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs +Action: (continue) ${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + # The loginfo Log message should be an empty line and not "(null)" + # which is what some fprintf() implementations do with "%s" + # format and a NULL pointer... + if $remote; then + dotest editor-emptylog-continue-4r \ +"cat $CVSROOT_DIRNAME/CVSROOT/commitlog" \ +"Start-Log +Update of $CVSROOT_DIRNAME/CVSROOT +In directory $hostname:$TMPDIR/cvs-serv[0-9a-z]* + +Modified Files: + loginfo +Log Message: +loggem +End-Log +Start-Log +Update of $CVSROOT_DIRNAME/first-dir +In directory $hostname:$TMPDIR/cvs-serv[0-9a-z]* + +Modified Files: + file1 +Log Message: + +End-Log" + else + dotest editor-emptylog-continue-4 \ +"cat $CVSROOT_DIRNAME/CVSROOT/commitlog" \ +"Start-Log +Update of $CVSROOT_DIRNAME/CVSROOT +In directory $hostname:$TESTDIR/1/CVSROOT + +Modified Files: + loginfo +Log Message: +loggem +End-Log +Start-Log +Update of $CVSROOT_DIRNAME/first-dir +In directory $hostname:$TESTDIR/1/first-dir + +Modified Files: + file1 +Log Message: + +End-Log" + fi + # There should have an empty log message at this point + dotest editor-emptylog-continue-5 "${testcvs} log -N -r1.2 file1" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.2 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 3; selected revisions: 1 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: +0 -0; commitid: ${commitid}; +\*\*\* empty log message \*\*\* +=============================================================================" + + # clean up + dokeep + # restore the default loginfo script + restore_adm + cd ../.. + rm -r 1 + rm $TESTDIR/editme + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + env) + # Test to see if the CVS_PID environment variable is being set + mkdir ${TESTDIR}/env + cd ${TESTDIR}/env + dotest env-1 "${testcvs} -Q co . >>${LOGFILE}" '' + + cat > ${TESTDIR}/env/test-cvs-pid <<EOF +#!${TESTSHELL} +if test "x\$CVS_PID" != "x"; then + # In local mode, there is no directory with the pid in it for use. + # In remote mode the CVS_PID will be the parent process of the + # cvs process that runs the commitinfo script. + if test "x$remote" = "x:" ; then + ppid=\`pwd | sed -e 's,.*/cvs-serv,,'\` + else + # This assumes that the -l switch puts PPID in the banner and does + # not run the elements together such that whitespace surrounds the + # pid and ppid in the output. This could be made slightly simpler + # if all hosts had a 'ps' command that supported the -p switch, + # but Solaris 7 /usr/ucb/ps does not and that may be the one we use. + # It is because this is so messy that the CVS_PID feature exists. + pid=\$\$ + pidcmd="ps -o pid,ppid -p \$pid || ps -el || ps -al" + if echo \$pidcmd | sh >pid.stdout 2> pid.stderr; then + ppid=\`cat pid.stdout |\\ + awk '/PPID/ { for (i=1; i <= NF; i++) { + if (\$i == "PPID") ppidx = i; + if (\$i == "PID") pidx = i; + } + next; + } + { print \$pidx " " \$ppidx }' |\\ + grep "^\$pid " |\\ + awk '{ print \$NF }'\` + else + ppid=unkown + fi + fi + if test "x\$ppid" = "x\${CVS_PID}"; then + # The PID looks okay to me + # Clean up any temporary files + rm -f pid.stdout pid.stderr + exit 0 + else + echo The environment variable CVS_PID is not properly set. + echo It should have been set to \'\$ppid\' but instead was \'\$CVS_PID\' + echo It is possible that this test is broken for your host. + echo Current pid: \$pid + [ -n "\$pidcmd" ] && echo "Command: \$pidcmd" + [ -s pid.stdout ] && echo Standard Out: && cat pid.stdout + [ -s pid.stderr ] && echo Standard Error: && cat pid.stderr + exit 1 + fi +else + echo The environment variable CVS_PID is not set. + exit 1 +fi +EOF + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x ${TESTDIR}/env/test-cvs-pid" + else + chmod +x ${TESTDIR}/env/test-cvs-pid + fi + cd CVSROOT + echo "^env ${TESTDIR}/env/test-cvs-pid %r/%p %s" >>commitinfo + dotest env-2 "${testcvs} -q ci -m test-pid commitinfo" \ +"${CVSROOT_DIRNAME}/CVSROOT/commitinfo,v <-- commitinfo +new revision: 1\.2; previous revision: 1\.1 +${SPROG} commit: Rebuilding administrative file database" + cd .. + mkdir env + dotest env-3 "${testcvs} -q add env" \ +"Directory ${CVSROOT_DIRNAME}/env added to the repository" + cd env + echo testing >file1 + dotest env-4 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest env-5 "${testcvs} -q commit -m test-pid" \ +"${CVSROOT_DIRNAME}/env/file1,v <-- file1 +initial revision: 1\.1" + + dokeep + # undo commitinfo changes + restore_adm + cd ../.. + rm -fr $TESTDIR/env + modify_repo rm -rf $CVSROOT_DIRNAME/env + ;; + + + + errmsg1) + modify_repo mkdir $CVSROOT_DIRNAME/1dir + mkdir 1 + cd 1 + dotest errmsg1-init-1 "$testcvs -Q co 1dir" + cd 1dir + touch foo + dotest errmsg-init-2 "$testcvs -Q add foo" + if ${testcvs} ci -m added >>${LOGFILE} 2>&1; then + pass 164 + else + fail 164 + fi + cd ../.. + mkdir 2 + cd 2 + if ${testcvs} -q co 1dir >>${LOGFILE}; then + pass 165 + else + fail 165 + fi + chmod a-w 1dir + cd ../1/1dir + rm foo; + if ${testcvs} rm foo >>${LOGFILE} 2>&1; then + pass 166 + else + fail 166 + fi + if ${testcvs} ci -m removed >>${LOGFILE} 2>&1; then + pass 167 + else + fail 167 + fi + + cd ../../2/1dir + # The second case in the local and remote versions of errmsg1-168 + # below happens on Cygwin under Windows, where write privileges + # aren't enforced properly. + if $remote; then + dotest errmsg1-168r "${testcvs} -q update" \ +"${SPROG} update: \`foo' is no longer in the repository +$CPROG update: unable to remove \./foo: Permission denied" \ +"${SPROG} update: \`foo' is no longer in the repository" + else + dotest errmsg1-168 "${testcvs} -q update" \ +"${SPROG} update: \`foo' is no longer in the repository +${SPROG} update: unable to remove foo: Permission denied" \ +"${SPROG} update: \`foo' is no longer in the repository" + fi + + dokeep + cd .. + chmod u+w 1dir + cd .. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/1dir + ;; + + + + errmsg2) + # More tests of various miscellaneous error handling, + # and cvs add behavior in general. + # See also test basicb-4a, concerning "cvs ci CVS". + # Too many tests to mention test the simple cases of + # adding files and directories. + # Test basicb-2a10 tests cvs -n add. + + # First the usual setup; create a directory first-dir. + mkdir 1; cd 1 + dotest errmsg2-1 "$testcvs -q co -l ." + mkdir first-dir + dotest errmsg2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + dotest_fail errmsg2-3 "${testcvs} add CVS" \ +"${CPROG} add: cannot add special file .CVS.; skipping" + touch file1 + # For the most part add returns a failure exitstatus if + # there are any errors, even if the remaining files are + # processed without incident. The "cannot add + # special file" message fits this pattern, at + # least currently. + dotest_fail errmsg2-4 "${testcvs} add CVS file1" \ +"${CPROG} add: cannot add special file .CVS.; skipping +${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + # I'm not sure these tests completely convey the various strange + # behaviors that CVS had before it specially checked for "." and + # "..". Suffice it to say that these are unlikely to work right + # without a special case. + dotest_fail errmsg2-5 "${testcvs} add ." \ +"${CPROG} add: cannot add special file .\..; skipping" + dotest_fail errmsg2-6 "${testcvs} add .." \ +"${CPROG} add: cannot add special file .\.\..; skipping" + # Make sure that none of the error messages left droppings + # which interfere with normal operation. + dotest errmsg2-7 "${testcvs} -q ci -m add-file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + mkdir sdir + cd .. + dotest errmsg2-8 "${testcvs} add first-dir/sdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" + # while we're here... check commit with no CVS directory + dotest_fail errmsg2-8a "${testcvs} -q ci first-dir nonexistant" \ +"${CPROG} commit: nothing known about .nonexistant' +${CPROG} \[commit aborted\]: correct above errors first!" + dotest_fail errmsg2-8b "$testcvs -q ci nonexistant first-dir" \ +"$CPROG commit: nothing known about .nonexistant' +$CPROG \[commit aborted\]: correct above errors first!" + dotest errmsg2-8c "$testcvs -q ci first-dir" + + cd first-dir + + touch file10 + mkdir sdir10 + dotest errmsg2-10 "${testcvs} add file10 sdir10" \ +"${SPROG} add: scheduling file .file10. for addition +Directory ${CVSROOT_DIRNAME}/first-dir/sdir10 added to the repository +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest errmsg2-11 "${testcvs} -q ci -m add-file10" \ +"$CVSROOT_DIRNAME/first-dir/file10,v <-- file10 +initial revision: 1\.1" + # Try to see that there are no droppings left by + # any of the previous tests. + dotest errmsg2-12 "${testcvs} -q update" "" + + # Now test adding files with '/' in the name, both one level + # down and more than one level down. + cd .. + mkdir first-dir/sdir10/ssdir + dotest errmsg2-13 "${testcvs} add first-dir/sdir10/ssdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir added to the repository" + + touch first-dir/sdir10/ssdir/ssfile + dotest errmsg2-14 \ + "${testcvs} add first-dir/sdir10/ssdir/ssfile" \ +"${SPROG} add: scheduling file .first-dir/sdir10/ssdir/ssfile. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + touch first-dir/file15 + dotest errmsg2-15 "${testcvs} add first-dir/file15" \ +"${SPROG} add: scheduling file .first-dir/file15. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + + # Now the case where we try to give it a directory which is not + # under CVS control. + mkdir bogus-dir + touch bogus-dir/file16 + # FIXCVS: The first message, from local CVS, is nice. The second one + # is not nice; would be good to fix remote CVS to give a clearer + # message (e.g. the one from local CVS). But at least it is an + # error message. + dotest_fail errmsg2-16 "${testcvs} add bogus-dir/file16" \ +"${SPROG} add: in directory \`bogus-dir': +${SPROG} \[add aborted\]: there is no version here; do .${SPROG} checkout. first" \ +"${CPROG} add: cannot open CVS/Entries for reading: No such file or directory +${CPROG} \[add aborted\]: no repository" + rm -r bogus-dir + + # One error condition we don't test for is trying to add a file + # or directory which already is there. + + dotest errmsg2-17 "${testcvs} -q ci -m checkin" \ +"$CVSROOT_DIRNAME/first-dir/file15,v <-- first-dir/file15 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/sdir10/ssdir/ssfile,v <-- first-dir/sdir10/ssdir/ssfile +initial revision: 1\.1" + dotest errmsg2-18 "${testcvs} -Q tag test" '' + + # trying to import the repository + + if $remote; then :; else + cd ${CVSROOT_DIRNAME} + dotest_fail errmsg2-20 "${testcvs} import -mtest . A B" \ +"${SPROG} \[import aborted\]: attempt to import the repository" + dotest_fail errmsg2-21 "${testcvs} import -mtest first-dir A B" \ +"${SPROG} \[import aborted\]: attempt to import the repository" + fi + + dokeep + cd .. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + errmsg3) + # Test the *PANIC* message caused by missing administration files + mkdir errmsg3 + cd errmsg3 + mkdir CVS + dotest_fail errmsg3-1 "${testcvs} -q up" \ +"${CPROG} update: in directory \`.': +${CPROG} update: CVS directory found without administrative files\. +${CPROG} update: Use CVS to create the CVS directory, or rename the +${CPROG} update: directory if it is intended to store something +${CPROG} update: besides CVS administrative files\. +${CPROG} \[update aborted\]: \*PANIC\* administration files missing!" + + dokeep + cd .. + rm -r errmsg3 + ;; + + + + close-stdout) + # Ensure that cvs update -p FILE > /dev/full fails + # Perform this test IFF /dev/full is a writable character device. + if test -w /dev/full && test -c /dev/full; then + mkdir close-stdout + cd close-stdout + echo a > file + dotest close-stdout-1 "$testcvs -Q import -m. closeout X Y" '' + dotest close-stdout-2 "$testcvs -Q co closeout" '' + # Match either a bare `write error' or + # `write error: No space left on device', + # since closeout.c can produce both. + dotest_fail close-stdout-3 \ + "${testcvs} -Q update -p closeout/file > /dev/full" \ + "${CPROG} \[update aborted\]: write error.*" + + dokeep + cd .. + rm -r close-stdout + modify_repo rm -rf $CVSROOT_DIRNAME/closeout + else + skip close-stdout '/dev/full is not available' + fi + ;; + + + + debug-log-nonfatal) + # Once upon a time, failure to create the debug log could be fatal. + if $remote; then :; else + remoteonly debug-log-nonfatal + continue + fi + + mkdir $TESTDIR/unwritable + chmod a-w $TESTDIR/unwritable + if test -n "$CVS_CLIENT_LOG"; then + save_CVS_CLIENT_LOG=$CVS_CLIENT_LOG + fi + CVS_CLIENT_LOG=$TESTDIR/unwritable/cvsclientlog + export CVS_CLIENT_LOG + + dotest debug-log-nonfatal-1 \ +"$testcvs -Q co -p CVSROOT/config >/dev/null" \ +"$CPROG checkout: opening to-server logfile $TESTDIR/unwritable/cvsclientlog.in: Permission denied +$CPROG checkout: opening from-server logfile $TESTDIR/unwritable/cvsclientlog.out: Permission denied" + + dokeep + rm -rf $TESTDIR/unwritable + unset CVS_CLIENT_LOG + if test -n "$save_CVS_CLIENT_LOG"; then + CVS_CLIENT_LOG=$save_CVS_CLIENT_LOG + fi + ;; + + + + adderrmsg) + # Test some of the error messages the 'add' command can return and + # their reactions to '-q'. + + # First the usual setup; create a directory first-dir. + mkdir 1; cd 1 + dotest adderrmsg-init1 "${testcvs} -q co -l ." '' + mkdir adderrmsg-dir + dotest adderrmsg-init2 "${testcvs} add adderrmsg-dir" \ +"Directory ${CVSROOT_DIRNAME}/adderrmsg-dir added to the repository" + cd adderrmsg-dir + + # try to add the admin dir + dotest_fail adderrmsg-1 "${testcvs} add CVS" \ +"${CPROG} add: cannot add special file .CVS.; skipping" + # might not want to see this message when you 'cvs add *' + dotest_fail adderrmsg-2 "${testcvs} -q add CVS" "" + + # to test some other messages + touch file1 + dotest adderrmsg-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + + # add it twice + dotest_fail adderrmsg-4 "${testcvs} add file1" \ +"${SPROG} add: \`file1' has already been entered" + dotest_fail adderrmsg-5 "${testcvs} -q add file1" "" + + dotest adderrmsg-6 "${testcvs} -q ci -madd" \ +"$CVSROOT_DIRNAME/adderrmsg-dir/file1,v <-- file1 +initial revision: 1\.1" + + # file in Entries & repository + dotest_fail adderrmsg-7 "${testcvs} add file1" \ +"${SPROG} add: \`file1' already exists, with version number 1\.1" + dotest_fail adderrmsg-8 "${testcvs} -q add file1" "" + + # clean up + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/adderrmsg-dir + ;; + + + + opterrmsg) + # Test some option parsing error messages + + # No init is necessary since these error messages are printed b4 + # CVS looks for a sandbox or repository + + # -z used to accept non-numeric arguments. This bit someone who + # attempted `cvs -z -n up' when the -n was read as the argument to + # -z. + dotest_fail opterrmsg-1 "${testcvs} -z -n up" \ +"${CPROG}: gzip compression level must be between 0 and 9" + + # Some general -z checks + dotest_fail opterrmsg-2 "${testcvs} -z -1 up" \ +"${CPROG}: gzip compression level must be between 0 and 9" + dotest_fail opterrmsg-3 "${testcvs} -z10 up" \ +"${CPROG}: gzip compression level must be between 0 and 9" + ;; + + + + devcom) + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1 + cd 1 + dotest devcom-1 "$testcvs -q co first-dir" + + cd first-dir + echo abb >abb + dotest devcom-2 "$testcvs add abb" \ +"$SPROG add: scheduling file \`abb' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + + dotest devcom-3 "$testcvs -q ci -m added" \ +"$CVSROOT_DIRNAME/first-dir/abb,v <-- abb +initial revision: 1\.1" + + dotest_fail devcom-4 "$testcvs watch" "Usage$DOTSTAR" + + dotest devcom-5 "$testcvs watch on" + + echo abc >abc + dotest devcom-6 "$testcvs add abc" \ +"$SPROG add: scheduling file \`abc' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + + dotest devcom-7 "$testcvs -q ci -m added" \ +"$CVSROOT_DIRNAME/first-dir/abc,v <-- abc +initial revision: 1\.1" + + cd ../.. + mkdir 2 + cd 2 + + dotest devcom-8 "$testcvs -q co first-dir" \ +"U first-dir/abb +U first-dir/abc" + + cd first-dir + dotest_fail devcom-9 "test -w abb" + dotest_fail devcom-9b "test -w abc" + + dotest devcom-10 "$testcvs editors" + dotest devcom-11 "$testcvs edit abb" + + # Here we test for the traditional ISO C ctime() date format. + # We assume the C locale; I guess that works provided we set + # LC_ALL at the start of this script but whether these + # strings should vary based on locale does not strike me as + # self-evident. + dotest devcom-12 "$testcvs editors" \ +"abb ${username} [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 [-a-zA-Z_.0-9]* ${TESTDIR}/2/first-dir" + + echo aaaa >>abb + dotest devcom-13 "$testcvs ci -m modify abb" \ +"${CVSROOT_DIRNAME}/first-dir/abb,v <-- abb +new revision: 1\.2; previous revision: 1\.1" + + # Unedit of a file not being edited should be a noop. + dotest devcom-14 "$testcvs unedit abb" '' + + dotest devcom-15 "$testcvs editors" "" + + dotest_fail devcom-16 "test -w abb" + + dotest devcom-17 "$testcvs edit abc" + + # Unedit of an unmodified file. + dotest devcom-18 "$testcvs unedit abc" + dotest devcom-19 "$testcvs edit abc" + + echo changedabc >abc + # Try to unedit a modified file; cvs should ask for confirmation + dotest devcom-20 "echo no | $testcvs unedit abc" \ +"abc has been modified; revert changes? " + + dotest devcom-21 "echo changedabc | cmp - abc" + + # OK, now confirm the unedit + dotest devcom-22 "echo yes |$testcvs unedit abc" \ +"abc has been modified; revert changes? " + + dotest devcom-23 "echo abc |cmp - abc" + + dotest devcom-24 "$testcvs watchers" '' + + # FIXME: This probably should be an error message instead + # of silently succeeding and printing nothing. + dotest devcom-a-nonexist "$testcvs watchers nonexist" '' + + dotest devcom-a1 "$testcvs watch add" '' + dotest devcom-a2 "$testcvs watchers" \ +"abb $username edit unedit commit +abc $username edit unedit commit" + dotest devcom-a3 "$testcvs watch remove -a unedit abb" '' + dotest devcom-a4 "$testcvs watchers abb" \ +"abb $username edit commit" + + # Check tagging and checking out while we have a CVS + # directory in the repository. + dotest devcom-t0 "${testcvs} -q tag tag" \ +'T abb +T abc' + cd ../.. + mkdir 3 + cd 3 + + # Test commented out because the bug it tests for is not fixed + # The error is: + # cvs watchers: cannot open CVS/Entries for reading: No such file or directory + # cvs: ../../work/ccvs/src/fileattr.c:75: fileattr_read: Assertion `fileattr_stored_repos != ((void *)0)' failed. +: dotest devcom-t-nonexist "${testcvs} watchers nonexist" fixme + + dotest devcom-t1 "${testcvs} -q co -rtag first-dir/abb" \ +'U first-dir/abb' + cd .. + # Since first-dir/abb is readonly, use -f. + rm -rf 3 + + # Test checking out the directory rather than the file. + mkdir 3 + cd 3 + dotest devcom-t2 "${testcvs} -q co -rtag first-dir" \ +'U first-dir/abb +U first-dir/abc' + cd .. + # Since the files are readonly, use -f. + rm -rf 3 + + # Now do it again, after removing the val-tags file created + # by devcom-t1 to force CVS to search the repository + # containing CVS directories. + rm ${CVSROOT_DIRNAME}/CVSROOT/val-tags + mkdir 3 + cd 3 + dotest devcom-t3 "${testcvs} -q co -rtag first-dir" \ +'U first-dir/abb +U first-dir/abc' + cd .. + # Since the files are readonly, use -f. + rm -rf 3 + + # Now remove all the file attributes + cd 2/first-dir + dotest devcom-b0 "${testcvs} watch off" '' + dotest devcom-b1 "${testcvs} watch remove" '' + # Test that CVS 1.6 and earlier can handle the repository. + dotest_fail devcom-b2 "test -d ${CVSROOT_DIRNAME}/first-dir/CVS" + + # Now test watching just some, not all, files. + dotest devcom-some0 "${testcvs} watch on abc" '' + cd ../.. + mkdir 3 + cd 3 + dotest devcom-some1 "${testcvs} -q co first-dir" 'U first-dir/abb +U first-dir/abc' + dotest devcom-some2 "test -w first-dir/abb" '' + dotest_fail devcom-some3 "test -w first-dir/abc" '' + + dokeep + cd .. + # Use -f because of the readonly files. + rm -rf 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + devcom2) + # More watch tests, most notably setting watches on + # files in various different states. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1 + cd 1 + dotest devcom2-1 "${testcvs} -q co first-dir" '' + cd first-dir + + # This should probably be an error; setting a watch on a totally + # unknown file is more likely to be a typo than intentional. + # But that isn't the currently implemented behavior. + dotest devcom2-2 "${testcvs} watch on w1" '' + + touch w1 w2 w3 nw1 + dotest devcom2-3 "${testcvs} add w1 w2 w3 nw1" "${DOTSTAR}" + # Letting the user set the watch here probably can be considered + # a feature--although it leads to a few potentially strange + # consequences like one user can set the watch and another actually + # adds the file. + dotest devcom2-4 "${testcvs} watch on w2" '' + dotest devcom2-5 "${testcvs} -Q ci -m add-them" + + # Note that this test differs in a subtle way from devcom-some0; + # in devcom-some0 the watch is creating a new fileattr file, and + # here we are modifying an existing one. + dotest devcom2-6 "${testcvs} watch on w3" '' + + # Now test that all the watches got set on the correct files + # FIXME: CVS should have a way to report whether watches are + # set, I think. The "check it out and see if it read-only" is + # sort of OK, but is complicated by CVSREAD and doesn't help + # if the file is added and not yet committed or some such. + # Probably "cvs status" should report "watch: on" if watch is on + # (and nothing if watch is off, so existing behavior is preserved). + cd ../.. + mkdir 2 + cd 2 + dotest devcom2-7 "${testcvs} -q co first-dir" 'U first-dir/nw1 +U first-dir/w1 +U first-dir/w2 +U first-dir/w3' + dotest devcom2-8 "test -w first-dir/nw1" '' + dotest_fail devcom2-9 "test -w first-dir/w1" '' + dotest_fail devcom2-10 "test -w first-dir/w2" '' + dotest_fail devcom2-11 "test -w first-dir/w3" '' + + cd first-dir + # OK, now we want to try files in various states with cvs edit. + dotest_fail devcom2-12 "$testcvs edit w4" \ +"${CPROG} edit: no such file w4; ignored" + # Try the same thing with a per-directory watch set. + dotest devcom2-13 "${testcvs} watch on" '' + dotest_fail devcom2-14 "$testcvs edit w5" \ +"${CPROG} edit: no such file w5; ignored" + dotest devcom2-15 "${testcvs} editors" '' + dotest devcom2-16 "${testcvs} editors w4" '' + # Make sure there are no droppings lying around + dotest devcom2-17 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ +"Fw1 _watched= +Fw2 _watched= +Fw3 _watched= +Fnw1 _watched= +D _watched=" + cd .. + + # Do a little error testing + dotest devcom2-18 "${testcvs} -q co -d first+dir first-dir" \ +"U first${PLUS}dir/nw1 +U first${PLUS}dir/w1 +U first${PLUS}dir/w2 +U first${PLUS}dir/w3" + cd first+dir + dotest_fail devcom2-19 "${testcvs} edit" \ +"${CPROG} \[edit aborted\]: current directory (${TESTDIR}/2/first${PLUS}dir) contains an invalid character (${PLUS},>;=\\\\t\\\\n)" + + # Make sure there are no droppings lying around + dotest devcom2-20 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ +"Fw1 _watched= +Fw2 _watched= +Fw3 _watched= +Fnw1 _watched= +D _watched=" + + dokeep + cd ../.. + # Use -f because of the readonly files. + rm -rf 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + devcom3) + # More watch tests, most notably handling of features designed + # for future expansion. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1 + cd 1 + + # Set up logging via the postwatch script hook. See the `info' test + # for a list of tests where other script hooks are tested. + dotest devcom3-init-1 "$testcvs -Q co CVSROOT" + cd CVSROOT + echo "ALL $TESTDIR/1/loggit %r %p %c" >>postwatch + dotest devcom3-init-2 "$testcvs -Q ci -mlog-watch" + cd .. # 1 + + cat >loggit <<EOF +#!$TESTSHELL +echo \${1+"\$@"} >>$TESTDIR/1/watch-log +EOF + # #^@&!^@ Cygwin. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x $TESTDIR/1/loggit" + else + chmod +x loggit + fi + + + + dotest devcom3-1 "$testcvs -q co first-dir" + cd first-dir + + touch w1 w2 + dotest devcom3-2 "${testcvs} add w1 w2" "${DOTSTAR}" + dotest devcom3-3 "${testcvs} watch on w1 w2" '' + dotest devcom3-4 "${testcvs} -Q ci -m add-them" + + # OK, since we are about to delve into CVS's internals, make + # sure that we seem to be correct about how they work. + dotest devcom3-5 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ +"Fw1 _watched= +Fw2 _watched=" + # Now write a few more lines, just as if we were a newer version + # of CVS implementing some new feature. + cat <<'EOF' >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr +Enew line here +G@#$^!@#=& +EOF + # Now get CVS to write to the fileattr file.... + dotest devcom3-6 "${testcvs} watch off w1" '' + # ...and make sure that it hasn't clobbered our new lines. + # Note that writing these lines in another order would be OK + # too. + dotest devcom3-7 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ +"Fw2 _watched= +G@#..!@#=& +Enew line here" + + # See what CVS does when a file name is duplicated. The + # behavior of all versions of CVS since file attributes were + # implemented is that it nukes the duplications. This seems + # reasonable enough, although it means it isn't clear how + # useful duplicates would be for purposes of future + # expansion. But in the interests of keeping behaviors + # predictable, might as well test for it, I guess. + echo 'Fw2 duplicate=' >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr + dotest devcom3-8 "${testcvs} watch on w1" '' + dotest devcom3-9 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ +"Fw2 _watched= +Fw1 _watched= +Enew line here +G@#..!@#=&" + + # Now test disconnected "cvs edit" and the format of the + # CVS/Notify file. + if $remote; then + CVS_SERVER_save=$CVS_SERVER + CVS_SERVER=$TESTDIR/cvs-none; export CVS_SERVER + + # The ${DOTSTAR} below matches the exact CVS server error message, + # which in :fork: mode is: + # "$SPROG \[edit aborted\]: cannot exec $TESTDIR/cvs-none: ${DOTSTAR}", + # but which is: + # "bash2: line 1: $TESTDIR/cvs-none: No such file or directory" + # when testing across an :ext:/ssh link to my Linux 2.4 box. + # + # I can't even test for the second part of the error message, + # from the client, which varies more consistently, usually either + # "end of file from server" (if the process doing the exec exits + # before the parent gets around to sending data to it) or + # "received broken pipe signal" (if it is the other way around), + # since HP-UX fails to output it. + dotest_fail devcom3-9ar "$testcvs edit w1 2>/dev/null" + dotest devcom3-9br "test -w w1" + dotest devcom3-9cr "cat CVS/Notify" \ +"Ew1 [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 [-a-zA-Z_.0-9]* ${TESTDIR}/1/first-dir EUC" + CVS_SERVER=${CVS_SERVER_save}; export CVS_SERVER + if $proxy; then + dotest_fail devcom3-9dp "$testcvs -q update" \ +"This CVS server does not support disconnected \`cvs edit'\. For now, remove all \`CVS/Notify' files in your workspace and try your command again\." + dotest devcom3-9ep "test -f CVS/Notify" + rm CVS/Notify + dotest devcom3-9hp "$testcvs watchers w1" + else + dotest devcom3-9dr "$testcvs -q update" + dotest_fail devcom3-9er "test -f CVS/Notify" + dotest devcom3-9fr "$testcvs watchers w1" \ +"w1 $username tedit tunedit tcommit" + fi + dotest devcom3-9gr "$testcvs unedit w1" + dotest devcom3-9hr "$testcvs watchers w1" + fi + + cd ../.. + # OK, now change the tab to a space, and see that CVS gives + # a reasonable error (this is database corruption but CVS should + # not lose its mind). + sed -e 's/Fw2 /Fw2 /' <$CVSROOT_DIRNAME/first-dir/CVS/fileattr \ + >$CVSROOT_DIRNAME/first-dir/CVS/fileattr.new + modify_repo mv $CVSROOT_DIRNAME/first-dir/CVS/fileattr.new \ + $CVSROOT_DIRNAME/first-dir/CVS/fileattr + mkdir 2; cd 2 + dotest_fail devcom3-10 "${testcvs} -Q co ." \ +"${SPROG} \[checkout aborted\]: file attribute database corruption: tab missing in ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" + + notifyworks=false + if $remote; then + if $proxy; then :; else + notifyworks=: + fi + fi + if $notifyworks; then + dotest devcom3-postwatch-examine-1r "cat $TESTDIR/1/watch-log" \ +"$CVSROOT_DIRNAME first-dir watch +$CVSROOT_DIRNAME first-dir watch +$CVSROOT_DIRNAME first-dir watch +$CVSROOT_DIRNAME first-dir update +$CVSROOT_DIRNAME first-dir server" + else + dotest devcom3-postwatch-examine-1 "cat $TESTDIR/1/watch-log" \ +"$CVSROOT_DIRNAME first-dir watch +$CVSROOT_DIRNAME first-dir watch +$CVSROOT_DIRNAME first-dir watch" + fi + + dokeep + restore_adm + cd .. + # Use -f because of the readonly files. + rm -rf 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + watch4) + # More watch tests, including adding directories. + mkdir 1; cd 1 + dotest watch4-0a "${testcvs} -q co -l ." '' + mkdir first-dir + dotest watch4-0b "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + + cd first-dir + dotest watch4-1 "${testcvs} watch on" '' + # This is just like the 173 test + touch file1 + dotest watch4-2 "$testcvs add file1" \ +"$SPROG add: scheduling file .file1. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest watch4-3 "$testcvs -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + # Now test the analogous behavior for directories. + mkdir subdir + dotest watch4-4 "${testcvs} add subdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" + cd subdir + touch sfile + dotest watch4-5 "${testcvs} add sfile" \ +"${SPROG} add: scheduling file .sfile. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest watch4-6 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/subdir/sfile,v <-- sfile +initial revision: 1\.1" + cd ../../.. + mkdir 2; cd 2 + dotest watch4-7 "${testcvs} -q co first-dir" "U first-dir/file1 +U first-dir/subdir/sfile" + dotest_fail watch4-8 "test -w first-dir/file1" '' + dotest_fail watch4-9 "test -w first-dir/subdir/sfile" '' + cd first-dir + dotest watch4-10 "${testcvs} edit file1" '' + echo 'edited in 2' >file1 + cd ../.. + + cd 1/first-dir + + # NOTE: I'm leaving in '' as acceptable + # to maintain partial compatibility with CVS versions + # prior to the edit check patch. + editorsLineRE="file1 $username [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR/2/first-dir" + dotest watch4-11 "$testcvs edit file1" "$editorsLineRE" + + echo 'edited in 1' >file1 + dotest watch4-12 "${testcvs} -q ci -m edit-in-1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + cd ../.. + cd 2/first-dir + dotest watch4-13 "${testcvs} -q update" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into file1 +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in file1 +C file1" + if (echo yes | ${testcvs} unedit file1) >>${LOGFILE}; then + pass watch4-14 + else + fail watch4-15 + fi + # This could plausibly be defined to either go back to the revision + # which was cvs edit'd (the status quo), or back to revision 1.2 + # (that is, the merge could update CVS/Base/file1). We pick the + # former because it is easier to implement, not because we have + # thought much about which is better. + dotest watch4-16 "cat file1" '' + # Make sure CVS really thinks we are at 1.1. + dotest watch4-17 "${testcvs} -q update" "U file1" + dotest watch4-18 "cat file1" "edited in 1" + cd ../.. + + # As a sanity check, make sure we are in the right place. + dotest watch4-cleanup-1 "test -d 1" + dotest watch4-cleanup-1 "test -d 2" + + dokeep + # Specify -f because of the readonly files. + rm -rf 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + watch5) + # This test was designed to catch a problem in server + # mode where an 'cvs edit'd file disappeared from the + # CVS/Base directory when 'cvs status' or 'cvs update' + # was called on the file after the file was touched. + # + # This test is still here to prevent the bug from + # being reintroduced. + # + # The rationale for having CVS/Base stay around is that + # CVS/Base should be there if "cvs edit" has been run (this + # may be helpful as a "cvs editors" analogue, it is + # client-side and based on working directory not username; + # but more importantly, it isn't clear why a "cvs status" + # would act like an unedit, and even if it does, it would + # need to make the file read-only again). + + mkdir watch5; cd watch5 + dotest watch5-0a "${testcvs} -q co -l ." '' + mkdir first-dir + dotest watch5-0b "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + + cd first-dir + dotest watch5-1 "${testcvs} watch on" '' + # This is just like the 173 test + touch file1 + dotest watch5-2 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest watch5-3 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + dotest watch5-4 "${testcvs} edit file1" '' + dotest watch5-5 "test -f CVS/Base/file1" '' + if ${testcvs} status file1 >>${LOGFILE} 2>&1; then + pass watch5-6 + else + fail watch5-6 + fi + dotest watch5-7 "test -f CVS/Base/file1" '' + + # Here's where the file used to dissappear + touch file1 + if ${testcvs} status file1 >>${LOGFILE} 2>&1; then + pass watch5-8 + else + fail watch5-8 + fi + dotest watch5-10 "test -f CVS/Base/file1" '' + + # Make sure update won't remove the file either + touch file1 + dotest watch5-11 "${testcvs} -q up" '' + dotest watch5-12 "test -f CVS/Base/file1" '' + + dokeep + cd ../.. + rm -r watch5 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + watch6-0) + + # Make sure that default attributes are being set properly. + # Specifying a directory has, it seems, never worked, + # and 1.12.10 broke it completely. + mkdir watch6-0; cd watch6-0 + + dotest watch6-0-setup-1 "$testcvs -Q co -ldtop ." + cd top + mkdir watch6-0 + dotest watch6-0-setup-2 "$testcvs -Q add watch6-0" + cd watch6-0 + dotest watch6-0-1 "$testcvs watch add" + dotest watch6-0-2 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/CVS/fileattr" + dotest watch6-0-3 "$testcvs watch remove" + dotest_fail watch6-0-4 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/CVS/fileattr 2>/dev/null" + + dotest watch6-0-5 "$testcvs watch add ." + dotest watch6-0-6 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/CVS/fileattr" + dotest watch6-0-7 "$testcvs watch remove ." + dotest_fail watch6-0-8 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/CVS/fileattr 2>/dev/null" + + # OK, basic add/remove work. Now, make sure it works with named directories + mkdir dir1 + mkdir dir2 + mkdir dir3 + echo afile>afile + $testcvs -Q add afile dir1 dir2 dir3 + $testcvs -Q ci -m "Adding test files" + + # Current directory should not be watched, but there should be a watch on the file, + # and on dir1 & dir2, but not on dir3. + dotest watch6-0-9 "$testcvs -Q watch add afile dir1 dir2" + dotest_fail watch6-0-10 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/CVS/fileattr 2>/dev/null" + dotest watch6-0-11 "grep -qE '^Fafile' $CVSROOT_DIRNAME/watch6-0/CVS/fileattr" + dotest watch6-0-12 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/dir1/CVS/fileattr" + dotest watch6-0-13 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/dir2/CVS/fileattr" + dotest_fail watch6-0-12 "grep -qE '^D' $CVSROOT_DIRNAME/watch6-0/dir3/CVS/fileattr 2>/dev/null" + + dokeep + cd ../../.. + rm -rf watch6-0 + modify_repo rm -rf $CVSROOT_DIRNAME/watch6-0 + ;; + + + + watch6) + # Check that `cvs watch on' does not reset the fileattr file. + mkdir watch6; cd watch6 + + dotest watch6-setup-1 "$testcvs -Q co -ldtop ." + cd top + mkdir watch6 + dotest watch6-setup-2 "$testcvs -Q add watch6" + + # I don't recall why I had these next 3 lines. + cd .. + dotest watch6-setup-3 "$testcvs -Q co watch6" + cd watch6 + + mkdir subdir + dotest watch6-setup-4 "$testcvs -Q add subdir" + cd subdir + + # START watch add/remove sequence + dotest watch6-1 "$testcvs -Q watch add" + dotest watch6-2 \ +"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + + dotest watch6-3 "$testcvs watch on" + dotest watch6-4 \ +"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + dotest watch6-5 \ +"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + + dotest watch6-6 "$testcvs watch off" + dotest watch6-7 \ +"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + dotest_fail watch6-8 \ +"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + + dotest watch6-9 "$testcvs watch remove" + dotest_fail watch6-10 \ +"test -d $CVSROOT_DIRNAME/test-directory/subdir/CVS" + dotest_fail watch6-11 \ +"test -f $CVSROOT_DIRNAME/test-directory/subdir/CVS/fileattr" + # END watch add/remove sequence + + echo Hi there >afile + dotest watch6-12 "$testcvs -Q add afile" + dotest watch6-13 "$testcvs ci -m 'A file' afile" \ +"$CVSROOT_DIRNAME/watch6/subdir/afile,v <-- afile +initial revision: 1.1" + + # START watch add/remove sequence + dotest watch6-14 "$testcvs -Q watch add" + dotest watch6-15 \ +"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + + dotest watch6-16 "$testcvs watch on" + dotest watch6-17 \ +"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + dotest watch6-18 \ +"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + + dotest watch6-19 "$testcvs watch off" + dotest watch6-20 \ +"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + dotest_fail watch6-21 \ +"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" + + dotest watch6-22 "$testcvs watch remove" + dotest_fail watch6-23 \ +"test -d $CVSROOT_DIRNAME/test-directory/subdir/CVS" + dotest_fail watch6-24 \ +"test -f $CVSROOT_DIRNAME/test-directory/subdir/CVS/fileattr" + # END watch add/remove sequence + + if $keep; then + echo Keeping $TESTDIR and exiting due to --keep + exit 0 + fi + cd ../../.. + rm -r watch6 + modify_repo rm -rf $CVSROOT_DIRNAME/watch6 + ;; + + + + edit-check) + # This tests the edit -c/-f and related features. + + mkdir edit-check; cd edit-check + dotest edit-check-0a "$testcvs -q co -l ." + mkdir first-dir + dotest edit-check-0b "$testcvs add first-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir added to the repository" + + cd first-dir + dotest edit-check-1 "$testcvs watch on" + + echo foo > file1 + dotest edit-check-2a "$testcvs add -minitial file1" \ +"$SPROG [a-z]*: scheduling file .file1. for addition +$SPROG [a-z]*: use .$SPROG commit. to add this file permanently" + + dotest edit-check-2b "$testcvs commit -m 'c1' file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + editorsLineRE="file1 $username [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR/edit-check/first-dir" + + R_editorsLineRE="first-dir/file1 $username [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR/edit-check" + F3_editorsLineRE="second-dir/file3 $username [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR/edit-check/first-dir" + + A_editorsLineRE="file1 [-a-zA-Z0-9_]* [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR[0-9]*/edit-check/first-dir" + + AF_editorsLineRE="file[12] [-a-zA-Z0-9_]* [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR/edit-check/first-dir" + + NF_editorsLineRE=" [-a-zA-Z0-9_]* [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR/edit-check/first-dir" + + dotest edit-check-3 "$testcvs edit file1" + dotest edit-check-4 "$testcvs edit file1" "$editorsLineRE" + + dotest_fail edit-check-5a "$testcvs edit -c file1" \ +"$editorsLineRE +$SPROG edit: Skipping file \`file1' due to existing editors\." + + dotest edit-check-5b "$testcvs editors" "$editorsLineRE" + + dotest edit-check-6a "$testcvs edit -c -f file1" "$editorsLineRE" + dotest edit-check-6b "$testcvs editors" "$editorsLineRE" + + dotest edit-check-7a "cat file1" "foo" + echo "bar" > file1 + dotest_fail edit-check-7b "$testcvs edit -c file1" \ +"$editorsLineRE +$SPROG edit: Skipping file \`file1' due to existing editors\." + dotest edit-check-7c "cat file1" "bar" + + # edit-check-8a has issues. It copies the current (modified) + # version of the file into CVS/Base, so that edit-check-9a and + # edit-check-9b don't get the expected results. + # Maybe unedit is *supposed* to return it to the state + # it was in before the edit (even if it was modified), + # but while that has a certain symetry, it doesn't seem + # to pass the intuitive-usability test. + # This aspect of the general problem could + # be fixed by not overwriting pre-existing Base versions, + # but it still wouldn't fix it if the user manually + # modified the file before doing the first edit. + # Because of the possibility that this is working as + # intended, I'm just commenting out the test, not fixing + # the issue. + #dotest edit-check-8a "${testcvs} edit -c -f file1" \ + # "${editorsLineRE}" + dotest edit-check-8b "$testcvs editors" "$editorsLineRE" + + dotest edit-check-9a "echo yes | $testcvs unedit file1" \ +"file1 has been modified; revert changes? " + dotest edit-check-9b "$testcvs editors" + dotest edit-check-9c "cat file1" "foo" + + dotest edit-check-10 "$testcvs edit -c file1" + dotest_fail edit-check-11 "$testcvs edit -c file1" \ +"$editorsLineRE +$SPROG edit: Skipping file \`file1' due to existing editors\." + + echo "morefoo" > file1 + dotest edit-check-12a "$testcvs commit -m 'c2' -c file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + dotest edit-check-12b "$testcvs editors file1" + + chmod u+w file1 + echo "morebar" > file1 + dotest_fail edit-check-13a "$testcvs commit -m 'c3' -c file1" \ +"$SPROG [a-z]*: Valid edit does not exist for file1 +$SPROG \[[a-z]* aborted\]: correct above errors first!" + dotest edit-check-13b "$testcvs editors file1" + + dotest edit-check-14a "$testcvs commit -m 'c4' -c -f file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + dotest edit-check-14b "$testcvs editors file1" + + dotest edit-check-15 "$testcvs edit -c file1" + cd .. + + dotest edit-check-16a "echo yes | $testcvs release -d first-dir" \ +"You have \[0\] altered files in this repository. +Are you sure you want to release (and delete) directory \`first-dir': " + dotest edit-check-16b "$testcvs -q update -d first-dir" \ + "U first-dir/file1" + cd first-dir + dotest edit-check-16c "$testcvs editors file1" + + cd .. + dotest edit-check-17a "$testcvs edit -c" + dotest_fail edit-check-17b "$testcvs edit -c" \ +"$R_editorsLineRE +$SPROG edit: Skipping file \`first-dir/file1' due to existing editors\." + dotest edit-check-17c "$testcvs edit -c -f" "$R_editorsLineRE" + + echo "more changes" > first-dir/file1 + dotest edit-check-18a "$testcvs -q commit -m 'c5' -c" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- first-dir/file1 +new revision: 1\.4; previous revision: 1\.3" + dotest edit-check-18b "$testcvs editors" + + cd first-dir + + # Manually fake another editor: + + # Try to gaurantee a seperate name for an "other" user editting + # the file. + otherUser="dummyUser" + if [ x"$USER" = x"$otherUser" ] ; then + otherUser="dummyUser2" + fi + if [ x"$LOGNAME" = x"$otherUser" ] ; then + otherUser="dummyUser3" + fi + tabChar=' ' + + backupFileattrName="$CVSROOT_DIRNAME/first-dir/CVS/bak.fileattr.$$" + mv $CVSROOT_DIRNAME/first-dir/CVS/fileattr $backupFileattrName + + otherDir="`pwd | sed 's%/edit-check/%2/edit-check/%'`" + echo \ +"Ffile1${tabChar}_watched=;_editors=$otherUser>Sat Oct 6 04:25:00 2001 -0000+`hostname`+$otherDir;_watchers=$otherUser>tedit+tunedit+tcommit +D${tabChar}_watched=" > $CVSROOT_DIRNAME/first-dir/CVS/fileattr + + editFileattrName="$CVSROOT_DIRNAME/first-dir/CVS/edit.fileattr.$$" + cp $CVSROOT_DIRNAME/first-dir/CVS/fileattr $editFileattrName + + O_editorsLineRE="file1 $otherUser [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR[0-9]/edit-check/first-dir" + + dotest edit-check-19a "$testcvs edit file1" "$O_editorsLineRE" + dotest edit-check-19b "$testcvs editors" \ +"$A_editorsLineRE +$NF_editorsLineRE" + + dotest edit-check-20a "$testcvs unedit file1" + dotest edit-check-20b "$testcvs editors" "$O_editorsLineRE" + + dotest_fail edit-check-21a "$testcvs edit -c file1" \ +"$O_editorsLineRE +$SPROG edit: Skipping file \`file1' due to existing editors\." + dotest edit-check-21b "$testcvs editors" "$O_editorsLineRE" + + dotest edit-check-22a "$testcvs edit -c -f file1" "$O_editorsLineRE" + dotest edit-check-22b "$testcvs editors" \ +"$A_editorsLineRE +$NF_editorsLineRE" + + echo "Yet another change" >file1 + + dotest_fail edit-check-23a "$testcvs edit -c" \ +"$A_editorsLineRE +$NF_editorsLineRE +$SPROG edit: Skipping file \`file1' due to existing editors\." + + dotest edit-check-23b "$testcvs editors" \ +"$A_editorsLineRE +$NF_editorsLineRE" + + dotest edit-check-24a "echo y | $testcvs unedit" \ + "file1 has been modified; revert changes? " + dotest edit-check-24b "$testcvs editors" "$O_editorsLineRE" + dotest edit-check-24c "cat file1" "more changes" + + dotest edit-check-25a "$testcvs unedit" + dotest edit-check-25b "$testcvs editors" "$O_editorsLineRE" + dotest_fail edit-check-25c "test -w file1" + + dotest edit-check-26a "$testcvs edit file1" "$O_editorsLineRE" + dotest edit-check-26b "$testcvs editors file1" \ +"$A_editorsLineRE +$NF_editorsLineRE" + dotest edit-check-26c "test -w file1" + + echo "Yet more changes" >file1 + dotest edit-check-27a "$testcvs -q commit -mmsg -c file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4" + dotest edit-check-27b "$testcvs editors" "$O_editorsLineRE" + + chmod u+w file1 + echo "unofficial change" >file1 + + dotest_fail edit-check-28a "$testcvs -q commit -mmsg -c" \ +"$SPROG commit: Valid edit does not exist for file1 +$SPROG \[commit aborted\]: correct above errors first!" + dotest edit-check-28b "$testcvs editors" "$O_editorsLineRE" + + dotest edit-check-29a "$testcvs -q commit -mmsg -c -f" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.6; previous revision: 1\.5" + dotest edit-check-29b "$testcvs editors" "$O_editorsLineRE" + dotest edit-check-29c "cat file1" "unofficial change" + + modify_repo cp "$backupFileattrName" \ + $CVSROOT_DIRNAME/first-dir/CVS/fileattr + dotest edit-check-30 "$testcvs editors" + + # Make sure earlier unreported editors are reported properly + # with the edit-check code running. + if $remote; then + CVS_SERVER_SAVED=$CVS_SERVER + CVS_SERVER=$TESTDIR/cvs-none; export CVS_SERVER + + # The $DOTSTAR matches the exact exec error message + # (which varies) and either "end of file from server" + # (if the process doing the exec exits before the parent + # gets around to sending data to it) or "broken pipe" (if it + # is the other way around). + dotest_fail edit-check-31ar "$testcvs edit file1" \ +"$SPROG \[edit aborted\]: cannot exec $TESTDIR/cvs-none: $DOTSTAR" + dotest edit-check-31br "test -w file1" + dotest edit-check-31cr "cat CVS/Notify" \ +"Efile1 [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 [-a-zA-Z_.0-9]* $TESTDIR/edit-check/first-dir EUC" + CVS_SERVER=$CVS_SERVER_SAVED; export CVS_SERVER + + dotest_fail edit-check-31dr "$testcvs edit -c file1" \ +"$editorsLineRE +$SPROG edit: Skipping file \`file1' due to existing editors\." + dotest edit-check-31er "$testcvs editors file1" "$editorsLineRE" + dotest edit-check-31fr "$testcvs unedit file1" + fi + + # Make sure it isn't confused by handling multiple files at + # the same time: + echo file2Data >file2 + + dotest edit-check-32a "$testcvs add file2" \ +"$SPROG [a-z]*: scheduling file .file2. for addition +$SPROG [a-z]*: use .$SPROG commit. to add this file permanently" + + dotest edit-check-32b "$testcvs commit -m 'c1' file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + + mkdir second-dir + dotest edit-check-32c "$testcvs add second-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir/second-dir added to the repository" + cd second-dir + echo ThirdFile >file3 + + dotest edit-check-32d "$testcvs add file3" \ +"$SPROG [a-z]*: scheduling file .file3. for addition +$SPROG [a-z]*: use .$SPROG commit. to add this file permanently" + + dotest edit-check-32f "$testcvs commit -m 'c1' file3" \ +"$CVSROOT_DIRNAME/first-dir/second-dir/file3,v <-- file3 +initial revision: 1\.1" + dotest_fail edit-check-32g "test -w file3" + + cd .. + + dotest edit-check-33a "$testcvs edit -c" + + dotest edit-check-33b "$testcvs editors" \ +"$AF_editorsLineRE +$AF_editorsLineRE +$F3_editorsLineRE" + dotest edit-check-33c "test -w second-dir/file3" + + dotest_fail edit-check-34a "$testcvs edit -c file1 file2" \ +"$AF_editorsLineRE +$SPROG edit: Skipping file \`file1' due to existing editors\. +$AF_editorsLineRE +$SPROG edit: Skipping file \`file2' due to existing editors\." + + dotest edit-check-34b "$testcvs editors file1 file2" \ +"$editorsLineRE +$AF_editorsLineRE" + + dotest edit-check-35a "$testcvs unedit file1" + dotest edit-check-35b "$testcvs editors" \ +"$AF_editorsLineRE +$F3_editorsLineRE" + dotest edit-check-35c "test -w second-dir/file3" + + dotest edit-check-36a "$testcvs unedit" + dotest edit-check-36b "$testcvs editors" + dotest_fail edit-check-36c "test -w second-dir/file3" + + dokeep + cd ../.. + rm -rf edit-check + rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + unedit-without-baserev) + mkdir 1; cd 1 + module=x + + file=m + echo foo > $file + dotest unedit-without-baserev-1 \ + "$testcvs -Q import -m . $module X Y" '' + dotest unedit-without-baserev-2 "$testcvs -Q co $module" '' + cd $module + + dotest unedit-without-baserev-3 "$testcvs -Q edit $file" '' + + echo add a line >> $file + rm -f CVS/Baserev + + # This will fail on most systems. + dotest unedit-without-baserev-4 "echo yes |${testcvs} -Q unedit $file" \ +"m has been modified; revert changes${QUESTION} ${CPROG} unedit: m not mentioned in CVS/Baserev +${CPROG} unedit: run update to complete the unedit" + + # SunOS4.1.4 systems make it this far, but with a corrupted + # CVS/Entries file. Demonstrate the corruption! + dotest unedit-without-baserev-5 "cat CVS/Entries" \ + "/$file/1\.1\.1\.1/${DOTSTAR}" + + dotest unedit-without-baserev-6 "${testcvs} -q update" \ +"$SPROG update: warning: \`m' was lost +U m" + + # OK, those were the easy cases. Now tackle the hard one + # (the reason that CVS/Baserev was invented rather than just + # getting the revision from CVS/Entries). This is very + # similar to watch4-10 through watch4-18 but with Baserev + # missing. + cd ../.. + mkdir 2; cd 2 + dotest unedit-without-baserev-7 "${testcvs} -Q co x" '' + cd x + + dotest unedit-without-baserev-10 "${testcvs} edit m" '' + echo 'edited in 2' >m + cd ../.. + + cd 1/x + + editorsLineRE="m $username [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] -0000 $hostname $TESTDIR/2/x" + dotest unedit-without-baserev-11 "$testcvs edit m" "$editorsLineRE" + + echo 'edited in 1' >m + dotest unedit-without-baserev-12 "${testcvs} -q ci -m edit-in-1" \ +"$CVSROOT_DIRNAME/x/m,v <-- m +new revision: 1\.2; previous revision: 1\.1" + cd ../.. + cd 2/x + dotest unedit-without-baserev-13 "${testcvs} -q update" \ +"RCS file: ${CVSROOT_DIRNAME}/x/m,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1\.1\.1 and 1\.2 into m +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in m +C m" + rm CVS/Baserev + dotest unedit-without-baserev-14 "echo yes |${testcvs} unedit m" \ +"m has been modified; revert changes${QUESTION} ${CPROG} unedit: m not mentioned in CVS/Baserev +${CPROG} unedit: run update to complete the unedit" + dotest unedit-without-baserev-15 "${testcvs} -q update" \ +"$SPROG update: warning: \`m' was lost +U m" + # The following tests are kind of degenerate compared with + # watch4-16 through watch4-18 but might as well make sure that + # nothing seriously wrong has happened to the working directory. + dotest unedit-without-baserev-16 "cat m" 'edited in 1' + # Make sure CVS really thinks we are at 1.2. + dotest unedit-without-baserev-17 "${testcvs} -q update" "" + dotest unedit-without-baserev-18 "cat m" "edited in 1" + + dokeep + cd ../.. + rm -rf 1 + rm -r 2 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + ignore) + # On Windows, we can't check out CVSROOT, because the case + # insensitivity means that this conflicts with cvsroot. + mkdir ignore + cd ignore + + dotest ignore-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}" + cd CVSROOT + echo rootig.c >cvsignore + dotest ignore-2 "${testcvs} add cvsignore" "${SPROG}"' add: scheduling file `cvsignore'"'"' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + + dotest ignore-3 " ${testcvs} ci -m added" \ +"${CPROG} commit: Examining \. +${CVSROOT_DIRNAME}/CVSROOT/cvsignore,v <-- cvsignore +initial revision: 1\.1 +${SPROG} commit: Rebuilding administrative file database" + + cd .. + if echo "yes" | ${testcvs} release -d CVSROOT >>${LOGFILE} ; then + pass ignore-4 + else + fail ignore-4 + fi + + # CVS looks at the home dir from getpwuid, not HOME (is that correct + # behavior?), so this is hard to test and we won't try. + # echo foobar.c >${HOME}/.cvsignore + CVSIGNORE=envig.c; export CVSIGNORE + mkdir dir-to-import + cd dir-to-import + touch foobar.c bar.c rootig.c defig.o envig.c optig.c + # We use sort because we can't predict the order in which + # the files will be listed. + dotest_sort ignore-5 "${testcvs} import -m m -I optig.c ignore/first-dir tag1 tag2" \ +' + +I ignore/first-dir/defig.o +I ignore/first-dir/envig.c +I ignore/first-dir/optig.c +I ignore/first-dir/rootig.c +N ignore/first-dir/bar.c +N ignore/first-dir/foobar.c +No conflicts created by this import' + dotest_sort ignore-6 "${testcvs} import -m m -I ! ignore/second-dir tag3 tag4" \ +' + +N ignore/second-dir/bar.c +N ignore/second-dir/defig.o +N ignore/second-dir/envig.c +N ignore/second-dir/foobar.c +N ignore/second-dir/optig.c +N ignore/second-dir/rootig.c +No conflicts created by this import' + cd .. + rm -r dir-to-import + + mkdir 1 + cd 1 + dotest ignore-7 "${testcvs} -q co -dsecond-dir ignore/second-dir" \ +'U second-dir/bar.c +U second-dir/defig.o +U second-dir/envig.c +U second-dir/foobar.c +U second-dir/optig.c +U second-dir/rootig.c' + dotest ignore-8 "${testcvs} -q co -dfirst-dir ignore/first-dir" 'U first-dir/bar.c +U first-dir/foobar.c' + cd first-dir + touch rootig.c defig.o envig.c optig.c notig.c + dotest ignore-9 "${testcvs} -q update -I optig.c" "${QUESTION} notig.c" + # The fact that CVS requires us to specify -I CVS here strikes me + # as a bug. + dotest_sort ignore-10 "${testcvs} -q update -I ! -I CVS" \ +"${QUESTION} defig.o +${QUESTION} envig.c +${QUESTION} notig.c +${QUESTION} optig.c +${QUESTION} rootig.c" + + # Now test that commands other than update also print "? notig.c" + # where appropriate. Only test this for remote, because local + # CVS only prints it on update. + rm optig.c + if $remote; then + dotest ignore-11r "$testcvs -q diff" "$QUESTION notig.c" + + # Force the server to be contacted. Ugh. Having CVS + # contact the server for the sole purpose of checking + # the CVSROOT/cvsignore file does not seem like such a + # good idea, so I imagine this will continue to be + # necessary. Oh well, at least we test CVS's ablity to + # handle a file with a modified timestamp but unmodified + # contents. + touch bar.c + + dotest ignore-11ar "$testcvs -q ci -m commit-it" \ +"$QUESTION notig.c" + fi + + # now test .cvsignore files + cd .. + echo notig.c >first-dir/.cvsignore + echo foobar.c >second-dir/.cvsignore + touch first-dir/notig.c second-dir/notig.c second-dir/foobar.c + dotest_sort ignore-12 "${testcvs} -qn update" \ +"${QUESTION} first-dir/.cvsignore +${QUESTION} second-dir/.cvsignore +${QUESTION} second-dir/notig.c" + dotest_sort ignore-13 "${testcvs} -qn update -I! -I CVS" \ +"${QUESTION} first-dir/.cvsignore +${QUESTION} first-dir/defig.o +${QUESTION} first-dir/envig.c +${QUESTION} first-dir/rootig.c +${QUESTION} second-dir/.cvsignore +${QUESTION} second-dir/notig.c" + + echo yes | dotest ignore-14 "${testcvs} release -d first-dir" \ +"${QUESTION} \.cvsignore +You have \[0\] altered files in this repository. +Are you sure you want to release (and delete) directory .first-dir': " + + echo add a line >>second-dir/foobar.c + rm second-dir/notig.c second-dir/.cvsignore + echo yes | dotest ignore-15 "${testcvs} release -d second-dir" \ +"M foobar.c +You have \[1\] altered files in this repository. +Are you sure you want to release (and delete) directory .second-dir': " + + dokeep + cd ../.. + rm -r ignore + modify_repo rm -rf $CVSROOT_DIRNAME/ignore + ;; + + + + ignore-on-branch) + # Test that CVS _doesn't_ ignore files on branches because they were + # added to the trunk. + mkdir ignore-on-branch; cd ignore-on-branch + modify_repo mkdir $CVSROOT_DIRNAME/ignore-on-branch + + # create file1 & file2 on trunk + dotest ignore-on-branch-setup-1 "$testcvs -q co -dsetup ignore-on-branch" '' + cd setup + echo file1 >file1 + dotest ignore-on-branch-setup-2 "$testcvs -q add file1" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest ignore-on-branch-setup-3 "$testcvs -q ci -mfile1 file1" \ +"$CVSROOT_DIRNAME/ignore-on-branch/file1,v <-- file1 +initial revision: 1\.1" + dotest ignore-on-branch-setup-4 "$testcvs -q tag -b branch" 'T file1' + echo file2 >file2 + dotest ignore-on-branch-setup-5 "$testcvs -q add file2" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest ignore-on-branch-setup-6 "$testcvs -q ci -mtrunk file2" \ +"$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2 +initial revision: 1\.1" + + cd .. + + # Check out branch. + # + # - This was the original failure case - file2 would not be flagged + # with a '?' + dotest ignore-on-branch-1 "$testcvs -q co -rbranch ignore-on-branch" \ +'U ignore-on-branch/file1' + cd ignore-on-branch + echo file2 on branch >file2 + dotest ignore-on-branch-2 "$testcvs -nq update" '? file2' + + # Now set up for a join. One of the original fixes for this would + # print out a 'U' and a '?' during a join which added a file. + if $remote; then + dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" \ +'? file2 +T file1' + else + dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" 'T file1' + fi + dotest ignore-on-branch-4 "$testcvs -q add file2" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest ignore-on-branch-5 "$testcvs -q ci -mbranch file2" \ +"$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + dotest ignore-on-branch-6 "$testcvs -q up -rbranch2" \ +"${SPROG} update: \`file2' is no longer in the repository" + dotest ignore-on-branch-7 "$testcvs -q up -jbranch" 'U file2' + + dokeep + cd ../.. + rm -r ignore-on-branch + modify_repo rm -rf $CVSROOT_DIRNAME/ignore-on-branch + ;; + + + + binfiles) + # Test cvs's ability to handle binary files. + # List of binary file tests: + # * conflicts, "cvs admin": binfiles + # * branching and joining: binfiles2 + # * adding and removing files: binfiles3 + # * -k wrappers: binwrap, binwrap2, binwrap3 + # * "cvs import" and wrappers: binwrap, binwrap2, binwrap3 + # * -k option to "cvs import": none yet, as far as I know. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1; cd 1 + dotest binfiles-1 "${testcvs} -q co first-dir" '' + ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ + </dev/null | ${TR} '@' '\000' >binfile.dat + cat binfile.dat binfile.dat >binfile2.dat + cd first-dir + cp ../binfile.dat binfile + dotest binfiles-2 "${testcvs} add -kb binfile" \ +"${SPROG}"' add: scheduling file `binfile'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest binfiles-3 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/binfile,v <-- binfile +initial revision: 1\.1" + cd ../.. + mkdir 2; cd 2 + dotest binfiles-4 "${testcvs} -q co first-dir" 'U first-dir/binfile' + cd first-dir + dotest binfiles-5 "cmp ../../1/binfile.dat binfile" '' + # Testing that sticky options is -kb is the closest thing we have + # to testing that binary files work right on non-unix machines + # (until there is automated testing for such machines, of course). + dotest binfiles-5.5 "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + + # Test that "-kk" does not override "-kb" + cd ../.. + mkdir 2a; cd 2a + dotest binfiles-4 "${testcvs} -q co -kk first-dir" 'U first-dir/binfile' + cd first-dir + # Testing that sticky options is -kb is the closest thing we have + # to testing that binary files work right on non-unix machines + # (until there is automated testing for such machines, of course). + dotest binfiles-5.5 "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + + # Test whether the default options from the RCS file are + # also used when operating on files instead of whole + # directories + cd ../.. + rm -r 2a + mkdir 3; cd 3 + dotest binfiles-5.5b0 "${testcvs} -q co first-dir/binfile" \ +'U first-dir/binfile' + cd first-dir + dotest binfiles-5.5b1 "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + cd ../.. + rm -r 3 + # test that "-kk" does not override "-kb" + mkdir 3; cd 3 + dotest binfiles-5.5b0 "${testcvs} -q co -kk first-dir/binfile" \ +'U first-dir/binfile' + cd first-dir + dotest binfiles-5.5b1 "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + cd ../.. + rm -r 3 + cd 2/first-dir + + cp ../../1/binfile2.dat binfile + dotest binfiles-6 "${testcvs} -q ci -m modify-it" \ +"$CVSROOT_DIRNAME/first-dir/binfile,v <-- binfile +new revision: 1\.2; previous revision: 1\.1" + cd ../../1/first-dir + dotest binfiles-7 "${testcvs} -q update" '[UP] binfile' + dotest binfiles-8 "cmp ../binfile2.dat binfile" '' + + # Now test handling of conflicts with binary files. + cp ../binfile.dat binfile + dotest binfiles-con0 "${testcvs} -q ci -m modify-it" \ +"$CVSROOT_DIRNAME/first-dir/binfile,v <-- binfile +new revision: 1\.3; previous revision: 1\.2" + cd ../../2/first-dir + echo 'edits in dir 2' >binfile + dotest binfiles-con1 "${testcvs} -q update" \ +"$SPROG update: nonmergeable file needs merge +$SPROG update: revision 1\.3 from repository is now in binfile +$SPROG update: file from working directory is now in \.#binfile\.1\.2 +C binfile" + + dotest_fail binfiles-con1b "$testcvs -q up" "C binfile" + + dotest binfiles-con2 "cmp binfile ../../1/binfile.dat" '' + dotest binfiles-con3 "cat .#binfile.1.2" 'edits in dir 2' + + cp ../../1/binfile2.dat binfile + dotest binfiles-con4 "$testcvs -q ci -m resolve-it" \ +"$CVSROOT_DIRNAME/first-dir/binfile,v <-- binfile +new revision: 1\.4; previous revision: 1\.3" + cd ../../1/first-dir + dotest binfiles-con5 "${testcvs} -q update" '[UP] binfile' + + dotest binfiles-9 "${testcvs} -q update -A" '' + # "-kk" no longer does anything with "-kb" + dotest binfiles-10 "${testcvs} -q update -kk" '' + dotest binfiles-11 "${testcvs} -q update" '' + # "-kk" no longer does anything with "-kb" + dotest binfiles-12 "${testcvs} -q update -A" '' + dotest binfiles-13 "${testcvs} -q update -A" '' + + cd ../.. + + mkdir 3 + cd 3 + dotest binfiles-13a0 "${testcvs} -q co -r HEAD first-dir" \ +'U first-dir/binfile' + cd first-dir + dotest binfiles-13a1 "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.4.* + Repository revision: 1\.4 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: HEAD (revision: 1\.4) + Sticky Date: (none) + Sticky Options: -kb" + cd ../.. + rm -r 3 + + cd 2/first-dir + echo 'this file is $''RCSfile$' >binfile + dotest binfiles-14a "${testcvs} -q ci -m modify-it" \ +"$CVSROOT_DIRNAME/first-dir/binfile,v <-- binfile +new revision: 1\.5; previous revision: 1\.4" + dotest binfiles-14b "cat binfile" 'this file is $''RCSfile$' + # See binfiles-5.5 for discussion of -kb. + dotest binfiles-14c "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.5.* + Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + dotest binfiles-14d "${testcvs} admin -kv binfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v +done" + # cvs admin doesn't change the checked-out file or its sticky + # kopts. There probably should be a way which does (but + # what if the file is modified? And do we try to version + # control the kopt setting?) + dotest binfiles-14e "cat binfile" 'this file is $''RCSfile$' + dotest binfiles-14f "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.5.* + Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + dotest binfiles-14g "${testcvs} -q update -A" '[UP] binfile' + dotest binfiles-14h "cat binfile" 'this file is binfile,v' + dotest binfiles-14i "${testcvs} status binfile" \ +"=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.5.* + Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kv" + + # Do sticky options work when used with 'cvs update'? + echo "Not a binary file." > nibfile + dotest binfiles-sticky1 "${testcvs} -q add nibfile" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest binfiles-sticky2 "${testcvs} -q ci -m add-it nibfile" \ +"$CVSROOT_DIRNAME/first-dir/nibfile,v <-- nibfile +initial revision: 1\.1" + dotest binfiles-sticky3 "${testcvs} -q update -kb nibfile" \ + '[UP] nibfile' + dotest binfiles-sticky4 "${testcvs} -q status nibfile" \ +"=================================================================== +File: nibfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + + # Now test that -A can clear the sticky option. + dotest binfiles-sticky5 "${testcvs} -q update -A nibfile" \ +"[UP] nibfile" + dotest binfiles-sticky6 "${testcvs} -q status nibfile" \ +"=================================================================== +File: nibfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest binfiles-15 "${testcvs} -q admin -kb nibfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/nibfile,v +done" + dotest binfiles-16 "${testcvs} -q update nibfile" "[UP] nibfile" + dotest binfiles-17 "${testcvs} -q status nibfile" \ +"=================================================================== +File: nibfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + + dotest binfiles-o1 "${testcvs} admin -o1.3:: binfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v +deleting revision 1\.5 +deleting revision 1\.4 +done" + dotest binfiles-o2 "${testcvs} admin -o::1.3 binfile" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v +deleting revision 1\.2 +deleting revision 1\.1 +done" + dotest binfiles-o3 "${testcvs} -q log -h -N binfile" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v +Working file: binfile +head: 1\.3 +branch: +locks: strict +access list: +keyword substitution: v +total revisions: 1 +=============================================================================" + + # Check that the contents were right. This isn't the hard case + # (in which RCS_delete_revs does a diff), but might as well. + dotest binfiles-o4 "${testcvs} -q update binfile" "U binfile" + dotest binfiles-o5 "cmp binfile ../../1/binfile.dat" "" + + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r 1 2 + ;; + + + + binfiles2) + # Test cvs's ability to handle binary files, particularly branching + # and joining. The key thing we are worrying about is that CVS + # doesn't print "cannot merge binary files" or some such, in + # situations where no merging is required. + # See also "join" which does this with non-binary files. + # + # Cases (we are merging from the branch to the trunk): + # binfile.dat) File added on branch, not on trunk. + # File should be marked for addition. + # brmod) File modified on branch, not on trunk. + # File should be copied over to trunk (no merging is needed). + # brmod-trmod) File modified on branch, also on trunk. + # This is a conflict. Present the user with both files and + # let them figure it out. + # brmod-wdmod) File modified on branch, not modified in the trunk + # repository, but modified in the (trunk) working directory. + # This is also a conflict. + + modify_repo mkdir ${CVSROOT_DIRNAME}/first-dir + mkdir 1; cd 1 + dotest binfiles2-1 "${testcvs} -q co first-dir" '' + cd first-dir + + # The most important thing here is that binfile, binfile2, &c + # each be distinct from each other. We also make sure to include + # a few likely end-of-line patterns to make sure nothing is + # being munged as if in text mode. + ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ + </dev/null | ${TR} '@' '\000' >../binfile + # Use binfl2 rather than binfile2 because of a problem with Cygwin + # and Samba. that causes cat to report that the input and output file + # are the same when outputting to binfile3. Why? I don't know, but + # it is consistently reproducible. + cat ../binfile ../binfile >../binfl2 + cat ../binfl2 ../binfile >../binfile3 + + # FIXCVS: unless a branch has at least one file on it, + # tag_check_valid won't know it exists. So if brmod didn't + # exist, we would have to invent it. + cp ../binfile brmod + cp ../binfile brmod-trmod + cp ../binfile brmod-wdmod + dotest binfiles2-1a \ +"${testcvs} add -kb brmod brmod-trmod brmod-wdmod" \ +"${SPROG} add: scheduling file .brmod. for addition +${SPROG} add: scheduling file .brmod-trmod. for addition +${SPROG} add: scheduling file .brmod-wdmod. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest binfiles2-1b "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/brmod,v <-- brmod +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-wdmod,v <-- brmod-wdmod +initial revision: 1\.1" + dotest binfiles2-2 "${testcvs} -q tag -b br" 'T brmod +T brmod-trmod +T brmod-wdmod' + dotest binfiles2-3 "${testcvs} -q update -r br" '' + cp ../binfile binfile.dat + dotest binfiles2-4 "${testcvs} add -kb binfile.dat" \ +"${SPROG} add: scheduling file .binfile\.dat. for addition on branch .br. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cp ../binfl2 brmod + cp ../binfl2 brmod-trmod + cp ../binfl2 brmod-wdmod + dotest binfiles2-5 "${testcvs} -q ci -m br-changes" \ +"$CVSROOT_DIRNAME/first-dir/Attic/binfile\.dat,v <-- binfile\.dat +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod,v <-- brmod +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-wdmod,v <-- brmod-wdmod +new revision: 1\.1\.2\.1; previous revision: 1\.1" + dotest binfiles2-6 "${testcvs} -q update -A" \ +"${SPROG} update: \`binfile\.dat' is no longer in the repository +[UP] brmod +[UP] brmod-trmod +[UP] brmod-wdmod" + dotest_fail binfiles2-7 "test -f binfile.dat" '' + dotest binfiles2-7-brmod "cmp ../binfile brmod" + cp ../binfile3 brmod-trmod + dotest binfiles2-7a "${testcvs} -q ci -m tr-modify" \ +"$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +new revision: 1\.2; previous revision: 1\.1" + cp ../binfile3 brmod-wdmod + + dotest binfiles2-8 "${testcvs} -q update -j br" \ +"U binfile\.dat +U brmod +${SPROG} update: nonmergeable file needs merge +${SPROG} update: revision 1.1.2.1 from repository is now in brmod-trmod +${SPROG} update: file from working directory is now in .#brmod-trmod.1.2 +C brmod-trmod +M brmod-wdmod +${SPROG} update: nonmergeable file needs merge +${SPROG} update: revision 1.1.2.1 from repository is now in brmod-wdmod +${SPROG} update: file from working directory is now in .#brmod-wdmod.1.1 +C brmod-wdmod" + + dotest binfiles2-9 "cmp ../binfile binfile.dat" + dotest binfiles2-9-brmod "cmp ../binfl2 brmod" + dotest binfiles2-9-brmod-trmod "cmp ../binfl2 brmod-trmod" + dotest binfiles2-9-brmod-trmod "cmp ../binfl2 brmod-wdmod" + dotest binfiles2-9a-brmod-trmod "cmp ../binfile3 .#brmod-trmod.1.2" + dotest binfiles2-9a-brmod-wdmod "cmp ../binfile3 .#brmod-wdmod.1.1" + + # Test that everything was properly scheduled. + dotest binfiles2-10 "${testcvs} -q ci -m checkin" \ +"$CVSROOT_DIRNAME/first-dir/binfile\.dat,v <-- binfile\.dat +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod,v <-- brmod +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +new revision: 1\.3; previous revision: 1\.2 +$CVSROOT_DIRNAME/first-dir/brmod-wdmod,v <-- brmod-wdmod +new revision: 1\.2; previous revision: 1\.1" + + dotest_fail binfiles2-o1 "${testcvs} -q admin -o :1.2 brmod-trmod" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v +deleting revision 1\.2 +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v: can't remove branch point 1\.1 +${SPROG} admin: RCS file for .brmod-trmod. not modified\." + dotest binfiles2-o2 "${testcvs} -q admin -o 1.1.2.1: brmod-trmod" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v +deleting revision 1\.1\.2\.1 +done" + dotest binfiles2-o3 "${testcvs} -q admin -o :1.2 brmod-trmod" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v +deleting revision 1\.2 +deleting revision 1\.1 +done" + dotest binfiles2-o4 "${testcvs} -q log -N brmod-trmod" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v +Working file: brmod-trmod +head: 1\.3 +branch: +locks: strict +access list: +keyword substitution: b +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +checkin +=============================================================================" + + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r 1 + ;; + + + + binfiles3) + # More binary file tests, especially removing, adding, &c. + # See "binfiles" for a list of binary file tests. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1; cd 1 + dotest binfiles3-1 "${testcvs} -q co first-dir" '' + ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ + </dev/null | ${TR} '@' '\000' >binfile.dat + cd first-dir + echo hello >file1 + dotest binfiles3-2 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest binfiles3-3 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + rm file1 + dotest binfiles3-4 "${testcvs} rm file1" \ +"${SPROG} remove: scheduling .file1. for removal +${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest binfiles3-5 "${testcvs} -q ci -m remove-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.1" + cp ../binfile.dat file1 + dotest binfiles3-6 "${testcvs} add -kb file1" \ +"$SPROG add: Re-adding file .file1. after dead revision 1\.2\. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + # The idea behind this test is to make sure that the file + # gets opened in binary mode to send to "cvs ci". + dotest binfiles3-6a "cat CVS/Entries" \ +"/file1/0/[A-Za-z0-9 :]*/-kb/ +D" + # TODO: This just tests the case where the old keyword + # expansion mode is the default (RCS_getexpand == NULL + # in checkaddfile()); should also test the case in which + # we are changing it from one non-default value to another. + dotest binfiles3-7 "$testcvs -q ci -m readd-it" \ +"$SPROG commit: changing keyword expansion mode to -kb +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + dotest binfiles3-8 "${testcvs} -q log -h -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.3 +branch: +locks: strict +access list: +keyword substitution: b +total revisions: 3 +=============================================================================" + + # OK, now test admin -o on a binary file. See "admin" + # test for a more complete list of admin -o tests. + cp ${TESTDIR}/1/binfile.dat ${TESTDIR}/1/binfile4.dat + echo '%%$$##@@!!jjiiuull' | ${TR} j '\000' >>${TESTDIR}/1/binfile4.dat + cp ${TESTDIR}/1/binfile4.dat ${TESTDIR}/1/binfile5.dat + echo 'aawwee%$$##@@!!jjil' | ${TR} w '\000' >>${TESTDIR}/1/binfile5.dat + + cp ../binfile4.dat file1 + dotest binfiles3-9 "${testcvs} -q ci -m change" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3" + cp ../binfile5.dat file1 + dotest binfiles3-10 "${testcvs} -q ci -m change" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4" + dotest binfiles3-11 "${testcvs} admin -o 1.3::1.5 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +deleting revision 1\.4 +done" + dotest binfiles3-12 "${testcvs} -q update -r 1.3 file1" "U file1" + dotest binfiles3-13 "cmp file1 ${TESTDIR}/1/binfile.dat" "" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + mcopy) + # See comment at "mwrap" test for list of other wrappers tests. + # Test cvs's ability to handle nonmergeable files specified with + # -m 'COPY' in wrappers. Similar to the binfiles2 test, + # which tests the same thing for binary files + # (which are non-mergeable in the same sense). + # + # Cases (we are merging from the branch to the trunk): + # brmod) File modified on branch, not on trunk. + # File should be copied over to trunk (no merging is needed). + # brmod-trmod) File modified on branch, also on trunk. + # This is a conflict. Present the user with both files and + # let them figure it out. + # brmod-wdmod) File modified on branch, not modified in the trunk + # repository, but modified in the (trunk) working directory. + # This is also a conflict. + + # For the moment, remote CVS can't pass wrappers from CVSWRAPPERS + # (see wrap_send). So skip these tests for remote. + if $remote; then :; else + + mkdir ${CVSROOT_DIRNAME}/first-dir + mkdir 1; cd 1 + dotest mcopy-1 "${testcvs} -q co first-dir" '' + cd first-dir + + # FIXCVS: unless a branch has at least one file on it, + # tag_check_valid won't know it exists. So if brmod didn't + # exist, we would have to invent it. + echo 'brmod initial contents' >brmod + echo 'brmod-trmod initial contents' >brmod-trmod + echo 'brmod-wdmod initial contents' >brmod-wdmod + echo "* -m 'COPY'" >.cvswrappers + dotest mcopy-1a \ +"${testcvs} add .cvswrappers brmod brmod-trmod brmod-wdmod" \ +"${SPROG} add: scheduling file .\.cvswrappers. for addition +${SPROG} add: scheduling file .brmod. for addition +${SPROG} add: scheduling file .brmod-trmod. for addition +${SPROG} add: scheduling file .brmod-wdmod. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest mcopy-1b "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/\.cvswrappers,v <-- \.cvswrappers +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod,v <-- brmod +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-wdmod,v <-- brmod-wdmod +initial revision: 1\.1" + + # NOTE: .cvswrappers files are broken (see comment in + # src/wrapper.c). So doing everything via the environment + # variable is a workaround. Better would be to test them + # both. + CVSWRAPPERS="* -m 'COPY'" + export CVSWRAPPERS + dotest mcopy-2 "${testcvs} -q tag -b br" 'T \.cvswrappers +T brmod +T brmod-trmod +T brmod-wdmod' + dotest mcopy-3 "${testcvs} -q update -r br" '' + echo 'modify brmod on br' >brmod + echo 'modify brmod-trmod on br' >brmod-trmod + echo 'modify brmod-wdmod on br' >brmod-wdmod + dotest mcopy-5 "${testcvs} -q ci -m br-changes" \ +"$CVSROOT_DIRNAME/first-dir/brmod,v <-- brmod +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-wdmod,v <-- brmod-wdmod +new revision: 1\.1\.2\.1; previous revision: 1\.1" + dotest mcopy-6 "${testcvs} -q update -A" \ +"[UP] brmod +[UP] brmod-trmod +[UP] brmod-wdmod" + dotest mcopy-7 "cat brmod brmod-trmod brmod-wdmod" \ +"brmod initial contents +brmod-trmod initial contents +brmod-wdmod initial contents" + + echo 'modify brmod-trmod again on trunk' >brmod-trmod + dotest mcopy-7a "${testcvs} -q ci -m tr-modify" \ +"$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +new revision: 1\.2; previous revision: 1\.1" + echo 'modify brmod-wdmod in working dir' >brmod-wdmod + + dotest mcopy-8 "${testcvs} -q update -j br" \ +"U brmod +${SPROG} update: nonmergeable file needs merge +${SPROG} update: revision 1.1.2.1 from repository is now in brmod-trmod +${SPROG} update: file from working directory is now in .#brmod-trmod.1.2 +C brmod-trmod +M brmod-wdmod +${SPROG} update: nonmergeable file needs merge +${SPROG} update: revision 1.1.2.1 from repository is now in brmod-wdmod +${SPROG} update: file from working directory is now in .#brmod-wdmod.1.1 +C brmod-wdmod" + + dotest mcopy-9 "cat brmod brmod-trmod brmod-wdmod" \ +"modify brmod on br +modify brmod-trmod on br +modify brmod-wdmod on br" + dotest mcopy-9a "cat .#brmod-trmod.1.2 .#brmod-wdmod.1.1" \ +"modify brmod-trmod again on trunk +modify brmod-wdmod in working dir" + + # Test that everything was properly scheduled. + dotest mcopy-10 "${testcvs} -q ci -m checkin" \ +"$CVSROOT_DIRNAME/first-dir/brmod,v <-- brmod +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/brmod-trmod,v <-- brmod-trmod +new revision: 1\.3; previous revision: 1\.2 +$CVSROOT_DIRNAME/first-dir/brmod-wdmod,v <-- brmod-wdmod +new revision: 1\.2; previous revision: 1\.1" + + dokeep + cd ../.. + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -r 1 + unset CVSWRAPPERS + fi # end of tests to be skipped for remote + ;; + + + + binwrap) + # Test the ability to specify binary-ness based on file name. + # See "mwrap" for a list of other wrappers tests. + + mkdir dir-to-import + cd dir-to-import + touch foo.c foo.exe + + # While we're here, test for rejection of duplicate tag names. + dotest_fail binwrap-0 \ + "${testcvs} import -m msg -I ! first-dir dup dup" \ +"${CPROG} \[import aborted\]: tag .dup. was specified more than once" + + if ${testcvs} import -m message -I ! -W "*.exe -k 'b'" \ + first-dir tag1 tag2 >>${LOGFILE}; then + pass binwrap-1 + else + fail binwrap-1 + fi + cd .. + rm -r dir-to-import + dotest binwrap-2 "${testcvs} -q co first-dir" 'U first-dir/foo.c +U first-dir/foo.exe' + dotest binwrap-3 "${testcvs} -q status first-dir" \ +"=================================================================== +File: foo\.c Status: Up-to-date + + Working revision: 1\.1\.1\.1.* + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.c,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: foo\.exe Status: Up-to-date + + Working revision: 1\.1\.1\.1.* + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.exe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + + dokeep + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + binwrap2) + # Test the ability to specify binary-ness based on file name. + # See "mwrap" for a list of other wrappers tests. + + mkdir dir-to-import + cd dir-to-import + touch foo.c foo.exe + + # Specify that all files are binary except *.c. + # The order seems to matter, with the earlier rules taking + # precedence. I'm not sure whether that is good or not, + # but it is the current behavior. + if ${testcvs} import -m message -I ! \ + -W "*.c -k 'o'" -W "* -k 'b'" \ + first-dir tag1 tag2 >>${LOGFILE}; then + pass binwrap2-1 + else + fail binwrap2-1 + fi + cd .. + rm -r dir-to-import + dotest binwrap2-2 "${testcvs} -q co first-dir" 'U first-dir/foo.c +U first-dir/foo.exe' + dotest binwrap2-3 "${testcvs} -q status first-dir" \ +"=================================================================== +File: foo\.c Status: Up-to-date + + Working revision: 1\.1\.1\.1.* + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.c,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -ko + +=================================================================== +File: foo\.exe Status: Up-to-date + + Working revision: 1\.1\.1\.1.* + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.exe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb" + + dokeep + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + binwrap3) + # Test communication of file-specified -k wrappers between + # client and server, in `import': + # + # 1. Set up a directory tree, populate it with files. + # 2. Give each directory a different .cvswrappers file. + # 3. Give the server its own .cvswrappers file. + # 4. Import the whole tree, see if the right files got set + # to binary. + # + # The tree has a top ("0th") level, and two subdirs, sub1/ + # and sub2/; sub2/ contains directory subsub/. Every + # directory has a .cvswrappers file as well as regular + # files. + # + # In the file names, "foo-b.*" should end up binary, and + # "foo-t.*" should end up text. Don't worry about the two + # letter extensions; they're just there to help me keep + # things straight. + # + # Here's the directory tree: + # + # ./ + # .cvswrappers + # foo-b.c0 + # foo-b.sb + # foo-t.c1 + # foo-t.st + # + # sub1/ sub2/ + # .cvswrappers .cvswrappers + # foo-b.c1 foo-b.sb + # foo-b.sb foo-b.st + # foo-t.c0 foo-t.c0 + # foo-t.st foo-t.c1 + # foo-t.c2 + # foo-t.c3 + # + # subsub/ + # .cvswrappers + # foo-b.c3 + # foo-b.sb + # foo-t.c0 + # foo-t.c1 + # foo-t.c2 + # foo-t.st + + binwrap3_line1="This is a test file " + binwrap3_line2="containing little of use " + binwrap3_line3="except this non-haiku" + + binwrap3_text="${binwrap3_line1}${binwrap3_line2}${binwrap3_line3}" + + cd ${TESTDIR} + + # On Windows, we can't check out CVSROOT, because the case + # insensitivity means that this conflicts with cvsroot. + mkdir wnt + cd wnt + + mkdir binwrap3 # the 0th dir + mkdir binwrap3/sub1 + mkdir binwrap3/sub2 + mkdir binwrap3/sub2/subsub + + echo "bar*" > binwrap3/.cvswrappers + echo "*.c0 -k 'b'" >> binwrap3/.cvswrappers + echo "whatever -k 'b'" >> binwrap3/.cvswrappers + echo ${binwrap3_text} > binwrap3/foo-b.c0 + echo ${binwrap3_text} > binwrap3/bar-t.c0 + echo ${binwrap3_text} > binwrap3/foo-b.sb + echo ${binwrap3_text} > binwrap3/foo-t.sb + echo ${binwrap3_text} > binwrap3/foo-t.c1 + echo ${binwrap3_text} > binwrap3/foo-t.st + + echo "bar* -k 'kv'" > binwrap3/sub1/.cvswrappers + echo "*.c1 -k 'b'" >> binwrap3/sub1/.cvswrappers + echo "whatever -k 'b'" >> binwrap3/sub1/.cvswrappers + echo ${binwrap3_text} > binwrap3/sub1/foo-b.c1 + echo ${binwrap3_text} > binwrap3/sub1/bar-t.c1 + echo ${binwrap3_text} > binwrap3/sub1/foo-b.sb + echo ${binwrap3_text} > binwrap3/sub1/foo-t.sb + echo ${binwrap3_text} > binwrap3/sub1/foo-t.c0 + echo ${binwrap3_text} > binwrap3/sub1/foo-t.st + + echo "bar*" > binwrap3/sub2/.cvswrappers + echo "*.st -k 'b'" >> binwrap3/sub2/.cvswrappers + echo ${binwrap3_text} > binwrap3/sub2/foo-b.sb + echo ${binwrap3_text} > binwrap3/sub2/foo-t.sb + echo ${binwrap3_text} > binwrap3/sub2/foo-b.st + echo ${binwrap3_text} > binwrap3/sub2/bar-t.st + echo ${binwrap3_text} > binwrap3/sub2/foo-t.c0 + echo ${binwrap3_text} > binwrap3/sub2/foo-t.c1 + echo ${binwrap3_text} > binwrap3/sub2/foo-t.c2 + echo ${binwrap3_text} > binwrap3/sub2/foo-t.c3 + + echo "bar* -k 'kv'" > binwrap3/sub2/subsub/.cvswrappers + echo "*.c3 -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers + echo "foo -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers + echo "c0* -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers + echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-b.c3 + echo ${binwrap3_text} > binwrap3/sub2/subsub/bar-t.c3 + echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-b.sb + echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.sb + echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c0 + echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c1 + echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c2 + echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.st + + # Now set up CVSROOT/cvswrappers, the easy way: + dotest binwrap3-1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" + cd CVSROOT + # This destroys anything currently in cvswrappers, but + # presumably other tests will take care of it themselves if + # they use cvswrappers: + echo "foo-t.sb" > cvswrappers + echo "foo*.sb -k 'b'" >> cvswrappers + dotest binwrap3-2 "${testcvs} -q ci -m cvswrappers-mod" \ +"$CVSROOT_DIRNAME/CVSROOT/cvswrappers,v <-- cvswrappers +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + + # Avoid environmental interference + CVSWRAPPERS_save=${CVSWRAPPERS} + unset CVSWRAPPERS + + # Do the import + cd binwrap3 + # Not importing .cvswrappers tests whether the client is really + # letting the server know "honestly" whether the file is binary, + # rather than just letting the server see the .cvswrappers file. + dotest binwrap3-2a \ +"${testcvs} import -m . -I .cvswrappers binwrap3 tag1 tag2" \ +"[NI] ${DOTSTAR}" + + # OK, now test "cvs add". + cd .. + rm -r binwrap3 + dotest binwrap3-2b "${testcvs} co binwrap3" "${DOTSTAR}" + cd binwrap3 + cd sub2 + echo "*.newbin -k 'b'" > .cvswrappers + echo .cvswrappers >.cvsignore + echo .cvsignore >>.cvsignore + touch file1.newbin file1.txt + dotest binwrap3-2c "${testcvs} add file1.newbin file1.txt" \ +"${SPROG} add: scheduling file .file1\.newbin. for addition +${SPROG} add: scheduling file .file1\.txt. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest binwrap3-2d "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/binwrap3/sub2/file1\.newbin,v <-- file1\.newbin +initial revision: 1\.1 +$CVSROOT_DIRNAME/binwrap3/sub2/file1\.txt,v <-- file1\.txt +initial revision: 1\.1" + cd .. + + # Now check out the module and see which files are binary. + cd .. + rm -r binwrap3 + dotest binwrap3-3 "${testcvs} co binwrap3" "${DOTSTAR}" + cd binwrap3 + + # Running "cvs status" and matching output is too + # error-prone, too likely to falsely fail. Instead, we'll + # just grep the Entries lines: + + dotest binwrap3-top1 "grep foo-b.c0 ./CVS/Entries" \ + "/foo-b.c0/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-top2 "grep foo-b.sb ./CVS/Entries" \ + "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-top3 "grep foo-t.c1 ./CVS/Entries" \ + "/foo-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-top4 "grep foo-t.st ./CVS/Entries" \ + "/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-top5 "grep foo-t.sb ./CVS/Entries" \ + "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-top6 "grep bar-t.c0 ./CVS/Entries" \ + "/bar-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub1-1 "grep foo-b.c1 sub1/CVS/Entries" \ + "/foo-b.c1/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-sub1-2 "grep foo-b.sb sub1/CVS/Entries" \ + "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-sub1-3 "grep foo-t.c0 sub1/CVS/Entries" \ + "/foo-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub1-4 "grep foo-t.st sub1/CVS/Entries" \ + "/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub1-5 "grep foo-t.sb sub1/CVS/Entries" \ + "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub1-6 "grep bar-t.c1 sub1/CVS/Entries" \ + "/bar-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub2-1 "grep foo-b.sb sub2/CVS/Entries" \ + "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-sub2-2 "grep foo-b.st sub2/CVS/Entries" \ + "/foo-b.st/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-sub2-3 "grep foo-t.c0 sub2/CVS/Entries" \ + "/foo-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub2-4 "grep foo-t.c1 sub2/CVS/Entries" \ + "/foo-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub2-5 "grep foo-t.c2 sub2/CVS/Entries" \ + "/foo-t.c2/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub2-6 "grep foo-t.c3 sub2/CVS/Entries" \ + "/foo-t.c3/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub2-7 "grep foo-t.sb sub2/CVS/Entries" \ + "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub2-8 "grep bar-t.st sub2/CVS/Entries" \ + "/bar-t.st/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-subsub1 "grep foo-b.c3 sub2/subsub/CVS/Entries" \ + "/foo-b.c3/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-subsub2 "grep foo-b.sb sub2/subsub/CVS/Entries" \ + "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" + + dotest binwrap3-subsub3 "grep foo-t.c0 sub2/subsub/CVS/Entries" \ + "/foo-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-subsub4 "grep foo-t.c1 sub2/subsub/CVS/Entries" \ + "/foo-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-subsub5 "grep foo-t.c2 sub2/subsub/CVS/Entries" \ + "/foo-t.c2/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-subsub6 "grep foo-t.st sub2/subsub/CVS/Entries" \ + "/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-subsub7 "grep foo-t.sb sub2/subsub/CVS/Entries" \ + "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-subsub8 "grep bar-t.c3 sub2/subsub/CVS/Entries" \ + "/bar-t.c3/1.1.1.1/[A-Za-z0-9 :]*//" + + dotest binwrap3-sub2-add1 "grep file1.newbin sub2/CVS/Entries" \ + "/file1.newbin/1.1/[A-Za-z0-9 :]*/-kb/" + dotest binwrap3-sub2-add2 "grep file1.txt sub2/CVS/Entries" \ + "/file1.txt/1.1/[A-Za-z0-9 :]*//" + + # Restore and clean up + dokeep + cd .. + rm -r binwrap3 CVSROOT + cd .. + rm -r wnt + modify_repo rm -rf $CVSROOT_DIRNAME/binwrap3 + CVSWRAPPERS=${CVSWRAPPERS_save} + ;; + + + + mwrap) + # Tests of various wrappers features: + # -m 'COPY' and cvs update: mwrap + # -m 'COPY' and joining: mcopy + # -k: binwrap, binwrap2 + # -t/-f: hasn't been written yet. + # + # Tests of different ways of specifying wrappers: + # CVSROOT/cvswrappers: mwrap + # -W: binwrap, binwrap2 + # .cvswrappers in working directory, local: mcopy + # CVSROOT/cvswrappers, .cvswrappers remote: binwrap3 + # CVSWRAPPERS environment variable: mcopy + + # This test is similar to binfiles-con1; -m 'COPY' specifies + # non-mergeableness the same way that -kb does. + + # On Windows, we can't check out CVSROOT, because the case + # insensitivity means that this conflicts with cvsroot. + mkdir wnt + cd wnt + + dotest mwrap-c1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" + cd CVSROOT + echo "* -m 'COPY'" >>cvswrappers + dotest mwrap-c2 "${testcvs} -q ci -m wrapper-mod" \ +"$CVSROOT_DIRNAME/CVSROOT/cvswrappers,v <-- cvswrappers +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + mkdir m1; cd m1 + dotest mwrap-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest mwrap-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch aa + dotest mwrap-3 "${testcvs} add aa" \ +"${SPROG} add: scheduling file .aa. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest mwrap-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +initial revision: 1\.1" + cd ../.. + mkdir m2; cd m2 + dotest mwrap-5 "${testcvs} -q co first-dir" "U first-dir/aa" + cd first-dir + echo "changed in m2" >aa + dotest mwrap-6 "${testcvs} -q ci -m m2-mod" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +new revision: 1\.2; previous revision: 1\.1" + cd ../.. + cd m1/first-dir + echo "changed in m1" >aa + dotest mwrap-7 "$testcvs -nq update" \ +"$SPROG update: nonmergeable file needs merge +$SPROG update: revision 1\.2 from repository is now in aa +$SPROG update: file from working directory is now in \.#aa\.1\.1 +C aa" + dotest mwrap-8 "$testcvs -q update" \ +"$SPROG update: nonmergeable file needs merge +$SPROG update: revision 1\.2 from repository is now in aa +$SPROG update: file from working directory is now in \.#aa\.1\.1 +C aa" + dotest mwrap-9 "cat aa" "changed in m2" + dotest mwrap-10 "cat .#aa.1.1" "changed in m1" + + dokeep + restore_adm + cd ../.. + rm -r CVSROOT + rm -r m1 m2 + cd .. + rm -r wnt + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + info) + # Administrative file tests. + # Here is a list of where each administrative file is tested: + # loginfo: info + # modules: modules, modules2, modules3 + # cvsignore: ignore + # verifymsg: info + # cvswrappers: mwrap + # taginfo: taginfo + # posttag: posttag + # postadmin: admin + # postwatch: devcom3 + # config: config + # config2: MinCompressionLevel and MaxCompressionLevel in config + + # On Windows, we can't check out CVSROOT, because the case + # insensitivity means that this conflicts with cvsroot. + mkdir wnt + cd wnt + + dotest info-1 "$testcvs -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" + cd CVSROOT + dotest info-2 "$testcvs -Q tag info-start" + sed -e's/%p/ALL/' <loginfo >tmploginfo + mv tmploginfo loginfo + echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$COMMITID=\$SESSIONID=\$CVSROOT= >>$TESTDIR/testlog; cat >/dev/null\"" >> loginfo + # The following cases test the format string substitution + echo "ALL echo %{} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %x >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo % >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %{sxVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %s %s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "first-dir echo %sux >>$TESTDIR/testlog2; cat >/dev/null" \ + >> loginfo + sed -e's/^UseNewInfoFmtStrings=yes$/#&/' <config >tmpconfig + mv tmpconfig config + + # Might be nice to move this to crerepos tests; it should + # work to create a loginfo file if you didn't create one + # with "cvs init". + : dotest info-2 "$testcvs add loginfo" \ +"$SPROG add: scheduling file \`loginfo' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + + dotest_fail info-3 "$testcvs -q ci -m new-loginfo" \ +"$TESTDIR/cvsroot/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$CVSROOT_DIRNAME/CVSROOT/loginfo,v <-- loginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database +$SPROG commit: loginfo:[0-9]*: no such user variable \${=MYENV} +$SPROG \[commit aborted\]: Unknown format character in info file (''). +Info files are the hook files, verifymsg, taginfo, commitinfo, etc\." + cd .. + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest info-5 "$testcvs -q co first-dir" '' + cd first-dir + touch file1 + dotest info-6 "$testcvs add file1" \ +"$SPROG add: scheduling file \`file1' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc + dotest info-6b "$testcvs -q -s OTHER=value ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$SPROG commit: loginfo:[0-9]*: no such user variable \${=ZEE} +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary .1. in +all info files after each .%. which doesn.t represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary .1. in +all info files after each .%. which doesn.t represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\. +$SPROG commit: loginfo:[0-9]*: no such user variable \${=ZEE}" + echo line0 >>file1 + dotest info-6c "$testcvs -q -sOTHER=foo ci -m mod-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +$SPROG commit: loginfo:[0-9]*: no such user variable \${=ZEE} +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary .1. in +all info files after each .%. which doesn.t represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary .1. in +all info files after each .%. which doesn.t represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\. +$SPROG commit: loginfo:[0-9]*: no such user variable \${=ZEE}" + echo line1 >>file1 + dotest info-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2 +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary .1. in +all info files after each .%. which doesn.t represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." + + cd .. + dotest info-9 "cat $TESTDIR/testlog" \ +"xenv-valueyz=${username}=${commitid}=${commitid}=${CVSROOT_DIRNAME}=" + dotest info-10 "cat $TESTDIR/testlog2" \ +'first-dir +first-dir +first-dir +first-dir file1,,NONE,1.1 +first-dir 1.1 +first-dir file1 %s +first-dir NONEAX +first-dir file1ux +first-dir +first-dir +first-dir +first-dir file1,,1.1,1.2 +first-dir 1.2 +first-dir file1 %s +first-dir 1.1AX +first-dir file1ux +first-dir +first-dir +first-dir +first-dir file1,,1.2,1.3 +first-dir 1.3 +first-dir file1 %s +first-dir 1.2AX +first-dir file1ux' + + # and make sure adding a '1' in the format strings really does ensure + # ensure backwards compatibility. + # + # these tests are identical to the above except for the loginfo setup + # and the project name + cd CVSROOT + dotest info-setup-intfmt-1 "$testcvs -q up -prinfo-start config >config" + dotest info-setup-intfmt-2 "$testcvs -q up -prinfo-start loginfo >loginfo" + sed -e's/%p/ALL/' <loginfo >tmploginfo + mv tmploginfo loginfo + echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$CVSROOT= >>$TESTDIR/testlog; cat >/dev/null\"" >> loginfo + # The following cases test the format string substitution + echo "ALL echo %1{} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %1x >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %1 >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %1{sxVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %1{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %1s %%s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %1{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "third-dir echo %1sux >>$TESTDIR/testlog2; cat >/dev/null" \ + >> loginfo + + dotest info-setup-intfmt-2 "${testcvs} -q -s ZEE=garbage ci -m nuke-admin-for-info-intfmt" \ +"$TESTDIR/cvsroot/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$TESTDIR/cvsroot/CVSROOT/loginfo,v <-- loginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary .1. in +all info files after each .%. which doesn.t represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." + cd .. + + # delete the logs now so the results look more like the last tests + # (they won't include the config file update) + rm ${TESTDIR}/testlog ${TESTDIR}/testlog2 + + modify_repo mkdir $CVSROOT_DIRNAME/third-dir + dotest info-intfmt-5 "${testcvs} -q co third-dir" '' + cd third-dir + touch file1 + dotest info-intfmt-6 "${testcvs} add file1" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc + dotest info-intfmt-6b "${testcvs} -q -s OTHER=value ci -m add-it" \ +"${TESTDIR}/cvsroot/third-dir/file1,v <-- file1 +initial revision: 1\.1 +${SPROG} commit: loginfo:[0-9]*: no such user variable \${=ZEE} +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\." + echo line0 >>file1 + dotest info-intfmt-6c "${testcvs} -q -sOTHER=foo ci -m mod-it" \ +"${TESTDIR}/cvsroot/third-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +${SPROG} commit: loginfo:[0-9]*: no such user variable \${=ZEE} +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\." + echo line1 >>file1 + dotest info-intfmt-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \ +"${TESTDIR}/cvsroot/third-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2 +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\. +${SPROG} commit: Using deprecated info format strings\. Convert your scripts to use +the new argument format and remove '1's from your info file format strings\." + + cd .. + dotest info-intfmt-9 "cat $TESTDIR/testlog" "xenv-valueyz=${username}=${TESTDIR}/cvsroot=" + dotest info-intfmt-10 "cat $TESTDIR/testlog2" \ +'third-dir +third-dir +third-dir +third-dir file1,,NONE,1.1 +third-dir 1.1 +third-dir file1 %s +third-dir NONEAX +third-dir file1ux +third-dir +third-dir +third-dir +third-dir file1,,1.1,1.2 +third-dir 1.2 +third-dir file1 %s +third-dir 1.1AX +third-dir file1ux +third-dir +third-dir +third-dir +third-dir file1,,1.2,1.3 +third-dir 1.3 +third-dir file1 %s +third-dir 1.2AX +third-dir file1ux' + + rm ${TESTDIR}/testlog ${TESTDIR}/testlog2 + + # test the new format strings too + cd CVSROOT + dotest info-setup-newfmt-1 "$testcvs -q up -prinfo-start loginfo >loginfo" + echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$CVSROOT= >>$TESTDIR/testlog; cat >/dev/null\" %{sVv}" >> loginfo + # The following cases test the format string substitution + echo "ALL echo %p \"%{sTVv}\" >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "ALL echo %{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "second-dir echo %sux >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + dotest info-setup-newfmt-2 "$testcvs -q -s ZEE=garbage ci -m nuke-admin-for-info-newfmt" \ +"${CVSROOT_DIRNAME}/CVSROOT/loginfo,v <-- loginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +${SPROG} commit: Rebuilding administrative file database" + cd .. + + # delete the logs now so the results look more like the last tests + # (they won't include the config file update) + rm ${TESTDIR}/testlog ${TESTDIR}/testlog2 + + modify_repo mkdir $CVSROOT_DIRNAME/fourth-dir + dotest info-newfmt-1 "${testcvs} -q co fourth-dir" '' + cd fourth-dir + touch file1 + dotest info-newfmt-2 "${testcvs} add file1" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc + dotest info-newfmt-3 "$testcvs -q -s OTHER=value ci -m add-it" \ +"$TESTDIR/cvsroot/fourth-dir/file1,v <-- file1 +initial revision: 1\.1 +$SPROG commit: loginfo:[0-9]*: no such user variable \${=ZEE}" + echo line0 >>file1 + dotest info-newfmt-4 "$testcvs -q -sOTHER=foo ci -m mod-it" \ +"$TESTDIR/cvsroot/fourth-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +$SPROG commit: loginfo:[0-9]*: no such user variable \${=ZEE}" + echo line1 >>file1 + dotest info-newfmt-5 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \ +"${TESTDIR}/cvsroot/fourth-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + + cd .. + dotest info-newfmt-6 "cat $TESTDIR/testlog" \ +"xenv-valueyz=${username}=${TESTDIR}/cvsroot=" + dotest info-newfmt-7 "cat $TESTDIR/testlog2" \ +'fourth-dir file1 NONE 1\.1 +1\.1 +file1 +NONEAX +fourth-dir file1 1\.1 1\.2 +1\.2 +file1 +1\.1AX +fourth-dir file1 1\.2 1\.3 +1\.3 +file1 +1\.2AX' + + # clean up after newfmt tests + cd CVSROOT + dotest info-cleanup-newfmt-1 "$testcvs -q up -prinfo-start loginfo >loginfo" + dotest info-cleanup-newfmt-2 "$testcvs -q ci -m nuke-loginfo" \ +"$CVSROOT_DIRNAME/CVSROOT/loginfo,v <-- loginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + # clean up the logs + rm ${TESTDIR}/testlog ${TESTDIR}/testlog2 + + # Now test verifymsg + cat >${TESTDIR}/vscript <<EOF +#!${TESTSHELL} +echo vscript "\$@" +if sed 1q < \$1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then + exit 0 +elif sed 1q < \$1 | grep '^BugId:[ ]*new$' > /dev/null; then + echo A new bugid was found. >> \$1 + exit 0 +else + echo "No BugId found." + sleep 1 + exit 1 +fi +EOF + cat >${TESTDIR}/vscript2 <<EOF +#!${TESTSHELL} +echo vscript2 "\$@" +if test -f CVS/Repository; then + repo=\`cat CVS/Repository\` +else + repo=\`pwd\` +fi +echo \$repo +if echo "\$repo" |grep yet-another/ >/dev/null 2>&1; then + exit 1 +else + exit 0 +fi +EOF + # Grumble, grumble, mumble, search for "Cygwin". + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x ${TESTDIR}/vscript*" + else + chmod +x ${TESTDIR}/vscript* + fi + echo "^first-dir/yet-another\\(/\\|\$\\) ${TESTDIR}/vscript2 %l %{sV}" >verifymsg + echo "^first-dir\\(/\\|\$\\) ${TESTDIR}/vscript %l %{sV}" >>verifymsg + echo "^missing-script\$ ${TESTDIR}/bogus %l" >>verifymsg + echo "^missing-var\$ ${TESTDIR}/vscript %l \${=Bogus}" >>verifymsg + # first test the directory independant verifymsg + dotest info-v1 "${testcvs} -q ci -m add-verification" \ +"$CVSROOT_DIRNAME/CVSROOT/verifymsg,v <-- verifymsg +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd ../first-dir + echo line2 >>file1 + dotest_fail info-v2 "${testcvs} -q ci -m bogus" \ +"vscript $tempname file1 1\.3 +No BugId found\. +${SPROG} \[commit aborted\]: Message verification failed" + + cat >${TESTDIR}/comment.tmp <<EOF +BugId: 42 +and many more lines after it +EOF + dotest info-v3 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \ +"vscript $tempname file1 1\.3 +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3" + rm ${TESTDIR}/comment.tmp + + cd .. + mkdir another-dir + cd another-dir + touch file2 + dotest_fail info-v4 \ + "${testcvs} import -m bogus first-dir/another x y" \ +"vscript $tempname - Imported sources NONE +No BugId found\. +${SPROG} \[import aborted\]: Message verification failed" + + # now verify that directory dependent verifymsgs work + dotest info-v5 \ + "${testcvs} import -m bogus first-dir/yet-another x y" \ +"vscript2 $tempname - Imported sources NONE +$TESTDIR/wnt/another-dir +N first-dir/yet-another/file2 + +No conflicts created by this import" \ +"vscript2 $tempname - Imported sources NONE +$CVSROOT_DIRNAME/first-dir/yet-another +N first-dir/yet-another/file2 + +No conflicts created by this import" + + # FIXCVS + # + # note that in the local case the error message is the same as + # info-v5 + # + # This means that the verifymsg scripts cannot reliably and + # consistantly obtain information on which directory is being + # committed to. Thus it is currently useless for them to be + # running in every dir. They should either be run once or + # directory information should be passed. + if $remote; then + dotest_fail info-v6r \ + "${testcvs} import -m bogus first-dir/yet-another/and-another x y" \ +"vscript2 $tempname - Imported sources NONE +$CVSROOT_DIRNAME/first-dir/yet-another/and-another +$SPROG \[import aborted\]: Message verification failed" + else + dotest info-v6 \ + "${testcvs} import -m bogus first-dir/yet-another/and-another x y" \ +"vscript2 $tempname - Imported sources NONE +$TESTDIR/wnt/another-dir +N first-dir/yet-another/and-another/file2 + +No conflicts created by this import" + fi + + # check that errors invoking the script cause verification failure + # + # The second text below occurs on Cygwin, where I assume execvp + # does not return to let CVS print the error message when its + # argument does not exist. + dotest_fail info-v7 "${testcvs} import -m bogus missing-script x y" \ +"${SPROG} import: cannot exec ${TESTDIR}/bogus: No such file or directory +${SPROG} \[import aborted\]: Message verification failed" \ +"${SPROG} \[import aborted\]: Message verification failed" + + dotest_fail info-v8 "${testcvs} import -m bogus missing-var x y" \ +"${SPROG} import: verifymsg:4: no such user variable \${=Bogus} +${SPROG} \[import aborted\]: Message verification failed" + + rm file2 + cd .. + rmdir another-dir + + cd CVSROOT + echo "RereadLogAfterVerify=always" >>config + dotest info-rereadlog-1 "${testcvs} -q ci -m add-RereadLogAfterVerify=always" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../first-dir + echo line3 >>file1 + cat >${TESTDIR}/comment.tmp <<EOF +BugId: new +See what happens next. +EOF + dotest info-reread-2 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \ +"vscript $tempname file1 1\.4 +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4" + dotest info-reread-3 "${testcvs} -q log -N -r1.5 file1" " +.* +BugId: new +See what happens next. +A new bugid was found. +=============================================================================" + + cd ../CVSROOT + grep -v "RereadLogAfterVerify" config > config.new + mv config.new config + echo "RereadLogAfterVerify=stat" >>config + dotest info-reread-4 \ +"$testcvs -q ci -m add-RereadLogAfterVerify=stat" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../first-dir + echo line4 >>file1 + cat >${TESTDIR}/comment.tmp <<EOF +BugId: new +See what happens next with stat. +EOF + dotest info-reread-5 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \ +"vscript $tempname file1 1\.5 +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.6; previous revision: 1\.5" + dotest info-reread-6 "${testcvs} -q log -N -r1.6 file1" " +.* +BugId: new +See what happens next with stat. +A new bugid was found. +=============================================================================" + + cd ../CVSROOT + grep -v "RereadLogAfterVerify" config > config.new + mv config.new config + echo "RereadLogAfterVerify=never" >>config + dotest info-reread-7 \ +"$testcvs -q ci -m add-RereadLogAfterVerify=never" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../first-dir + echo line5 >>file1 + cat >${TESTDIR}/comment.tmp <<EOF +BugId: new +See what happens next. +EOF + dotest info-reread-8 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \ +"vscript $tempname file1 1\.6 +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.7; previous revision: 1\.6" + dotest info-reread-6 "${testcvs} -q log -N -r1.7 file1" " +.* +BugId: new +See what happens next. +=============================================================================" + + cd ../CVSROOT + dotest info-reread-cleanup-1 "$testcvs -q up -prinfo-start config >config" + # Append the NULL format string until we remove the deprecation + # warning for lack of format strings. + echo 'DEFAULT false %n' >verifymsg + echo 'DEFAULT true %n' >>verifymsg + dotest info-multdef "${testcvs} -q ci -m multdef" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$CVSROOT_DIRNAME/CVSROOT/verifymsg,v <-- verifymsg +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd ../CVSROOT + dotest info-reread--cleanup-1 \ +"$testcvs -q up -prinfo-start verifymsg >verifymsg" + dotest info-cleanup-verifymsg "$testcvs -q ci -m nuke-verifymsg" \ +"$SPROG commit: Multiple .DEFAULT. lines (1 and 2) in verifymsg file +$CVSROOT_DIRNAME/CVSROOT/verifymsg,v <-- verifymsg +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + dokeep + rm ${TESTDIR}/vscript* + cd .. + + dotest info-cleanup-0 "$testcvs -n release -d CVSROOT" \ +"You have \[0\] altered files in this repository\." + + dotest info-cleanup-1 \ +"echo yes |${testcvs} -q release -d CVSROOT >/dev/null" + dotest info-cleanup-2 \ +"echo yes |${testcvs} -q release -d first-dir >/dev/null" + dotest info-cleanup-3 \ +"echo yes |${testcvs} -q release -d third-dir >/dev/null" + dotest info-cleanup-4 \ +"echo yes |${testcvs} -q release -d fourth-dir >/dev/null" + + dokeep + cd .. + rm -r wnt + rm $HOME/.cvsrc + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/third-dir \ + $CVSROOT_DIRNAME/fourth-dir + ;; + + + + taginfo) + # Tests of the CVSROOT/taginfo file. See the comment at the + # "info" tests for a full list of administrative file tests. + + # all the oldfmt stuff can come out once we finish deprecating + # the old info file command line format stuff. + # + # grep the code for SUPPORT_OLD_INFO_FMT_STRINGS and see the stuff + # in configure.in about oldinfoformatsupport + + mkdir 1; cd 1 + dotest taginfo-init-1 "$testcvs -q co CVSROOT" "U CVSROOT/$DOTSTAR" + cd CVSROOT + dotest taginfo-init-2 "$testcvs -Q tag taginfo-start" + cat >$TESTDIR/1/loggit <<EOF +#!$TESTSHELL +if test "\$1" = rejectme; then + exit 1 +else + echo "\$@" >>$TESTDIR/1/taglog + exit 0 +fi +EOF + # #^@&!^@ Cygwin. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x ${TESTDIR}/1/loggit" + else + chmod +x ${TESTDIR}/1/loggit + fi + echo "ALL ${TESTDIR}/1/loggit" >>taginfo + sed -e's/^UseNewInfoFmtStrings=yes$/#&/' <config >tmpconfig + mv tmpconfig config + sed -e's/%p/ALL/' <loginfo >tmploginfo + mv tmploginfo loginfo + dotest taginfo-2 "${testcvs} -q ci -m check-in-taginfo" \ +"$TESTDIR/cvsroot/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$CVSROOT_DIRNAME/CVSROOT/loginfo,v <-- loginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$CVSROOT_DIRNAME/CVSROOT/taginfo,v <-- taginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + + # taginfo-3 used to rely on the top-level CVS directory + # being created to add "first-dir" to the repository. Since + # that won't happen anymore, we create the directory in the + # repository. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest taginfo-3 "$testcvs -q co first-dir" + + cd first-dir + echo first >file1 + dotest taginfo-4 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest taginfo-5 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary '1' in +all info files after each '%' which doesn't represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." + dotest taginfo-6 "${testcvs} -q tag tag1" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\. +T file1" + dotest taginfo-7 "${testcvs} -q tag -b br" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\. +T file1" + dotest taginfo-8 "$testcvs -q update -r br" + echo add text on branch >>file1 + dotest taginfo-9 "${testcvs} -q ci -m modify-on-br" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary '1' in +all info files after each '%' which doesn't represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." + dotest taginfo-10 "${testcvs} -q tag -F -c brtag" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\. +T file1" + + dotest_fail taginfo-11 "${testcvs} -q tag rejectme" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\. +${SPROG} tag: Pre-tag check failed +${SPROG} \[tag aborted\]: correct the above errors first!" + + # When we are using taginfo to allow/disallow, it would be + # convenient to be able to use "cvs -n tag" to test whether + # the allow/disallow functionality is working as expected. + dotest taginfo-12 "${testcvs} -nq tag rejectme" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\. +T file1" + + # But when taginfo is used for logging, it is a pain for -n + # to call taginfo, since taginfo doesn't know whether -n was + # specified or not. + dotest taginfo-13 "${testcvs} -nq tag would-be-tag" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\. +T file1" + + # Deleting: the cases are basically either the tag existed, + # or it didn't exist. + dotest taginfo-14 "${testcvs} -q tag -d tag1" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\. +D file1" + dotest taginfo-15 "${testcvs} -q tag -d tag1" \ +"${SPROG} tag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\." + + # Likewise with rtag. + dotest taginfo-16 "${testcvs} -q rtag tag1 first-dir" \ +"${SPROG} rtag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\." + dotest taginfo-17 "${testcvs} -q rtag -d tag1 first-dir" \ +"${SPROG} rtag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\." + dotest taginfo-18 "${testcvs} -q rtag -d tag1 first-dir" \ +"${SPROG} rtag: warning: taginfo line contains no format strings: + \"${TESTDIR}/1/loggit\" +Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this +usage is deprecated\." + + # The "br" example should be passing 1.1.2 or 1.1.0.2. + # But it turns out that is very hard to implement, since + # check_fileproc doesn't know what branch number it will + # get. Probably the whole thing should be re-architected + # so that taginfo only allows/denies tagging, and a new + # hook, which is done from tag_fileproc, does logging. + # That would solve this, some more subtle races, and also + # the fact that it is nice for users to run "-n tag foo" to + # see whether a tag would be allowed. Failing that, + # I suppose passing "1.1.branch" or "branch" for "br" + # would be an improvement. + dotest taginfo-examine-1 "cat ${TESTDIR}/1/taglog" \ +"tag1 add first-dir file1 1\.1 +br add first-dir file1 1\.1 +brtag mov first-dir file1 1\.1\.2\.1 +tag1 del first-dir file1 1\.1 +tag1 del first-dir +tag1 add first-dir file1 1\.1 +tag1 del first-dir file1 1\.1 +tag1 del first-dir" + + # now that we've tested the default operation, try a new + # style fmt string. + rm $TESTDIR/1/taglog + cd .. + cd CVSROOT + dotest taginfo-newfmt-init-1 \ +"$testcvs -q up -prtaginfo-start taginfo >taginfo" + echo "ALL $TESTDIR/1/loggit %r %t %o %b %p %{sTVv}" >>taginfo + dotest taginfo-newfmt-init-2 "$testcvs -q ci -m check-in-taginfo" \ +"$TESTDIR/cvsroot/CVSROOT/taginfo,v <-- taginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" \ +"$TESTDIR/cvsroot/CVSROOT/taginfo,v <-- taginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary '1' in +all info files after each '%' which doesn't represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." + + cat >${TESTDIR}/1/loggit <<EOF +#!${TESTSHELL} +if test "\$1" = rejectme; then + exit 1 +else + while test "\$#" -gt 0; do + echo "\$1" >>${TESTDIR}/1/taglog + shift + done + exit 0 +fi +EOF + + cd .. + cd first-dir + dotest taginfo-newfmt-2 "${testcvs} -q update -A" "[UP] file1" + echo "bull pucky" >'file 2' + dotest taginfo-newfmt-2b "${testcvs} add 'file 2'" \ +"${SPROG} add: scheduling file .file 2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest taginfo-newfmt-2c "$testcvs -q ci -m add-it" \ +"$TESTDIR/cvsroot/first-dir/file 2,v <-- file 2 +initial revision: 1\.1" \ +"$TESTDIR/cvsroot/first-dir/file 2,v <-- file 2 +initial revision: 1\.1 +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary '1' in +all info files after each '%' which doesn't represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." + + dotest taginfo-newfmt-3 "${testcvs} -q tag tag1" \ +"T file 2 +T file1" + dotest taginfo-newfmt-4 "${testcvs} -q tag tag3" \ +"T file 2 +T file1" + dotest taginfo-newfmt-5 "$testcvs -q tag -rtag1 tag4" \ +"T file 2 +T file1" + + dotest taginfo-newfmt-examine-1 "cat ${TESTDIR}/1/taglog" \ +"$TESTDIR/cvsroot +tag1 +add +N +first-dir +file 2 + +NONE +1\.1 +file1 + +NONE +1\.1 +$TESTDIR/cvsroot +tag3 +add +N +first-dir +file 2 + +NONE +1\.1 +file1 + +NONE +1\.1 +$TESTDIR/cvsroot +tag4 +add +N +first-dir +file 2 +tag1 +NONE +1\.1 +file1 +tag1 +NONE +1\.1" + + # now update to use the new format strings (really, disable support + # of the old format) and run the whole gamut of tests again. + rm ${TESTDIR}/1/taglog + cd .. + cd CVSROOT + cat >${TESTDIR}/1/loggit <<EOF +#!${TESTSHELL} +if test "\$1" = rejectme; then + exit 1 +else + echo "\$@" >>${TESTDIR}/1/taglog + exit 0 +fi +EOF + dotest taginfo-newfmt-init-7 \ +"$testcvs -q up -prtaginfo-start taginfo >taginfo" + echo "ALL ${TESTDIR}/1/loggit %{t} %b %{o} %p %{sTVv}" >>taginfo + echo "UseNewInfoFmtStrings=yes" >>config + dotest taginfo-newfmt-7 "$testcvs -q ci -m check-in-taginfo" \ +"$TESTDIR/cvsroot/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$TESTDIR/cvsroot/CVSROOT/taginfo,v <-- taginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" \ +"$TESTDIR/cvsroot/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$TESTDIR/cvsroot/CVSROOT/taginfo,v <-- taginfo +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database +$SPROG commit: warning: Set to use deprecated info format strings\. Establish +compatibility with the new info file format strings (add a temporary '1' in +all info files after each '%' which doesn't represent a literal percent) +and set UseNewInfoFmtStrings=yes in CVSROOT/config\. After that, convert +individual command lines and scripts to handle the new format at your +leisure\." + + cd ../first-dir + dotest taginfo-newfmt-8 "${testcvs} -q tag tag1" "" + mkdir sdir + dotest taginfo-newfmt-8b "${testcvs} -q add sdir" \ +"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository" + touch sdir/file3 + dotest taginfo-newfmt-8c "${testcvs} -q add sdir/file3" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest taginfo-newfmt-8d "${testcvs} -q ci -m added-sdir" \ +"${TESTDIR}/cvsroot/first-dir/sdir/file3,v <-- sdir/file3 +initial revision: 1\.1" + dotest taginfo-newfmt-9 "${testcvs} -q tag -b br" \ +"T file 2 +W file1 : br already exists on branch 1\.1\.2\.1 : NOT MOVING tag to branch 1\.1\.0\.4 +T sdir/file3" + dotest taginfo-newfmt-10 "${testcvs} -q update -r br" "[UP] file1" + echo add more text on branch >>file1 + dotest taginfo-newfmt-11 "${testcvs} -q ci -m modify-on-br" \ +"${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1" + dotest taginfo-newfmt-12 "${testcvs} -q tag -F -c brtag" \ +"T file 2 +T file1 +T sdir/file3" + + # we are being called once for each directory. I'm not sure + # I like this, but I'm also not sure how hard it would be to change, + # It seems like it would be more trouble than it is really worth + # to let a partial tag go through... + dotest_fail taginfo-newfmt-13 "${testcvs} -q tag rejectme" \ +"${SPROG} tag: Pre-tag check failed +${SPROG} tag: Pre-tag check failed +${SPROG} \[tag aborted\]: correct the above errors first!" + + # When we are using taginfo to allow/disallow, it would be + # convenient to be able to use "cvs -n tag" to test whether + # the allow/disallow functionality is working as expected. + # see the comment before taginfo-newfmt-15 for notes on + # pretag and posttag proc + dotest taginfo-newfmt-14 "${testcvs} -nq tag rejectme" \ +"T file 2 +T file1 +T sdir/file3" + + # But when taginfo is used for logging, it is a pain for -n + # to call taginfo, since taginfo doesn't know whether -n was + # specified or not. (this could be fixed pretty easily now + # with a new fmt string. i suppose it would be better to + # have a pretag proc and a posttag proc, though.) + dotest taginfo-newfmt-15 "${testcvs} -nq tag would-be-tag" \ +"T file 2 +T file1 +T sdir/file3" + + # Deleting: the cases are basically either the tag existed, + # or it didn't exist. + dotest taginfo-newfmt-16 "${testcvs} -q tag -d tag1" \ +"D file 2 +D file1" + dotest taginfo-newfmt-17 "${testcvs} -q tag -d tag1" "" + + # Likewise with rtag. + dotest taginfo-newfmt-18 "${testcvs} -q rtag tag1 first-dir" "" + dotest taginfo-newfmt-19 "${testcvs} -q rtag -d tag1 first-dir" "" + dotest taginfo-newfmt-20 "${testcvs} -q rtag -d tag1 first-dir" "" + + # The "br" example should be passing 1.1.2 or 1.1.0.2. + # But it turns out that is very hard to implement, since + # check_fileproc doesn't know what branch number it will + # get. Probably the whole thing should be re-architected + # so that taginfo only allows/denies tagging, and a new + # hook, which is done from tag_fileproc, does logging. + # That would solve this, some more subtle races, and also + # the fact that it is nice for users to run "-n tag foo" to + # see whether a tag would be allowed. Failing that, + # I suppose passing "1.1.branch" or "branch" for "br" + # would be an improvement. + dotest taginfo-newfmt-examine-2 "cat ${TESTDIR}/1/taglog" \ +"tag1 N add first-dir +br T add first-dir file 2 NONE 1\.1 +br T add first-dir/sdir file3 NONE 1\.1 +brtag N mov first-dir file 2 br NONE 1\.1 file1 br 1\.1\.2\.1 1\.1\.2\.2 +brtag N mov first-dir/sdir file3 br NONE 1\.1 +tag1 ? del first-dir file 2 br 1\.1 1\.1 file1 br 1\.1 1\.1 +tag1 ? del first-dir/sdir +tag1 ? del first-dir +tag1 ? del first-dir/sdir +tag1 N add first-dir file 2 NONE 1\.1 file1 NONE 1\.1 +tag1 N add first-dir/sdir file3 NONE 1\.1 +tag1 ? del first-dir file 2 1\.1 1\.1 file1 1\.1 1\.1 +tag1 ? del first-dir/sdir file3 1\.1 1\.1 +tag1 ? del first-dir +tag1 ? del first-dir/sdir" + + dokeep + restore_adm + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + posttag) + # Tests of the CVSROOT/taginfo file. See the comment at the + # "info" tests for a full list of administrative file tests. + + mkdir 1; cd 1 + + dotest posttag-init-1 "$testcvs -q co CVSROOT" "U CVSROOT/$DOTSTAR" + + # now that we've tested the default operation, try a new + # style fmt string. + cd CVSROOT + echo "ALL $TESTDIR/1/loggit %r %t %o %b %p %{sVv}" >posttag + dotest posttag-init-2 "$testcvs -q ci -m check-in-taginfo" \ +"$TESTDIR/cvsroot/CVSROOT/posttag,v <-- posttag +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd .. + + cat >$TESTDIR/1/loggit <<EOF +#!$TESTSHELL +if test "\$1" = rejectme; then + error=: +else + error=false +fi + +while [ -n "\$1" ]; do + echo "\$1" >>$TESTDIR/1/taglog + shift +done + +if \$error; then + exit 1 +fi +exit 0 +EOF + # #^@&!^@ Cygwin. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x $TESTDIR/1/loggit" + else + chmod +x $TESTDIR/1/loggit + fi + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest posttag-init-3 "$testcvs -q co first-dir" + + cd first-dir + echo first >file1 + echo "bull pucky" >'file 2' + dotest posttag-init-4 "$testcvs add file1 'file 2'" \ +"$SPROG add: scheduling file \`file1' for addition +$SPROG add: scheduling file \`file 2' for addition +$SPROG add: use \`$SPROG commit' to add these files permanently" + dotest posttag-init-5 "$testcvs -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file 2,v <-- file 2 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + dotest posttag-1 "$testcvs -q tag tag1" \ +"T file 2 +T file1" + dotest posttag-2 "$testcvs -q tag tag3" \ +"T file 2 +T file1" + + dotest posttag-3 "$testcvs -q tag rejectme" \ +"T file 2 +T file1" + + dotest posttag-4 "$testcvs -q tag -d rejectme" \ +"D file 2 +D file1" + + dotest posttag-examine-1 "cat $TESTDIR/1/taglog" \ +"$TESTDIR/cvsroot +tag1 +add +N +first-dir +file 2 +NONE +1\.1 +file1 +NONE +1\.1 +$TESTDIR/cvsroot +tag3 +add +N +first-dir +file 2 +NONE +1\.1 +file1 +NONE +1\.1 +$TESTDIR/cvsroot +rejectme +add +N +first-dir +file 2 +NONE +1.1 +file1 +NONE +1.1 +$TESTDIR/cvsroot +rejectme +del +? +first-dir +file 2 +1.1 +1.1 +file1 +1.1 +1.1" + + dokeep + cd ../.. + restore_adm + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + config) + # Tests of the CVSROOT/config file. See the comment at the + # "info" tests for a full list of administrative file tests. + + # See note in keywordexpand about config errors from a proxied + # primary. + if $noredirect; then + notnoredirect config + continue + fi + + # On Windows, we can't check out CVSROOT, because the case + # insensitivity means that this conflicts with cvsroot. + mkdir wnt + cd wnt + + dotest config-init-1 "$testcvs -q co CVSROOT" "U CVSROOT/$DOTSTAR" + cd CVSROOT + dotest config-init-2 "$testcvs -Q tag config-start" + echo 'bogus line' >>config + dotest config-3 "$testcvs -q ci -m change-to-bogus-line" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + dotest config-3a "$testcvs -Q update -jHEAD -jconfig-start" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: syntax error: missing \`=' between keyword and value +RCS file: $CVSROOT_DIRNAME/CVSROOT/config,v +retrieving revision 1.[0-9]* +retrieving revision 1.[0-9]* +Merging differences between 1.[0-9]* and 1.[0-9]* into config" + echo 'BogusOption=yes' >>config + if $proxy; then + dotest config-4p "$testcvs -q ci -m change-to-bogus-opt" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[99\]: syntax error: missing \`=' between keyword and value +$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[99\]: syntax error: missing \`=' between keyword and value +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + else + dotest config-4 "$testcvs -q ci -m change-to-bogus-opt" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[1-9][0-9]*\]: syntax error: missing \`=' between keyword and value +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + fi + + if $proxy; then + : # FIXME: don't try in proxy mode + else + # Now test the HistoryLogPath and HistorySearchPath options. + mkdir $TESTDIR/historylogs + echo >config \ + 'HistoryLogPath=$CVSROOT/../historylogs/%Y-%m-%d-%H-%M-%S' + echo 'HistorySearchPath=$CVSROOT/../historylogs/*' >>config + + # The warning is left over from the previous test. + dotest config-5 "$testcvs -q ci -m set-HistoryLogPath" \ +"$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[98\]: unrecognized keyword \`BogusOption' +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + echo '# noop' >> config + dotest config-6 "$testcvs -q ci -mlog-commit" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + sleep 1 + echo '# noop' >> config + dotest config-7 "$testcvs -q ci -mlog-commit" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + # The log entry was intentionally split across multiple files. + dotest config-8 "ls -l $TESTDIR/historylogs/*" \ +"-rw-rw-r--.*$TESTDIR/historylogs/2[0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]-[0-2][0-9]-[0-5][0-9]-[0-5][0-9] +-rw-rw-r--.*$TESTDIR/historylogs/2[0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]-[0-2][0-9]-[0-5][0-9]-[0-5][0-9]" + + # Should still see both commits. + if $remote; then + dotest config-9r "$testcvs history -ea" \ +"M [0-9-]* [0-9:]* ${PLUS}0000 $username 1\.[0-9]* config CVSROOT == <remote> +M [0-9-]* [0-9:]* ${PLUS}0000 $username 1\.[0-9]* config CVSROOT == <remote>" + else + dotest config-9 "$testcvs history -ea" \ +"M [0-9-]* [0-9:]* ${PLUS}0000 $username 1\.[0-9]* config CVSROOT == $TESTDIR/wnt/CVSROOT +M [0-9-]* [0-9:]* ${PLUS}0000 $username 1\.[0-9]* config CVSROOT == $TESTDIR/wnt/CVSROOT" + fi + + # Remove this now to see what kind of error messages we get. + rm -r $TESTDIR/historylogs + fi + + dokeep + restore_adm + cd ../.. + rm -r wnt + ;; + + + + config2) + # Tests of the CVSROOT/config file. See the comment at the + # "info" tests for a full list of administrative file tests. + + # No point in testing compression effects in local mode. + if $remote; then :; else + remoteonly config2 + continue + fi + + # On Windows, we can't check out CVSROOT, because the case + # insensitivity means that this conflicts with cvsroot. + mkdir wnt + cd wnt + + # Set MinCompressionLevel and MaxCompressionLevel in config. + dotest config2-init-1 "$testcvs -q co CVSROOT" "U CVSROOT/$DOTSTAR" + dotest config2-init-1b "$testcvs -Q tag initial" + cd CVSROOT + cat << EOF >> config +MinCompressionLevel=5 +MaxCompressionLevel=6 +EOF + dotest config2-init-2 \ +"$testcvs -q ci -m set-compression-constraints" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + # Verify that the server reports forcing compression to an allowed + # level. + + # Too high. + dotest config2-1 "$testcvs -z9 update" \ +"$SPROG server: Forcing compression level 6 (allowed: 5 <= z <= 6)\. +$SPROG update: Updating \." + # Too low. + dotest config2-2 "$testcvs -z1 update" \ +"$SPROG server: Forcing compression level 5 (allowed: 5 <= z <= 6)\. +$SPROG update: Updating \." + # From zero. + dotest config2-3 "$testcvs update" \ +"$SPROG server: Forcing compression level 5 (allowed: 5 <= z <= 6)\. +$SPROG update: Updating \." + # Just right. + dotest config2-3 "$testcvs -z5 update" \ +"$SPROG update: Updating \." + + # Check that compression may be forced to 0. + dotest config2-init-2b "$testcvs -z5 up -jHEAD -jinitial" "$DOTSTAR" + cat << EOF >> config +MaxCompressionLevel=0 +EOF + dotest config2-init-3 "$testcvs -qz5 ci -m no-compression" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + # Too high. + dotest config2-5 "$testcvs -z9 update" \ +"$SPROG server: Forcing compression level 0 (allowed: 0 <= z <= 0)\. +$SPROG update: Updating \." + # Just right. + dotest config2-6 "$testcvs update" \ +"$SPROG update: Updating \." + + # And verify effect without restrictions. + dotest config2-init-3b "$testcvs up -jHEAD -jinitial" "$DOTSTAR" + dotest config2-init-4 "$testcvs -q ci -m change-to-comment" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + dotest config2-7 "$testcvs update" \ +"$SPROG update: Updating \." + + dokeep + restore_adm + cd ../.. + rm -r wnt + ;; + + config3) + # Verify comments, white space, & [rootspecs] in CVSROOT/config + # + # `cvs server' `-c' option tested in `server' test + modify_repo mkdir $CVSROOT_DIRNAME/config3 + mkdir config3 + cd config3 + + dotest config3-init-1 "$testcvs -q co CVSROOT" "U CVSROOT/$DOTSTAR" + cd CVSROOT + + # I break the usual sanity.sh indentation standard for here-docs + # mostly to test that leading white-space is now ignored. + dotest config3-init-1b "$testcvs -Q tag initial-config" + + cat <<EOF >>config + # Ignore a comment with leading spaces. + GLOBAL-BAD-OPTION=WWW + + [/ignore/this/root] + [/and/this/one] + IGNORED-BAD-OPTION=YYY +EOF + dotest config3-init-2 \ +"$testcvs -q ci -m test-root-specs" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd .. + dotest config3-1 "$testcvs co config3" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`GLOBAL-BAD-OPTION' +$SPROG checkout: Updating config3" + + cd CVSROOT + dotest config3-init-2a "$testcvs -Q up -jHEAD -jinitial-config" \ +"$DOTSTAR +Merging differences between 1\.[0-9]* and 1\.[0-9]* into config" + + cat <<EOF >>config + # Ignore a comment with leading spaces. + + [/ignore/this/root] + [/and/this/one] + IGNORED-BAD-OPTION=YYY + # Ignore a comment with leading spaces. + + [/some/other/root] + + # Comments and blank lines do not affect fall-through behavior. + + [$CVSROOT_DIRNAME] + [$SECONDARY_CVSROOT_DIRNAME] + + # Comments and blank lines do not affect fall-through behavior. + + [/yet/another/root] + # Ignore a comment with leading spaces. + PROCESS-BAD-OPTION=XXX +EOF + dotest config3-init-3 \ +"$testcvs -q ci -m test-root-specs" \ +"$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`GLOBAL-BAD-OPTION' +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`GLOBAL-BAD-OPTION' +$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`GLOBAL-BAD-OPTION' +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd .. + dotest config3-2 "$testcvs co config3" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`PROCESS-BAD-OPTION' +$SPROG checkout: Updating config3" + + # The next few tests make sure both global options and root + # specific options are processed by setting the history log and + # search paths in different locations and then verifying that + # both registered. It also verifies that a key for a different + # root is ignored. + cd CVSROOT + dotest config3-init-3a "$testcvs -Q up -jHEAD -jinitial-config" \ +"$DOTSTAR +Merging differences between 1\.[0-9]* and 1\.[0-9]* into config" + + cat <<EOF >>config + HistoryLogPath=$TESTDIR/historylog + + [/ignore/this/root] + [/and/this/one] + IGNORED-BAD-OPTION=YYY + + [/some/other/root] + [$CVSROOT_DIRNAME] + [$SECONDARY_CVSROOT_DIRNAME] + [/yet/another/root] + HistorySearchPath=$TESTDIR/historylog + + [/ignore/another/root] + [/and/this/one/too] + ANOTHER-IGNORED-BAD-OPTION=ZZZ + + [$CVSROOT_DIRNAME] + [$SECONDARY_CVSROOT_DIRNAME] + LogHistory=TMAR +EOF + dotest config3-init-4 \ +"$testcvs -q ci -m test-root-specs" \ +"$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`PROCESS-BAD-OPTION' +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" \ +"$SPROG [a-z]*: $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`PROCESS-BAD-OPTION' +$SPROG [a-z]*: $CVSROOT_DIRNAME/CVSROOT/config \[[0-9]*\]: unrecognized keyword \`PROCESS-BAD-OPTION' +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cd .. + dotest config3-3 "$testcvs co -d config3-2 config3" \ +"$SPROG checkout: Updating config3-2" + + cd config3-2 + touch newfile + dotest config3-4 "$testcvs -Q add newfile" + dotest config3-5 "$testcvs -q ci -madd-file" \ +"$CVSROOT_DIRNAME/config3/newfile,v <-- newfile +initial revision: 1\.1" + + dotest config3-6 "$testcvs rtag testtag config3" \ +"$SPROG rtag: Tagging config3" + + cd .. + dotest config3-7 "$testcvs history -ea" \ +"A [0-9-]* [0-9:]* ${PLUS}0000 $username 1\.1 newfile config3 == [-_/a-zA-Z0-9<>]* +T [0-9-]* [0-9:]* ${PLUS}0000 $username config3 \[testtag:A\]" + + dokeep + restore_adm + cd .. + rm -r config3 + modify_repo rm -rf $CVSROOT_DIRNAME/config3 + ;; + + + + config4) + # TmpDir + mkdir config4 + cd config4 + + dotest config4-init-1 "$testcvs -q co CVSROOT" "U CVSROOT/$DOTSTAR" + cd CVSROOT + mkdir $TESTDIR/config4/tmp + echo "TmpDir=$TESTDIR/config4/tmp" >>config + echo "DEFAULT $TESTDIR/config4/verify %l" >>verifymsg + dotest config4-init-2 "$testcvs -q ci -m change-tmpdir" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$CVSROOT_DIRNAME/CVSROOT/verifymsg,v <-- verifymsg +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + cat >$TESTDIR/config4/verify <<EOF +#! /bin/sh +echo \$1 +exit 0 +EOF + chmod a+x $TESTDIR/config4/verify + dotest config4-1 \ +"$testcvs -q ci -fmtest-tmpdir config" \ +"$TESTDIR/config4/tmp/$tempfile +$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + dokeep + restore_adm + cd ../.. + rm -r config4 + modify_repo rm -rf $CVSROOT_DIRNAME/config4 + ;; + + + + serverpatch) + # Test remote CVS handling of unpatchable files. This isn't + # much of a test for local CVS. + # We test this with some keyword expansion games, but the situation + # also arises if the user modifies the file while CVS is running. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + mkdir 1 + cd 1 + dotest serverpatch-1 "$testcvs -q co first-dir" + + cd first-dir + + # Add a file with an RCS keyword. + echo '$''Name$' > file1 + echo '1' >> file1 + dotest serverpatch-2 "$testcvs add file1" \ +"$SPROG add: scheduling file \`file1' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + + dotest serverpatch-3 "${testcvs} -q commit -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + # Tag the file. + dotest serverpatch-4 "${testcvs} -q tag tag file1" 'T file1' + + # Check out a tagged copy of the file. + cd ../.. + mkdir 2 + cd 2 + dotest serverpatch-5 "${testcvs} -q co -r tag first-dir" \ +'U first-dir/file1' + + # Remove the tag. This will leave the tag string in the + # expansion of the Name keyword. + dotest serverpatch-6 "${testcvs} -q update -A first-dir" '' + + # Modify and check in the first copy. + cd ../1/first-dir + echo '2' >> file1 + dotest serverpatch-7 "${testcvs} -q ci -mx file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + + # Now update the second copy. When using remote CVS, the + # patch will fail, forcing the file to be refetched. + cd ../../2/first-dir + dotest serverpatch-8 "${testcvs} -q update" \ +'U file1' \ +"P file1 +${CPROG} update: checksum failure after patch to \./file1; will refetch +${CPROG} client: refetching unpatchable files +$SPROG update: warning: \`file1' was lost +U file1" + + dokeep + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + log) + # Test selecting revisions with cvs log. + # See also log2 tests for more tests. + # See also branches-14.3 for logging with a branch off of a branch. + # See also multibranch-14 for logging with several branches off the + # same branchpoint. + # Tests of each option to cvs log: + # -h: admin-19a-log + # -N: log, log2, admin-19a-log + # -b, -r: log + # -d: logopt, rcs + # -s: logopt, rcs3 + # -R: logopt, rcs3 + # -w, -t: not tested yet (TODO) + + # Check in a file with a few revisions and branches. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest log-1 "$testcvs -q co first-dir" + cd first-dir + echo 'first revision' > file1 + echo 'first revision' > file2 + dotest log-2 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + + # While we're at it, check multi-line comments, input from file, + # and trailing whitespace trimming + echo 'line 1 ' >${TESTDIR}/comment.tmp + echo ' ' >>${TESTDIR}/comment.tmp + echo 'line 2 ' >>${TESTDIR}/comment.tmp + echo ' ' >>${TESTDIR}/comment.tmp + echo ' ' >>${TESTDIR}/comment.tmp + dotest log-3 "${testcvs} -q commit -F ${TESTDIR}/comment.tmp" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + rm -f ${TESTDIR}/comment.tmp + + echo 'second revision' > file1 + echo 'second revision' > file2 + dotest log-4 "${testcvs} -q ci -m2 file1 file2" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.2; previous revision: 1\.1" + + dotest log-5 "${testcvs} -q tag -b branch file1" 'T file1' + dotest log-5a "${testcvs} -q tag tag1 file2" 'T file2' + + echo 'third revision' > file1 + echo 'third revision' > file2 + dotest log-6 "${testcvs} -q ci -m3 file1 file2" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.3; previous revision: 1\.2" + + dotest log-6a "${testcvs} -q tag tag2 file2" 'T file2' + + dotest log-7 "${testcvs} -q update -r branch" \ +"[UP] file1 +${SPROG} update: \`file2' is no longer in the repository" + + echo 'first branch revision' > file1 + dotest log-8 "${testcvs} -q ci -m1b file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2\.2\.1; previous revision: 1\.2" + + dotest log-9 "${testcvs} -q tag tag file1" 'T file1' + + echo 'second branch revision' > file1 + dotest log-10 "${testcvs} -q ci -m2b file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1" + + # Set up a bunch of shell variables to make the later tests + # easier to describe.= + log_header1=" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.3 +branch: +locks: strict +access list:" + rlog_header1=" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +head: 1\.3 +branch: +locks: strict +access list:" + log_tags1='symbolic names: + tag: 1\.2\.2\.1 + branch: 1\.2\.0\.2' + log_keyword='keyword substitution: kv' + log_dash='---------------------------- +revision' + log_date="date: ${ISO8601DATE}; author: ${username}; state: Exp;" + log_lines=" lines: ${PLUS}1 -1;" + log_commitid=" commitid: ${commitid};" + log_rev1="${log_dash} 1\.1 +${log_date}${log_commitid} +line 1 + +line 2" + log_rev2="${log_dash} 1\.2 +${log_date}${log_lines}${log_commitid} +branches: 1\.2\.2; +2" + log_rev3="${log_dash} 1\.3 +${log_date}${log_lines}${log_commitid} +3" + log_rev1b="${log_dash} 1\.2\.2\.1 +${log_date}${log_lines}${log_commitid} +1b" + log_rev2b="${log_dash} 1\.2\.2\.2 +${log_date}${log_lines}${log_commitid} +2b" + log_trailer='=============================================================================' + + # Now, finally, test the log output. + + dotest log-11 "${testcvs} log file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-12 "${testcvs} log -N file1" \ +"${log_header1} +${log_keyword} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-13 "${testcvs} log -b file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 3 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-14 "${testcvs} log -r file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-14a "${testcvs} log -rHEAD file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + # The user might not realize that "-r" must not take a space. + # In the error message, HEAD is a file name, not a tag name (which + # might be confusing itself). + dotest_fail log-14b "${testcvs} log -r HEAD file1" \ +"${SPROG} log: nothing known about HEAD +${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + +# Check that unusual syntax works correctly. + + dotest log-14c "${testcvs} log -r: file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-14d "${testcvs} log -r, file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-14e "${testcvs} log -r. file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-14f "${testcvs} log -r:: file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-15 "${testcvs} log -r1.2 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + dotest log-16 "${testcvs} log -r1.2.2 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + # This test would fail with the old invocation of rlog, but it + # works with the builtin log support. + dotest log-17 "${testcvs} log -rbranch file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-18 "${testcvs} log -r1.2.2. file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + # Multiple -r options are undocumented; see comments in + # cvs.texinfo about whether they should be deprecated. + dotest log-18a "${testcvs} log -r1.2.2.2 -r1.3:1.3 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2b} +${log_trailer}" + + # This test would fail with the old invocation of rlog, but it + # works with the builtin log support. + dotest log-19 "${testcvs} log -rbranch. file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + dotest log-20 "${testcvs} log -r1.2: file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + + dotest log-20a "${testcvs} log -r1.2:: file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-21 "${testcvs} log -r:1.2 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-21a "${testcvs} log -r::1.2 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-22 "${testcvs} log -r1.1:1.2 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-22a "${testcvs} log -r1.1::1.2 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + dotest log-22b "${testcvs} log -r1.1::1.3 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + + dotest log-23 "${testcvs} log -rfoo:: file1" \ +"${SPROG} log: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-24 "${testcvs} log -rfoo::1.3 file1" \ +"${SPROG} log: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-25 "${testcvs} log -r::foo file1" \ +"${SPROG} log: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-26 "${testcvs} log -r1.1::foo file1" \ +"${SPROG} log: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + # Test BASE pseudotag + dotest log-27 "${testcvs} log -rBASE file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + dotest log-28 "${testcvs} -q up -r1.2 file1" "[UP] file1" + dotest log-29 "${testcvs} log -rBASE file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + dotest log-30 "${testcvs} -q up -rbranch file1" "[UP] file1" + + # Now the same tests but with rlog + + dotest log-r11 "${testcvs} rlog first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r12 "${testcvs} rlog -N first-dir/file1" \ +"${rlog_header1} +${log_keyword} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r13 "${testcvs} rlog -b first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 3 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-r14 "${testcvs} rlog -r first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-r14a "${testcvs} rlog -rHEAD first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest_fail log-r14b "${testcvs} rlog -r HEAD first-dir/file1" \ +"${SPROG} rlog: cannot find module .HEAD. - ignored +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-r14c "${testcvs} rlog -r: first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-r14d "${testcvs} rlog -r, first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-r14e "${testcvs} rlog -r. first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-r14f "${testcvs} rlog -r:: first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-r15 "${testcvs} rlog -r1.2 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + dotest log-r16 "${testcvs} rlog -r1.2.2 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r17 "${testcvs} rlog -rbranch first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r18 "${testcvs} rlog -r1.2.2. first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + dotest log-r18a "${testcvs} rlog -r1.2.2.2 -r1.3:1.3 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2b} +${log_trailer}" + + dotest log-r19 "${testcvs} rlog -rbranch. first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + dotest log-r20 "${testcvs} rlog -r1.2: first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + + dotest log-r20a "${testcvs} rlog -r1.2:: first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-r21 "${testcvs} rlog -r:1.2 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-r21a "${testcvs} rlog -r::1.2 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-r22 "${testcvs} rlog -r1.1:1.2 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-r22a "${testcvs} rlog -r1.1::1.2 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + dotest log-r22b "${testcvs} rlog -r1.1::1.3 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + + dotest log-r23 "${testcvs} rlog -rfoo:: first-dir/file1" \ +"${SPROG} rlog: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-r24 "${testcvs} rlog -rfoo::1.3 first-dir/file1" \ +"${SPROG} rlog: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-r25 "${testcvs} rlog -r::foo first-dir/file1" \ +"${SPROG} rlog: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-r26 "${testcvs} rlog -r1.1::foo first-dir/file1" \ +"${SPROG} rlog: warning: no revision .foo. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + # Test BASE pseudotag + dotest log-r27 "${testcvs} rlog -rBASE first-dir/file1" \ +"${SPROG} rlog: warning: no revision .BASE. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-r28 "${testcvs} -q up -r1.2 file1" "[UP] file1" + dotest log-r29 "${testcvs} rlog -rBASE first-dir/file1" \ +"${SPROG} rlog: warning: no revision .BASE. in .${CVSROOT_DIRNAME}/first-dir/file1,v. +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + # Test when head is dead + + dotest log-d0 "${testcvs} -q up -A" \ +"[UP] file1 +U file2" + dotest log-d1 "${testcvs} -q rm -f file1" \ +"${SPROG} remove: use .${SPROG} commit. to remove this file permanently" + dotest log-d2 "${testcvs} -q ci -m4" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.3" + + log_header1=" +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +Working file: file1 +head: 1\.4 +branch: +locks: strict +access list:" + rlog_header1=" +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +head: 1\.4 +branch: +locks: strict +access list:" + log_header2=" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.3 +branch: +locks: strict +access list:" + rlog_header2=" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +head: 1\.3 +branch: +locks: strict +access list:" + log_tags2='symbolic names: + tag2: 1\.3 + tag1: 1\.2' + log_rev4="${log_dash} 1\.4 +date: ${ISO8601DATE}; author: ${username}; state: dead; lines: ${PLUS}0 -0; commitid: ${commitid}; +4" + log_rev22="${log_dash} 1\.2 +${log_date}${log_lines}${log_commitid} +2" + + dotest log-d3 "${testcvs} log -rbranch file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + dotest log-rd3 "${testcvs} rlog -rbranch first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + dotest log-d4 "${testcvs} -q log -rbranch" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer} +${SPROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. +${log_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 0 +description: +${log_trailer}" + dotest log-d4a "${testcvs} -q log -t -rbranch" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6 +description: +${log_trailer} +${SPROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. +${log_header2} +${log_tags2} +${log_keyword} +total revisions: 3 +description: +${log_trailer}" + dotest log-d4b "${testcvs} -q log -tS -rbranch" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_trailer} +${SPROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." + dotest log-d4c "${testcvs} -q log -h -rbranch" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6 +${log_trailer} +${SPROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. +${log_header2} +${log_tags2} +${log_keyword} +total revisions: 3 +${log_trailer}" + dotest log-d4d "${testcvs} -q log -hS -rbranch" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +${log_trailer} +${SPROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." + dotest log-d4e "$testcvs -q log -R -rbranch" \ +"$CVSROOT_DIRNAME/first-dir/Attic/file1,v +$CVSROOT_DIRNAME/first-dir/file2,v" + dotest log-d4f "${testcvs} -q log -R -S -rbranch" \ +"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +${SPROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." + dotest log-rd4 "${testcvs} -q rlog -rbranch first-dir" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer} +${SPROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. +${rlog_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 0 +description: +${log_trailer}" + dotest log-rd4a "${testcvs} -q rlog -t -rbranch first-dir" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6 +description: +${log_trailer} +${SPROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. +${rlog_header2} +${log_tags2} +${log_keyword} +total revisions: 3 +description: +${log_trailer}" + dotest log-rd4b "${testcvs} -q rlog -St -rbranch first-dir" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_trailer} +${SPROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." + dotest log-rd4c "${testcvs} -q rlog -h -rbranch first-dir" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6 +${log_trailer} +${SPROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. +${rlog_header2} +${log_tags2} +${log_keyword} +total revisions: 3 +${log_trailer}" + dotest log-rd4d "${testcvs} -q rlog -Sh -rbranch first-dir" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +${log_trailer} +${SPROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." + dotest log-rd4e "${testcvs} -q rlog -R -rbranch first-dir" \ +"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +${CVSROOT_DIRNAME}/first-dir/file2,v" + dotest log-rd4f "${testcvs} -q rlog -R -S -rbranch first-dir" \ +"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +${SPROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." + dotest log-d5 "${testcvs} log -r1.2.2.1:1.2.2.2 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + dotest log-rd5 "${testcvs} rlog -r1.2.2.1:1.2.2.2 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + dotest log-d6 "${testcvs} -q log -r1.2.2.1:1.2.2.2" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer} +${log_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 0 +description: +${log_trailer}" + dotest log-rd6 "${testcvs} -q rlog -r1.2.2.1:1.2.2.2 first-dir" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer} +${rlog_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 0 +description: +${log_trailer}" + dotest log-d7 "${testcvs} log -r1.2:1.3 file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + dotest log-rd7 "${testcvs} -q rlog -r1.2:1.3 first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + dotest log-d8 "${testcvs} -q log -rtag1:tag2" \ +"${SPROG} log: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${SPROG} log: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${log_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 0 +description: +${log_trailer} +${log_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 2 +description: +${log_rev3} +${log_rev22} +${log_trailer}" + dotest log-d8a "${testcvs} -q log -rtag1:tag2 -S" \ +"${SPROG} log: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${SPROG} log: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${log_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 2 +description: +${log_rev3} +${log_rev22} +${log_trailer}" + dotest log-rd8 "${testcvs} -q rlog -rtag1:tag2 first-dir" \ +"${SPROG} rlog: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${SPROG} rlog: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 6; selected revisions: 0 +description: +${log_trailer} +${rlog_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 2 +description: +${log_rev3} +${log_rev22} +${log_trailer}" + dotest log-rd8a "${testcvs} -q rlog -rtag1:tag2 -S first-dir" \ +"${SPROG} rlog: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${SPROG} rlog: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. +${rlog_header2} +${log_tags2} +${log_keyword} +total revisions: 3; selected revisions: 2 +description: +${log_rev3} +${log_rev22} +${log_trailer}" + + dotest log-d99 "${testcvs} -q up -rbranch" \ +"[UP] file1 +${SPROG} update: \`file2' is no longer in the repository" + + # Now test outdating revisions + + dotest log-o0 "${testcvs} admin -o 1.2.2.2:: file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +done" + dotest log-o1 "${testcvs} admin -o ::1.2.2.1 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +done" + dotest log-o2 "${testcvs} admin -o 1.2.2.1:: file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v +deleting revision 1\.2\.2\.2 +done" + dotest log-o3 "${testcvs} log file1" \ +"${log_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 5 +description: +${log_rev4} +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev1b} +${log_trailer}" + dotest log-ro3 "${testcvs} rlog first-dir/file1" \ +"${rlog_header1} +${log_tags1} +${log_keyword} +total revisions: 5; selected revisions: 5 +description: +${log_rev4} +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev1b} +${log_trailer}" + dotest log-o4 "${testcvs} -q update -p -r 1.2.2.1 file1" \ +"first branch revision" + + dokeep + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + log2) + # More "cvs log" tests, for example the file description. + + # Check in a file + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest log2-1 "$testcvs -q co first-dir" + cd first-dir + echo 'first revision' > file1 + dotest log2-2 "${testcvs} add -m file1-is-for-testing file1" \ +"${SPROG}"' add: scheduling file `file1'\'' for addition +'"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + dotest log2-3 "${testcvs} -q commit -m 1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + # Setting the file description with add -m doesn't yet work + # client/server, so skip log2-4 for remote. + if $remote; then :; else + + dotest log2-4 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +file1-is-for-testing +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +1 +=============================================================================" + + fi # end of tests skipped for remote + + dotest log2-5 "${testcvs} admin -t-change-description file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest log2-6 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +change-description +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +1 +=============================================================================" + + echo 'longer description' >${TESTDIR}/descrip + echo 'with two lines' >>${TESTDIR}/descrip + dotest log2-7 "${testcvs} admin -t${TESTDIR}/descrip file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest_fail log2-7a "${testcvs} admin -t${TESTDIR}/nonexist file1" \ +"${CPROG} \[admin aborted\]: can't stat ${TESTDIR}/nonexist: No such file or directory" + dotest log2-8 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +longer description +with two lines +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +1 +=============================================================================" + + # TODO: `cvs admin -t "my message" file1' is a request to + # read the message from stdin and to operate on two files. + # Should test that there is an error because "my message" + # doesn't exist. + + dotest log2-9 "echo change from stdin | ${testcvs} admin -t -q file1" "" + dotest log2-10 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +change from stdin +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +1 +=============================================================================" + + dokeep + cd .. + rm $TESTDIR/descrip + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + logopt) + # Some tests of log.c's option parsing and such things. + mkdir 1; cd 1 + dotest logopt-1 "$testcvs -q co -l ." '' + mkdir first-dir + dotest logopt-2 "$testcvs add first-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir added to the repository" + cd first-dir + echo hi >file1 + dotest logopt-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest logopt-4 "${testcvs} -q ci -m add file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + cd .. + + dotest logopt-5 "${testcvs} log -R -d 2038-01-01" \ +"${SPROG} log: Logging \. +${SPROG} log: Logging first-dir +${CVSROOT_DIRNAME}/first-dir/file1,v" + dotest logopt-6 "${testcvs} log -d 2038-01-01 -R" \ +"${SPROG} log: Logging \. +${SPROG} log: Logging first-dir +${CVSROOT_DIRNAME}/first-dir/file1,v" + dotest logopt-6a "${testcvs} log -Rd 2038-01-01" \ +"${SPROG} log: Logging \. +${SPROG} log: Logging first-dir +${CVSROOT_DIRNAME}/first-dir/file1,v" + dotest logopt-7 "${testcvs} log -s Exp -R" \ +"${SPROG} log: Logging \. +${SPROG} log: Logging first-dir +${CVSROOT_DIRNAME}/first-dir/file1,v" + + dokeep + cd .. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + ann) + # Tests of "cvs annotate". See also: + # basica-10 A simple annotate test + # rcs Annotate and the year 2000 + # keywordlog Annotate and $Log. + mkdir 1; cd 1 + dotest ann-1 "$testcvs -q co -l ." + mkdir first-dir + dotest ann-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + cat >file1 <<EOF +this +is +the +ancestral +file +EOF + dotest ann-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest ann-4 "${testcvs} -q ci -m add file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + cat >file1 <<EOF +this +is +a +file + +with +a +blank +line +EOF + dotest ann-5 "${testcvs} -q ci -m modify file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + dotest ann-6 "${testcvs} -q tag -b br" "T file1" + cat >file1 <<EOF +this +is +a +trunk file + +with +a +blank +line +EOF + dotest ann-7 "${testcvs} -q ci -m modify file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + dotest ann-8 "${testcvs} -q update -r br" "[UP] file1" + cat >file1 <<EOF +this +is +a +file + +with +a +blank +line +and some +branched content +EOF + dotest ann-9 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2\.2\.1; previous revision: 1\.2" + # Note that this annotates the trunk despite the presence + # of a sticky tag in the current directory. This is + # fairly bogus, but it is the longstanding behavior for + # whatever that is worth. + dotest ann-10 "${testcvs} ann" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 ($username8 *[0-9a-zA-Z-]*): this +1\.1 ($username8 *[0-9a-zA-Z-]*): is +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.3 ($username8 *[0-9a-zA-Z-]*): trunk file +1\.2 ($username8 *[0-9a-zA-Z-]*): +1\.2 ($username8 *[0-9a-zA-Z-]*): with +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.2 ($username8 *[0-9a-zA-Z-]*): blank +1\.2 ($username8 *[0-9a-zA-Z-]*): line" + dotest ann-11 "${testcvs} ann -r br" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 ($username8 *[0-9a-zA-Z-]*): this +1\.1 ($username8 *[0-9a-zA-Z-]*): is +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.1 ($username8 *[0-9a-zA-Z-]*): file +1\.2 ($username8 *[0-9a-zA-Z-]*): +1\.2 ($username8 *[0-9a-zA-Z-]*): with +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.2 ($username8 *[0-9a-zA-Z-]*): blank +1\.2 ($username8 *[0-9a-zA-Z-]*): line +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): branched content" + # FIXCVS: shouldn't "-r 1.2.0.2" be the same as "-r br"? + dotest ann-12 "${testcvs} ann -r 1.2.0.2 file1" "" + dotest ann-13 "${testcvs} ann -r 1.2.2 file1" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 ($username8 *[0-9a-zA-Z-]*): this +1\.1 ($username8 *[0-9a-zA-Z-]*): is +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.1 ($username8 *[0-9a-zA-Z-]*): file +1\.2 ($username8 *[0-9a-zA-Z-]*): +1\.2 ($username8 *[0-9a-zA-Z-]*): with +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.2 ($username8 *[0-9a-zA-Z-]*): blank +1\.2 ($username8 *[0-9a-zA-Z-]*): line +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): branched content" + dotest_fail ann-14 "$testcvs ann -r bill-clintons-chastity file1" \ +"$SPROG \[annotate aborted\]: no such tag \`bill-clintons-chastity'" + + # Now get rid of the working directory and test rannotate + + cd ../.. + rm -r 1 + dotest ann-r10 "${testcvs} rann first-dir" \ +" +Annotations for first-dir/file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 ($username8 *[0-9a-zA-Z-]*): this +1\.1 ($username8 *[0-9a-zA-Z-]*): is +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.3 ($username8 *[0-9a-zA-Z-]*): trunk file +1\.2 ($username8 *[0-9a-zA-Z-]*): +1\.2 ($username8 *[0-9a-zA-Z-]*): with +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.2 ($username8 *[0-9a-zA-Z-]*): blank +1\.2 ($username8 *[0-9a-zA-Z-]*): line" + dotest ann-r11 "${testcvs} rann -r br first-dir" \ +" +Annotations for first-dir/file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 ($username8 *[0-9a-zA-Z-]*): this +1\.1 ($username8 *[0-9a-zA-Z-]*): is +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.1 ($username8 *[0-9a-zA-Z-]*): file +1\.2 ($username8 *[0-9a-zA-Z-]*): +1\.2 ($username8 *[0-9a-zA-Z-]*): with +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.2 ($username8 *[0-9a-zA-Z-]*): blank +1\.2 ($username8 *[0-9a-zA-Z-]*): line +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): branched content" + dotest ann-r12 "${testcvs} rann -r 1.2.0.2 first-dir/file1" "" + dotest ann-r13 "${testcvs} rann -r 1.2.2 first-dir/file1" \ +" +Annotations for first-dir/file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 ($username8 *[0-9a-zA-Z-]*): this +1\.1 ($username8 *[0-9a-zA-Z-]*): is +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.1 ($username8 *[0-9a-zA-Z-]*): file +1\.2 ($username8 *[0-9a-zA-Z-]*): +1\.2 ($username8 *[0-9a-zA-Z-]*): with +1\.2 ($username8 *[0-9a-zA-Z-]*): a +1\.2 ($username8 *[0-9a-zA-Z-]*): blank +1\.2 ($username8 *[0-9a-zA-Z-]*): line +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some +1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): branched content" + dotest_fail ann-r14 "$testcvs rann -r bill-clintons-chastity first-dir/file1" \ +"$SPROG \[rannotate aborted\]: no such tag \`bill-clintons-chastity'" + + dokeep + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + ann-id) + # Demonstrate that cvs-1.9.28.1 improperly expands rcs keywords in + # the output of `cvs annotate' -- it uses values from the previous + # delta. In this case, `1.1' instead of `1.2', even though it puts + # the proper version number on the prefix to each line of output. + mkdir 1; cd 1 + dotest ann-id-1 "$testcvs -q co -l ." + module=x + mkdir $module + dotest ann-id-2 "${testcvs} add $module" \ +"Directory ${CVSROOT_DIRNAME}/$module added to the repository" + cd $module + + file=m + echo '$Id''$' > $file + + dotest ann-id-3 "$testcvs add $file" \ +"$SPROG add: scheduling file .$file. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest ann-id-4 "$testcvs -Q ci -m . $file" + + echo line2 >> $file + dotest ann-id-5 "$testcvs -Q ci -m . $file" + + # The version number after $file,v should be `1.2'. + # 1.9.28.1 puts `1.1' there. + dotest ann-id-6 "$testcvs -Q ann $file" \ +" +Annotations for $file +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1.2 ($username8 *[0-9a-zA-Z-]*): "'\$'"Id: $file,v 1.1 [0-9/]* [0-9:]* $username Exp "'\$'" +1.2 ($username8 *[0-9a-zA-Z-]*): line2" + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + crerepos) + # Various tests relating to creating repositories, operating + # on repositories created with old versions of CVS, etc. + + CVS_SERVER_save=$CVS_SERVER + + # Because this test is all about -d options and such, it + # at least to some extent needs to be different for remote vs. + # local. + if $remote; then + + # Use :ext: rather than :fork:. Most of the tests use :fork:, + # so we want to make sure that we test :ext: _somewhere_. + # Make sure 'rsh' works first. + require_rsh "$CVS_RSH" + if test $? -eq 77; then + skip crerepos "$skipreason" + continue + fi + + # Make sure server ignores real $HOME/.cvsrc: + cat >$TESTDIR/cvs-setHome <<EOF +#!$TESTSHELL +HOME=$HOME +export HOME +exec $CVS_SERVER "\$@" +EOF + chmod a+x $TESTDIR/cvs-setHome + + # Note that we set CVS_SERVER at the beginning. + CVS_SERVER=$TESTDIR/cvs-setHome; export CVS_SERVER + CREREPOS_ROOT=:ext:$host$TESTDIR/crerepos + else # local + CREREPOS_ROOT=$TESTDIR/crerepos + fi + + # First, if the repository doesn't exist at all... + dotest_fail crerepos-1 \ +"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \ +"${SPROG} \[checkout aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*" + mkdir crerepos + + # The repository exists but CVSROOT doesn't. + dotest_fail crerepos-2 \ +"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \ +"${SPROG} \[checkout aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*" + mkdir crerepos/CVSROOT + + # Checkout of nonexistent module + dotest_fail crerepos-3 \ +"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \ +"${SPROG} checkout: cannot find module .cvs-sanity. - ignored" + + # Now test that CVS works correctly without a modules file + # or any of that other stuff. In particular, it *must* + # function if administrative files added to CVS recently (since + # CVS 1.3) do not exist, because the repository might have + # been created with an old version of CVS. + mkdir 1; cd 1 + dotest crerepos-4 \ +"${testcvs} -q -d ${TESTDIR}/crerepos co CVSROOT" \ +'' + dotest crerepos-5 \ +"echo yes | $testcvs -d $TESTDIR/crerepos release -d CVSROOT" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory \`CVSROOT': " + rm -rf CVS + cd .. + # The directory 1 should be empty + dotest crerepos-6 "rmdir 1" + + if $remote; then + # Test that CVS rejects a relative path in CVSROOT. + mkdir 1; cd 1 + # Note that having the client reject the pathname (as :fork: + # does), does _not_ test for the bugs we are trying to catch + # here. The point is that malicious clients might send all + # manner of things and the server better protect itself. + dotest_fail crerepos-6a-r \ +"${testcvs} -q -d :ext:`hostname`:../crerepos get ." \ +"${CPROG} checkout: CVSROOT may only specify a positive, non-zero, integer port (not .\.\..)\. +${CPROG} checkout: Perhaps you entered a relative pathname${QUESTION} +${CPROG} \[checkout aborted\]: Bad CVSROOT: .:ext:${hostname}:\.\./crerepos.\." + cd .. + rm -r 1 + + mkdir 1; cd 1 + dotest_fail crerepos-6b-r \ +"${testcvs} -d :ext:`hostname`:crerepos init" \ +"${CPROG} init: CVSROOT requires a path spec: +${CPROG} init: :(gserver|kserver|pserver):\[\[user\]\[:password\]@\]host\[:\[port\]\]/path +${CPROG} init: \[:(ext|server):\]\[\[user\]@\]host\[:\]/path +${CPROG} \[init aborted\]: Bad CVSROOT: .:ext:${hostname}:crerepos.\." + cd .. + rm -r 1 + else # local + # Test that CVS rejects a relative path in CVSROOT. + + mkdir 1; cd 1 + # Set CVS_RSH=false since ocassionally (e.g. when CVS_RSH=ssh on + # some systems) some rsh implementations will block because they + # can look up '..' and want to ask the user about the unknown host + # key or somesuch. Which error message we get depends on whether + # false finishes running before we try to talk to it or not. + dotest_fail crerepos-6a "CVS_RSH=false ${testcvs} -q -d ../crerepos get ." \ +"${SPROG} \[checkout aborted\]: end of file from server (consult above messages if any)" \ +"${SPROG} \[checkout aborted\]: received broken pipe signal" + cd .. + rm -r 1 + + mkdir 1; cd 1 + dotest_fail crerepos-6b "${testcvs} -d crerepos init" \ +"${SPROG} init: CVSROOT must be an absolute pathname (not .crerepos.) +${SPROG} init: when using local access method\. +${SPROG} \[init aborted\]: Bad CVSROOT: .crerepos.\." + cd .. + rm -r 1 + fi # end of tests to be skipped for remote + + # CVS should have created a history file. If the administrator + # doesn't need it and wants to save on disk space, they just + # delete it and set LogHistory = the empty string in config. + dotest crerepos-7 "test -f $TESTDIR/crerepos/CVSROOT/history" + + # Now test mixing repositories. This kind of thing tends to + # happen accidentally when people work with several repositories. + mkdir 1; cd 1 + dotest crerepos-8 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest crerepos-9 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch file1 + dotest crerepos-10 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest crerepos-11 "${testcvs} -q ci -m add-it" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + cd ../.. + rm -r 1 + + mkdir 1; cd 1 + dotest crerepos-12 "$testcvs -d $CREREPOS_ROOT -q co -l ." + mkdir crerepos-dir + dotest crerepos-13 "$testcvs add crerepos-dir" \ +"Directory $TESTDIR/crerepos/crerepos-dir added to the repository" + cd crerepos-dir + touch cfile + dotest crerepos-14 "${testcvs} add cfile" \ +"${SPROG} add: scheduling file .cfile. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest crerepos-15 "${testcvs} -q ci -m add-it" \ +"$TESTDIR/crerepos/crerepos-dir/cfile,v <-- cfile +initial revision: 1\.1" + cd ../.. + rm -r 1 + + mkdir 1; cd 1 + dotest crerepos-16 "${testcvs} co first-dir" \ +"${SPROG} checkout: Updating first-dir +U first-dir/file1" + dotest crerepos-17 "${testcvs} -d ${CREREPOS_ROOT} co crerepos-dir" \ +"${SPROG} checkout: Updating crerepos-dir +U crerepos-dir/cfile" + dotest crerepos-18 "${testcvs} update" \ +"${SPROG} update: Updating first-dir +${SPROG} update: Updating crerepos-dir" + + cd .. + + CVS_SERVER=$CVS_SERVER_save; export CVS_SERVER + + if $keep; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + + dokeep + rm -f $TESTDIR/cvs-setHome + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + rm -rf $TESTDIR/crerepos + ;; + + + + rcs) + # Test ability to import an RCS file. Note that this format + # is fixed--files written by RCS5, and other software which + # implements this format, will be out there "forever" and + # CVS must always be able to import such files. + + # See tests admin-13, admin-25 and rcs-8a for exporting RCS files. + + # Save the timezone and set it to UTC for these tests to make the + # value more predicatable. + save_TZ=$TZ + TZ=UTC0; export TZ + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + + # Currently the way to import an RCS file is to copy it + # directly into the repository. + # + # This file was written by RCS 5.7, and then the dates were + # hacked so that we test year 2000 stuff. Note also that + # "author" names are just strings, as far as importing + # RCS files is concerned--they need not correspond to user + # IDs on any particular system. + # + # I also tried writing a file with the RCS supplied with + # HPUX A.09.05. According to "man rcsintro" this is + # "Revision Number: 3.0; Release Date: 83/05/11". There + # were a few minor differences like whitespace but at least + # in simple cases like this everything else seemed the same + # as the file written by RCS 5.7 (so I won't try to make it + # a separate test case). + + cat <<EOF >$TESTDIR/file1,v +head 1.3; +access; +symbols; +locks; strict; +comment @# @; + + +1.3 +date ${RAWRCSDATE2000A}; author kingdon; state Exp; +branches; +next 1.2; + +1.2 +date ${RAWRCSDATE1996A}; author kingdon; state Exp; +branches; +next 1.1; + +1.1 +date ${RAWRCSDATE1996B}; author kingdon; state Exp; +branches; +next ; + + +desc +@file1 is for testing CVS +@ + + +1.3 +log +@delete second line; modify twelfth line +@ +text +@This is the first line +This is the third line +This is the fourth line +This is the fifth line +This is the sixth line +This is the seventh line +This is the eighth line +This is the ninth line +This is the tenth line +This is the eleventh line +This is the twelfth line (and what a line it is) +This is the thirteenth line +@ + + +1.2 +log +@add more lines +@ +text +@a1 1 +This is the second line +d11 1 +a11 1 +This is the twelfth line +@ + + +1.1 +log +@add file1 +@ +text +@d2 12 +@ +EOF + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/first-dir/file1,v + + dotest rcs-1 "$testcvs -q co first-dir" 'U first-dir/file1' + cd first-dir + dotest rcs-2 "$testcvs -q log" " +RCS file: $CVSROOT_DIRNAME/first-dir/file1,v +Working file: file1 +head: 1\.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +file1 is for testing CVS +---------------------------- +revision 1\.3 +date: ${ISO8601DATE2000A}; author: kingdon; state: Exp; lines: ${PLUS}1 -2; +delete second line; modify twelfth line +---------------------------- +revision 1\.2 +date: ${ISO8601DATE1996A}; author: kingdon; state: Exp; lines: ${PLUS}12 -0; +add more lines +---------------------------- +revision 1\.1 +date: ${ISO8601DATE1996B}; author: kingdon; state: Exp; +add file1 +=============================================================================" + + # Note that the dates here are chosen so that (a) we test + # at least one date after 2000, (b) we will notice if the + # month and day are getting mixed up with each other. + # TODO: also test that year isn't getting mixed up with month + # or day, for example 01-02-03. + + # ISO8601 format. There are many, many, other variations + # specified by ISO8601 which we should be testing too. + dotest rcs-3 "${testcvs} -q log -d '1996-12-11<'" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 1 +description: +file1 is for testing CVS +---------------------------- +revision 1\.3 +date: ${ISO8601DATE2000A}; author: kingdon; state: Exp; lines: ${PLUS}1 -2; +delete second line; modify twelfth line +=============================================================================" + + # RFC822 format (as amended by RFC1123). + dotest rcs-4 "${testcvs} -q log -d '<3 Apr 2000 00:00'" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 2 +description: +file1 is for testing CVS +---------------------------- +revision 1\.2 +date: ${ISO8601DATE1996A}; author: kingdon; state: Exp; lines: ${PLUS}12 -0; +add more lines +---------------------------- +revision 1\.1 +date: ${ISO8601DATE1996B}; author: kingdon; state: Exp; +add file1 +=============================================================================" + + # Intended behavior for "cvs annotate" is that it displays the + # last two digits of the year. Make sure it does that rather + # than some bogosity like "100". + dotest rcs-4a "${testcvs} annotate file1" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1 (kingdon 24-Nov-96): This is the first line +1\.2 (kingdon 24-Nov-96): This is the third line +1\.2 (kingdon 24-Nov-96): This is the fourth line +1\.2 (kingdon 24-Nov-96): This is the fifth line +1\.2 (kingdon 24-Nov-96): This is the sixth line +1\.2 (kingdon 24-Nov-96): This is the seventh line +1\.2 (kingdon 24-Nov-96): This is the eighth line +1\.2 (kingdon 24-Nov-96): This is the ninth line +1\.2 (kingdon 24-Nov-96): This is the tenth line +1\.2 (kingdon 24-Nov-96): This is the eleventh line +1\.3 (kingdon 24-Nov-00): This is the twelfth line (and what a line it is) +1\.2 (kingdon 24-Nov-96): This is the thirteenth line" + + # Probably should split this test into two at this point (file1 + # above this line and file2 below), as the two share little + # data/setup. + + # OK, here is another one. This one was written by hand based on + # doc/RCSFILES and friends. One subtle point is that none of + # the lines end with newlines; that is a feature which we + # should be testing. + cat <<EOF >$TESTDIR/file2,v +head 1.5 ; + branch 1.2.6; +access ; +symbols branch:1.2.6; +locks; +testofanewphrase @without newphrase we'd have trouble extending @@ all@ ; +1.5 date 71.01.01.01.00.00; author joe; state bogus; branches; next 1.4; +1.4 date 71.01.01.00.00.05; author joe; state bogus; branches; next 1.3; +1.3 date 70.12.31.15.00.05; author joe; state bogus; branches; next 1.2; +1.2 date 70.12.31.12.15.05; author me; state bogus; branches 1.2.6.1; next 1.1; +1.1 date 70.12.31.11.00.05; author joe; state bogus; branches; next; newph; +1.2.6.1 date 71.01.01.08.00.05; author joe; state Exp; branches; next; +desc @@ +1.5 log @@ newphrase1; newphrase2 42; text @head revision@ +1.4 log @@ text @d1 1 +a1 1 +new year revision@ +1.3 log @@ text @d1 1 +a1 1 +old year revision@ +1.2 log @@ text @d1 1 +a1 1 +mid revision@ 1.1 + +log @@ text @d1 1 +a1 1 +start revision@ +1.2.6.1 log @@ text @d1 1 +a1 1 +branch revision@ +EOF + modify_repo mv $TESTDIR/file2,v $CVSROOT_DIRNAME/first-dir/file2,v + # ' Match the single quote in above here doc -- for font-lock mode. + + # First test the default branch. + dotest rcs-5 "${testcvs} -q update file2" "U file2" + dotest rcs-6 "cat file2" "branch revision" + + # Check in a revision on the branch to force CVS to + # interpret every revision in the file. + dotest rcs-6a "${testcvs} -q update -r branch file2" "" + echo "next branch revision" > file2 + dotest rcs-6b "${testcvs} -q ci -m mod file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.2\.6\.2; previous revision: 1\.2\.6\.1" + + # Now get rid of the default branch, it will get in the way. + dotest rcs-7 "${testcvs} admin -b file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + # But we do want to make sure that "cvs admin" leaves the newphrases + # in the file. + # The extra whitespace regexps are for the RCS library, which does + # not preserve whitespace in the dogmatic manner of RCS 5.7. -twp + dotest rcs-8 \ +"grep testofanewphrase ${CVSROOT_DIRNAME}/first-dir/file2,v" \ +"testofanewphrase[ ][ ]*@without newphrase we'd have trouble extending @@ all@[ ]*;" + # The easiest way to test for newphrases in deltas and deltatexts + # is to just look at the whole file, I guess. + dotest rcs-8a "cat ${CVSROOT_DIRNAME}/first-dir/file2,v" \ +"head 1\.5; +access; +symbols + branch:1.2.6; +locks; + +testofanewphrase @without newphrase we'd have trouble extending @@ all@; + +1\.5 +date 71\.01\.01\.01\.00\.00; author joe; state bogus; +branches; +next 1\.4; + +1\.4 +date 71\.01\.01\.00\.00\.05; author joe; state bogus; +branches; +next 1\.3; + +1\.3 +date 70\.12\.31\.15\.00\.05; author joe; state bogus; +branches; +next 1\.2; + +1\.2 +date 70\.12\.31\.12\.15\.05; author me; state bogus; +branches + 1\.2\.6\.1; +next 1\.1; + +1\.1 +date 70\.12\.31\.11\.00\.05; author joe; state bogus; +branches; +next ; +newph ; + +1\.2\.6\.1 +date 71\.01\.01\.08\.00\.05; author joe; state Exp; +branches; +next 1\.2\.6\.2; + +1\.2\.6\.2 +date [0-9.]*; author ${username}; state Exp; +branches; +next ; +commitid ${commitid}; + + +desc +@@ + + +1\.5 +log +@@ +newphrase1 ; +newphrase2 42; +text +@head revision@ + + +1\.4 +log +@@ +text +@d1 1 +a1 1 +new year revision@ + + +1\.3 +log +@@ +text +@d1 1 +a1 1 +old year revision@ + + +1\.2 +log +@@ +text +@d1 1 +a1 1 +mid revision@ + + +1\.1 +log +@@ +text +@d1 1 +a1 1 +start revision@ + + +1\.2\.6\.1 +log +@@ +text +@d1 1 +a1 1 +branch revision@ + + +1\.2\.6\.2 +log +@mod +@ +text +@d1 1 +a1 1 +next branch revision +@" + + dotest rcs-9 "${testcvs} -q update -p -D '1970-12-31 11:30 UT' file2" \ +"start revision" + + dotest rcs-10 "${testcvs} -q update -p -D '1970-12-31 12:30 UT' file2" \ +"mid revision" + + dotest rcs-11 "${testcvs} -q update -p -D '1971-01-01 00:30 UT' file2" \ +"new year revision" + + # Same test as rcs-10, but with am/pm. + dotest rcs-12 "${testcvs} -q update -p -D 'December 31, 1970 12:30pm UT' file2" \ +"mid revision" + + # Same test as rcs-11, but with am/pm. + dotest rcs-13 "${testcvs} -q update -p -D 'January 1, 1971 12:30am UT' file2" \ +"new year revision" + + # OK, now make sure cvs log doesn't have any trouble with the + # newphrases and such. + dotest rcs-14 "${testcvs} -q log file2" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.5 +branch: +locks: +access list: +symbolic names: + branch: 1\.2\.6 +keyword substitution: kv +total revisions: 7; selected revisions: 7 +description: +---------------------------- +revision 1\.5 +date: 1971-01-01 01:00:00 [+-]0000; author: joe; state: bogus; lines: ${PLUS}1 -1; +\*\*\* empty log message \*\*\* +---------------------------- +revision 1\.4 +date: 1971-01-01 00:00:05 [+-]0000; author: joe; state: bogus; lines: ${PLUS}1 -1; +\*\*\* empty log message \*\*\* +---------------------------- +revision 1\.3 +date: 1970-12-31 15:00:05 [+-]0000; author: joe; state: bogus; lines: ${PLUS}1 -1; +\*\*\* empty log message \*\*\* +---------------------------- +revision 1\.2 +date: 1970-12-31 12:15:05 [+-]0000; author: me; state: bogus; lines: ${PLUS}1 -1; +branches: 1\.2\.6; +\*\*\* empty log message \*\*\* +---------------------------- +revision 1\.1 +date: 1970-12-31 11:00:05 [+-]0000; author: joe; state: bogus; +\*\*\* empty log message \*\*\* +---------------------------- +revision 1\.2\.6\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +mod +---------------------------- +revision 1\.2\.6\.1 +date: 1971-01-01 08:00:05 [+-]0000; author: joe; state: Exp; lines: ${PLUS}1 -1; +\*\*\* empty log message \*\*\* +=============================================================================" + # Now test each date format for "cvs log -d". + # Earlier than 1971-01-01 + dotest rcs-15 "${testcvs} -q log -d '<1971-01-01 00:00 GMT' file2 \ + | grep revision" \ +"total revisions: 7; selected revisions: 3 +revision 1\.3 +revision 1\.2 +revision 1\.1" + # Later than 1971-01-01 + dotest rcs-16 "${testcvs} -q log -d '1971-01-01 00:00 GMT<' file2 \ + | grep revision" \ +"total revisions: 7; selected revisions: 4 +revision 1\.5 +revision 1\.4 +revision 1\.2\.6\.2 +revision 1\.2\.6\.1" + # Alternate syntaxes for later and earlier; multiple -d options + dotest rcs-17 "${testcvs} -q log -d '>1971-01-01 00:00 GMT' \ + -d '1970-12-31 12:15 GMT>' file2 | grep revision" \ +"total revisions: 7; selected revisions: 5 +revision 1\.5 +revision 1\.4 +revision 1\.1 +revision 1\.2\.6\.2 +revision 1\.2\.6\.1" + # Range, and single date + dotest rcs-18 "${testcvs} -q log -d '1970-12-31 11:30 GMT' \ + -d '1971-01-01 00:00:05 GMT<1971-01-01 01:00:01 GMT' \ + file2 | grep revision" \ +"total revisions: 7; selected revisions: 2 +revision 1\.5 +revision 1\.1" + # Alternate range syntax; equality + dotest rcs-19 "${testcvs} -q log \ + -d '1971-01-01 01:00:01 GMT>=1971-01-01 00:00:05 GMT' \ + file2 | grep revision" \ +"total revisions: 7; selected revisions: 2 +revision 1\.5 +revision 1\.4" + + dokeep + TZ=$save_TZ + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + rcs2) + # More date tests. Might as well do this as a separate + # test from "rcs", so that we don't need to perturb the + # "written by RCS 5.7" RCS file. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + # Significance of various dates: + # * At least one Y2K standard refers to recognizing 9 Sep 1999 + # (as an example of a pre-2000 date, I guess). + # * At least one Y2K standard refers to recognizing 1 Jan 2001 + # (as an example of a post-2000 date, I guess). + # * Many Y2K standards refer to 2000 being a leap year. + cat <<EOF >$TESTDIR/file1,v +head 1.7; access; symbols; locks; strict; +1.7 date 2004.08.31.01.01.01; author sue; state; branches; next 1.6; +1.6 date 2004.02.29.01.01.01; author sue; state; branches; next 1.5; +1.5 date 2003.02.28.01.01.01; author sue; state; branches; next 1.4; +1.4 date 2001.01.01.01.01.01; author sue; state; branches; next 1.3; +1.3 date 2000.02.29.01.01.01; author sue; state; branches; next 1.2; +1.2 date 99.09.09.01.01.01; author sue; state; branches; next 1.1; +1.1 date 98.09.10.01.01.01; author sue; state; branches; next; +desc @a test file@ +1.7 log @@ text @head revision@ +1.6 log @@ text @d1 1 +a1 1 +2004 was a great year for leaping@ +1.5 log @@ text @d1 1 +a1 1 +2003 wasn't@ +1.4 log @@ text @d1 1 +a1 1 +two year hiatus@ +1.3 log @@ text @d1 1 +a1 1 +2000 is also a good year for leaping@ +1.2 log @@ text @d1 1 +a1 1 +Tonight we're going to party like it's a certain year@ +1.1 log @@ text @d1 1 +a1 1 +Need to start somewhere@ +EOF + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/first-dir/file1,v + # ' Match the 3rd single quote in the here doc -- for font-lock mode. + + dotest rcs2-1 "${testcvs} -q co first-dir" 'U first-dir/file1' + cd first-dir + + # 9 Sep 1999 + dotest rcs2-2 "${testcvs} -q update -p -D '1999-09-09 11:30 UT' file1" \ +"Tonight we're going to party like it's a certain year" + # 1 Jan 2001. + dotest rcs2-3 "${testcvs} -q update -p -D '2001-01-01 11:30 UT' file1" \ +"two year hiatus" + # 29 Feb 2000 + dotest rcs2-4 "${testcvs} -q update -p -D '2000-02-29 11:30 UT' file1" \ +"2000 is also a good year for leaping" + # 29 Feb 2003 is invalid + dotest_fail rcs2-5 "${testcvs} -q update -p -D '2003-02-29 11:30 UT' file1" \ +"$CPROG \[update aborted\]: Can't parse date/time: \`2003-02-29 11:30 UT'" + + dotest rcs2-6 "${testcvs} -q update -p -D 2007-01-07 file1" \ +"head revision" + # This assumes that the clock of the machine running the tests + # is set to at least the year 1998 or so. There don't seem + # to be a lot of ways to test the relative date code (short + # of something like LD_LIBRARY_PRELOAD'ing in our own + # getttimeofday, or hacking the CVS source with testing + # features, which always seems to be problematic since then + # someone feels like documenting them and things go downhill + # from there). + # + # These tests can be expected to fail 3 times every 400 years + # starting Feb. 29, 2096 (because 8 years from that date would + # be Feb. 29, 2100, which is an invalid date -- 2100 isn't a + # leap year because it's divisible by 100 but not by 400). + + dotest rcs2-7 "${testcvs} -q update -p -D '96 months' file1" \ +"head revision" + dotest rcs2-8 "${testcvs} -q update -p -D '8 years' file1" \ +"head revision" + + dokeep + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + rcs3) + # More RCS file tests, in particular at least some of the + # error handling issues. + mkdir ${CVSROOT_DIRNAME}/first-dir + cat <<EOF >$TESTDIR/file1,v +head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 +; author jeremiah ;state ; branches; next;desc@@1.1log@@text@head@ +EOF + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/first-dir/file1,v + mkdir 1; cd 1 + # CVS requires whitespace between "desc" and its value. + # The rcsfile(5) manpage doesn't really seem to answer the + # question one way or the other (it has a grammar but almost + # nothing about lexical analysis). + dotest_fail rcs3-1 "${testcvs} -q co first-dir" \ +"${SPROG} \[checkout aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" + cat <<EOF >$TESTDIR/file1,v +head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 +; author jeremiah ;state ; branches; next;desc @@1.1log@@text@head@ +EOF + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/first-dir/file1,v + # Whitespace issues, likewise. + dotest_fail rcs3-2 "${testcvs} -q co first-dir" \ +"${SPROG} \[checkout aborted\]: unexpected '.x6c' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" + cat <<EOF >$TESTDIR/file1,v +head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 +; author jeremiah ;state ; branches; next;desc @@1.1 log@@text@head@ +EOF + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/first-dir/file1,v + # Charming array of different messages for similar + # whitespace issues (depending on where the whitespace is). + dotest_fail rcs3-3 "${testcvs} -q co first-dir" \ +"${SPROG} \[checkout aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" + cat <<EOF >$TESTDIR/file1,v +head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 +; author jeremiah ;state ; branches; next;desc @@1.1 log @@text @head@ +EOF + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/first-dir/file1,v + dotest rcs3-4 "${testcvs} -q co first-dir" 'U first-dir/file1' + + # Ouch, didn't expect this one. FIXCVS. Or maybe just remove + # the feature, if this is a -s problem? + dotest_fail rcs3-5 "${testcvs} log -s nostate first-dir/file1" \ +"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}" + cd first-dir + dotest_fail rcs3-5a "${testcvs} log -s nostate file1" \ +"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}" + cd .. + + # See remote code above for rationale for cd. + cd first-dir + dotest rcs3-6 "${testcvs} log -R file1" \ +"${CVSROOT_DIRNAME}/first-dir/file1,v" + + # OK, now put an extraneous '\0' at the end. + mv $CVSROOT_DIRNAME/first-dir/file1,v $TESTDIR/file1,v + ${AWK} </dev/null 'BEGIN { printf "@%c", 10 }' | ${TR} '@' '\000' \ + >>$TESTDIR/file1,v + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/first-dir/file1,v + dotest_fail rcs3-7 "${testcvs} log -s nostate file1" \ +"${SPROG} \[log aborted\]: unexpected '.x0' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + rcs4) + # Fix a bug that shows up when checking out files by date with the + # "-D date" command line option. There is code in the original to + # handle a special case. If the date search finds revision 1.1 it + # is supposed to check whether revision 1.1.1.1 has the same date + # stamp, which would indicate that the file was originally brought + # in with "cvs import". In that case it is supposed to return the + # vendor branch version 1.1.1.1. + # + # However, there is a bug in the code. It actually compares + # the date of revision 1.1 for equality with the date given + # on the command line -- clearly wrong. This commit fixes + # the coding bug. + # + # There is an additional bug which is _not_ fixed yet. + # The date comparison should not be a strict + # equality test. It should allow a fudge factor of, say, 2-3 + # seconds. Old versions of CVS created the two revisions + # with two separate invocations of the RCS "ci" command. We + # have many old files in the tree in which the dates of + # revisions 1.1 and 1.1.1.1 differ by 1 second. + + # Need a predictable time zone. + save_TZ=$TZ + TZ=UTC0; export TZ + + mkdir rcs4 + cd rcs4 + + mkdir imp-dir + cd imp-dir + echo 'OpenMunger sources' >file1 + + # choose a time in the past to demonstrate the problem + touch -t 200012010123 file1 + + dotest_sort rcs4-1 \ +"${testcvs} import -d -m add rcs4-dir openmunger openmunger-1_0" \ +' + +N rcs4-dir/file1 +No conflicts created by this import' + echo 'OpenMunger sources release 1.1 extras' >>file1 + touch -t 200112011234 file1 + dotest_sort rcs4-2 \ +"${testcvs} import -d -m add rcs4-dir openmunger openmunger-1_1" \ +' + +No conflicts created by this import +U rcs4-dir/file1' + cd .. + # Next checkout the new module + dotest rcs4-3 \ +"${testcvs} -q co rcs4-dir" \ +'U rcs4-dir/file1' + cd rcs4-dir + echo 'local change' >> file1 + + # commit a local change + dotest rcs4-4 "${testcvs} -q commit -m hack file1" \ +"$CVSROOT_DIRNAME/rcs4-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + # now see if we get version 1.1 or 1.1.1.1 when we ask for + # a checkout by time... it really should be 1.1.1.1 as + # that was indeed the version that was visible at the target + # time. + dotest rcs4-5 \ +"${testcvs} -q update -D 'October 1, 2001 UTC' file1" \ +'[UP] file1' + dotest rcs4-6 \ +"${testcvs} -q status file1" \ +'=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1\.1\.1.* + Repository revision: 1\.1\.1\.1 '${CVSROOT_DIRNAME}'/rcs4-dir/file1,v + Commit Identifier: '${commitid}' + Sticky Tag: (none) + Sticky Date: 2001\.10\.01\.00\.00\.00 + Sticky Options: (none)' + + dokeep + TZ=$save_TZ + cd ../.. + rm -r rcs4 + modify_repo rm -rf $CVSROOT_DIRNAME/rcs4-dir + ;; + + + + rcs5) + # Some tests of the $Log keyword and log message without a trailing + # EOL. This used to look ugly and, in the worst case, could cause + # a seg fault due to a buffer overflow. + # + # Note that it should not be possible to create this situation via a + # CVS server (and any client), since the server itself inserts the + # trailing EOL onto log messages that are missing one. Still, we + # shouldn't segfault due to a corrupt RCS file and I think that a log + # message without the trailing EOL doesn't actually violate the RCS + # spec, though it doesn't appear to be possible to create such a log + # message using RCS 5.7. + + modify_repo mkdir $CVSROOT_DIRNAME/rcs5 + cat <<\EOF >$TESTDIR/file1,v +head 1.1; +access; +symbols; +locks; +expand kv; + +1.1 date 2007.03.20.04.03.02; author jeremiah; state Ext; branches; next; + +desc +@@ + +1.1 +log +@he always had very fine wine@ +text +@line1 +/* +EOF +echo ' * History: $''Log$' >>$TESTDIR/file1,v + cat <<\EOF >>$TESTDIR/file1,v + */ +line5 +@ +EOF + modify_repo mv $TESTDIR/file1,v $CVSROOT_DIRNAME/rcs5/file1,v + + mkdir rcs5 + cd rcs5 + dotest rcs5-1 "$testcvs -Q co rcs5" + dotest rcs5-2 "cat rcs5/file1" \ +"line1 +/\\* + \\* History: "'\$'"Log: file1,v "'\$'" + \\* History: Revision 1\.1 2007/03/20 04:03:02 jeremiah + \\* History: he always had very fine wine + \\* History: + \\*/ +line5" + + cd .. + rm -r rcs5 + modify_repo rm -rf $CVSROOT_DIRNAME/rcs5 + ;; + + + + lockfiles) + # Tests of CVS lock files. + # TODO-maybe: Add a test where we arrange for a loginfo + # script (or some such) to ensure that locks are in place + # so then we can see how they are behaving. + + if $proxy; then + # don't even try + continue + fi + + mkdir 1; cd 1 + mkdir sdir + mkdir sdir/ssdir + echo file >sdir/ssdir/file1 + dotest lockfiles-1 \ +"${testcvs} -Q import -m import-it first-dir bar baz" "" + cd .. + + mkdir 2; cd 2 + dotest lockfiles-2 "${testcvs} -q co first-dir" \ +"U first-dir/sdir/ssdir/file1" + dotest lockfiles-3 "${testcvs} -Q co CVSROOT" "" + cd CVSROOT + echo "LockDir=${TESTDIR}/locks" >>config + dotest lockfiles-4 "${testcvs} -q ci -m config-it" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cd ../first-dir/sdir/ssdir + # The error message appears twice because Lock_Cleanup only + # stops recursing after the first attempt. + dotest_fail lockfiles-5 "${testcvs} -q update" \ +"${SPROG} \[update aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory" + mkdir ${TESTDIR}/locks + # Grumble, mumble. Cygwin. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod u=rwx,g=r,o= ${TESTDIR}/locks" + else + chmod u=rwx,g=r,o= ${TESTDIR}/locks + fi + save_umask=`umask` + umask 0077 + CVSUMASK=0077; export CVSUMASK + dotest lockfiles-6 "${testcvs} -q update" "" + # TODO: should also be testing that CVS continues to honor the + # umask and CVSUMASK normally. In the case of the umask, CVS + # doesn't seem to use it for much (although it perhaps should). + dotest lockfiles-7 "ls ${TESTDIR}/locks/first-dir/sdir/ssdir" "" + + # The policy is that when CVS creates new lock directories, they + # inherit the permissions from the parent directory. CVSUMASK + # isn't right, because typically the reason for LockDir is to + # use a different set of permissions. + # + # Bah! Cygwin! + if test -n "$remotehost"; then + dotest lockfiles-7a "$CVS_RSH $remotehost 'ls -ld ${TESTDIR}/locks/first-dir'" \ +"drwxr-----.*first-dir" + dotest lockfiles-7b "$CVS_RSH $remotehost 'ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir'" \ +"drwxr-----.*first-dir/sdir/ssdir" + else + dotest lockfiles-7a "ls -ld ${TESTDIR}/locks/first-dir" \ +"drwxr-----.*first-dir" + dotest lockfiles-7b "ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir" \ +"drwxr-----.*first-dir/sdir/ssdir" + fi + + cd ../../.. + dotest lockfiles-8 "${testcvs} -q update" "" + dotest lockfiles-9 "${testcvs} -q co -l ." "" + + ### + ### There are race conditions in the following tests, but hopefully + ### the 5 seconds the first process waits to remove the lockdir and + ### the 30 seconds CVS waits betweens checks will be significant + ### enough to render the case moot. + ### + # Considers the following cases: + # + # Lock Present + # Operation Allowed (case #) + # + # Read Promotable Write + # _______ __________ ______ + # Read |Yes (1) Yes (2) No (3) + # Promotable Read |Yes (4) No (5) No (6) + # Write |No (7) No (8) No (9) + # + # Tests do not appear in same ordering as table: + # 1. Read when read locks are present... + # 2. Read when promotable locks are present... + # 3. Don't read when write locks present... + # 4. Read but don't write when read locks are present... (fail + # commit up-to-date check with promotable lock present). + # 5. Don't allow promotable read when promotable locks are present... + # (fail to perform commit up-to-date check with promotable lock + # present). + # 6. Don't allow promotable read when write locks are present... + # (fail to perform commit up-to-date check with promotable lock + # present). + # 7. Don't write when read locks are present... + # 8. Don't write when promotable locks are present... + # 9. Don't write when write locks are present... + + # 3. Don't read when write locks present... + mkdir "$TESTDIR/locks/first-dir/#cvs.lock" + (sleep 5; rmdir "$TESTDIR/locks/first-dir/#cvs.lock")& + dotest lockfiles-10 "$testcvs -q co -l first-dir" \ +"$SPROG checkout: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir +$SPROG checkout: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir" + + # 1. Read when read locks are present... + touch "$TESTDIR/locks/first-dir/#cvs.rfl.test.lock" + dotest lockfiles-11 "$testcvs -q co -l first-dir" + rm "$TESTDIR/locks/first-dir/#cvs.rfl.test.lock" + + # 2. Read when promotable locks are present... + cd .. + mkdir 3; cd 3 + touch "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.pfl.test.lock" + dotest lockfiles-12 "$testcvs -q co first-dir" \ +"U first-dir/sdir/ssdir/file1" + rm "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.pfl.test.lock" + + # 7. Don't write when read locks are present... + echo I always have trouble coming up with witty text for the test files >>first-dir/sdir/ssdir/file1 + touch "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock" + (sleep 5; rm "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock")& + dotest lockfiles-13 "$testcvs -q ci -mconflict first-dir" \ +"$SPROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$SPROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- first-dir/sdir/ssdir/file1 +new revision: 1\.2; previous revision: 1\.1" + + # 4. Read but don't write when read locks are present... (fail + # commit up-to-date check with promotable lock present). + cd ../2 + echo something that would render readers all full of smiles >>first-dir/sdir/ssdir/file1 + touch "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock" + dotest_fail lockfiles-14 "$testcvs -q ci -mnot-up-to-date first-dir" \ +"$SPROG commit: Up-to-date check failed for \`first-dir/sdir/ssdir/file1' +$SPROG \[commit aborted\]: correct above errors first!" + rm "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock" + + # 5. Don't allow promotable read when promotable locks are present... + # (fail to perform commit up-to-date check with promotable lock + # present). + touch "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.pfl.test.lock" + (sleep 5; rm "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.pfl.test.lock")& + dotest_fail lockfiles-15 "$testcvs -q ci -mnot-up-to-date first-dir" \ +"$SPROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$SPROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$SPROG commit: Up-to-date check failed for \`first-dir/sdir/ssdir/file1' +$SPROG \[commit aborted\]: correct above errors first!" + + # 6. Don't allow promotable read when write locks are present... + # (fail to perform commit up-to-date check with promotable lock + # present). + mkdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock" + (sleep 5; rmdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock")& + dotest_fail lockfiles-16 "$testcvs -q ci -mnot-up-to-date first-dir" \ +"$SPROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$SPROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$SPROG commit: Up-to-date check failed for \`first-dir/sdir/ssdir/file1' +$SPROG \[commit aborted\]: correct above errors first!" + + # 8. Don't write when promotable locks are present... + dotest lockfiles-17 "$testcvs -Q up -C first-dir/sdir/ssdir" + echo the kinds of smiles that light faces for miles >>first-dir/sdir/ssdir/file1 + touch "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.pfl.test.lock" + (sleep 5; rm "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.pfl.test.lock")& + dotest lockfiles-18 "$testcvs -q ci -mnot-up-to-date first-dir" \ +"$SPROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$SPROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- first-dir/sdir/ssdir/file1 +new revision: 1\.3; previous revision: 1\.2" + + # 9. Don't write when write locks are present... + echo yet this poem would probably only give longfellow bile >>first-dir/sdir/ssdir/file1 + mkdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock" + (sleep 5; rmdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock")& + dotest lockfiles-19 "$testcvs -q ci -mnot-up-to-date first-dir" \ +"$SPROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$SPROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir +$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- first-dir/sdir/ssdir/file1 +new revision: 1\.4; previous revision: 1\.3" + + # 10. Don't write when history locks are present... + echo have you ever heard a poem quite so vile\? >>first-dir/sdir/ssdir/file1 + mkdir "$TESTDIR/locks/CVSROOT/#cvs.history.lock" + (sleep 5; rmdir "$TESTDIR/locks/CVSROOT/#cvs.history.lock")& + dotest lockfiles-20 "$testcvs -q ci -mnot-up-to-date first-dir" \ +"$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- first-dir/sdir/ssdir/file1 +new revision: 1\.5; previous revision: 1\.4 +$SPROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/CVSROOT +$SPROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT" + + dotest lockfiles-21 "$testcvs -Q tag newtag first-dir" + + rm $CVSROOT_DIRNAME/CVSROOT/val-tags + mkdir "$TESTDIR/locks/CVSROOT/#cvs.val-tags.lock" + (sleep 5; rmdir "$TESTDIR/locks/CVSROOT/#cvs.val-tags.lock")& + dotest lockfiles-22 "$testcvs -q up -r newtag first-dir" \ +"$SPROG update: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/CVSROOT +$SPROG update: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT" + + cd CVSROOT + dotest lockfiles-cleanup-1 "$testcvs -q up -pr1.1 config >config" "" + dotest lockfiles-cleanup-2 "$testcvs -q ci -m config-it" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + dokeep + cd ../.. + # Restore umask. + umask $save_umask + unset CVSUMASK + rm -r $TESTDIR/locks + rm -r 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + backuprecover) + # Tests to make sure we get the expected behavior + # when we recover a repository from an old backup + # + # Details: + # Backup will be older than some developer's workspaces + # This means the first attempt at an update will fail + # The workaround for this is to replace the CVS + # directories with those from a "new" checkout from + # the recovered repository. Due to this, multiple + # merges should cause conflicts (the same data + # will be merged more than once). + # A workspace updated before the date of the recovered + # copy will not need any extra attention + # + # Note that backuprecover-15 is probably a failure case + # If nobody else had a more recent update, the data would be lost + # permanently + # Granted, the developer should have been notified not to do this + # by now, but still... + # + mkdir backuprecover; cd backuprecover + mkdir 1; cd 1 + dotest backuprecover-1 "$testcvs -q co -l ." + mkdir first-dir + dotest backuprecover-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + mkdir dir + dotest backuprecover-3 "${testcvs} add dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository" + touch file1 dir/file2 + dotest backuprecover-4 "${testcvs} -q add file1 dir/file2" \ +"${SPROG} add: use \`${SPROG} commit' to add these files permanently" + dotest backuprecover-5 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +initial revision: 1\.1" + echo "Line one" >>file1 + echo " is the place" >>file1 + echo " we like to begin" >>file1 + echo "Anything else" >>file1 + echo " looks like" >>file1 + echo " a sin" >>file1 + echo "File 2" >>dir/file2 + echo " is the place" >>dir/file2 + echo " the rest of it goes" >>dir/file2 + echo "Why I don't use" >>dir/file2 + echo " something like 'foo'" >>dir/file2 + echo " God only knows" >>dir/file2 + dotest backuprecover-6 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +new revision: 1\.2; previous revision: 1\.1" + + # Simulate the lazy developer + # (he did some work but didn't check it in...) + cd ../.. + mkdir 2; cd 2 + dotest backuprecover-7 "${testcvs} -Q co first-dir" '' + cd first-dir + sed -e "s/looks like/just looks like/" file1 >tmp; mv tmp file1 + sed -e "s/don't use/don't just use/" dir/file2 >tmp; mv tmp dir/file2 + + # developer 1 is on a roll + cd ../../1/first-dir + echo "I need some more words" >>file1 + echo " to fill up this space" >>file1 + echo " anything else would be a disgrace" >>file1 + echo "My rhymes cross many boundries" >>dir/file2 + echo " this time it's files" >>dir/file2 + echo " a word that fits here would be something like dials" >>dir/file2 + dotest backuprecover-8 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2 +$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +new revision: 1\.3; previous revision: 1\.2" + + # Save a backup copy + cp -R $CVSROOT_DIRNAME/first-dir $TESTDIR/backup + + # Simulate developer 3 + cd ../.. + mkdir 3; cd 3 + dotest backuprecover-9a "${testcvs} -Q co first-dir" '' + cd first-dir + echo >>file1 + echo >>dir/file2 + echo "Developer 1 makes very lame rhymes" >>file1 + echo " I think he should quit and become a mime" >>file1 + echo "What the %*^# kind of rhyme crosses a boundry?" >>dir/file2 + echo " I think you should quit and get a job in the foundry" >>dir/file2 + dotest backuprecover-9b "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3 +$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +new revision: 1\.4; previous revision: 1\.3" + + # Developer 4 so we can simulate a conflict later... + cd ../.. + mkdir 4; cd 4 + dotest backuprecover-10 "${testcvs} -Q co first-dir" '' + cd first-dir + sed -e "s/quit and/be fired so he can/" dir/file2 >tmp; mv tmp dir/file2 + + # And back to developer 1 + cd ../../1/first-dir + dotest backuprecover-11 "${testcvs} -Q update" '' + echo >>file1 + echo >>dir/file2 + echo "Oh yeah, well rhyme this" >>file1 + echo " developer three" >>file1 + echo " you want opposition" >>file1 + echo " you found some in me!" >>file1 + echo "I'll give you mimes" >>dir/file2 + echo " and foundries galore!" >>dir/file2 + echo " your head will spin" >>dir/file2 + echo " once you find what's in store!" >>dir/file2 + dotest backuprecover-12 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4 +$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +new revision: 1\.5; previous revision: 1\.4" + + # developer 3'll do a bit of work that never gets checked in + cd ../../3/first-dir + dotest backuprecover-13 "${testcvs} -Q update" '' + sed -e "s/very/some extremely/" file1 >tmp; mv tmp file1 + dotest backuprecover-14 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.6; previous revision: 1\.5" + echo >>file1 + echo "Tee hee hee hee" >>file1 + echo >>dir/file2 + echo "Find what's in store?" >>dir/file2 + echo " Oh, I'm so sure!" >>dir/file2 + echo " You've got an ill, and I have the cure!" >>dir/file2 + + # Slag the original and restore it a few revisions back + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + modify_repo mv $TESTDIR/backup $CVSROOT_DIRNAME/first-dir + + # Have developer 1 try an update and lose some data + # + # Feel free to imagine the horrific scream of despair + cd ../../1/first-dir + dotest backuprecover-15 "${testcvs} update" \ +"${SPROG} update: Updating . +U file1 +${SPROG} update: Updating dir +U dir/file2" + + # Developer 3 tries the same thing (he has an office) + # but fails without losing data since all of his files have + # uncommitted changes + cd ../../3/first-dir + dotest_fail backuprecover-16 "${testcvs} update" \ +"${SPROG} update: Updating \. +${SPROG} \[update aborted\]: could not find desired version 1\.6 in ${CVSROOT_DIRNAME}/first-dir/file1,v" + + # create our workspace fixin' script + cd ../.. + echo \ +"#!$TESTSHELL + +# This script will copy the CVS database dirs from the checked out +# version of a newly recovered repository and replace the CVS +# database dirs in a workspace with later revisions than those in the +# recovered repository +cd repos-first-dir +DATADIRS=\`find . -name CVS -print\` +cd ../first-dir +find . -name CVS -print | xargs rm -rf +for file in \${DATADIRS}; do + cp -R ../repos-first-dir/\${file} \${file} +done" >fixit + + # We only need to fix the workspaces of developers 3 and 4 + # (1 lost all her data and 2 has an update date from + # before the date the backup was made) + cd 3 + dotest backuprecover-17 \ + "${testcvs} -Q co -d repos-first-dir first-dir" '' + cd ../4 + dotest backuprecover-18 \ + "${testcvs} -Q co -d repos-first-dir first-dir" '' + sh ../fixit + cd ../3; sh ../fixit + + # (re)commit developer 3's stuff + cd first-dir + dotest backuprecover-19 "${testcvs} -q ci -mrecover/merge" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3 +$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +new revision: 1\.4; previous revision: 1\.3" + + # and we should get a conflict on developer 4's stuff + cd ../../4/first-dir + dotest backuprecover-20 "${testcvs} update" \ +"${SPROG} update: Updating \. +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.3 +retrieving revision 1\.4 +Merging differences between 1\.3 and 1\.4 into file1 +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in file1 +C file1 +${SPROG} update: Updating dir +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v +retrieving revision 1\.3 +retrieving revision 1\.4 +Merging differences between 1\.3 and 1\.4 into file2 +rcsmerge: warning: conflicts during merge +${SPROG} update: conflicts found in dir/file2 +C dir/file2" + sed -e \ +"/^<<<<<<</,/^=======/d +/^>>>>>>>/d" file1 >tmp; mv tmp file1 + sed -e \ +"/^<<<<<<</,/^=======/d +/^>>>>>>>/d +s/quit and/be fired so he can/" dir/file2 >tmp; mv tmp dir/file2 + dotest backuprecover-21 "${testcvs} -q ci -mrecover/merge" \ +"$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +new revision: 1\.5; previous revision: 1\.4" + + # go back and commit developer 2's stuff to prove it can still be done + cd ../../2/first-dir + dotest backuprecover-22 "${testcvs} -Q update" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.2 +retrieving revision 1\.4 +Merging differences between 1\.2 and 1\.4 into file1 +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v +retrieving revision 1\.2 +retrieving revision 1\.5 +Merging differences between 1\.2 and 1\.5 into file2" + dotest backuprecover-23 "${testcvs} -q ci -mtest" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4 +$CVSROOT_DIRNAME/first-dir/dir/file2,v <-- dir/file2 +new revision: 1\.6; previous revision: 1\.5" + + # and restore the data to developer 1 + cd ../../1/first-dir + dotest backuprecover-24 "${testcvs} -Q update" '' + + dokeep + cd ../../.. + rm -r backuprecover + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + sshstdio) + # CVS_RSH=ssh can have a problem with a non-blocking stdio + # in some cases. So, this test is all about testing :ext: + # with CVS_RSH=ssh. The problem is that not all machines + # will necessarily have ssh available, so be prepared to + # skip this test. + + if $proxy; then + notproxy sshstdio + continue + fi + + if $remote; then :; else + remoteonly sshstdio + continue + fi + + require_ssh + if test $? -eq 77; then + skip sshstdio "$skipreason" + continue + fi + + SSHSTDIO_ROOT=:ext:$host$CVSROOT_DIRNAME + + mkdir sshstdio; cd sshstdio + dotest sshstdio-1 "$testcvs -d $SSHSTDIO_ROOT -q co -l ." + mkdir first-dir + dotest sshstdio-2 "$testcvs add first-dir" \ + "Directory $CVSROOT_DIRNAME/first-dir added to the repository" + cd first-dir + a='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + c='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + # Generate 1024 lines of $a + cnt=0 + echo $a > aaa + while [ $cnt -lt 5 ] ; do + cnt=`expr $cnt + 1` ; + mv aaa aaa.old + cat aaa.old aaa.old aaa.old aaa.old > aaa + done + dotest sshstdio-3 "$testcvs -q add aaa" \ +"$SPROG add: use .$SPROG commit. to add this file permanently" + dotest sshstdio-4 "$testcvs -q ci -mcreate aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +initial revision: 1\.1" + # replace lines 1, 512, 513, 1024 with $c + sed 510q < aaa > aaa.old + (echo $c; cat aaa.old; echo $c; \ + echo $c; cat aaa.old; echo $c) > aaa + dotest sshstdio-5 "$testcvs -q ci -mmodify-it aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.2; previous revision: 1\.1" + cat > wrapper.sh <<EOF +#!$TESTSHELL +exec "\$@" 2>&1 < /dev/null | cat +EOF + chmod +x wrapper.sh + ./wrapper.sh \ + $testcvs -z5 -Q diff --side-by-side -W 500 -r 1.1 -r 1.2 \ + aaa > wrapper.dif + + $testcvs -z5 -Q diff --side-by-side -W 500 -r 1.1 -r 1.2 \ + aaa > good.dif + + dotest sshstdio-6 "cmp wrapper.dif good.dif" + + dokeep + cd ../.. + CVS_RSH=$save_CVS_RSH; export CVS_RSH + rm -r sshstdio + rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + parseroot2) + # Test some :ext: roots for consistancy. + if $remote; then :; else + remoteonly parseroot2 + continue + fi + + require_rsh "$CVS_RSH" + if test $? -eq 77; then + skip parseroot2 "$skipreason" + continue + fi + + # Test checking out and subsequently updating with some different + # CVSROOTs. + + # A standard case, hostname:dirname. + mkdir parseroot2; cd parseroot2 + save_CVSROOT=$CVSROOT + CVSROOT=$host:$CVSROOT_DIRNAME + dotest parseroot2-1 "$testcvs -Q co CVSROOT" + cd CVSROOT + dotest parseroot2-2 "$testcvs -Q up" + cd .. + + # A degenerate remote case, just the server name and the directory + # name, with no :'s to help parsing. It can be mistaken for a + # relative directory name. + rm -r CVSROOT + CVSROOT=$host$CVSROOT_DIRNAME + dotest parseroot2-3 "$testcvs -Q co CVSROOT" + cd CVSROOT + dotest parseroot2-4 "$testcvs -Q up" + + dokeep + cd ../.. + CVSROOT=$save_CVSROOT + rm -r parseroot2 + ;; + + + + parseroot3) + # Test some :ext: roots for consistancy. + if $remote; then :; else + remoteonly parseroot3 + continue + fi + + require_rsh "$CVS_RSH" + if test $? -eq 77; then + skip parseroot3 "$skipreason" + continue + fi + + # Test checking out and subsequently updating with some different + # CVSROOTs. + + # A standard case, hostname:dirname. + mkdir parseroot3; cd parseroot3 + save_CVSROOT=$CVSROOT + save_CVS_RSH=$CVS_RSH + save_CVS_SERVER=$CVS_SERVER + unset CVS_RSH + unset CVS_SERVER + CVSROOT=":ext;CVS_RSH=$save_CVS_RSH;CVS_SERVER=$save_CVS_SERVER:$host:$CVSROOT_DIRNAME" + dotest parseroot3-1 "$testcvs -Q co CVSROOT" + cd CVSROOT + dotest parseroot3-2 "$testcvs -Q up" + cd .. + + # Initial checkout. + rm -r CVSROOT + CVSROOT=":ext;cvs_RSH=$save_CVS_RSH;CVS_Server=$save_CVS_SERVER:$host$CVSROOT_DIRNAME" + dotest parseroot3-3 "$testcvs -Q co CVSROOT" + cd CVSROOT + dotest parseroot3-4 "$testcvs -Q up" + cd .. + + # Checkout bogus values for Redirect + rm -r CVSROOT + CVSROOT=":ext;Redirect=bogus;CVS_RSH=$save_CVS_RSH;CVS_SERVER=$save_CVS_SERVER:$host$CVSROOT_DIRNAME" + dotest parseroot3-5 "$testcvs -Q co CVSROOT" \ +"$SPROG checkout: CVSROOT: unrecognized value \`bogus' for \`Redirect'" + cd CVSROOT + # FIXCVS: parse_cvsroot is called more often that is + # desirable. + dotest parseroot3-6 "$testcvs -Q up" \ +"$SPROG update: CVSROOT: unrecognized value \`bogus' for \`Redirect'" + cd .. + + # Checkout good values for Redirect + rm -r CVSROOT + CVSROOT=":EXT;Redirect=no;CVS_RSH=$save_CVS_RSH;CVS_SERVER=$save_CVS_SERVER:$host$CVSROOT_DIRNAME" + dotest parseroot3-7 "$testcvs -Q co CVSROOT" + cd CVSROOT + dotest parseroot3-8 "$testcvs -Q up" + cd .. + + dotest parseroot3-9 "$testcvs -Q co -ldtop ." + dotest parseroot3-10 "test -d top" + dotest parseroot3-11 "test -d top/CVS" + dotest parseroot3-10 "cat top/CVS/Root" "$CVSROOT" + + dokeep + cd .. + CVSROOT=$save_CVSROOT + CVS_RSH=$save_CVS_RSH + CVS_SERVER=$save_CVS_SERVER + export CVS_RSH CVS_SERVER + rm -r parseroot3 + ;; + + + + history) + # CVSROOT/history tests: + # history: various "cvs history" invocations + # basic2: Generating the CVSROOT/history file via CVS commands. + + # Put in some data for the history file (discarding what was + # there before). Note that this file format is fixed; the + # user may wish to analyze data from a previous version of + # CVS. If we phase out this format, it should be done + # slowly and carefully. + + if $proxy; then + # don't even try + continue + fi + + cat <<EOF >$CVSROOT_DIRNAME/CVSROOT/history +O3395c677|anonymous|<remote>/*0|ccvs||ccvs +O3396c677|anonymous|<remote>/src|ccvs||src +O3397c677|kingdon|<remote>/*0|ccvs||ccvs +M339cafae|nk|<remote>|ccvs/src|1.229|sanity.sh +M339cafff|anonymous|<remote>|ccvs/src|1.23|Makefile +M339dc339|kingdon|~/work/*0|ccvs/src|1.231|sanity.sh +W33a6eada|anonymous|<remote>*4|ccvs/emx||Makefile.in +C3b235f50|kingdon|<remote>|ccvs/emx|1.3|README +M3b23af50|kingdon|~/work/*0|ccvs/doc|1.281|cvs.texinfo +EOF + + dotest history-1 "${testcvs} history -e -a" \ +"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= <remote>/\* +O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= <remote>/\* +M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote> +W 1997-06-17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == <remote>/emx +O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= <remote>/\* +M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src +C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote> +M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc +M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>" + + dotest history-2 "${testcvs} history -e -a -D '10 Jun 1997 13:00 UT'" \ +"W 1997-06-17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == <remote>/emx +M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src +C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote> +M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc" + + dotest history-3 "${testcvs} history -e -a -D '10 Jun 2001 13:00 UT'" \ +"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc" + + dotest history-4 "${testcvs} history -ac sanity.sh" \ +"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src +M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>" + + dotest history-5 "${testcvs} history -a -xCGUWAMR README sanity.sh" \ +"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src +C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote> +M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>" + + dotest history-6 "${testcvs} history -xCGUWAMR -a -f README -f sanity.sh" \ +"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src +C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote> +M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>" + + dotest history-7 "${testcvs} history -xCGUWAMR -a -f sanity.sh README" \ +"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src +C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote> +M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>" + + dotest history-8 "${testcvs} history -ca -D '1970-01-01 00:00 UT'" \ +"M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity.sh ccvs/src == <remote> +M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote> +M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src +M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc" + + dotest history-9 "${testcvs} history -acl" \ +"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc +M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote> +M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src" + + dotest history-10 "${testcvs} history -lca -D '1970-01-01 00:00 UT'" \ +"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc +M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote> +M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src" + + dotest history-11 "${testcvs} history -aw" \ +"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= <remote>/\* +O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= <remote>/\* +O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= <remote>/\*" + + dotest history-12 "${testcvs} history -aw -D'1970-01-01 00:00 UT'" \ +"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= <remote>/\* +O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= <remote>/\* +O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= <remote>/\*" + ;; + + + + big) + + # Test ability to operate on big files. Intention is to + # test various realloc'ing code in RCS_deltas, rcsgetkey, + # etc. "big" is currently defined to be 1000 lines (64000 + # bytes), which in terms of files that users will use is not + # large, merely average, but my reasoning is that this + # should be big enough to make sure realloc'ing is going on + # and that raising it a lot would start to stress resources + # on machines which run the tests, without any significant + # benefit. + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest big-1 "$testcvs -q co first-dir" + cd first-dir + for i in 0 1 2 3 4 5 6 7 8 9; do + for j in 0 1 2 3 4 5 6 7 8 9; do + for k in 0 1 2 3 4 5 6 7 8 9; do + echo \ +"This is line ($i,$j,$k) which goes into the file file1 for testing" >>file1 + done + done + done + dotest big-2 "$testcvs add file1" \ +"$SPROG add: scheduling file .file1. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest big-3 "$testcvs -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + cd .. + mkdir 2 + cd 2 + dotest big-4 "$testcvs -q get first-dir" "U first-dir/file1" + cd ../first-dir + echo "add a line to the end" >>file1 + + dotest_fail big-4b "$testcvs -q diff -u" \ +"Index: file1 +=================================================================== +RCS file: $CVSROOT_DIRNAME/first-dir/file1,v +retrieving revision 1\.1 +diff -u -r1\.1 file1 +--- file1 $RFCDATE 1\.1 +$PLUS$PLUS$PLUS file1 $RFCDATE +@@ -998,3 ${PLUS}998,4 @@ + This is line (9,9,7) which goes into the file file1 for testing + This is line (9,9,8) which goes into the file file1 for testing + This is line (9,9,9) which goes into the file file1 for testing +${PLUS}add a line to the end" + + dotest big-5 "$testcvs -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + cd ../2/first-dir + # The idea here is particularly to test the Rcs-diff response + # and the reallocing thereof, for remote. + dotest big-6 "$testcvs -q update" "[UP] file1" + + dokeep + cd ../.. + rm -r first-dir 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + modes) + # Test repository permissions (CVSUMASK and so on). + # Although the tests in this section "cheat" by testing + # repository permissions, which are sort of not a user-visible + # sort of thing, the modes do have user-visible consequences, + # such as whether a second user can check out the files. But + # it would be awkward to test the consequences, so we don't. + + # Solaris /bin/sh doesn't support export -n. I'm not sure + # what we can do about this, other than hope that whoever + # is running the tests doesn't have CVSUMASK set. + #export -n CVSUMASK # if unset, defaults to 002 + + save_umask=`umask` + umask 077 + mkdir 1; cd 1 + dotest modes-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest modes-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch aa + dotest modes-3 "${testcvs} add aa" \ +"${SPROG} add: scheduling file .aa. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest modes-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +initial revision: 1\.1" + # Yawn. Cygwin. + if test -n "$remotehost"; then + dotest modes-5remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \ +"-r--r--r-- .*" + else + dotest modes-5 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ +"-r--r--r-- .*" + fi + + # Test for whether we can set the execute bit. + chmod +x aa + echo change it >>aa + dotest modes-6 "${testcvs} -q ci -m set-execute-bit" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +new revision: 1\.2; previous revision: 1\.1" + # If CVS let us update the execute bit, it would be set here. + # But it doesn't, and as far as I know that is longstanding + # CVS behavior. + # + # Yeah, yeah. Search for "Cygwin". + if test -n "$remotehost"; then + dotest modes-7remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \ +"-r--r--r-- .*" + else + dotest modes-7 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ +"-r--r--r-- .*" + fi + + # OK, now manually change the modes and see what happens. + # + # Cygwin, already. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v" + else + chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v + fi + echo second line >>aa + dotest modes-7a "${testcvs} -q ci -m set-execute-bit" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +new revision: 1\.3; previous revision: 1\.2" + # Cygwin. + if test -n "$remotehost"; then + dotest modes-7bremotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \ +"-r--r----- .*" + else + dotest modes-7b "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ +"-r--r----- .*" + fi + + CVSUMASK=007 + export CVSUMASK + touch ab + # Might as well test the execute bit too. + chmod +x ab + dotest modes-8 "$testcvs add ab" \ +"$SPROG add: scheduling file .ab. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest modes-9 "$testcvs -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/ab,v <-- ab +initial revision: 1\.1" + + # The ssh-wrapper script set up by this script forwards CVSUMASK to + # the server. In practice it would be set on the server in some + # other manner (for instance, by the `env' command, or as an option + # in the xinted.conf file). + # + # I don't recall why, but I used to look for: + # + # dotest modes-10remotehost \ + # "$CVS_RSH $remotehost 'ls -l $CVSROOT_DIRNAME/first-dir/ab,v'" \ + # "-r--r--r--.*" + # + # here when $remotehost was set. I'm not sure why. Maybe this was + # one of the innumerable Cygwin issues? + dotest modes-10 "ls -l $CVSROOT_DIRNAME/first-dir/ab,v" \ +"-r-xr-x---.*" + + # OK, now add a file on a branch. Check that the mode gets + # set the same way (it is a different code path in CVS). + dotest modes-11 "${testcvs} -q tag -b br" 'T aa +T ab' + dotest modes-12 "${testcvs} -q update -r br" '' + touch ac + dotest modes-13 "${testcvs} add ac" \ +"${SPROG} add: scheduling file .ac. for addition on branch .br. +${SPROG} add: use .${SPROG} commit. to add this file permanently" + # Not sure it really makes sense to refer to a "previous revision" + # when we are just now adding the file; as far as I know + # that is longstanding CVS behavior, for what it's worth. + dotest modes-14 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/Attic/ac,v <-- ac +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # ssh-wrapper forwards CVSUMASK. See modes-10 for notes. + dotest modes-15 \ +"ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v" \ +"-r--r-----.*" + + dokeep + cd ../.. + # Restore umask. + umask $save_umask + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + modes2) + # More tests of file permissions in the working directory + # and that sort of thing. + + # The usual setup, file first-dir/aa with two revisions. + mkdir 1; cd 1 + dotest modes2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest modes2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch aa + dotest modes2-3 "${testcvs} add aa" \ +"${SPROG} add: scheduling file .aa. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest modes2-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +initial revision: 1\.1" + echo "more money" >> aa + dotest modes2-5 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +new revision: 1\.2; previous revision: 1\.1" + + # OK, here is the test. The idea is to see what + # No_Difference does if it can't open the file. + # If we don't change the st_mtime, CVS doesn't even try to read + # the file. Note that some versions of "touch" require that we + # do this while the file is still writable. + touch aa + chmod a= aa + # Don't try this when permissions are broken, as with Cygwin. + if ${LS} ${CVSROOT_DIRNAME}/first-dir >/dev/null 2>&1; then :; else + dotest_fail modes2-6 "${testcvs} -q update -r 1.1 aa" \ +"${CPROG} \[update aborted\]: cannot open file aa for comparing: Permission denied" \ +"${CPROG} \[update aborted\]: reading aa: Permission denied" + fi + + dokeep + chmod u+rwx aa + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + modes3) + # Repository permissions. Particularly, what happens if we + # can't read/write in the repository. + # TODO: the case where we can access the repository, just not + # the attic (may that one can remain a fatal error, seems less + # useful for access control). + mkdir 1; cd 1 + dotest modes3-1 "$testcvs -q co -l ." + mkdir first-dir second-dir + dotest modes3-2 "${testcvs} add first-dir second-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" + touch first-dir/aa second-dir/ab + dotest modes3-3 "${testcvs} add first-dir/aa second-dir/ab" \ +"${SPROG} add: scheduling file .first-dir/aa. for addition +${SPROG} add: scheduling file .second-dir/ab. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest modes3-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- first-dir/aa +initial revision: 1\.1 +$CVSROOT_DIRNAME/second-dir/ab,v <-- second-dir/ab +initial revision: 1\.1" + # quiet down this one as it will be noisy in proxy mode + modify_repo chmod a= $CVSROOT_DIRNAME/first-dir >/dev/null 2>&1 + if ${LS} ${CVSROOT_DIRNAME}/first-dir >/dev/null 2>&1; then + # Avoid this test under Cygwin since permissions work differently + # there. + # + # This test also gets avoided under Mac OS X since the system `ls' + # is broken and exits with a 0 status despite the permission + # denied error. + if test -n "$remotehost"; then + cygwin_hack=false + else + cygwin_hack=: + fi + else + cygwin_hack=false + fi + + cd $TESTDIR/1 + if $cygwin_hack; then :; else + dotest modes3-5 "${testcvs} update" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating first-dir +${SPROG} update: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied +${SPROG} update: skipping directory first-dir +${SPROG} update: Updating second-dir" + fi + + # OK, I can see why one might say the above case could be a + # fatal error, because normally users without access to first-dir + # won't have it in their working directory. But the next + # one is more of a problem if it is fatal. + # + # The second text string below is for Cygwin again, and again it + # should really be XFAIL under Cygwin, but for now deal with the + # passing opendir by accepting the alternate string. + rm -r first-dir + dotest modes3-6 "${testcvs} update -dP" \ +"${SPROG} update: Updating . +${SPROG} update: Updating CVSROOT +U ${DOTSTAR} +${SPROG} update: Updating first-dir +${SPROG} update: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied +${SPROG} update: skipping directory first-dir +${SPROG} update: Updating second-dir" \ +"${SPROG} update: Updating . +${SPROG} update: Updating CVSROOT +U ${DOTSTAR} +${SPROG} update: Updating first-dir +${SPROG} update: Updating second-dir" + + dokeep + cd .. + rm -r 1 + # quiet down this one as it will be noisy in proxy mode + modify_repo chmod u+rwx $CVSROOT_DIRNAME/first-dir 2>/dev/null + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir \ + $CVSROOT_DIRNAME/second-dir + ;; + + + + stamps) + # Test timestamps. + mkdir 1; cd 1 + dotest stamps-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest stamps-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch aa + echo '$''Id$' >kw + # Cygwin, *cough*, puts the year in the time column until the minute + # is no longer the current minute. Sleep 60 seconds to avoid this + # problem. + sleep 60 + ls -l aa >${TESTDIR}/1/stamp.aa.touch + ls -l kw >${TESTDIR}/1/stamp.kw.touch + # "sleep 1" would suffice if we could assume ls --full-time, but + # that is as far as I know unique to GNU ls. Is there some POSIX.2 + # way to get the timestamp of a file, including the seconds? + sleep 60 + dotest stamps-3 "${testcvs} add aa kw" \ +"${SPROG} add: scheduling file .aa. for addition +${SPROG} add: scheduling file .kw. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + ls -l aa >${TESTDIR}/1/stamp.aa.add + ls -l kw >${TESTDIR}/1/stamp.kw.add + # "cvs add" should not muck with the timestamp. + dotest stamps-4aa \ +"cmp ${TESTDIR}/1/stamp.aa.touch ${TESTDIR}/1/stamp.aa.add" '' + dotest stamps-4kw \ +"cmp ${TESTDIR}/1/stamp.kw.touch ${TESTDIR}/1/stamp.kw.add" '' + sleep 60 + dotest stamps-5 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/kw,v <-- kw +initial revision: 1\.1" + # Cygwin, *cough*, puts the year in the time column until the minute + # is no longer the current minute. Sleep 60 seconds to avoid this + # problem. + sleep 60 + ls -l aa >${TESTDIR}/1/stamp.aa.ci + ls -l kw >${TESTDIR}/1/stamp.kw.ci + # If there are no keywords, "cvs ci" leaves the timestamp alone + # If there are, it sets the timestamp to the date of the commit. + # I'm not sure how logical this is, but it is intentional. + # If we wanted to get fancy we would make sure the time as + # reported in "cvs log kw" matched stamp.kw.ci. But that would + # be a lot of work. + dotest stamps-6aa \ + "cmp ${TESTDIR}/1/stamp.aa.add ${TESTDIR}/1/stamp.aa.ci" '' + if cmp ${TESTDIR}/1/stamp.kw.add ${TESTDIR}/1/stamp.kw.ci >/dev/null + then + fail stamps-6kw + else + pass stamps-6kw + fi + cd ../.. + sleep 60 + mkdir 2 + cd 2 + dotest stamps-7 "${testcvs} -q get first-dir" "U first-dir/aa +U first-dir/kw" + cd first-dir + ls -l aa >${TESTDIR}/1/stamp.aa.get + ls -l kw >${TESTDIR}/1/stamp.kw.get + # On checkout, CVS should set the timestamp to the date that the + # file was committed. Could check that the time as reported in + # "cvs log aa" matches stamp.aa.get, but that would be a lot of + # work. + dotest_fail stamps-8aa \ +"cmp $TESTDIR/1/stamp.aa.ci $TESTDIR/1/stamp.aa.get >/dev/null" + dotest stamps-8kw \ +"cmp $TESTDIR/1/stamp.kw.ci $TESTDIR/1/stamp.kw.get" + + # Now we want to see what "cvs update" does. + sleep 60 + echo add a line >>aa + echo add a line >>kw + dotest stamps-9 "${testcvs} -q ci -m change-them" \ +"$CVSROOT_DIRNAME/first-dir/aa,v <-- aa +new revision: 1\.2; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/kw,v <-- kw +new revision: 1\.2; previous revision: 1\.1" + + # Cygwin, *cough*, puts the year in the time column until the minute + # is no longer the current minute. Sleep 60 seconds to avoid this + # problem. + sleep 60 + ls -l aa >${TESTDIR}/1/stamp.aa.ci2 + ls -l kw >${TESTDIR}/1/stamp.kw.ci2 + cd ../.. + cd 1/first-dir + sleep 60 + dotest stamps-10 "${testcvs} -q update" '[UP] aa +[UP] kw' + # this doesn't serve any function other than being able to + # look at it manually, as we have no machinery for dates being + # newer or older than other dates. + date >$TESTDIR/1/stamp.debug.update + ls -l aa >$TESTDIR/1/stamp.aa.update + ls -l kw >$TESTDIR/1/stamp.kw.update + # stamp.aa.update and stamp.kw.update should both be approximately + # the same as stamp.debug.update. Perhaps we could be testing + # this in a more fancy fashion by "touch stamp.before" before + # stamps-10, "touch stamp.after" after, and then using ls -t + # to check them. But for now we just make sure that the *.update + # stamps differ from the *.ci2 ones. + # As for the rationale, this is so that if one updates and gets + # a new revision, then "make" will be sure to regard those files + # as newer than .o files which may be sitting around. + dotest_fail stamps-11aa \ +"cmp $TESTDIR/1/stamp.aa.update $TESTDIR/1/stamp.aa.ci2 >/dev/null" + dotest_fail stamps-11kw \ +"cmp $TESTDIR/1/stamp.kw.update $TESTDIR/1/stamp.kw.ci2 >/dev/null" + + dokeep + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + perms) + mkdir 1; cd 1 + dotest perms-init-1 "$testcvs -Q co CVSROOT" + cd CVSROOT + echo 'PreservePermissions=yes' >> ${CVSROOT_DIRNAME}/CVSROOT/config + dotest perms-init-2 "$testcvs -Q ci -mperms" + cd .. + + dotest perms-1 "$testcvs -q co -l ." + mkdir first-dir + dotest perms-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + touch foo + chmod 431 foo + dotest perms-3 "${testcvs} add foo" \ +"${SPROG} add: scheduling file .foo. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest perms-4 "${testcvs} -q ci -m ''" \ +"$CVSROOT_DIRNAME/first-dir/foo,v <-- foo +initial revision: 1\.1" + + # Test checking out files with different permissions. + cd ../.. + mkdir 2; cd 2 + dotest perms-5 "${testcvs} -q co first-dir" "U first-dir/foo" + cd first-dir + if $remote; then :; else + # PreservePermissions not yet implemented for remote. + dotest perms-6 "ls -l foo" "-r---wx--x .* foo" + fi + + dokeep + cd ../1/CVSROOT + restore_adm + cd ../.. + rm -rf 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + symlinks) + # short cut around checking out and committing CVSROOT + rm -f $CVSROOT_DIRNAME/CVSROOT/config + echo 'PreservePermissions=yes' >> $CVSROOT_DIRNAME/CVSROOT/config + chmod 444 $CVSROOT_DIRNAME/CVSROOT/config + + mkdir 1; cd 1 + dotest symlinks-1 "$testcvs -q co -l ." + mkdir first-dir + dotest symlinks-2 "$testcvs add first-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir added to the repository" + cd first-dir + + dotest symlinks-2.1 "ln -s $TESTDIR/fumble slink" + dotest symlinks-3 "$testcvs add slink" \ +"$SPROG add: scheduling file .slink. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + if $remote; then + # Remote doesn't implement PreservePermissions, and in its + # absence the correct behavior is to follow the symlink. + dotest_fail symlinks-4r "$testcvs -q ci -m ''" \ +"$SPROG \[commit aborted\]: reading slink: No such file or directory" + else + dotest symlinks-4 "$testcvs -q ci -m ''" \ +"$CVSROOT_DIRNAME/first-dir/slink,v <-- slink +initial revision: 1\.1" + + # Test checking out symbolic links. + cd ../.. + mkdir 2; cd 2 + dotest symlinks-5 "$testcvs -q co first-dir" "U first-dir/slink" + cd first-dir + dotest symlinks-6 "ls -l slink" \ +"l[rwx\-]* .* slink -> $TESTDIR/fumble" + fi + + dokeep + cd ../.. + rm -rf 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + restore_adm + ;; + + + + symlinks2) + # Symlinks in working directory without PreservePermissions. + # Also see: symlinks: with PreservePermissions + # rcslib-symlink-*: symlinks in repository. + mkdir 1; cd 1 + dotest symlinks2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest symlinks2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo nonsymlink > slink + dotest symlinks2-3 "${testcvs} add slink" \ +"${SPROG} add: scheduling file .slink. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest symlinks2-4 "${testcvs} -q ci -m ''" \ +"$CVSROOT_DIRNAME/first-dir/slink,v <-- slink +initial revision: 1\.1" + rm slink + # Choose name cvslog.* so it is in default ignore list. + echo second file >cvslog.file2 + dotest symlinks2-5 "ln -s cvslog.file2 slink" "" + dotest symlinks2-6 "${testcvs} -q ci -m linkify" \ +"$CVSROOT_DIRNAME/first-dir/slink,v <-- slink +new revision: 1\.2; previous revision: 1\.1" + dotest symlinks2-7 "${testcvs} -q update -r 1.1 slink" "[UP] slink" + dotest symlinks2-8 "cat slink" "nonsymlink" + dotest symlinks2-9 "ls -l slink" "-[-rwx]* .* slink" + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + hardlinks) + # short cut around checking out and committing CVSROOT + rm -f ${CVSROOT_DIRNAME}/CVSROOT/config + echo 'PreservePermissions=yes' > ${CVSROOT_DIRNAME}/CVSROOT/config + chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config + + mkdir 1; cd 1 + dotest hardlinks-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest hardlinks-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + # Make up some ugly filenames, to test that they get + # encoded properly in the delta nodes. Note that `dotest' screws + # up if some arguments have embedded spaces. + if touch aaaa + then + pass hardlinks-2.1 + else + fail hardlinks-2.1 + fi + + if ln aaaa b.b.b.b + then + pass hardlinks-2.2 + else + fail hardlinks-2.2 + fi + + if ln aaaa 'dd dd dd' + then + pass hardlinks-2.3 + else + fail hardlinks-2.3 + fi + + dotest hardlinks-3 "${testcvs} add [abd]*" \ +"${SPROG} add: scheduling file .aaaa. for addition +${SPROG} add: scheduling file .b\.b\.b\.b. for addition +${SPROG} add: scheduling file .dd dd dd. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest hardlinks-4 "${testcvs} -q ci -m ''" \ +"$CVSROOT_DIRNAME/first-dir/aaaa,v <-- aaaa +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/b\.b\.b\.b,v <-- b\.b\.b\.b +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/dd dd dd,v <-- dd dd dd +initial revision: 1\.1" + # Test checking out hardlinked files. + cd ../.. + mkdir 2; cd 2 + if $remote; then + # Remote does not implement PreservePermissions. + dotest hardlinks-5r "${testcvs} -q co first-dir" \ +"U first-dir/aaaa +U first-dir/b\.b\.b\.b +U first-dir/dd dd dd" + cd first-dir + dotest hardlinks-6r "ls -l [abd]*" \ +"-[rwx\-]* *1 .* aaaa +-[rwx\-]* *1 .* b\.b\.b\.b +-[rwx\-]* *1 .* dd dd dd" + else + dotest hardlinks-5 "${testcvs} -q co first-dir" \ +"U first-dir/aaaa +U first-dir/b\.b\.b\.b +U first-dir/dd dd dd" + cd first-dir + # To make sure that the files are properly hardlinked, it + # would be nice to do `ls -i' and make sure all the inodes + # match. But I think that would require expr to support + # tagged regexps, and I don't think we can rely on that. + # So instead we just see that each file has the right + # number of links. -twp + dotest hardlinks-6 "ls -l [abd]*" \ +"-[rwx\-]* *3 .* aaaa +-[rwx\-]* *3 .* b\.b\.b\.b +-[rwx\-]* *3 .* dd dd dd" + fi + + dokeep + cd ../.. + rm -rf 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + restore_adm + ;; + + + + sticky) + # More tests of sticky tags, particularly non-branch sticky tags. + # See many tests (e.g. multibranch) for ordinary sticky tag + # operations such as adding files on branches. + # See "head" test for interaction between stick tags and HEAD. + mkdir 1; cd 1 + dotest sticky-1 "$testcvs -q co -l ." + mkdir first-dir + dotest sticky-2 "$testcvs add first-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir added to the repository" + cd first-dir + + touch file1 + dotest sticky-3 "$testcvs add file1" \ +"$SPROG add: scheduling file .file1. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest sticky-4 "$testcvs -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + dotest sticky-5 "$testcvs -q tag tag1" "T file1" + echo add a line >>file1 + dotest sticky-6 "$testcvs -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + dotest sticky-7 "$testcvs -q update -r tag1" "[UP] file1" + dotest sticky-8 "cat file1" '' + dotest sticky-9 "$testcvs -q update" '' + dotest sticky-10 "cat file1" '' + touch file2 + dotest_fail sticky-11 "$testcvs add file2" \ +"$SPROG add: cannot add file on non-branch tag \`tag1'" + dotest sticky-12 "$testcvs -q update -A" "[UP] file1 +$QUESTION file2" "$QUESTION file2 +[UP] file1" + dotest sticky-13 "${testcvs} add file2" \ +"$SPROG add: scheduling file .file2. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest sticky-14 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + + # Now back to tag1 + dotest sticky-15 "${testcvs} -q update -r tag1" "[UP] file1 +$SPROG update: \`file2' is no longer in the repository" + + rm file1 + dotest sticky-16 "${testcvs} rm file1" \ +"$SPROG remove: scheduling .file1. for removal +$SPROG remove: use .$SPROG commit. to remove this file permanently" + # Hmm, this command seems to silently remove the tag from + # the file. This appears to be intentional. + # The silently part especially strikes me as odd, though. + dotest sticky-17 "$testcvs -q ci -m remove-it" "" + dotest sticky-18 "$testcvs -q update -A" "U file1 +U file2" + dotest sticky-19 "$testcvs -q update -r tag1" \ +"${SPROG} update: \`file1' is no longer in the repository +${SPROG} update: \`file2' is no longer in the repository" + dotest sticky-20 "$testcvs -q update -A" "U file1 +U file2" + + # Now try with a numeric revision. + dotest sticky-21 "$testcvs -q update -r 1.1 file1" "U file1" + dotest sticky-22 "$testcvs rm -f file1" \ +"$SPROG remove: cannot remove file .file1. which has a numeric sticky tag of .1\.1." + # The old behavior was that remove allowed this and then commit + # gave an error, which was somewhat hard to clear. I mean, you + # could get into a long elaborate discussion of this being a + # conflict and two ways to resolve it, but I don't really see + # why CVS should have a concept of conflict that arises, not from + # parallel development, but from CVS's own sticky tags. + + # Ditto with a sticky date. + # + # I'm kind of surprised that the "file1 was lost" doesn't crop + # up elsewhere in the testsuite. It is a long-standing + # discrepency between local and remote CVS and should probably + # be cleaned up at some point. + dotest sticky-23 "$testcvs -q update -Dnow file1" \ +"$SPROG update: warning: \`file1' was lost +U file1" "U file1" + dotest sticky-24 "$testcvs rm -f file1" \ +"$SPROG remove: cannot remove file .file1. which has a sticky date of .[0-9.]*." + + dotest sticky-25 "$testcvs -q update -A" \ +"$SPROG update: warning: \`file1' was lost +U file1" "U file1" + + dokeep + restore_adm + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + keyword) + # Test keyword expansion. + # Various other tests relate to our ability to correctly + # set the keyword expansion mode. + # "binfiles" tests "cvs admin -k". + # "binfiles" and "binfiles2" test "cvs add -k". + # "rdiff" tests "cvs co -k". + # "binfiles" (and this test) test "cvs update -k". + # "binwrap" tests setting the mode from wrappers. + # "keyword2" tests "cvs update -kk -j" with text and binary files + # I don't think any test is testing "cvs import -k". + # Other keyword expansion tests: + # keywordlog - $Log. + mkdir 1; cd 1 + dotest keyword-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keyword-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + echo '$''Author$' > file1 + echo '$''Date$' >> file1 + echo '$''Header$' >> file1 + echo '$''Id$' >> file1 + echo '$''Locker$' >> file1 + echo '$''Name$' >> file1 + echo '$''RCSfile$' >> file1 + echo '$''Revision$' >> file1 + echo '$''Source$' >> file1 + echo '$''State$' >> file1 + echo '$''Nonkey$' >> file1 + # Omit the trailing dollar sign + echo '$''Date' >> file1 + # Put two keywords on one line + echo '$''State$' '$''State$' >> file1 + # Use a header for Log + echo 'xx $''Log$' >> file1 + + dotest keyword-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest keyword-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + dotest keyword-5 "cat file1" \ +'\$'"Author: ${username} "'\$'" +"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" +"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Locker: "'\$'" +"'\$'"Name: "'\$'" +"'\$'"RCSfile: file1,v "'\$'" +"'\$'"Revision: 1\.1 "'\$'" +"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" +"'\$'"State: Exp "'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.1 [0-9/]* [0-9:]* ${username} +xx add +xx" + + # Use cvs admin to lock the RCS file in order to check -kkvl + # vs. -kkv. CVS does not normally lock RCS files, but some + # people use cvs admin to enforce reserved checkouts. + dotest keyword-6 "${testcvs} admin -l file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +1\.1 locked +done" + + dotest keyword-7 "${testcvs} update -kkv file1" "U file1" + dotest keyword-8 "cat file1" \ +'\$'"Author: ${username} "'\$'" +"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" +"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Locker: "'\$'" +"'\$'"Name: "'\$'" +"'\$'"RCSfile: file1,v "'\$'" +"'\$'"Revision: 1\.1 "'\$'" +"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" +"'\$'"State: Exp "'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.1 [0-9/]* [0-9:]* ${username} +xx add +xx" + + dotest keyword-9 "${testcvs} update -kkvl file1" "U file1" + dotest keyword-10 "cat file1" \ +'\$'"Author: ${username} "'\$'" +"'\$'"Date: ${RCSKEYDATE} "'\$'" +"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 ${RCSKEYDATE} ${username} Exp ${username} "'\$'" +"'\$'"Id: file1,v 1\.1 ${RCSKEYDATE} ${username} Exp ${username} "'\$'" +"'\$'"Locker: ${username} "'\$'" +"'\$'"Name: "'\$'" +"'\$'"RCSfile: file1,v "'\$'" +"'\$'"Revision: 1\.1 "'\$'" +"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" +"'\$'"State: Exp "'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.1 ${RCSKEYDATE} ${username} +xx add +xx" + + dotest keyword-11 "${testcvs} update -kk file1" "U file1" + dotest keyword-12 "cat file1" \ +'\$'"Author"'\$'" +"'\$'"Date"'\$'" +"'\$'"Header"'\$'" +"'\$'"Id"'\$'" +"'\$'"Locker"'\$'" +"'\$'"Name"'\$'" +"'\$'"RCSfile"'\$'" +"'\$'"Revision"'\$'" +"'\$'"Source"'\$'" +"'\$'"State"'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State"'\$'" "'\$'"State"'\$'" +xx "'\$'"Log"'\$'" +xx Revision 1\.1 ${RCSKEYDATE} ${username} +xx add +xx" + + dotest keyword-13 "${testcvs} update -kv file1" "U file1" + dotest keyword-14 "cat file1" \ +"${username} +${RCSKEYDATE} +${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 ${RCSKEYDATE} ${username} Exp +file1,v 1\.1 ${RCSKEYDATE} ${username} Exp + + +file1,v +1\.1 +${CVSROOT_DIRNAME}/first-dir/file1,v +Exp +"'\$'"Nonkey"'\$'" +"'\$'"Date +Exp Exp +xx file1,v +xx Revision 1\.1 ${RCSKEYDATE} ${username} +xx add +xx" + + dotest keyword-15 "${testcvs} update -ko file1" "U file1" + dotest keyword-16 "cat file1" \ +'\$'"Author"'\$'" +"'\$'"Date"'\$'" +"'\$'"Header"'\$'" +"'\$'"Id"'\$'" +"'\$'"Locker"'\$'" +"'\$'"Name"'\$'" +"'\$'"RCSfile"'\$'" +"'\$'"Revision"'\$'" +"'\$'"Source"'\$'" +"'\$'"State"'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State"'\$'" "'\$'"State"'\$'" +xx "'\$'"Log"'\$' + + # Test the Name keyword. First go back to normal expansion. + + dotest keyword-17 "${testcvs} update -A file1" "U file1" + + echo '$''Name$' > file1 + dotest keyword-18 "${testcvs} ci -m modify file1" \ +"${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + dotest keyword-19 "${testcvs} -q tag tag1" "T file1" + echo "change" >> file1 + dotest keyword-20 "${testcvs} -q ci -m mod2 file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + # FIXCVS - These unpatchable files are happening because the tag + # associated with the current base version of the file in the + # sandbox is not available in these cases. See the note in the + # patch_file function in update.c. + dotest keyword-21 "${testcvs} -q update -r tag1" "U file1" \ +"P file1 +${CPROG} update: checksum failure after patch to \./file1; will refetch +${CPROG} client: refetching unpatchable files +$SPROG update: warning: \`file1' was lost +U file1" + + dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$' + + if $remote; then + # Like serverpatch-8. Not sure there is anything much we + # can or should do about this. + dotest keyword-23r "${testcvs} update -A file1" "P file1 +${CPROG} update: checksum failure after patch to \./file1; will refetch +${CPROG} client: refetching unpatchable files +$SPROG update: warning: \`file1' was lost +U file1" + else + dotest keyword-23 "${testcvs} update -A file1" "[UP] file1" + fi + dotest keyword-24 "cat file1" '\$'"Name: "'\$'" +change" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + keywordlog) + # Test the Log keyword. + mkdir 1; cd 1 + dotest keywordlog-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keywordlog-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + echo initial >file1 + dotest keywordlog-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + + # See "rmadd" for a list of other tests of cvs ci -r. + dotest keywordlog-4 "${testcvs} -q ci -r 1.3 -m add file1" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.3" + + cd ../.. + mkdir 2; cd 2 + dotest keywordlog-4a "${testcvs} -q co first-dir" "U first-dir/file1" + cd ../1/first-dir + + echo 'xx $''Log$' >> file1 + cat >${TESTDIR}/comment.tmp <<EOF +First log line +Second log line +EOF + # As with rmadd-25, "cvs ci -r" sets a sticky tag. + dotest_fail keywordlog-4b \ +"${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \ +"${SPROG} commit: sticky tag .1\.3. for file .file1. is not a branch +${SPROG} \[commit aborted\]: correct above errors first!" + dotest keywordlog-4c "${testcvs} -q update -A" "M file1" + + dotest keywordlog-5 "${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \ +"${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3" + rm -f ${TESTDIR}/comment.tmp + dotest keywordlog-6 "${testcvs} -q tag -b br" "T file1" + dotest keywordlog-7 "cat file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx" + + cd ../../2/first-dir + dotest keywordlog-8 "${testcvs} -q update" "[UP] file1" + dotest keywordlog-9 "cat file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx" + cd ../../1/first-dir + + echo "change" >> file1 + dotest keywordlog-10 "${testcvs} ci -m modify file1" \ +"${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4" + dotest keywordlog-11 "cat file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.5 ${RCSKEYDATE} ${username} +xx modify +xx +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx +change" + + cd ../../2/first-dir + dotest keywordlog-12 "${testcvs} -q update" "[UP] file1" + dotest keywordlog-13 "cat file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.5 ${RCSKEYDATE} ${username} +xx modify +xx +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx +change" + + cd ../../1/first-dir + dotest keywordlog-14 "${testcvs} -q update -r br" "[UP] file1" + echo br-change >>file1 + dotest keywordlog-15 "${testcvs} -q ci -m br-modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4\.2\.1; previous revision: 1\.4" + dotest keywordlog-16 "cat file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4\.2\.1 ${RCSKEYDATE} ${username} +xx br-modify +xx +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx +br-change" + cd ../../2/first-dir + dotest keywordlog-17 "${testcvs} -q update -r br" "[UP] file1" + dotest keywordlog-18 "cat file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4\.2\.1 ${RCSKEYDATE} ${username} +xx br-modify +xx +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx +br-change" + cd ../.. + dotest keywordlog-19 "${testcvs} -q co -p -r br first-dir/file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4\.2\.1 ${RCSKEYDATE} ${username} +xx br-modify +xx +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx +br-change" + dotest keywordlog-20 "${testcvs} -q co -p first-dir/file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.5 ${RCSKEYDATE} ${username} +xx modify +xx +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx +change" + dotest keywordlog-21 "${testcvs} -q co -p -r 1.4 first-dir/file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx" + + cd 2/first-dir + # OK, the basic rule for keyword expansion is that it + # happens on checkout. And the rule for annotate is that + # it annotates a checked-in revision, rather than a checked-out + # file. So, although it is kind of confusing that the latest + # revision does not appear in the annotated output, and the + # annotated output does not quite match what you'd get with + # update or checkout, the behavior is more or less logical. + # The same issue occurs with annotate and other keywords, + # I think, although it is particularly noticeable for $Log. + dotest keywordlog-22 "${testcvs} ann -r br file1" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.3 ($username8 *[0-9a-zA-Z-]*): initial +1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'" +1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx Revision 1\.4 ${RCSKEYDATE} $username +1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx First log line +1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx Second log line +1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx +1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): br-change" + dotest keywordlog-23 "${testcvs} ann -r HEAD file1" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.3 ($username8 *[0-9a-zA-Z-]*): initial +1\.5 ($username8 *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'" +1\.5 ($username8 *[0-9a-zA-Z-]*): xx Revision 1\.4 ${RCSKEYDATE} $username +1\.5 ($username8 *[0-9a-zA-Z-]*): xx First log line +1\.5 ($username8 *[0-9a-zA-Z-]*): xx Second log line +1\.5 ($username8 *[0-9a-zA-Z-]*): xx +1\.5 ($username8 *[0-9a-zA-Z-]*): change" + cd ../.. + + # + # test the operation of 'admin -o' in conjunction with keywords + # (especially Log - this used to munge the RCS file for all time) + # + + dotest keywordlog-24 \ +"${testcvs} admin -oHEAD 1/first-dir/file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +deleting revision 1\.5 +done" + + dotest keywordlog-25 \ +"${testcvs} -q co -p first-dir/file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4 ${RCSKEYDATE} ${username} +xx First log line +xx Second log line +xx" + + # Now test the behavior when the comment leader exceeds the + # configured maximum. + mkdir 3; cd 3 + dotest keywordlog-26 "$testcvs -Q co first-dir" + + cd first-dir + sed 's/xx \$/1234567890123456789 $/' <file1 >tmp + mv tmp file1 + dotest keywordlog-27 "$testcvs -Q ci -mrevision-5" + dotest keywordlog-28 "cat file1" \ +"initial +1234567890123456789 "'\$'"Log: file1,v "'\$'" +1234567890123456789 Revision 1\.5 $RCSKEYDATE $username +1234567890123456789 revision-5 +1234567890123456789 +xx Revision 1\.4 $RCSKEYDATE $username +xx First log line +xx Second log line +xx" + + sed 's/1234567890123456789 \$/12345678901234567890 $/' <file1 >tmp + mv tmp file1 + dotest keywordlog-29 "$testcvs -Q ci -mrevision-6" \ +"$SPROG commit: Skipping "'`$''Log$'"' keyword due to excessive comment leader\." + dotest keywordlog-30 "cat file1" \ +"initial +12345678901234567890 "'\$'"Log: file1,v "'\$'" +1234567890123456789 Revision 1\.5 $RCSKEYDATE $username +1234567890123456789 revision-5 +1234567890123456789 +xx Revision 1\.4 $RCSKEYDATE $username +xx First log line +xx Second log line +xx" + + # Check that the Log-related config options work. + cd .. + dotest keywordlog-31 "$testcvs -Q co CVSROOT" + cd CVSROOT + echo "UseArchiveCommentLeader=TrUe" >>config + dotest keywordlog-32 "$testcvs -Q ci -mset-UseArchiveCommentLeader" + + cd ../first-dir + dotest keywordlog-33 "$testcvs -Q ci -fmrevision-7 file1" + dotest keywordlog-34 "cat file1" \ +"initial +12345678901234567890 "'\$'"Log: file1,v "'\$'" +# Revision 1\.7 $RCSKEYDATE $username +# revision-7 +# +1234567890123456789 Revision 1\.5 $RCSKEYDATE $username +1234567890123456789 revision-5 +1234567890123456789 +xx Revision 1\.4 $RCSKEYDATE $username +xx First log line +xx Second log line +xx" + + cd ../CVSROOT + echo "MaxCommentLeaderLength=1k" >>config + dotest keywordlog-35 "$testcvs -Q ci -mset-MaxCommentLeaderLength" + + cd ../first-dir + dotest keywordlog-36 "$testcvs -Q ci -fmrevision-8 file1" + dotest keywordlog-37 "cat file1" \ +"initial +12345678901234567890 "'\$'"Log: file1,v "'\$'" +12345678901234567890 Revision 1\.8 $RCSKEYDATE $username +12345678901234567890 revision-8 +12345678901234567890 +# Revision 1\.7 $RCSKEYDATE $username +# revision-7 +# +1234567890123456789 Revision 1\.5 $RCSKEYDATE $username +1234567890123456789 revision-5 +1234567890123456789 +xx Revision 1\.4 $RCSKEYDATE $username +xx First log line +xx Second log line +xx" + + dokeep + cd ../.. + restore_adm + rm -r 1 2 3 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + keywordname) + # Test the Name keyword. + # See the keyword test for a descriptions of some other tests that + # test keyword expansion modes. + mkdir keywordname; cd keywordname + mkdir 1; cd 1 + dotest keywordname-init-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keywordname-init-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + echo '$'"Name$" >file1 + echo '$'"Name$" >file2 + dotest keywordname-init-3 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + + # See "rmadd" for a list of other tests of cvs ci -r. + dotest keywordname-init-4 "${testcvs} -q ci -r 1.3 -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.3 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.3" + + dotest keywordname-init-6 "${testcvs} -q up -A" + dotest keywordname-init-7 "${testcvs} -q tag -b br" \ +"T file1 +T file2" + + echo new data >>file1 + dotest keywordname-init-8 "${testcvs} -q ci -mchange" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3" + + # First check out a branch. + # + # There used to be a bug where static tags would be substituted for + # Name keywords but not branch tags. + # + # FIXCVS - BUG + # Why shouldn't the non-update case not cause a substitution? + # An update -kk or -A will unsub and sub keywords without updates + # being required. + # FIXCVS - see note above keyword-21 + dotest keywordname-update-1 "${testcvs} -q up -rbr" "U file1" \ +"P file1 +${CPROG} update: checksum failure after patch to \./file1; will refetch +${CPROG} client: refetching unpatchable files +$SPROG update: warning: \`file1' was lost +U file1" + dotest keywordname-update-2 "cat file1" '\$'"Name: br "'\$' + dotest keywordname-update-3 "cat file2" '\$'"Name: "'\$' + + # Now verify that updating to the trunk leaves no substitution for + # $Name + dotest keywordname-update-4 "${testcvs} -q tag firsttag" \ +"T file1 +T file2" + # FIXCVS - see note above keyword-21 + dotest keywordname-update-5 "${testcvs} -q up -A" "U file1" \ +"P file1 +${CPROG} update: checksum failure after patch to \./file1; will refetch +${CPROG} client: refetching unpatchable files +$SPROG update: warning: \`file1' was lost +U file1" + dotest keywordname-update-6 "cat file1" \ +'\$'"Name: "'\$'" +new data" + dotest keywordname-update-7 "cat file2" '\$'"Name: "'\$' + + # But updating to a static tag does cause a substitution + # FIXCVS - see same note above + dotest keywordname-update-8 "${testcvs} -q up -rfirsttag" "U file1" \ +"P file1 +${CPROG} update: checksum failure after patch to \./file1; will refetch +${CPROG} client: refetching unpatchable files +$SPROG update: warning: \`file1' was lost +U file1" + dotest keywordname-update-9 "cat file1" '\$'"Name: firsttag "'\$' + dotest keywordname-update-10 "cat file2" '\$'"Name: "'\$' + + # And reverify the trunk update when the change is actually removed. + dotest keywordname-update-11 "${testcvs} -q up -A" "[UP] file1" \ +"P file1 +${CPROG} update: checksum failure after patch to ./file1; will refetch +${CPROG} client: refetching unpatchable files +$SPROG update: warning: \`file1' was lost +U file1" + dotest keywordname-update-12 "cat file1" \ +'\$'"Name: "'\$'" +new data" + dotest keywordname-update-13 "cat file2" '\$'"Name: "'\$' + + cd ../.. + + # now verify that a fresh checkout substitutes all the $Name fields + mkdir 2; cd 2 + dotest keywordname-checkout-1 \ +"${testcvs} -q co -rfirsttag first-dir" \ +"U first-dir/file1 +U first-dir/file2" + cd first-dir + dotest keywordname-checkout-2 "cat file1" '\$'"Name: firsttag "'\$' + dotest keywordname-checkout-3 "cat file2" '\$'"Name: firsttag "'\$' + + dokeep + cd ../../.. + rm -r keywordname + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + keyword2) + # Test merging on files with keywords: + # without -kk + # with -kk + # on text files + # on binary files + # Note: This test assumes that CVS has already passed the binfiles + # test sequence + # Note2: We are testing positive on binary corruption here + # we probably really DON'T want to 'cvs update -kk' a binary file... + mkdir 1; cd 1 + dotest keyword2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keyword2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + echo '$''Revision$' >> file1 + echo "I" >>file1 + echo "like" >>file1 + echo "long" >>file1 + echo "files!" >>file1 + echo "" >>file1 + echo "a test line for our times" >>file1 + echo "" >>file1 + echo "They" >>file1 + echo "make" >>file1 + echo "diff" >>file1 + echo "look like it" >>file1 + echo "did a much better" >>file1 + echo "job." >>file1 + dotest keyword2-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + + ${AWK} 'BEGIN { printf "%c%c%c%sRevision: 1.1 $@%c%c", \ + 2, 10, 137, "$", 13, 10 }' \ + </dev/null | ${TR} '@' '\000' >../binfile.dat + cp ../binfile.dat . + dotest keyword2-5 "${testcvs} add -kb binfile.dat" \ +"${SPROG} add: scheduling file .binfile\.dat. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + + dotest keyword2-6 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/binfile\.dat,v <-- binfile\.dat +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + dotest keyword2-7 "${testcvs} -q tag -b branch" \ +"T binfile\.dat +T file1" + + sed -e 's/our/the best of and the worst of/' file1 >f; mv f file1 + dotest keyword2-8 "${testcvs} -q ci -m change" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + + dotest keyword2-9 "${testcvs} -q update -r branch" '[UP] file1' + + echo "what else do we have?" >>file1 + dotest keyword2-10 "${testcvs} -q ci -m change" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + # Okay, first a conflict in file1 - should be okay with binfile.dat + dotest keyword2-11 "${testcvs} -q update -A -j branch" \ +"U file1 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file1 +rcsmerge: warning: conflicts during merge" + + dotest_fail keyword2-12 "${testcvs} diff file1" \ +"Index: file1 +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.2 +diff -r1\.2 file1 +0a1 +> <<<<<<< file1 +1a3,5 +> ======= +> \\\$""Revision: 1\.1\.2\.1 \\\$ +> >>>>>>> 1\.1\.2\.1 +14a19 +> what else do we have${QUESTION}" + + # Here's the problem... shouldn't -kk a binary file... + rm file1 + dotest keyword2-13 "${testcvs} -q update -A -kk -j branch" \ +"${SPROG} update: warning: \`file1' was lost +U file1 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file1" + + # binfile won't get checked in, but it is now corrupt and could + # have been checked in if it had changed on the branch... + dotest keyword2-14 "${testcvs} -q ci -m change" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + + # "-kk" no longer corrupts binary files + dotest keyword2-15 "cmp binfile.dat ../binfile.dat" '' + + # Okay, restore everything and make CVS try and merge a binary file... + # "-kk" no longer affects binary files + dotest keyword2-16 "${testcvs} -q update -A" \ +"[UP] file1" + dotest keyword2-17 "${testcvs} -q tag -b branch2" \ +"T binfile\.dat +T file1" + dotest keyword2-18 "${testcvs} -q update -r branch2" '' + + ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ + </dev/null | ${TR} '@' '\000' >>binfile.dat + dotest keyword2-19 "$testcvs -q ci -m badbadbad" \ +"$CVSROOT_DIRNAME/first-dir/binfile\.dat,v <-- binfile\.dat +new revision: 1\.1\.4\.1; previous revision: 1\.1" + # "-kk" no longer affects binary files + + # XXXX: do not ask, why we get the "U binfile.dat" line twice + # looks like a bug! + dotest keyword2-20 "${testcvs} -q update -A -kk -j branch2" \ +"U binfile\.dat +U binfile\.dat +U file1" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + head) + # Testing handling of the HEAD special tag. + # There are many cases involving added and removed files + # which we don't yet try to deal with. + # TODO: We also could be paying much closer attention to + # "head of the trunk" versus "head of the default branch". + # That is what "cvs import" is doing here (but I didn't really + # fully follow through on writing the tests for that case). + mkdir imp-dir + cd imp-dir + echo 'imported contents' >file1 + # It may seem like we don't do much with file2, but do note that + # the "cvs diff" invocations do also diff file2 (and come up empty). + echo 'imported contents' >file2 + dotest_sort head-1 "${testcvs} import -m add first-dir tag1 tag2" \ +" + +N first-dir/file1 +N first-dir/file2 +No conflicts created by this import" + cd .. + rm -r imp-dir + mkdir 1 + cd 1 + dotest head-2 "${testcvs} -q co first-dir" \ +"U first-dir/file1 +U first-dir/file2" + cd first-dir + echo 'add a line on trunk' >> file1 + dotest head-3 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + dotest head-4 "${testcvs} -q tag trunktag" "T file1 +T file2" + echo 'add a line on trunk after trunktag' >> file1 + dotest head-5 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2" + dotest head-6 "${testcvs} -q tag -b br1" "T file1 +T file2" + dotest head-7 "${testcvs} -q update -r br1" "" + echo 'modify on branch' >>file1 + dotest head-8 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3\.2\.1; previous revision: 1\.3" + dotest head-9 "${testcvs} -q tag brtag" "T file1 +T file2" + echo 'modify on branch after brtag' >>file1 + dotest head-10 "${testcvs} -q ci -m modify" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.3\.2\.2; previous revision: 1\.3\.2\.1" + # With no sticky tags, HEAD is the head of the trunk. + dotest head-trunk-setup "${testcvs} -q update -A" "[UP] file1" + dotest head-trunk-update "${testcvs} -q update -r HEAD -p file1" \ +"imported contents +add a line on trunk +add a line on trunk after trunktag" + # and diff thinks so too. Case (a) from the comment in + # cvs.texinfo (Common options). + dotest_fail head-trunk-diff "${testcvs} -q diff -c -r HEAD -r br1" \ +"Index: file1 +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.3 +retrieving revision 1\.3\.2\.2 +diff -c -r1\.3 -r1\.3\.2\.2 +\*\*\* file1 ${RFCDATE} 1\.3 +--- file1 ${RFCDATE} 1\.3\.2\.2 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1,3 \*\*\*\* +--- 1,5 ---- + imported contents + add a line on trunk + add a line on trunk after trunktag +${PLUS} modify on branch +${PLUS} modify on branch after brtag" + + # With a branch sticky tag, HEAD is the head of the trunk. + dotest head-br1-setup "${testcvs} -q update -r br1" "[UP] file1" + dotest head-br1-update "${testcvs} -q update -r HEAD -p file1" \ +"imported contents +add a line on trunk +add a line on trunk after trunktag" + # But diff thinks that HEAD is "br1". Case (b) from cvs.texinfo. + # Probably people are relying on it. + dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" "" + + # With a nonbranch sticky tag on a branch, + # HEAD is the head of the trunk + dotest head-brtag-setup "${testcvs} -q update -r brtag" "[UP] file1" + dotest head-brtag-update "${testcvs} -q update -r HEAD -p file1" \ +"imported contents +add a line on trunk +add a line on trunk after trunktag" + + # CVS 1.9 and older thought that HEAD is "brtag" (this was + # noted as "strange, maybe accidental"). But "br1" makes a + # whole lot more sense. + dotest head-brtag-diff "${testcvs} -q diff -c -r HEAD -r br1" "" + + # With a nonbranch sticky tag on the trunk, HEAD is the head + # of the trunk, I think. + dotest head-trunktag-setup "${testcvs} -q update -r trunktag" \ +"[UP] file1" + dotest head-trunktag-check "cat file1" "imported contents +add a line on trunk" + dotest head-trunktag-update "${testcvs} -q update -r HEAD -p file1" \ +"imported contents +add a line on trunk +add a line on trunk after trunktag" + # Like head-brtag-diff, there is a non-branch sticky tag. + dotest_fail head-trunktag-diff \ + "${testcvs} -q diff -c -r HEAD -r br1" \ +"Index: file1 +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +retrieving revision 1\.3 +retrieving revision 1\.3\.2\.2 +diff -c -r1\.3 -r1\.3\.2\.2 +\*\*\* file1 ${RFCDATE} 1\.3 +--- file1 ${RFCDATE} 1\.3\.2\.2 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1,3 \*\*\*\* +--- 1,5 ---- + imported contents + add a line on trunk + add a line on trunk after trunktag +${PLUS} modify on branch +${PLUS} modify on branch after brtag" + + # Also might test what happens if we setup with update -r + # HEAD. In general, if sticky tags matter, does the + # behavior of "update -r <foo>" (without -p) depend on the + # sticky tags before or after the update? + + # Note that we are testing both the case where this deletes + # a revision (file1) and the case where it does not (file2) + dotest_fail head-o0a "${testcvs} admin -o ::br1" \ +"${SPROG} admin: Administrating \. +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +${SPROG} admin: cannot remove revision 1\.3\.2\.1 because it has tags +${SPROG} admin: RCS file for .file1. not modified\. +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + dotest head-o0b "${testcvs} tag -d brtag" \ +"${SPROG} tag: Untagging \. +D file1 +D file2" + dotest head-o1 "${testcvs} admin -o ::br1" \ +"${SPROG} admin: Administrating \. +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +deleting revision 1\.3\.2\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + tagdate) + # Test combining -r and -D. + # + # Note that this is not a complete test. It relies on the fact + # that update, checkout and export have a LOT of shared code. + # Notice: + # 1) checkout is never tested at all with -r -D + # 2) update never uses an argument to '-D' besides 'now' + # (this test does not provide enough data to prove + # that 'cvs update' with both a '-r' and a '-D' + # specified does not ignore '-D': a 'cvs up + # -r<branch> -Dnow' and a 'cvs up -r<branch>' + # should specify the same file revision). + # 3) export uses '-r<branch> -D<when there was a different + # revision>', hopefully completing this behavior test + # for checkout and update as well. + # + mkdir 1; cd 1 + save_TZ=$TZ + TZ=UTC0; export TZ + dotest tagdate-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest tagdate-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + echo trunk-1 >file1 + dotest tagdate-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest tagdate-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + date_T1=`getrlogdate -r1.1 first-dir/file1` + + dotest tagdate-5 "${testcvs} -q tag -b br1" "T file1" + dotest tagdate-6 "${testcvs} -q tag -b br2" "T file1" + echo trunk-2 >file1 + dotest tagdate-7 "${testcvs} -q ci -m modify-on-trunk" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" + date_T2=`getrlogdate -r1.2 first-dir/file1` + + # We are testing -r -D where br1 is a (magic) branch without + # any revisions. First the case where br2 doesn't have any + # revisions either: + dotest tagdate-8 "${testcvs} -q update -p -r br1 -D now" "trunk-1" + dotest tagdate-9 "${testcvs} -q update -r br2" "[UP] file1" + echo br2-1 >file1 + dotest tagdate-10 "${testcvs} -q ci -m modify-on-br2" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.4\.1; previous revision: 1\.1" + date_T3=`getrlogdate -r1.1.4.1 first-dir/file1` + + # Then the case where br2 does have revisions: + dotest tagdate-11 "${testcvs} -q update -p -r br1 -D now" "trunk-1" + + # Joins from dates on the head used to be prohibited. + dotest tagdate-12 "$testcvs -q update -j:yesterday -j:now" + dotest tagdate-12b "$testcvs -Q update -C" + # And check export + + echo br2-2 >file1 + dotest tagdate-13 "${testcvs} -q ci -m modify-2-on-br2" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.4\.2; previous revision: 1\.1\.4\.1" + date_T4=`getrlogdate -r1.1.4.2 first-dir/file1` + + # Test diff -r<tag>:<date> with two revisions specified. + dotest_fail tagdate-13b \ +"$testcvs -q diff -u -rbr2:'$date_T3' -rbr2:now file1" \ +"Index: file1 +=================================================================== +RCS file: $CVSROOT_DIRNAME/first-dir/file1,v +retrieving revision 1\.1\.4\.1 +retrieving revision 1\.1\.4\.2 +diff -u -r1\.1\.4\.1 -r1\.1\.4\.2 +--- file1 $RFCDATE 1\.1\.4\.1 ++++ file1 $RFCDATE 1\.1\.4\.2 +@@ -1 ${PLUS}1 @@ +-br2-1 +${PLUS}br2-2" + + # Tag a date on a branch. + dotest tagdate-13c "$testcvs -q tag -rbr2:'$date_T3' tagdate" \ +"T file1" + dotest tagdate-13d "$testcvs -q update -rtagdate" "[UP] file1" + dotest tagdate-13e "cat file1" "br2-1" + + # This one should fail, though currently without an error message, + # since a date on a static tag is meaningless. + dotest tagdate-13f "$testcvs -q tag -rtagdate:'$date_T3' tagdate" + + # and restore to using the trunk for future tests. + dotest tagdate-13g "$testcvs -q up -rbr2" "[UP] file1" + + cd ../.. + mkdir 2; cd 2 + dotest tagdate-14 \ +"$testcvs -q export -r br2 -D'$date_T3' first-dir" \ +"[UP] first-dir/file1" + dotest tagdate-14b "cat first-dir/file1" "br2-1" + dotest tagdate-15 \ +"$testcvs -q export -rbr2:'$date_T3' -dsecond-dir first-dir" \ +"[UP] second-dir/file1" + dotest tagdate-15b "cat second-dir/file1" "br2-1" + + # Now for annotate + cd ../1/first-dir + dotest tagdate-16 "${testcvs} annotate -rbr2 -D'$date_T3'" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1\.4\.1 ($username8 *[0-9a-zA-Z-]*): br2-1" + + dotest tagdate-17 "${testcvs} annotate -rbr2 -Dnow" \ +" +Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1\.4\.2 ($username8 *[0-9a-zA-Z-]*): br2-2" + + # Now check to see what happens when we add files to br2 and trunk + echo br2-1 > file3 + dotest tagdate-18 "${testcvs} add file3" \ +"${SPROG} add: scheduling file \`file3' for addition on branch \`br2' +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + dotest tagdate-19 "${testcvs} -q ci -m add file3" \ +"$CVSROOT_DIRNAME/first-dir/Attic/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + date_T5=`getrlogdate -r1.1 first-dir/file3` + date_T6=`getrlogdate -r1.1.2.1 first-dir/file3` + + cd ../.. + mkdir 3; cd 3 + dotest tagdate-20 "${testcvs} -Q co first-dir" '' + cd first-dir + echo trunk-1 > file2 + dotest tagdate-21 "${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest tagdate-22 "${testcvs} -q ci -m add file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + date_T7=`getrlogdate -r1.1 first-dir/file2` + echo "trunk-2" >file2 + dotest tagdate-23 "${testcvs} -q ci -m update file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.2; previous revision: 1\.1" + date_T8=`getrlogdate -r1.2 first-dir/file2` + + cd ../../1/first-dir + echo br2-1 > file2 + dotest tagdate-24 "${testcvs} add file2" \ +"${SPROG} add: scheduling file \`file2' for addition on branch \`br2' +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + dotest tagdate-25 "${testcvs} -q ci -m add file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1" + date_T9=`getrlogdate -r1.2.2.2 first-dir/file2` + cd ../.. + + # Time Rev Branch Comments + # T0 trunk first-dir created + # T1 1.1 trunk first-dir/file1 committed "trunk-1" + # br1 branch created + # br2 branch created + # T2 1.2 trunk first-dir/file1 committed "trunk-2" + # T3 1.1.4.1 br2 first-dir/file1 committed "br2-1" + # +60s + # T4 1.1.4.2 br2 first-dir/file1 committed "br2-2" + # T5 1.1 trunk first-dir/file3 dead + # T6 1.1.2.1 br2 first-dir/file3 committed "br2-1" + # T7 1.1 trunk first-dir/file2 committed "trunk-1" + # T8 1.2 trunk first-dir/file2 committed "trunk-2" + # T8 1.2.2.1 br2 first-dir/file2 dead + # T9 1.2.2.2 br2 first-dir/file2 committed "br2-1" + # + + mkdir 4; cd 4 + (echo Dates for tagdate-26-* are:;\ + echo " date_T1='$date_T1'";\ + echo " date_T2='$date_T2'";\ + echo " date_T3='$date_T3'";\ + echo " date_T4='$date_T4'";\ + echo " date_T5='$date_T5'";\ + echo " date_T6='$date_T6'";\ + echo " date_T7='$date_T7'";\ + echo " date_T8='$date_T8'";\ + echo " date_T9='$date_T9'") >>$LOGFILE + dotest tagdate-26-trunk-t1 \ +"${testcvs} co -D'$date_T1' -d first-dir-trunk-t1 first-dir" \ +"${SPROG} checkout: Updating first-dir-trunk-t1 +U first-dir-trunk-t1/file1" + dotest tagdate-26-br2-t1 \ +"${testcvs} co -r br2 -D'$date_T1' -d first-dir-br2-t1 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t1 +U first-dir-br2-t1/file1" + dotest tagdate-26-trunk-t2 \ +"${testcvs} co -D'$date_T2' -d first-dir-trunk-t2 first-dir" \ +"${SPROG} checkout: Updating first-dir-trunk-t2 +U first-dir-trunk-t2/file1" + dotest tagdate-26-br2-t2 \ +"${testcvs} co -r br2 -D'$date_T2' -d first-dir-br2-t2 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t2 +U first-dir-br2-t2/file1" + dotest tagdate-26-br2-t3 \ +"${testcvs} co -r br2 -D'$date_T3' -d first-dir-br2-t3 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t3 +U first-dir-br2-t3/file1" + dotest tagdate-26-br2-t4 \ +"${testcvs} co -r br2 -D'$date_T4' -d first-dir-br2-t4 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t4 +U first-dir-br2-t4/file1" + dotest tagdate-26-br2-t6 \ +"${testcvs} co -r br2 -D'$date_T6' -d first-dir-br2-t6 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t6 +U first-dir-br2-t6/file1 +U first-dir-br2-t6/file3" + dotest tagdate-26-trunk-t7 \ +"${testcvs} co -D'$date_T7' -d first-dir-trunk-t7 first-dir" \ +"${SPROG} checkout: Updating first-dir-trunk-t7 +U first-dir-trunk-t7/file1 +U first-dir-trunk-t7/file2" + dotest tagdate-26-br2-t7 \ +"${testcvs} co -r br2 -D'$date_T7' -d first-dir-br2-t7 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t7 +U first-dir-br2-t7/file1 +U first-dir-br2-t7/file3" + dotest tagdate-26-trunk-t8 \ +"${testcvs} co -D'$date_T8' -d first-dir-trunk-t8 first-dir" \ +"${SPROG} checkout: Updating first-dir-trunk-t8 +U first-dir-trunk-t8/file1 +U first-dir-trunk-t8/file2" + dotest tagdate-26-br2-t8 \ +"${testcvs} co -r br2 -D'$date_T8' -d first-dir-br2-t8 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t8 +U first-dir-br2-t8/file1 +U first-dir-br2-t8/file3" + dotest tagdate-26-br2-t9 \ +"${testcvs} co -r br2 -D'$date_T9' -d first-dir-br2-t9 first-dir" \ +"${SPROG} checkout: Updating first-dir-br2-t9 +U first-dir-br2-t9/file1 +U first-dir-br2-t9/file2 +U first-dir-br2-t9/file3" + dotest tagdate-27-trunk-t1 \ +"${testcvs} status first-dir-trunk-t1" \ +"${SPROG} status: Examining first-dir-trunk-t1 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1[^.]* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: ${RCSDELTADATE} + Sticky Options: (none)" + dotest tagdate-27-br2-t1 \ +"${testcvs} status first-dir-br2-t1" \ +"${SPROG} status: Examining first-dir-br2-t1 +=================================================================== +File: file1 Status: Needs Patch + + Working revision: 1\.1[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none)" + dotest tagdate-27-trunk-t2 \ +"${testcvs} status first-dir-trunk-t2" \ +"${SPROG} status: Examining first-dir-trunk-t2 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.2[^.]* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: ${RCSDELTADATE} + Sticky Options: (none)" + dotest tagdate-27-br2-t2 \ +"${testcvs} status first-dir-br2-t2" \ +"${SPROG} status: Examining first-dir-br2-t2 +=================================================================== +File: file1 Status: Needs Patch + + Working revision: 1\.1[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none)" + dotest tagdate-27-br2-t3 \ +"${testcvs} status first-dir-br2-t3" \ +"${SPROG} status: Examining first-dir-br2-t3 +=================================================================== +File: file1 Status: Needs Patch + + Working revision: 1\.1\.4\.1[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none)" + dotest tagdate-27-br2-t4 \ +"${testcvs} status first-dir-br2-t4" \ +"${SPROG} status: Examining first-dir-br2-t4 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1\.4\.2[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none)" + dotest tagdate-27-br2-t6 \ +"${testcvs} status first-dir-br2-t6" \ +"${SPROG} status: Examining first-dir-br2-t6 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1\.4\.2[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1[^.]* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + dotest tagdate-27-trunk-t7 \ +"${testcvs} status first-dir-trunk-t7" \ +"${SPROG} status: Examining first-dir-trunk-t7 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.2[^.]* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: ${RCSDELTADATE} + Sticky Options: (none) + +=================================================================== +File: file2 Status: Up-to-date + + Working revision: 1\.1[^.]* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: ${RCSDELTADATE} + Sticky Options: (none)" + dotest tagdate-27-br2-t7 \ +"${testcvs} status first-dir-br2-t7" \ +"${SPROG} status: Examining first-dir-br2-t7 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1\.4\.2[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1[^.]* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + dotest tagdate-27-trunk-t8 \ +"${testcvs} status first-dir-trunk-t8" \ +"${SPROG} status: Examining first-dir-trunk-t8 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.2[^.]* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: ${RCSDELTADATE} + Sticky Options: (none) + +=================================================================== +File: file2 Status: Up-to-date + + Working revision: 1\.2[^.]* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: ${RCSDELTADATE} + Sticky Options: (none)" + dotest tagdate-27-br2-t8 \ +"${testcvs} status first-dir-br2-t8" \ +"${SPROG} status: Examining first-dir-br2-t8 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1\.4\.2[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1[^.]* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + dotest tagdate-27-br2-t9 \ +"${testcvs} status first-dir-br2-t9" \ +"${SPROG} status: Examining first-dir-br2-t9 +=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1\.4\.2[^.]* + Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file2 Status: Up-to-date + + Working revision: 1\.2\.2\.2[^.]* + Repository revision: 1\.2\.2\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.2\.2) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1[^.]* + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v + Commit Identifier: ${commitid} + Sticky Tag: br2 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + + # Now check the contents of the files + dotest tagdate-28-trunk-t1 'cat first-dir-trunk-t1/file1' 'trunk-1' + dotest tagdate-28-br2-t1 'cat first-dir-br2-t1/file1' 'trunk-1' + dotest tagdate-28-trunk-t2 'cat first-dir-trunk-t2/file1' 'trunk-2' + dotest tagdate-28-br2-t2 'cat first-dir-br2-t2/file1' 'trunk-1' + dotest tagdate-28-br2-t3 'cat first-dir-br2-t3/file1' 'br2-1' + dotest tagdate-28-br2-t4 'cat first-dir-br2-t4/file1' 'br2-2' + dotest tagdate-28-br2-t6a 'cat first-dir-br2-t6/file1' "br2-2" + dotest tagdate-28-br2-t6b 'cat first-dir-br2-t6/file3' "br2-1" + dotest tagdate-28-trunk-t7a 'cat first-dir-trunk-t7/file1' "trunk-2" + dotest tagdate-28-trunk-t7b 'cat first-dir-trunk-t7/file2' "trunk-1" + dotest tagdate-28-br2-t7a 'cat first-dir-br2-t7/file1' "br2-2" + dotest tagdate-28-br2-t7b 'cat first-dir-br2-t7/file3' "br2-1" + dotest tagdate-28-trunk-t8a 'cat first-dir-trunk-t8/file1' "trunk-2" + dotest tagdate-28-trunk-t8b 'cat first-dir-trunk-t8/file2' "trunk-2" + dotest tagdate-28-br2-t8a 'cat first-dir-br2-t8/file1' "br2-2" + dotest tagdate-28-br2-t8c 'cat first-dir-br2-t8/file3' "br2-1" + dotest tagdate-28-br2-t9a 'cat first-dir-br2-t9/file1' "br2-2" + dotest tagdate-28-br2-t9b 'cat first-dir-br2-t9/file2' "br2-1" + dotest tagdate-28-br2-t9c 'cat first-dir-br2-t9/file3' "br2-1" + cd .. + + unset date_T1 date_T2 date_T3 date_T4 date_T5 + unset date_T6 date_T7 date_T8 date_T9 + TZ=$save_TZ + + dokeep + rm -r 1 2 3 4 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + multibranch2) + # Commit the first delta on branch A when there is an older + # branch, B, that already has a delta. A and B come from the + # same branch point. Then verify that branches A and B are + # in the right order. + mkdir 1; cd 1 + dotest multibranch2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest multibranch2-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + echo trunk-1 >file1 + echo trunk-1 >file2 + dotest multibranch2-3 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest multibranch2-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + dotest multibranch2-5 "${testcvs} -q tag -b A" "T file1 +T file2" + dotest multibranch2-6 "${testcvs} -q tag -b B" "T file1 +T file2" + + dotest multibranch2-7 "${testcvs} -q update -r B" '' + echo branch-B >file1 + echo branch-B >file2 + dotest multibranch2-8 "${testcvs} -q ci -m modify-on-B" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.4\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.4\.1; previous revision: 1\.1" + + dotest multibranch2-9 "${testcvs} -q update -r A" '[UP] file1 +[UP] file2' + echo branch-A >file1 + # When using cvs-1.9.20, this commit gets a failed assertion in rcs.c. + dotest multibranch2-10 "${testcvs} -q ci -m modify-on-A" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + dotest multibranch2-11 "${testcvs} -q log file1" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + B: 1\.1\.0\.4 + A: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; 1\.1\.4; +add +---------------------------- +revision 1\.1\.4\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +modify-on-B +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; lines: ${PLUS}1 -1; commitid: ${commitid}; +modify-on-A +=============================================================================" + + # This one is more concise. + dotest multibranch2-12 "${testcvs} -q log -r1.1 file1" \ +" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + B: 1\.1\.0\.4 + A: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 3; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; 1\.1\.4; +add +=============================================================================" + + # OK, try very much the same thing except we run update -j to + # bring the changes from B to A. Probably tests many of the + # same code paths but might as well keep it separate, I guess. + + dotest multibranch2-13 "${testcvs} -q update -r B" "[UP] file1 +[UP] file2" + dotest multibranch2-14 "${testcvs} -q update -r A -j B file2" \ +"[UP] file2 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +retrieving revision 1.1 +retrieving revision 1.1.4.1 +Merging differences between 1.1 and 1.1.4.1 into file2" + dotest multibranch2-15 "${testcvs} -q ci -m commit-on-A file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + tag8k) + # In cvs-1.9.27, there is a bug that can cause an abort. + # It happens when you commit a change to a ,v file that has + # just the right amount of tag/branch info to align one of the + # semicolons in the branch info to be on a 8k-byte boundary. + # The result: rcsbuf_getkey got an abort. This failure doesn't + # corrupt the ,v file -- that would be really serious. But it + # does leave stale write locks that have to be removed manually. + + mkdir 1 + cd 1 + + module=x + + : > junk + dotest tag8k-1 "$testcvs -Q import -m . $module X Y" '' + dotest tag8k-2 "$testcvs -Q co $module" '' + cd $module + + file=m + : > $file + dotest tag8k-3 "$testcvs add $file" \ +"$SPROG add: scheduling file .$file. for addition +$SPROG add: use .$SPROG commit. to add this file permanently" + dotest tag8k-4 "$testcvs -Q ci -m . $file" + + # It seems there have to be at least two versions. + echo a > $file + dotest tag8k-5 "$testcvs -Q ci -m . $file" + + # Add just under 8K worth of tags. + t=TAG--------------------------------------------------------------------- + t=$t$t + t=$t$t$t$t$t + # Now $t is 720 bytes long. + + # Apply some tags with that long prefix. + dotest tag8k-6 "$testcvs -Q tag $t-0 $file" '' + dotest tag8k-7 "$testcvs -Q tag $t-1 $file" '' + dotest tag8k-8 "$testcvs -Q tag $t-2 $file" '' + dotest tag8k-9 "$testcvs -Q tag $t-3 $file" '' + dotest tag8k-10 "$testcvs -Q tag $t-4 $file" '' + dotest tag8k-11 "$testcvs -Q tag $t-5 $file" '' + dotest tag8k-12 "$testcvs -Q tag $t-6 $file" '' + dotest tag8k-13 "$testcvs -Q tag $t-7 $file" '' + dotest tag8k-14 "$testcvs -Q tag $t-8 $file" '' + dotest tag8k-15 "$testcvs -Q tag $t-9 $file" '' + dotest tag8k-16 "$testcvs -Q tag $t-a $file" '' + + # Extract the author value. + name=`sed -n 's/.*; author \([^;]*\);.*/\1/p' ${CVSROOT_DIRNAME}/$module/$file,v|sed 1q` + + # Form a suffix string of length (16 - length($name)). + # CAREFUL: this will lose if $name is longer than 16. + sed_pattern=`echo $name|sed s/././g` + suffix=`echo 1234567890123456|sed s/$sed_pattern//` + + # Add a final tag with length chosen so that it will push the + # offset of the `;' in the 2nd occurrence of `;\tauthor' in the + # ,v file to exactly 8192. + dotest tag8k-17 "$testcvs -Q tag "x8bytes-$suffix" $file" '' + + # This commit would fail with 1.9.27. + echo a >> $file + dotest tag8k-18 "$testcvs -Q ci -m . $file" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + admin) + # More "cvs admin" tests. + # The basicb-21 test tests rejecting an invalid option. + # For -l and -u, see "reserved" and "keyword" tests. + # "binfiles" test has a test of "cvs admin -k". + # "log2" test has tests of -t and -q options to cvs admin. + # "rcs" tests -b option also. + # For -o, see: + # admin-22-o1 through admin-23 (various cases not involving ::) + # binfiles2-o* (:rev, rev on trunk; rev:, deleting entire branch) + # basicb-o* (attempt to delete all revisions) + # basica-o1 through basica-o3 (basic :: usage) + # head-o1 (::branch, where this deletes a revision or is noop) + # branches-o1 (::branch, similar, with different branch topology) + # log-o1 (1.3.2.1::) + # binfiles-o1 (1.3:: and ::1.3; binary files) + # binfiles3-9 (binary files) + # Also could be testing: + # 1.3.2.6::1.3.2.8 + # 1.3.2.6::1.3.2 + # 1.3.2.1::1.3.2.6 + # 1.3::1.3.2.6 (error? or synonym for ::1.3.2.6?) + # -n: admin, tagf tests. + + # Test the postadmin hook as a side effect of the rest of the tests. + # See the `info' test for notes on where other script hooks are + # tested. + mkdir 2; cd 2 + dotest admin-init-1 "$testcvs -Q co CVSROOT" + cd CVSROOT + echo "ALL $TESTDIR/2/loggit %r %p %c" >>postadmin + dotest admin-init-2 "$testcvs -Q ci -mlog-admin" + cd .. # 2 + + cat >loggit <<EOF +#!$TESTSHELL +echo \${1+"\$@"} >>$TESTDIR/2/admin-log +EOF + # #^@&!^@ Cygwin. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x $TESTDIR/2/loggit" + else + chmod +x loggit + fi + cd .. # $TESTDIR + + + mkdir 1; cd 1 + dotest admin-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest admin-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + + dotest_fail admin-3 "${testcvs} -q admin -i file1" \ +"${CPROG} admin: the -i option to admin is not supported +${CPROG} admin: run add or import to create an RCS file +${CPROG} \[admin aborted\]: specify ${CPROG} -H admin for usage information" + dotest_fail admin-4 "${testcvs} -q log file1" \ +"${SPROG} log: nothing known about file1" + dotest_fail admin-4a "${testcvs} -q admin file1" \ +"${SPROG} admin: nothing known about file1" + + # Set up some files, file2 a plain one and file1 with a revision + # on a branch. + touch file1 file2 + dotest admin-5 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest admin-6 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + dotest admin-7 "${testcvs} -q tag -b br" "T file1 +T file2" + dotest admin-8 "${testcvs} -q update -r br" "" + echo 'add a line on the branch' >> file1 + echo 'add a file on the branch' >> file3 + dotest admin-9a "${testcvs} -q add file3" \ +"${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest admin-9b "${testcvs} -q ci -m modify-on-branch" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/Attic/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1" + dotest admin-10 "${testcvs} -q update -A" \ +"U file1 +${SPROG} update: \`file3' is no longer in the repository" + + # Check that we can administer files in the repository that + # aren't in the working directory. + dotest admin-10-1 "${testcvs} admin ." \ +"${SPROG} admin: Administrating . +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + dotest admin-10-2 "${testcvs} -q admin file3" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v +done" + + # Try to recurse with a numeric revision arg. + # If we wanted to comprehensive about this, we would also test + # this for -l, -u, and all the different -o syntaxes. + dotest_fail admin-10a "${testcvs} -q admin -b1.1.2" \ +"${CPROG} admin: while processing more than one file: +${CPROG} \[admin aborted\]: attempt to specify a numeric revision" + dotest_fail admin-10b "${testcvs} -q admin -m1.1:bogus file1 file2" \ +"${CPROG} admin: while processing more than one file: +${CPROG} \[admin aborted\]: attempt to specify a numeric revision" + + # try a bad symbolic revision + dotest_fail admin-10c "${testcvs} -q admin -bBOGUS" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/file1,v: Symbolic name BOGUS is undefined. +${SPROG} admin: RCS file for .file1. not modified\. +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name BOGUS is undefined. +${SPROG} admin: RCS file for .file2. not modified\." + + # Note that -s option applies to the new default branch, not + # the old one. + # Also note that the implementation of -a via "rcs" requires + # no space between -a and the argument. However, we expect + # to change that once CVS parses options. + dotest admin-11 "${testcvs} -q admin -afoo,bar -abaz \ +-b1.1.2 -cxx -U -sfoo file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest admin-11a "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: 1\.1\.2 +locks: +access list: + foo + bar + baz +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +add +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: foo; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify-on-branch +=============================================================================" + dotest admin-12 "${testcvs} -q admin -bbr file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest admin-12a "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: 1\.1\.2 +locks: +access list: + foo + bar + baz +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +add +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: foo; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify-on-branch +=============================================================================" + + # "cvs log" doesn't print the comment leader. RCS 5.7 will print + # the comment leader only if one specifies "-V4" to rlog. So it + # seems like the only way to test it is by looking at the RCS file + # directly. This also serves as a test of exporting RCS files + # (analogous to the import tests in "rcs"). + # Rather than try to write a rigorous check for whether the + # file CVS exports is valid, we just write a simpler + # test for what CVS actually exports, and figure we can revise + # the check as needed (within the confines of the RCS5 format as + # documented in RCSFILES). + # Note that we must accept either 2 or 4 digit year. + dotest admin-13 "cat ${CVSROOT_DIRNAME}/first-dir/file1,v" \ +"head 1\.1; +branch 1\.1\.2; +access + foo + bar + baz; +symbols + br:1\.1\.0\.2; +locks; +comment @xx@; + + +1\.1 +date ${RCSDELTADATE}; author ${username}; state Exp; +branches + 1\.1\.2\.1; +next ; +commitid ${commitid}; + +1\.1\.2\.1 +date ${RCSDELTADATE}; author ${username}; state foo; +branches; +next ; +commitid ${commitid}; + + +desc +@@ + + +1\.1 +log +@add +@ +text +@@ + + +1\.1\.2\.1 +log +@modify-on-branch +@ +text +@a0 1 +add a line on the branch +@" + dotest_fail admin-14-1 "${testcvs} -q admin \ +-m1.1.1.1:changed-bogus-log-message file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +$SPROG admin: $CVSROOT_DIRNAME/first-dir/file2,v: no such revision 1\.1\.1\.1 +$SPROG admin: RCS file for .file2. not modified." + dotest admin-14-2 "${testcvs} -q log file2" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + br: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +add +=============================================================================" + + dotest admin-14-3 "${testcvs} -q admin -aauth3 -aauth2,foo \ +-soneone:1.1 -m1.1:changed-log-message -ntagone: file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + dotest admin-15 "${testcvs} -q log file2" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.1 +branch: +locks: strict +access list: + auth3 + auth2 + foo +symbolic names: + tagone: 1\.1 + br: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: oneone; commitid: ${commitid}; +changed-log-message +=============================================================================" + + dotest admin-16 "${testcvs} -q admin \ +-A${CVSROOT_DIRNAME}/first-dir/file2,v -b -L -Nbr:1.1 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest admin-17 "${testcvs} -q log file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: + foo + bar + baz + auth3 + auth2 +symbolic names: + br: 1\.1 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +add +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: foo; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify-on-branch +=============================================================================" + + dotest_fail admin-18 "${testcvs} -q admin -nbr:1.1.2 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/file1,v: symbolic name br already bound to 1\.1 +${SPROG} admin: RCS file for .file1. not modified\." + dotest admin-19 "${testcvs} -q admin -ebaz -ebar,auth3 -nbr file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest admin-20 "${testcvs} -q log file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: + foo + auth2 +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +add +---------------------------- +revision 1.1.2.1 +date: ${ISO8601DATE}; author: ${username}; state: foo; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify-on-branch +=============================================================================" + + # OK, this is starting to get ridiculous, in terms of + # testing a feature (access lists) which doesn't do anything + # useful, but what about nonexistent files and + # relative pathnames in admin -A? + dotest_fail admin-19a-nonexist \ +"${testcvs} -q admin -A${TESTDIR}/foo/bar file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +${SPROG} admin: Couldn't open rcs file .${TESTDIR}/foo/bar.: No such file or directory +${SPROG} \[admin aborted\]: cannot continue" + + # In the remote case, we are cd'd off into the temp directory + # and so these tests give "No such file or directory" errors. + if $remote; then :; else + dotest admin-19a-admin "${testcvs} -q admin -A../../cvsroot/first-dir/file2,v file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest admin-19a-log "${testcvs} -q log -h -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: + foo + auth2 + auth3 +keyword substitution: kv +total revisions: 2 +=============================================================================" + fi # end of tests skipped for remote + + # Now test that plain -e works right. + dotest admin-19a-2 "${testcvs} -q admin -e file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest admin-19a-3 "${testcvs} -q log -h -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 2 +=============================================================================" + + # Put the access list back, to avoid special cases later. + dotest admin-19a-4 "${testcvs} -q admin -afoo,auth2 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + + # Add another revision to file2, so we can delete one. + echo 'add a line' >> file2 + dotest admin-21 "${testcvs} -q ci -m modify file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.2; previous revision: 1\.1" + dotest admin-22 "${testcvs} -q admin -o1.1 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +deleting revision 1\.1 +done" + # Test admin -o. More variants that we could be testing: + # * REV: [on branch] + # * REV1:REV2 [deleting whole branch] + # * high branch numbers (e.g. 1.2.2.3.2.3) + # ... and probably others. See RCS_delete_revs for ideas. + + echo first rev > aaa + dotest admin-22-o1 "${testcvs} add aaa" \ +"${SPROG} add: scheduling file .aaa. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest admin-22-o2 "${testcvs} -q ci -m first aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +initial revision: 1\.1" + echo second rev >> aaa + dotest admin-22-o3 "${testcvs} -q ci -m second aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.2; previous revision: 1\.1" + echo third rev >> aaa + dotest admin-22-o4 "${testcvs} -q ci -m third aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.3; previous revision: 1\.2" + echo fourth rev >> aaa + dotest admin-22-o5 "${testcvs} -q ci -m fourth aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.4; previous revision: 1\.3" + echo fifth rev >>aaa + dotest admin-22-o6 "${testcvs} -q ci -m fifth aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.5; previous revision: 1\.4" + echo sixth rev >> aaa + dotest admin-22-o7 "${testcvs} -q ci -m sixth aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.6; previous revision: 1\.5" + dotest admin-22-o8 "${testcvs} admin -l1.6 aaa" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +1\.6 locked +done" + dotest admin-22-o9 "${testcvs} log -r1.6 aaa" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +Working file: aaa +head: 1\.6 +branch: +locks: strict + ${username}: 1\.6 +access list: +symbolic names: +keyword substitution: kv +total revisions: 6; selected revisions: 1 +description: +---------------------------- +revision 1\.6 locked by: ${username}; +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +sixth +=============================================================================" + dotest_fail admin-22-o10 "${testcvs} admin -o1.5: aaa" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove locked revision 1\.6 +${SPROG} admin: RCS file for .aaa. not modified\." + dotest admin-22-o11 "${testcvs} admin -u aaa" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +1\.6 unlocked +done" + dotest admin-22-o12 "${testcvs} admin -o1.5: aaa" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +deleting revision 1\.6 +deleting revision 1\.5 +done" + dotest admin-22-o13 "${testcvs} log aaa" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +Working file: aaa +head: 1\.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 4 +description: +---------------------------- +revision 1\.4 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +fourth +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +third +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +second +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +first +=============================================================================" + + dotest admin-22-o14 "${testcvs} tag -b -r1.3 br1 aaa" "T aaa" + dotest admin-22-o15 "${testcvs} update -rbr1 aaa" "U aaa" + echo new branch rev >> aaa + dotest admin-22-o16 "${testcvs} ci -m new-branch aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.3\.2\.1; previous revision: 1\.3" + dotest_fail admin-22-o17 "${testcvs} admin -o1.2:1.4 aaa" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +deleting revision 1\.4 +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove branch point 1\.3 +${SPROG} admin: RCS file for .aaa. not modified\." + dotest admin-22-o18 "${testcvs} update -p -r1.4 aaa" \ +"=================================================================== +Checking out aaa +RCS: ${CVSROOT_DIRNAME}/first-dir/aaa,v +VERS: 1\.4 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +first rev +second rev +third rev +fourth rev" + echo second branch rev >> aaa + dotest admin-22-o19 "${testcvs} ci -m branch-two aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.3\.2\.2; previous revision: 1\.3\.2\.1" + echo third branch rev >> aaa + dotest admin-22-o20 "${testcvs} ci -m branch-three aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.3\.2\.3; previous revision: 1\.3\.2\.2" + echo fourth branch rev >> aaa + dotest admin-22-o21 "${testcvs} ci -m branch-four aaa" \ +"$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa +new revision: 1\.3\.2\.4; previous revision: 1\.3\.2\.3" + dotest admin-22-o22 "${testcvs} admin -o:1.3.2.3 aaa" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +deleting revision 1\.3\.2\.1 +deleting revision 1\.3\.2\.2 +deleting revision 1\.3\.2\.3 +done" + dotest admin-22-o23 "${testcvs} log aaa" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +Working file: aaa +head: 1\.4 +branch: +locks: strict +access list: +symbolic names: + br1: 1\.3\.0\.2 +keyword substitution: kv +total revisions: 5; selected revisions: 5 +description: +---------------------------- +revision 1\.4 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +fourth +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +branches: 1\.3\.2; +third +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +second +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +first +---------------------------- +revision 1\.3\.2\.4 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}4 -0; commitid: ${commitid}; +branch-four +=============================================================================" + + dotest admin-22-o24 "${testcvs} -q update -p -r 1.3.2.4 aaa" \ +"first rev +second rev +third rev +new branch rev +second branch rev +third branch rev +fourth branch rev" + + # The bit here about how there is a "tagone" tag pointing to + # a nonexistent revision is documented by rcs. I dunno, I + # wonder whether the "cvs admin -o" should give a warning in + # this case. + dotest admin-23 "${testcvs} -q log file2" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.2 +branch: +locks: strict +access list: + auth3 + auth2 + foo +symbolic names: + tagone: 1\.1 + br: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +modify +=============================================================================" + + dotest admin-25 "cat ${CVSROOT_DIRNAME}/first-dir/file1,v" \ +"head 1\.1; +access + foo + auth2; +symbols; +locks; strict; +comment @xx@; + + +1\.1 +date ${RCSDELTADATE}; author ${username}; state Exp; +branches + 1\.1\.2\.1; +next ; +commitid ${commitid}; + +1\.1\.2\.1 +date ${RCSDELTADATE}; author ${username}; state foo; +branches; +next ; +commitid ${commitid}; + + +desc +@@ + + +1\.1 +log +@add +@ +text +@@ + + +1\.1\.2\.1 +log +@modify-on-branch +@ +text +@a0 1 +add a line on the branch +@" + + # Tests of cvs admin -n. Make use of the results of + # admin-1 through admin-25. + # FIXME: We probably shouldn't make use of those results; + # this test is way too long as it is. + + # tagtwo should be a revision + # + dotest admin-26-1 "${testcvs} admin -ntagtwo:tagone file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + # br1 should be a branch + # + dotest admin-26-2 "${testcvs} admin -nbr1:br file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + # Attach some tags using RCS versions + # + dotest admin-26-3 "${testcvs} admin -ntagthree:1.1 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + dotest admin-26-4 "${testcvs} admin -nbr2:1.1.2 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + dotest admin-26-5 "${testcvs} admin -nbr4:1.1.0.2 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + # Check results so far + # + dotest admin-26-6 "${testcvs} status -v file2" \ +"=================================================================== +File: file2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + br4 (branch: 1\.1\.2) + br2 (branch: 1\.1\.2) + tagthree (revision: 1\.1) + br1 (branch: 1\.1\.2) + tagtwo (revision: 1\.1) + tagone (revision: 1\.1) + br (branch: 1\.1\.2)" + + + # Add a couple more revisions + # + echo "nuthr_line" >> file2 + dotest admin-27-1 "${testcvs} commit -m nuthr_line file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.3; previous revision: 1\.2" + + echo "yet_another" >> file2 + dotest admin-27-2 "${testcvs} commit -m yet_another file2" \ +"$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +new revision: 1\.4; previous revision: 1\.3" + + # Fail trying to reattach existing tag with -n + # + dotest admin-27-3 "${testcvs} admin -ntagfour:1.1 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + dotest_fail admin-27-4 "${testcvs} admin -ntagfour:1.3 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: symbolic name tagfour already bound to 1\.1 +${SPROG} admin: RCS file for .file2. not modified\." + + # Succeed at reattaching existing tag, using -N + # + dotest admin-27-5 "${testcvs} admin -Ntagfour:1.3 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +done" + + # Fail on some bogus operations + # Try to attach to nonexistant tag + # + dotest_fail admin-28-1 "${testcvs} admin -ntagsix:tagfive file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision tagfive is undefined\. +${SPROG} admin: RCS file for .file2. not modified\." + + # Try a some nonexisting numeric target tags + # + dotest_fail admin-28-2 "${testcvs} admin -ntagseven:2.1 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} \[admin aborted\]: revision .2\.1. does not exist" + + dotest_fail admin-28-3 "${testcvs} admin -ntageight:2.1.2 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} \[admin aborted\]: revision .2\.1\.2. does not exist" + + # Try some invalid targets + # + dotest_fail admin-28-4 "${testcvs} admin -ntagnine:1.a.2 file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} \[admin aborted\]: tag .1\.a\.2. must start with a letter" + + # Confirm that a missing tag is not a fatal error. + dotest admin-28-5.1 "${testcvs} -Q tag BO+GUS file1" '' + dotest_fail admin-28-5.2 "${testcvs} admin -ntagten:BO+GUS file2 file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision BO${PLUS}GUS is undefined\. +${SPROG} admin: RCS file for .file2. not modified\. +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + + dotest_fail admin-28-6 "${testcvs} admin -nq.werty:tagfour file2" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} \[admin aborted\]: tag .q\.werty. must not contain the characters ..*" + + # Verify the archive + # + dotest admin-29 "cat ${CVSROOT_DIRNAME}/first-dir/file2,v" \ +"head 1\.4; +access + auth3 + auth2 + foo; +symbols + tagfour:1\.3 + br4:1\.1\.0\.2 + br2:1\.1\.0\.2 + tagthree:1\.1 + br1:1\.1\.0\.2 + tagtwo:1\.1 + tagone:1\.1 + br:1\.1\.0\.2; +locks; strict; +comment @# @; + + +1\.4 +date ${RCSDELTADATE}; author ${username}; state Exp; +branches; +next 1\.3; +commitid ${commitid}; + +1\.3 +date ${RCSDELTADATE}; author ${username}; state Exp; +branches; +next 1\.2; +commitid ${commitid}; + +1\.2 +date ${RCSDELTADATE}; author ${username}; state Exp; +branches; +next ; +commitid ${commitid}; + + +desc +@@ + + +1\.4 +log +@yet_another +@ +text +@add a line +nuthr_line +yet_another +@ + + +1\.3 +log +@nuthr_line +@ +text +@d3 1 +@ + + +1\.2 +log +@modify +@ +text +@d2 1 +@" + + dotest_fail admin-30 "${testcvs} admin -mbr:another-log-message \ +file2 aaa file3" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: no such revision br: 1\.1 +${SPROG} admin: RCS file for .file2. not modified. +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: no such revision br +${SPROG} admin: RCS file for .aaa. not modified. +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v +done" + dotest admin-31 "${testcvs} log" \ +"${SPROG} log: Logging \. + +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v +Working file: aaa +head: 1\.4 +branch: +locks: strict +access list: +symbolic names: + br1: 1\.3\.0\.2 +keyword substitution: kv +total revisions: 5; selected revisions: 5 +description: +---------------------------- +revision 1\.4 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +fourth +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +branches: 1\.3\.2; +third +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +second +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +first +---------------------------- +revision 1\.3\.2\.4 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}4 -0; commitid: ${commitid}; +branch-four +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: + foo + auth2 +symbolic names: + tagten: 1\.1 + BO${PLUS}GUS: 1\.1 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +branches: 1\.1\.2; +add +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: foo; lines: ${PLUS}1 -0; commitid: ${commitid}; +modify-on-branch +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +Working file: file2 +head: 1\.4 +branch: +locks: strict +access list: + auth3 + auth2 + foo +symbolic names: + tagfour: 1\.3 + br4: 1\.1\.0\.2 + br2: 1\.1\.0\.2 + tagthree: 1\.1 + br1: 1\.1\.0\.2 + tagtwo: 1\.1 + tagone: 1\.1 + br: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.4 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +yet_another +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +nuthr_line +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +modify +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v +Working file: file3 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + br: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: dead; commitid: ${commitid}; +branches: 1\.1\.2; +file file3 was initially added on branch br\. +---------------------------- +revision 1\.1\.2\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +another-log-message +=============================================================================" + + # Currently, this test outputs 36 identical lines, so I am just + # checking $DOTSTAR for brevity. + dotest admin-postadmin-examine-1 "cat $TESTDIR/2/admin-log" \ +"$CVSROOT_DIRNAME first-dir admin$DOTSTAR" + + dokeep + + # clean up our after ourselves + restore_adm + cd ../.. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + reserved) + # Tests of reserved checkouts. Eventually this will test + # rcslock.pl (or equivalent) and all kinds of stuff. Right + # now it just does some very basic checks on cvs admin -u + # and cvs admin -l. + # Also should test locking on a branch (and making sure that + # locks from one branch don't get mixed up with those from + # another. Both the case where one of the branches is the + # main branch, and in which neither one is). + # See also test keyword, which tests that keywords and -kkvl + # do the right thing in the presence of locks. + + # The usual setup, directory first-dir containing file file1. + mkdir 1; cd 1 + dotest reserved-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest reserved-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch file1 + dotest reserved-3 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest reserved-4 "${testcvs} -q ci -m add" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1" + + dotest reserved-5 "${testcvs} -q admin -l file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +1\.1 locked +done" + dotest reserved-6 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict + ${username}: 1\.1 +access list: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 locked by: ${username}; +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +add +=============================================================================" + + # Note that this just tests the owner of the lock giving + # it up. It doesn't test breaking a lock. + dotest reserved-7 "${testcvs} -q admin -u file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +1\.1 unlocked +done" + + dotest reserved-8 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +add +=============================================================================" + + # rcslock.pl tests. Of course, the point isn't to test + # rcslock.pl from the distribution but equivalent + # functionality (for example, many sites may have an old + # rcslock.pl). The functionality of this hook falls + # short of the real rcslock.pl though. + # Note that we can use rlog or look at the RCS file directly, + # but we can't use "cvs log" because "cvs commit" has a lock. + + cat >${TESTDIR}/lockme <<EOF +#!${TESTSHELL} +line=\`grep <\$1/\$2,v 'locks $anyusername:1\.[0-9];'\` +if test -z "\$line"; then + # It isn't locked + exit 0 +else + user=\`echo \$line | sed -e 's/locks \\($anyusername\\):[0-9.]*;.*/\\1/'\` + version=\`echo \$line | sed -e 's/locks $anyusername:\\([0-9.]*\\);.*/\\1/'\` + echo "\$user has file a-lock locked for version \$version" >&2 + exit 1 +fi +EOF + # Cygwin. Blaaarg. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x ${TESTDIR}/lockme" + else + chmod +x ${TESTDIR}/lockme + fi + + echo stuff > a-lock + dotest reserved-9 "${testcvs} add a-lock" \ +"${SPROG} add: scheduling file .a-lock. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest reserved-10 "${testcvs} -q ci -m new a-lock" \ +"$CVSROOT_DIRNAME/first-dir/a-lock,v <-- a-lock +initial revision: 1\.1" + # FIXME: the contents of CVSROOT fluctuate a lot + # here. Maybe the expect pattern should just + # confirm that commitinfo is one of the files checked out, + # but for now we just check that CVS exited with success. + cd .. + if ${testcvs} -q co CVSROOT >>${LOGFILE} ; then + pass reserved-11 + else + fail reserved-11 + fi + cd CVSROOT + echo "DEFAULT ${TESTDIR}/lockme" >>commitinfo + dotest reserved-12 "${testcvs} -q ci -m rcslock commitinfo" \ +"$CVSROOT_DIRNAME/CVSROOT/commitinfo,v <-- commitinfo +new revision: 1\.2; previous revision: 1\.1 +$SPROG commit: Rebuilding administrative file database" + cd ..; cd first-dir + + # Simulate (approximately) what a-lock would look like + # if someone else had locked revision 1.1. + sed -e 's/locks; strict;/locks fred:1.1; strict;/' ${CVSROOT_DIRNAME}/first-dir/a-lock,v > a-lock,v + # Cygwin. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v" + else + chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v + fi + dotest reserved-13 "mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v" + # Cygwin. Blah. + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v" + else + chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v + fi + echo more stuff >> a-lock + dotest_fail_sort reserved-13b "$testcvs ci -m '' a-lock" \ +" \"$TESTDIR/lockme\" +Appending defaults (\" %r/%p %s\"), but please be aware that this usage is +$SPROG \[commit aborted\]: correct above errors first! +$SPROG commit: Pre-commit check failed +$SPROG commit: warning: commitinfo line contains no format strings: +deprecated\. +fred has file a-lock locked for version 1\.1" + # OK, now test "cvs admin -l" in the case where someone + # else has the file locked. + dotest_fail reserved-13c "${testcvs} admin -l a-lock" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v +${SPROG} \[admin aborted\]: Revision 1\.1 is already locked by fred" + + dotest reserved-14 "${testcvs} admin -u1.1 a-lock" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v +${SPROG} admin: ${CVSROOT_DIRNAME}/first-dir/a-lock,v: revision 1\.1 locked by fred; breaking lock +1\.1 unlocked +done" + dotest reserved-15 "$testcvs -q ci -m success a-lock" \ +"$SPROG commit: warning: commitinfo line contains no format strings: + \"$TESTDIR/lockme\" +Appending defaults (\" %r/%p %s\"), but please be aware that this usage is +deprecated\. +$CVSROOT_DIRNAME/first-dir/a-lock,v <-- a-lock +new revision: 1\.2; previous revision: 1\.1" + + # Now test for a bug involving branches and locks + sed -e 's/locks; strict;/locks fred:1.2; strict;/' ${CVSROOT_DIRNAME}/first-dir/a-lock,v > a-lock,v + chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v + dotest reserved-16 \ +"mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v" "" + chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v + dotest reserved-17 "${testcvs} -q tag -b br a-lock" "T a-lock" + dotest reserved-18 "${testcvs} -q update -r br a-lock" "" + echo edit it >>a-lock + dotest reserved-19 "${testcvs} -q ci -m modify a-lock" \ +"$SPROG commit: warning: commitinfo line contains no format strings: + \"$TESTDIR/lockme\" +Appending defaults (\" %r/%p %s\"), but please be aware that this usage is +deprecated\. +$CVSROOT_DIRNAME/first-dir/a-lock,v <-- a-lock +new revision: 1\.2\.2\.1; previous revision: 1\.2" + + # undo commitinfo changes + cd ../CVSROOT + echo '# vanilla commitinfo' >commitinfo + dotest reserved-cleanup-1 "${testcvs} -q ci -m back commitinfo" \ +"$SPROG commit: warning: commitinfo line contains no format strings: + \"$TESTDIR/lockme\" +Appending defaults (\" %r/%p %s\"), but please be aware that this usage is +deprecated\. +$CVSROOT_DIRNAME/CVSROOT/commitinfo,v <-- commitinfo +new revision: 1\.3; previous revision: 1\.2 +$SPROG commit: Rebuilding administrative file database" + + dokeep + cd ..; rm -r CVSROOT + cd .. + rm -r 1 + rm $TESTDIR/lockme + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + diffmerge1) + # Make sure CVS can merge correctly in circumstances where it + # used to mess up (due to a bug which existed in diffutils 2.7 + # and 2.6, but not 2.5, and which has been fixed in CVS's diff + # lib by Paul Eggert, bless his bitty heart). + + # This first test involves two working copies, "mine" and + # "yours", checked out from the same repository at the same + # time. In yours, you remove some text from the end of the + # file and check it in; meanwhile, "me" has commented out some + # lines earlier in the file, and I go to check it in right + # after you checked yours in. CVS naturally tells me the file + # is not up-to-date, so I run cvs update, but it updates + # incorrectly, leaving in the lines of text you just deleted. + # Bad! I'm in too much of a hurry to actually look at the + # file, so I check it in and go home, and so your changes have + # been lost. Later you discover this, and you suspect me of + # deliberately sabotaging your work, so you let all the air + # out of my tires. Only after a series of expensive lawsuits + # and countersuits do we discover that this was all CVS's + # fault. + # + # Luckily, this problem has been fixed now, as our test will + # handily confirm, no doubt: + + # First make a repository containing the original text: + + # We should be here anyway, but cd to it just in case: + cd ${TESTDIR} + + mkdir diffmerge1 + cd diffmerge1 + + # These are the files we both start out with: + mkdir import + cd import + diffmerge_create_older_files + + dotest diffmerge1_import \ + "${testcvs} import -m import diffmerge1 tag1 tag2" \ + "${DOTSTAR}No conflicts created by this import" + cd .. + + # Check out two working copies, one for "you" and one for + # "me". If no branch is used and cvs detects that only one + # of the two people made changes, then cvs does not run the + # merge algorithm. But if a branch is used, then cvs does run + # the merge algorithm (even in this case of only one of the two + # people having made changes). CVS used to have a bug in this + # case. Therefore, it is important to test this case by + # using a branch: + ${testcvs} rtag -b tag diffmerge1 >/dev/null 2>&1 + ${testcvs} checkout -r tag diffmerge1 >/dev/null 2>&1 + mv diffmerge1 yours + ${testcvs} checkout diffmerge1 >/dev/null 2>&1 + mv diffmerge1 mine + + # In your working copy, you'll make changes, and + # then check in your changes before I check in mine: + cd yours + diffmerge_create_your_files + dotest diffmerge1_yours "${testcvs} -q ci -m yours" \ +"$CVSROOT_DIRNAME/diffmerge1/testcase01,v <-- testcase01 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase02,v <-- testcase02 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase03,v <-- testcase03 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase04,v <-- testcase04 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase05,v <-- testcase05 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase06,v <-- testcase06 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase07,v <-- testcase07 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase08,v <-- testcase08 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase09,v <-- testcase09 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +$CVSROOT_DIRNAME/diffmerge1/testcase10,v <-- testcase10 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1" + + # Change my copy. Then I + # update, after both my modifications and your checkin: + cd ../mine + diffmerge_create_my_files + dotest diffmerge1_mine "${testcvs} -q update -j tag" \ +"M testcase01 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase01,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase01 +M testcase02 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase02,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase02 +M testcase03 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase03,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase03 +M testcase04 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase04,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase04 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase05,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase05 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase06,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase06 +M testcase07 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase07,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase07 +testcase07 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 +M testcase08 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase08,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase08 +M testcase09 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase09,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase09 +M testcase10 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase10,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.1\.2\.1 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase10" + + # So if your changes didn't make it into my working copy, or + # in any case if the files do not look like the final text + # in the files in directory comp_me, then the test flunks: + cd .. + mkdir comp_me + cd comp_me + diffmerge_create_expected_files + cd .. + rm mine/.#* + + # If you have GNU's version of diff, you may try + # uncommenting the following line which will give more + # fine-grained information about how cvs differed from the + # correct result: + #dotest diffmerge1_cmp "diff -u --recursive --exclude=CVS comp_me mine" '' + dotest diffmerge1_cmp "directory_cmp comp_me mine" + + # Clean up after ourselves: + dokeep + cd .. + rm -r diffmerge1 + modify_repo rm -rf $CVSROOT_DIRNAME/diffmerge1 + ;; + + + + diffmerge2) + + # FIXME: This test should be rewritten to be much more concise. + # It currently weighs in at something like 600 lines, but the + # same thing could probably be tested in more like 50-100 lines. + mkdir diffmerge2 + + # This tests for another diffmerge bug reported by Martin + # Tomes; actually, his bug was probably caused by an initial + # fix for the bug in test diffmerge1, and likely wasn't ever + # a problem in CVS as long as one was using a normal + # distribution of diff or a version of CVS that has the diff + # lib in it. + # + # Nevertheless, once burned twice cautious, so we test for his + # bug here. + # + # Here is his report, more or less verbatim: + # ------------------------------------------ + # + # Put the attached file (sgrid.h,v) into your repository + # somewhere, check out the module and do this: + # + # cvs update -j Review_Phase_2_Enhancements sgrid.h + # cvs diff -r Review_V1p3 sgrid.h + # + # As there have been no changes made on the trunk there + # should be no differences, however this is output: + # + # % cvs diff -r Review_V1p3 sgrid.h + # Index: sgrid.h + # =================================================================== + # RCS file: /usr/local/repository/play/fred/sgrid.h,v + # retrieving revision 1.1.2.1 + # diff -r1.1.2.1 sgrid.h + # 178a179,184 + # > /*-------------------------------------------------------------- + # > INLINE FUNCTION : HORIZONTALLINES + # > NOTES : Description at the end of the file + # > ----------------------------------------------------------------*/ + # > uint16 horizontalLines( void ); + # > + # + # I did a cvs diff -c -r 1.1 -r 1.1.2.1 sgrid.h and patched those + # differences to sgrid.h version 1.1 and got the correct result + # so it looks like the built in patch is faulty. + # ------------------------------------------------------------------- + # + # This is the RCS file, sgrid.h,v, that he sent: + + echo "head 1.1; +access; +symbols + Review_V1p3:1.1.2.1 + Review_V1p3C:1.1.2.1 + Review_1p3A:1.1.2.1 + Review_V1p3A:1.1.2.1 + Review_Phase_2_Enhancements:1.1.0.2 + Review_V1p2:1.1 + Review_V1p2B:1.1 + Review_V1p2A:1.1 + Review_V1p1:1.1 + Review_1p1:1.1; +locks; strict; +comment @ * @; + + +1.1 +date 97.04.02.11.20.05; author colinl; state Exp; +branches + 1.1.2.1; +next ; + +1.1.2.1 +date 97.06.09.10.00.07; author colinl; state Exp; +branches; +next ; + + +desc +@@ + + +1.1 +log +@Project: DEV1175 +DCN: +Tested By: Colin Law +Reviewed By: +Reason for Change: Initial Revision of all files + +Design Change Details: + +Implications: +@ +text +@/* \$""Header: L:/gpanels/dis/sgrid.h_v 1.1.1.0 24 Jan 1996 14:59:20 PAULT \$ */ +/* + * \$""Log: L:/gpanels/dis/sgrid.h_v \$ + * + * Rev 1.1.1.0 24 Jan 1996 14:59:20 PAULT + * Branched + * + * Rev 1.1 24 Jan 1996 12:09:52 PAULT + * Consolidated 4100 code merged to trunk + * + * Rev 1.0.2.0 01 Jun 1995 14:18:58 DAVEH + * Branched + * + * Rev 1.0 19 Apr 1995 16:32:48 COLINL + * Initial revision. +*/ +/***************************************************************************** +FILE : SGRID.H +VERSION : 2.1 +AUTHOR : Dave Hartley +SYSTEM : Borland C++ +DESCRIPTION : The declaration of the scrolling grid class + +*****************************************************************************/ +#if !defined(__SGRID_H) +#define __SGRID_H + +#if !defined(__SCROLL_H) +#include <scroll.h> +#endif + +#if !defined(__GKI_H) +#include \"gki.h\" +#endif + +#if defined PRINTING_SUPPORT +class Printer; +#endif + +/***************************************************************************** +CLASS : ScrollingGrid +DESCRIPTION: This class inherits from a grid and a scrollable, and + can therefore use all the PUBLIC services provided by these + classes. A description of these can be found in + GRID.H and SCROLL.H. + A scrolling grid is a set of horizontal and vertical lines + that scroll and continually update to provide a complete grid + +*****************************************************************************/ + +class ScrollingGrid : public Scrollable +{ + public: +#if defined _WINDOWS +/*--------------------------------------------------------------------------- +FUNCTION : CONSTRUCTOR +DESCRIPTION : sets up the details of the grid, ready for painting +ARGUMENTS : name : sgColour + - the colour of the grid + sgLineType + - the syle of line + sgHorizontalTotal + - the total number of horizontal grid lines + verticalSpacingMin + - the min distance between the vertical grid lines + on the scrolling axis + currentTimestamp + - timestamp value now + ticksPerSecond + - number of timestamp ticks per second + ticksPerPixel + - number of timestamp ticks per pixel required + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + ScrollingGrid( GkiColour sgColour, GkiLineType sgLineType, + uint16 sgHorizontalTotal, + uint16 verticalSpacingMin, uint32 currentTimestamp, + uint16 ticksPerSecond, uint32 ticksPerPixel ); +#else +/*--------------------------------------------------------------------------- +FUNCTION : CONSTRUCTOR +DESCRIPTION : sets up the details of the grid, ready for painting +ARGUMENTS : name : sgColour + - the colour of the grid + sgLineType + - the syle of line + sgHorizontalTotal ( THE MAX NUMBER OF LINES IS 100 ) + - the total number of horizontal grid lines + sgVerticalSpacing + - the distance between the vertical grid lines + on the scrolling axis + +RETURN : None +NOTES : If the caller does not get the total grid lines value, synced + with the overall size of the viewport, the spacing between + grid lines will not be consistent. + +---------------------------------------------------------------------------*/ + ScrollingGrid( GkiColour sgColour, GkiLineType sgLineType + , uint16 sgHorizontalTotal, uint16 sgVerticalSpacing ); +#endif +/*--------------------------------------------------------------------------- +FUNCTION : DESTRUCTOR +DESCRIPTION : tidies it all up +ARGUMENTS : name : + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + ~ScrollingGrid( void ); + +/*--------------------------------------------------------------------------- +FUNCTION : ATTACH +DESCRIPTION : This service overloads the base class service, as it does + additional work at the time of attachment. + +ARGUMENTS : name : tDrawingArea + - the scrolled viewport to attach this trend to + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void attach( SViewport *tDrawingArea ); + +#if defined _WINDOWS +/*--------------------------------------------------------------------------- +FUNCTION : calculateVerticalSpacing +DESCRIPTION : determines optimum spacing along time axis +ARGUMENTS : +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void calculateVerticalSpacing(); + +/*--------------------------------------------------------------------------- +FUNCTION : gridSpacingTicks +DESCRIPTION : Provides the grid spacing in the time axis in ticks +ARGUMENTS : +RETURN : Number of ticks +NOTES : +---------------------------------------------------------------------------*/ + uint32 gridSpacingTicks(); + +#endif + +/*--------------------------------------------------------------------------- +INLINE FUNCTION : HORIZONTALLINES +NOTES : Description at the end of the file +---------------------------------------------------------------------------*/ + uint16 horizontalLines( void ); + +#if defined _WINDOWS +// In Windows the OnDraw() function replaces paint() +/*--------------------------------------------------------------------------- +FUNCTION : ScrollingGrid OnDraw +DESCRIPTION : Paints the given area of the grid. + Pure virtual +ARGUMENTS : pDC pointer to the device context to use for display + Note that the device context operates in the coords + of the window owning the viewport +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + virtual void OnDraw( CDC *pDC ); + +#else // not Windows + +/*--------------------------------------------------------------------------- +FUNCTION : PAINT +DESCRIPTION : This extends the standard grid paint method to paint the + viewport relative to its current position. + +ARGUMENTS : name : + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void paint( void ); +#endif + +/*--------------------------------------------------------------------------- +FUNCTION : P A I N T T E X T M A R K E R S +DESCRIPTION : this service allow the text markers to be painted seperatley + from the grid lines + +ARGUMENTS : name : + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void paintTextMarkers(); + +#if defined PRINTING_SUPPORT +/*--------------------------------------------------------------------------- +FUNCTION : P R I N T +DESCRIPTION : This print service prints a grid marker ( being either a + timestamp or a date, IF there is one at the plot position + given + +ARGUMENTS : name : + displayPosition + - Where in the log to look to see if there is an + entry to print + + - printerPtr + the printer to print to + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void print( uint16 currentPrintPos, Printer *printerPtr ); +#endif + +/*--------------------------------------------------------------------------- +FUNCTION : S E T D R I V E D I R E C T I O N +DESCRIPTION : Sets direction for update and scrolling forwards or backwards +ARGUMENTS : direction - required direction +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void setDriveDirection( ScrollDirection direction ); + +/*--------------------------------------------------------------------------- +FUNCTION : S E T U P +DESCRIPTION : service that will setup the grid prior to a paint + +ARGUMENTS : name : + - newTimestamp + + + - newTimeBase + the number of ticks that represent a plot point on + the trendgraph. + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void setup( uint32 newTimestamp, uint32 newTimeBase ); + +#if defined PRINTING_SUPPORT +/*--------------------------------------------------------------------------- +FUNCTION : S E T U P F O R P R I N T +DESCRIPTION : This service iis to be called prior to printing. It allows + the grid to prepare its markers ready for the print + commands + +ARGUMENTS : name : + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void setupForPrint(); +#endif + +/*--------------------------------------------------------------------------- +FUNCTION : UPDATE +DESCRIPTION : When this service is called it will calculate what needs to + be painted and fill in the display again. + +ARGUMENTS : name : timeStamp + - the reference time of this update. + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void update( uint32 timeStamp ); + +/*--------------------------------------------------------------------------- +FUNCTION : U P D A T E B U F F E R +DESCRIPTION : When a display update is not required, use this method. It + updates the internal data ready for a call to paint that + will then show the grid in the right position + +ARGUMENTS : name : + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void updateBuffer( void ); + + private: + +/*--------------------------------------------------------------------------- +FUNCTION : M A K E G R I D M A R K E R +DESCRIPTION : service that perpares a string for display. The string will + either be a short date, or short time. this is determined + by the current setting of the dateMarker flag + +ARGUMENTS : name : timestampVal + - the value to convert + + storePtr + - the place to put the string + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void makeGridMarker( uint32 timestampVal, char *storePtr ); + +/*--------------------------------------------------------------------------- +FUNCTION : P A I N T G R I D M A R K E R +DESCRIPTION : given a position will put the string on the display + +ARGUMENTS : name : + yPos + - were it goes on the Y-axis + + gridMarkerPtr + - what it is + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void paintGridMarker( uint16 yPos, char *gridMarkerPtr ); + +#if defined _WINDOWS +/*--------------------------------------------------------------------------- +FUNCTION : PAINTHORIZONTALLINES +DESCRIPTION : responsible for painting the grids horizontal lines +ARGUMENTS : pRectToDraw pointer to rectangle that needs refreshing. + in viewport coords + pDC pointer to device context to use + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void paintHorizontalLines(RectCoords* pRectToDraw, CDC* pDC ); +#else +/*--------------------------------------------------------------------------- +FUNCTION : PAINTHORIZONTALLINES +DESCRIPTION : responsible for painting the grids horizontal lines +ARGUMENTS : name: xStart + - the starting X co-ordinate for the horizontal line + xEnd + - the ending X co-ordinate for the horizontal line + +RETURN : None +NOTES : Remember lines are drawn from origin. The origin in a + horizontal viewport will be the top. +---------------------------------------------------------------------------*/ + void paintHorizontalLines( uint16 xStart, uint16 xEnd ); +#endif + +#if defined _WINDOWS +/*--------------------------------------------------------------------------- +FUNCTION : PAINTVERTICALLINES +DESCRIPTION : responsible for painting the grids vertical lines +ARGUMENTS : pRectToDraw pointer to rectangle that needs refreshing. + in viewport coords + offset offset from rhs that rightmost line would be + drawn if rectangle included whole viewport + pDC pointer to device context to use +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void paintVerticalLines( RectCoords* pRectToDraw, uint16 offset, + CDC* pDC ); +#else +/*--------------------------------------------------------------------------- +FUNCTION : PAINTVERTICALLINES +DESCRIPTION : responsible for painting the grids vertical lines +ARGUMENTS : name : yStart + - the starting Y co-ordinate for the vertical line + yEnd + - the ending Y co-ordinate for the vertical line + offset + - a starting point offset that determines at what X + position the first line will be drawn + + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void paintVerticalLines( uint16 yStart, uint16 yEnd, uint16 offset ); +#endif + +#if defined _WINDOWS +/*--------------------------------------------------------------------------- +FUNCTION : PAINTVERTICALLINE +DESCRIPTION : paints one line at the position specified, and length +ARGUMENTS : name : yStart + - the starting point on the y axis for the line + yEnd + - the end point on the y axis for the line + xPosition + - The horizontal offset from the start of the viewport + pDC pointer to device context to use + +RETURN : None +NOTES : There is not an equivalent horizontal method as yet. This + is a seperate method because the service is useful to a + derivation of this class +---------------------------------------------------------------------------*/ + void paintVerticalLine( uint16 yStart, uint16 yEnd + , uint16 xPosition, CDC *pDC ); +#else +/*--------------------------------------------------------------------------- +FUNCTION : PAINTVERTICALLINE +DESCRIPTION : paints one line at the position specified, and length +ARGUMENTS : name : yStart + - the starting point on the y axis for the line + yEnd + - the end point on the y axis for the line + xPosition + - The horizontal offset from the start of the viewport + +RETURN : None +NOTES : There is not an equivalent horizontal method as yet. This + is a seperate method because the service is useful to a + derivation of this class +---------------------------------------------------------------------------*/ + void paintVerticalLine( uint16 yStart, uint16 yEnd + , uint16 xPosition ); +#endif + +/*--------------------------------------------------------------------------- +INLINE FUNCTION : VERTICALSPACING +NOTES : Description at the end of the file +---------------------------------------------------------------------------*/ + uint16 verticalSpacing( void ); + + + // Position in viewport that we are now writing to if going forwards + // Note that if this is greater than viewport length then we have + // just scrolled and value must be adjusted before use. + sint16 forwardsOutputPosition; + + // Position in viewport that we are now writing to if going backwards + // Note that if this is less than zero then we have + // just scrolled and value must be adjusted before use. + sint16 backwardsOutputPosition; + + // position in grid cycle of forwards output position. + // if zero then it is time to output a grid line + sint16 forwardsIntervalCount; + + // position in grid cycle of forwards output position. + // if zero then it is time to output a grid line + sint16 backwardsIntervalCount; + + uint32 lastUpdateTimestamp; + uint32 timeBase; // ticks per pixel + uint16 currentOutputPosition; + uint16 gridTimestampSpacing; + uint16 intervalCount; + uint16 horizontalTotal; + uint16 vSpacing; +#if defined PRINTING_SUPPORT + uint16 numberOfGridMarkersPrinted; +#endif + bool firstTime; // indicates first time through + bool dateMarker; + + GkiLineType lineType; + GkiColour gridColour; + + #if defined _WINDOWS + uint16 ticksPerSec; // number of time ticks per second + uint16 vSpacingMin; // minimum pixels per division along time axis + CPen *pPen; // the pen to use for drawing in windows + #endif + +}; + + +/***************************************************************************** + I N L I N E F U N C T I O N S +*****************************************************************************/ + +/*--------------------------------------------------------------------------- +FUNCTION : HORIZONTALLINES +DESCRIPTION : supplies the number of horizontal lines in the grid +ARGUMENTS : name : + +RETURN : +NOTES : +---------------------------------------------------------------------------*/ +inline uint16 ScrollingGrid::horizontalLines( void ) +{ + return( horizontalTotal ); +} +/*--------------------------------------------------------------------------- +FUNCTION : VERTICALSPACING +DESCRIPTION : returns the distance between adjacent vertical lines +ARGUMENTS : name : + +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ +inline uint16 ScrollingGrid::verticalSpacing( void ) +{ + return( vSpacing ); +} + +#endif +@ + + +1.1.2.1 +log +@DEV1194:DS4 Provision of major and minor grid lines +@ +text +@d1 1 +a1 1 +/* \$""Header: /usr/local/repository/cmnsrc/review/src/sgrid.h,v 1.1 1997/04/02 11:20:05 colinl Exp \$ */ +d3 1 +a3 12 + * \$""Log: sgrid.h,v \$ + * Revision 1.1 1997/04/02 11:20:05 colinl + * Project: DEV1175 + * DCN: + * Tested By: Colin Law + * Reviewed By: + * Reason for Change: Initial Revision of all files + * + * Design Change Details: + * + * Implications: + * +d58 6 +a63 5 +ARGUMENTS : name : majorColour colour for major grid lines + minorColour colour for minor grid lines + sgLineType line type for minor grid lines + yMajorGridLines number of major y lines on grid + yMinorGridLines number of major y lines on grid +d77 2 +a78 3 + ScrollingGrid( GkiColour majorColour, GkiColour minorColour, + GkiLineType sgLineType, + uint16 yMajorGridLines, uint16 yMinorGridLines, +a137 17 +FUNCTION : DrawHorizontalGridLines + +DESCRIPTION : Draws major or minor grid lines +ARGUMENTS : pDC device context + pPen pen to use + numLines total lines required + yLow, yHigh, xLow, xHigh rectangle to draw in + yMax max y value +RETURN : None +NOTES : +---------------------------------------------------------------------------*/ + void DrawHorizontalGridLines( CDC* pDC, CPen* pPen, + uint16 numLines, + uint16 yLow, uint16 yHigh, uint16 xLow, uint16 xHigh, + uint16 yMax ); + +/*--------------------------------------------------------------------------- +d148 6 +d448 1 +a448 2 + uint16 m_yMajorGridLines; + uint16 m_yMinorGridLines; +d456 2 +a457 3 + GkiLineType lineType; // line type for minor grid lines + GkiColour m_majorColour; + GkiColour m_minorColour; +d462 1 +a462 2 + CPen *pMajorPen; // pen to use for drawing major grid lines + CPen *pMinorPen; // pen to use for drawing minor grid lines +d472 12 +@" > diffmerge2/sgrid.h,v + + # We have to put the RCS file in the repository by hand for + # this test: + modify_repo mkdir $CVSROOT_DIRNAME/diffmerge2 + modify_repo cp diffmerge2/sgrid.h,v \ + $CVSROOT_DIRNAME/diffmerge2/sgrid.h,v + rm -rf diffmerge2 + dotest diffmerge2_co \ + "$testcvs co diffmerge2" "${DOTSTAR}U $DOTSTAR" + cd diffmerge2 + dotest diffmerge2_update \ + "${testcvs} update -j Review_Phase_2_Enhancements sgrid.h" \ + "${DOTSTAR}erging ${DOTSTAR}" + # This is the one that counts -- there should be no output: + dotest diffmerge2_diff \ + "${testcvs} diff -r Review_V1p3 sgrid.h" '' + + dokeep + cd .. + rm -rf diffmerge2 + modify_repo rm -rf $CVSROOT_DIRNAME/diffmerge2 + ;; + + + + release) + # Tests of "cvs release", particularly multiple arguments. + # Other CVS release tests: + # info-cleanup-0 for "cvs -n release". + # ignore-193 for the text of the question that cvs release asks. + # Also for interactions with cvsignore. + # basicc: "-d .", global -Q, no arguments (is a noop), + # "cvs release" without -d, multiple arguments. + # dirs-4: repository directory has been deleted. + # modules2-6: multiple arguments. + + # First the usual setup; create a directory first-dir. + mkdir 1; cd 1 + dotest release-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest release-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + mkdir dir1 + dotest release-3 "${testcvs} add dir1" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" + mkdir dir2 + dotest release-4 "${testcvs} add dir2" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository" + cd dir2 + mkdir dir3 + dotest release-5 "${testcvs} add dir3" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 added to the repository" + + cd ../.. + dotest release-6 "${testcvs} release -d first-dir/dir2/dir3 first-dir/dir1" \ +"You have .0. altered files in this repository. +Are you sure you want to release (and delete) directory .first-dir/dir2/dir3.: \ +You have .0. altered files in this repository. +Are you sure you want to release (and delete) directory .first-dir/dir1.: " <<EOF +yes +yes +EOF + dotest_fail release-7 "test -d first-dir/dir1" '' + dotest_fail release-8 "test -d first-dir/dir2/dir3" '' + dotest release-9 "${testcvs} update" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating first-dir +${SPROG} update: Updating first-dir/dir2" + + cd first-dir + mkdir dir1 + dotest release-10 "${testcvs} add dir1" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" + cd dir2 + mkdir dir3 + dotest release-11 "${testcvs} add dir3" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 added to the repository" + + cd ../.. + dotest release-12 "${testcvs} release first-dir/dir2/dir3 first-dir/dir1" \ +"You have .0. altered files in this repository. +Are you sure you want to release directory .first-dir/dir2/dir3.: .. .release. aborted by user choice. +You have .0. altered files in this repository. +Are you sure you want to release directory .first-dir/dir1.: " <<EOF +no +yes +EOF + dotest release-13 "${testcvs} release first-dir/dir2/dir3 first-dir/dir2" \ +"You have .0. altered files in this repository. +Are you sure you want to release directory .first-dir/dir2/dir3.: \ +You have .0. altered files in this repository. +Are you sure you want to release directory .first-dir/dir2.: " <<EOF +yes +yes +EOF + dotest release-14 "test -d first-dir/dir1" '' + dotest release-15 "test -d first-dir/dir2/dir3" '' + + mkdir first-dir/dir1/dir4 + # FIXCVS: There should be a path showing in front of dir below, + # I believe. + dotest release-unrecognized-dir-1 \ +"${testcvs} release -d first-dir/dir1" \ +"${QUESTION} dir4 +You have .0. altered files in this repository. +Are you sure you want to release (and delete) directory \`first-dir/dir1': " <<EOF +yes +EOF + + rm -rf first-dir/dir2 + + dotest release-16 "${testcvs} update" \ +"$SPROG update: Updating \. +$SPROG update: Updating first-dir" + + # Check to make sure release isn't overwriting a + # CVS/Entries file in the current directory (using data + # from the released directory). + + # cvs 1.11 (remote) fails on release-21 (a message about + # chdir into the removed directory), although it seemingly + # unedits and removes the directory correctly. If + # you manually continue, it then fails on release-22 do + # to the messed up CVS/Entries file from release-21. + cd first-dir + mkdir second-dir + dotest release-18 "$testcvs add second-dir" \ +"Directory $CVSROOT_DIRNAME/first-dir/second-dir added to the repository" + + cd second-dir + touch file1 + dotest release-19 "$testcvs -Q add file1" + dotest release-20 '$testcvs -q ci -m add' \ +"$CVSROOT_DIRNAME/first-dir/second-dir/file1,v <-- file1 +initial revision: 1\.1" + dotest release-21 "$testcvs edit file1" + cd .. + dotest release-22 "echo yes | $testcvs release -d second-dir" \ +"You have \[0\] altered files in this repository. +Are you sure you want to release (and delete) directory \`second-dir': " + dotest release-23 "$testcvs -q update -d" "U second-dir/file1" + dotest release-24 "$testcvs edit" + + dokeep + cd ../.. + rm -r 1 + modify_repo rm -rf 1 $CVSROOT_DIRNAME/first-dir + ;; + + + + recase) + # + # Some tests of behavior which broke at one time or another when run + # from case insensitive clients against case sensitive servers. + # + # These tests are namned according to the following convention: + # + # ci Client (sandbox filesystem) case Insensitive + # cs Client (sandbox filesystem) case Sensitive + # si Server (repository filesystem) case Insensitive + # ss Server (repository filesystem) case Sensitive + # + + mkdir 1; cd 1 + + # First, we will expect different results for a few of these tests + # based on whether the repository is on a case sensitive filesystem + # or not and whether the sandbox is on a case sensitive filesystem or + # not, so determine which cases we are dealing with: + echo file >file + echo FiLe >FiLe + if cmp file FiLe >/dev/null; then + client_sensitive=false + else + client_sensitive=: + fi + if test -n "$remotehost"; then + $CVS_RSH $remotehost 'echo file >file' + $CVS_RSH $remotehost 'echo FiLe >FiLe' + if $CVS_RSH $remotehost 'cmp file FiLe >/dev/null'; then + server_sensitive=false + else + server_sensitive=: + fi + else + server_sensitive=$client_sensitive + fi + + # The first test (recase-1 & recase-2) is for a remove of a file then + # a readd in a different case. + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + dotest recase-init-1 "$testcvs -Q co first-dir" + cd first-dir + + echo this file has no content >file + dotest recase-init-2 "$testcvs -Q add file" + dotest recase-init-3 "$testcvs -Q ci -madd" + dotest recase-init-4 "$testcvs -Q tag first" + + # Now remove the file. + dotest recase-init-5 "$testcvs -Q rm -f file" + dotest recase-init-6 "$testcvs -Q ci -mrm" + + # Now the test - readd in a different case. + echo this file needs some content >FiLe + if $server_sensitive; then + dotest recase-1ss "$testcvs add FiLe" \ +"$SPROG add: scheduling file \`FiLe' for addition +$SPROG add: use \`$SPROG commit' to add this file permanently" + dotest recase-2ss "$testcvs -q ci -mrecase" \ +"$CVSROOT_DIRNAME/first-dir/FiLe,v <-- FiLe +initial revision: 1\.1" + else # server insensitive + dotest recase-1si "$testcvs add FiLe" \ +"$SPROG add: Re-adding file \`FiLe' after dead revision 1\.2\. +$SPROG add: use \`$SPROG commit' to add this file permanently" + dotest recase-2si "$testcvs -q ci -mrecase" \ +"$CVSROOT_DIRNAME/first-dir/FiLe,v <-- FiLe +new revision: 1\.3; previous revision: 1\.2" + fi + + # Now verify that a checkout will still work + cd ../.. + mkdir 2; cd 2 + dotest recase-3 "$testcvs -q co first-dir" \ +"U first-dir/FiLe" + + cd first-dir + # Prove that we can still get status and log information on + # conflicting case files (1 in Attic, one in parent). + if $remote; then + if $client_sensitive; then + file=file + fIlE=fIlE + else # client insensitive + # Because FiLe is present on a case insensitive client, it is the + # only one ever found and queried or altered. + file=FiLe + fIlE=FiLe + fi + else # ! $remote + file=file + fIlE=fIlE + fi + if $server_sensitive; then + if $client_sensitive; then + # Client finds Entry only for FiLe. Others returned by server. + dotest recase-4sscs "$testcvs status file" \ +"=================================================================== +File: no file file Status: Up-to-date + + Working revision: No entry for file + Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/Attic/file,v + Commit Identifier: ${commitid}" + dotest recase-5sscs "$testcvs log file" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file,v +Working file: file +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + first: 1\.1 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: $username; state: dead; lines: +0 -0; commitid: ${commitid}; +rm +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +add +=============================================================================" + dotest recase-6sscs "$testcvs status FiLe" \ +"=================================================================== +File: FiLe Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-7sscs "$testcvs log FiLe" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v +Working file: FiLe +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +recase +=============================================================================" + else # server sensitive && client insensitive + # Client finds same Entry for file & FiLe. + dotest recase-4ssci "$testcvs status file" \ +"=================================================================== +File: FiLe Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-5ssci "$testcvs log file" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v +Working file: FiLe +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +recase +=============================================================================" + dotest recase-6ss "$testcvs status FiLe" \ +"=================================================================== +File: FiLe Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-7ss "$testcvs log FiLe" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v +Working file: FiLe +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +recase +=============================================================================" + fi + else # server insensitive + # There is only one archive when the server is insensitive, but the + # printed file/archive name can vary. + dotest recase-4si "$testcvs status file" \ +"=================================================================== +File: $file Status: Up-to-date + + Working revision: 1\.3.* + Repository revision: 1\.3 $CVSROOT_DIRNAME/first-dir/$file,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-5si "$testcvs log file" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/$file,v +Working file: $file +head: 1\.3 +branch: +locks: strict +access list: +symbolic names: + first: 1\.1 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: $username; state: Exp; lines: +1 -1; commitid: ${commitid}; +recase +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: $username; state: dead; lines: +0 -0; commitid: ${commitid}; +rm +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +add +=============================================================================" + dotest recase-6si "$testcvs status FiLe" \ +"=================================================================== +File: FiLe Status: Up-to-date + + Working revision: 1\.3.* + Repository revision: 1\.3 $CVSROOT_DIRNAME/first-dir/FiLe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-7si "$testcvs log FiLe" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v +Working file: FiLe +head: 1\.3 +branch: +locks: strict +access list: +symbolic names: + first: 1\.1 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.3 +date: ${ISO8601DATE}; author: $username; state: Exp; lines: +1 -1; commitid: ${commitid}; +recase +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: $username; state: dead; lines: +0 -0; commitid: ${commitid}; +rm +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +add +=============================================================================" + fi + + # And when the file does not exist on the client, we go with the + # client Entries match. + if $client_sensitive && $server_sensitive; then + dotest recase-8sscs "$testcvs status fIlE" \ +"$SPROG status: nothing known about \`fIlE' +=================================================================== +File: no file fIlE Status: Unknown + + Working revision: No entry for fIlE + Repository revision: No revision control file" + else # !$client_sensitive || !$server_sensitive + dotest recase-8anyi "$testcvs status fIlE" \ +"=================================================================== +File: $fIlE Status: Up-to-date + + Working revision: 1\.[0-9]*.* + Repository revision: 1\.[0-9]* $CVSROOT_DIRNAME/first-dir/$fIlE,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + fi + + # and an update + if $server_sensitive; then + dotest recase-9ss "$testcvs -q up -rfirst" \ +"$SPROG update: \`FiLe' is no longer in the repository +U file" + + if $client_sensitive; then + dotest recase-10sscs "$testcvs -q up -A" \ +"U FiLe +$SPROG update: \`file' is no longer in the repository" + else # client insensitive + # FIXCVS: This should remove the offending file first. + dotest_fail recase-10ssci "$testcvs -q up -A" \ +"$SPROG update: move away \`\./FiLe'; it is in the way +C FiLe +$SPROG update: \`file' is no longer in the repository" + + cd .. + rm -r first-dir + dotest recase-11ssci "$testcvs -q co first-dir" \ +"U first-dir/FiLe" + cd first-dir + fi + + # + # See what happens when cased names clash. + # + + # Copy the archive + if test -n "$remotehost"; then + modify_repo $CVS_RSH $remotehost \ + "cp $CVSROOT_DIRNAME/first-dir/FiLe,v \ + $CVSROOT_DIRNAME/first-dir/FILE,v" + else + modify_repo cp $CVSROOT_DIRNAME/first-dir/FiLe,v \ + $CVSROOT_DIRNAME/first-dir/FILE,v + fi + + if $client_sensitive; then + dotest recase-12sscs "$testcvs -q up" "U FILE" + else # client insensitive + dotest_fail recase-12ssci "$testcvs -q up" \ +"$SPROG update: move away \`\./FILE'; it is in the way +C FILE" + fi + else # server insensitive + dotest recase-9si "$testcvs -q up -rfirst" "U FiLe" + dotest recase-10si "$testcvs -q up -A" "U FiLe" + fi + + # Prove that we can still get status and log information on + # conflicting case files (1 in Attic, two in parent). + if $server_sensitive; then + if $client_sensitive; then + # Client finds Entry only for FiLe. Others returned by server. + dotest recase-13sscs "$testcvs status file" \ +"=================================================================== +File: no file file Status: Up-to-date + + Working revision: No entry for file + Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/Attic/file,v + Commit Identifier: ${commitid}" + dotest recase-14sscs "$testcvs log file" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file,v +Working file: file +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + first: 1\.1 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: $username; state: dead; lines: +0 -0; commitid: ${commitid}; +rm +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +add +=============================================================================" + dotest recase-15sscs "$testcvs status FiLe" \ +"=================================================================== +File: FiLe Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-16sscs "$testcvs log FiLe" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v +Working file: FiLe +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +recase +=============================================================================" + dotest recase-17sscs "$testcvs status FILE" \ +"=================================================================== +File: FILE Status: Up-to-date + + Working revision: 1.1.* + Repository revision: 1.1 ${CVSROOT_DIRNAME}/first-dir/FILE,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-18sscs "$testcvs log FILE" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FILE,v +Working file: FILE +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +recase +=============================================================================" + else # $server_sensitive && !$client_sensitive + # Client finds same Entry for file & FiLe. + dotest recase-13ssci "$testcvs status file" \ +"=================================================================== +File: FiLe Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-16ssci "$testcvs log FiLe" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v +Working file: FiLe +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +recase +=============================================================================" + dotest recase-17ssci "$testcvs status FILE" \ +"=================================================================== +File: FiLe Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest recase-18ssci "$testcvs log FILE" \ +" +RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v +Working file: FiLe +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: $username; state: Exp; commitid: ${commitid}; +recase +=============================================================================" + fi + else # !$server_sensitive + # Skip these when the server is case insensitive - nothing + # has changed since recase-[4-7]si + : + fi + + if $client_sensitive && $server_sensitive; then + dotest recase-19sscs "$testcvs status fIlE" \ +"$SPROG status: nothing known about \`fIlE' +=================================================================== +File: no file fIlE Status: Unknown + + Working revision: No entry for fIlE + Repository revision: No revision control file" + else # !$client_sensitive || !$server_sensitive + dotest recase-19anyi "$testcvs status fIlE" \ +"=================================================================== +File: $fIlE Status: Up-to-date + + Working revision: 1\.[0-9]*.* + Repository revision: 1\.[0-9]* $CVSROOT_DIRNAME/first-dir/$fIlE,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + fi + + # And last but not least, prove that a checkout is still possible. + cd ../.. + mkdir 3; cd 3 + if $server_sensitive; then + if $client_sensitive; then + dotest recase-20sscs "$testcvs -q co first-dir" \ +"U first-dir/FILE +U first-dir/FiLe" + else # $server_senstive && !$client_sensitive + dotest_fail recase-20ssci "$testcvs -q co first-dir" \ +"U first-dir/FILE +$SPROG checkout: move away \`first-dir/FiLe'; it is in the way +C first-dir/FiLe" + fi + else # !$server_sensitive + # Skip these since nothing has changed. + : + fi + + dokeep + cd .. + rm -r 1 2 3 + if $server_sensitive && test -n "$remotehost"; then + # It is necessary to remove one of the case-conflicted files before + # recursively removing the rest under Cygwin on a Samba share or + # Samba returns a permission denied error due to its case + # confusion. + $CVS_RSH $remotehost "rm -f $CVSROOT_DIRNAME/first-dir/FILE,v" + fi + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + multiroot) + # + # set up two repositories + # + + if $proxy; then + # don't even try + continue + fi + + CVSROOT1_DIRNAME=${TESTDIR}/root.1 + CVSROOT2_DIRNAME=${TESTDIR}/root.2 + CVSROOT1=`newroot $CVSROOT1_DIRNAME` + CVSROOT2=`newroot $CVSROOT2_DIRNAME` + testcvs1="$testcvs -d '$CVSROOT1'" + testcvs2="$testcvs -d '$CVSROOT2'" + + dotest multiroot-setup-1 "mkdir $CVSROOT1_DIRNAME $CVSROOT2_DIRNAME" + dotest multiroot-setup-2 "$testcvs1 init" + dotest multiroot-setup-3 "$testcvs2 init" + + # + # create some directories in ${CVSROOT1_DIRNAME} + # + mkdir 1; cd 1 + dotest multiroot-setup-4 "${testcvs1} co -l ." "${SPROG} checkout: Updating ." + mkdir mod1-1 mod1-2 + dotest multiroot-setup-5 "${testcvs1} add mod1-1 mod1-2" \ +"Directory ${CVSROOT1_DIRNAME}/mod1-1 added to the repository +Directory ${CVSROOT1_DIRNAME}/mod1-2 added to the repository" + echo file1-1 > mod1-1/file1-1 + echo file1-2 > mod1-2/file1-2 + dotest multiroot-setup-6 "${testcvs1} add mod1-1/file1-1 mod1-2/file1-2" \ +"${SPROG} add: scheduling file .mod1-1/file1-1. for addition +${SPROG} add: scheduling file .mod1-2/file1-2. for addition +${SPROG} add: use \`${SPROG} commit' to add these files permanently" + dotest multiroot-setup-7 "${testcvs1} commit -m is" \ +"${CPROG} commit: Examining \. +${CPROG} commit: Examining mod1-1 +${CPROG} commit: Examining mod1-2 +${CVSROOT1_DIRNAME}/mod1-1/file1-1,v <-- mod1-1/file1-1 +initial revision: 1.1 +${CVSROOT1_DIRNAME}/mod1-2/file1-2,v <-- mod1-2/file1-2 +initial revision: 1.1" + cd .. + rm -rf 1 + + # + # create some directories in ${CVSROOT2_DIRNAME} + # + mkdir 1; cd 1 + dotest multiroot-setup-8 "${testcvs2} co -l ." "${SPROG} checkout: Updating ." + mkdir mod2-1 mod2-2 + dotest multiroot-setup-9 "${testcvs2} add mod2-1 mod2-2" \ +"Directory ${CVSROOT2_DIRNAME}/mod2-1 added to the repository +Directory ${CVSROOT2_DIRNAME}/mod2-2 added to the repository" + echo file2-1 > mod2-1/file2-1 + echo file2-2 > mod2-2/file2-2 + dotest multiroot-setup-6 "${testcvs2} add mod2-1/file2-1 mod2-2/file2-2" \ +"${SPROG} add: scheduling file .mod2-1/file2-1. for addition +${SPROG} add: scheduling file .mod2-2/file2-2. for addition +${SPROG} add: use \`${SPROG} commit' to add these files permanently" + dotest multiroot-setup-10 "${testcvs2} commit -m anyone" \ +"${CPROG} commit: Examining \. +${CPROG} commit: Examining mod2-1 +${CPROG} commit: Examining mod2-2 +${CVSROOT2_DIRNAME}/mod2-1/file2-1,v <-- mod2-1/file2-1 +initial revision: 1.1 +${CVSROOT2_DIRNAME}/mod2-2/file2-2,v <-- mod2-2/file2-2 +initial revision: 1.1" + cd .. + rm -rf 1 + + # check out a few directories, from simple/shallow to + # complex/deep + mkdir 1; cd 1 + + # OK, this case is kind of weird. If we just run things from + # here, without CVS/Root, then CVS will contact the server + # mentioned in CVSROOT (which is irrelevant) which will print + # some messages. Our workaround is to make sure we have a + # CVS/Root file at top level. In the future, it is possible + # the best behavior will be to extend the existing behavior + # ("being called from a directory without CVS administration + # has always meant to process each of the sub-dirs") to also + # do that if there is no CVSROOT, CVS/Root, or -d at top level. + # + # The local case could stumble through the tests without creating + # the top-level CVS/Root, but we create it for local and for + # remote to reduce special cases later in the test. + dotest multiroot-workaround "${testcvs1} -q co -l ." "" + + dotest multiroot-setup-11 "${testcvs1} co mod1-1 mod1-2" \ +"${SPROG} checkout: Updating mod1-1 +U mod1-1/file1-1 +${SPROG} checkout: Updating mod1-2 +U mod1-2/file1-2" + dotest multiroot-setup-12 "${testcvs2} co mod2-1 mod2-2" \ +"${SPROG} checkout: Updating mod2-1 +U mod2-1/file2-1 +${SPROG} checkout: Updating mod2-2 +U mod2-2/file2-2" + cd mod1-2 + dotest multiroot-setup-13 "${testcvs2} co mod2-2" \ +"${SPROG} checkout: Updating mod2-2 +U mod2-2/file2-2" + cd .. + cd mod2-2 + dotest multiroot-setup-14 "${testcvs1} co mod1-2" \ +"${SPROG} checkout: Updating mod1-2 +U mod1-2/file1-2" + cd .. + + # + # Make sure that the Root and Repository files contain the + # correct information. + # + dotest multiroot-cvsadm-1a "cat mod1-1/CVS/Root" "${CVSROOT1}" + dotest multiroot-cvsadm-1b "cat mod1-1/CVS/Repository" "mod1-1" + dotest multiroot-cvsadm-2a "cat mod2-1/CVS/Root" "${CVSROOT2}" + dotest multiroot-cvsadm-2b "cat mod2-1/CVS/Repository" "mod2-1" + dotest multiroot-cvsadm-3a "cat mod1-2/CVS/Root" "${CVSROOT1}" + dotest multiroot-cvsadm-3b "cat mod1-2/CVS/Repository" "mod1-2" + dotest multiroot-cvsadm-3c "cat mod1-2/mod2-2/CVS/Root" "${CVSROOT2}" + dotest multiroot-cvsadm-3d "cat mod1-2/mod2-2/CVS/Repository" "mod2-2" + dotest multiroot-cvsadm-4a "cat mod2-2/CVS/Root" "${CVSROOT2}" + dotest multiroot-cvsadm-4b "cat mod2-2/CVS/Repository" "mod2-2" + dotest multiroot-cvsadm-4c "cat mod2-2/mod1-2/CVS/Root" "${CVSROOT1}" + dotest multiroot-cvsadm-4d "cat mod2-2/mod1-2/CVS/Repository" "mod1-2" + + # + # Start testing various cvs commands. Begin with commands + # without extra arguments (e.g. "cvs update", "cvs diff", + # etc. + # + + # Do at least one command with both CVSROOTs to make sure + # that there's not some kind of unexpected dependency on the + # choice of which CVSROOT is specified on the command line. + + dotest multiroot-update-1a "${testcvs1} update" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating mod1-1 +${SPROG} update: Updating mod1-2 +${SPROG} update: Updating mod1-2/mod2-2 +${SPROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-2: No such file or directory +${SPROG} update: skipping directory mod1-2/mod2-2 +${SPROG} update: Updating mod2-1 +${SPROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-1: No such file or directory +${SPROG} update: skipping directory mod2-1 +${SPROG} update: Updating mod2-2 +${SPROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-2: No such file or directory +${SPROG} update: skipping directory mod2-2" + + # Same deal but with -d ${CVSROOT2}. + dotest multiroot-update-1b "${testcvs2} update" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating mod1-1 +${SPROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-1: No such file or directory +${SPROG} update: skipping directory mod1-1 +${SPROG} update: Updating mod1-2 +${SPROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-2: No such file or directory +${SPROG} update: skipping directory mod1-2 +${SPROG} update: Updating mod2-1 +${SPROG} update: Updating mod2-2 +${SPROG} update: Updating mod2-2/mod1-2 +${SPROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-2: No such file or directory +${SPROG} update: skipping directory mod2-2/mod1-2" + + # modify all files and do a diff + + echo bobby >> mod1-1/file1-1 + echo brown >> mod1-2/file1-2 + echo goes >> mod2-1/file2-1 + echo down >> mod2-2/file2-2 + + dotest_fail multiroot-diff-1 "${testcvs} diff" \ +"${SPROG} diff: Diffing \. +${SPROG} diff: Diffing mod1-1 +Index: mod1-1/file1-1 +=================================================================== +RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v +retrieving revision 1\.1 +diff -r1\.1 file1-1 +1a2 +> bobby +${SPROG} diff: Diffing mod1-2 +Index: mod1-2/file1-2 +=================================================================== +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v +retrieving revision 1\.1 +diff -r1\.1 file1-2 +1a2 +> brown +${SPROG} diff: Diffing mod2-2/mod1-2 +${SPROG} diff: Diffing mod1-2/mod2-2 +${SPROG} diff: Diffing mod2-1 +Index: mod2-1/file2-1 +=================================================================== +RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v +retrieving revision 1\.1 +diff -r1\.1 file2-1 +1a2 +> goes +${SPROG} diff: Diffing mod2-2 +Index: mod2-2/file2-2 +=================================================================== +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v +retrieving revision 1\.1 +diff -r1\.1 file2-2 +1a2 +> down" \ +"${SPROG} diff: Diffing \. +${SPROG} diff: Diffing mod1-1 +Index: mod1-1/file1-1 +=================================================================== +RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v +retrieving revision 1\.1 +diff -r1\.1 file1-1 +1a2 +> bobby +${SPROG} diff: Diffing mod1-2 +Index: mod1-2/file1-2 +=================================================================== +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v +retrieving revision 1\.1 +diff -r1\.1 file1-2 +1a2 +> brown +${SPROG} diff: Diffing mod2-2 +${SPROG} diff: Diffing mod2-2/mod1-2 +${SPROG} diff: Diffing mod1-2 +${SPROG} diff: Diffing mod1-2/mod2-2 +${SPROG} diff: Diffing mod2-1 +Index: mod2-1/file2-1 +=================================================================== +RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v +retrieving revision 1\.1 +diff -r1\.1 file2-1 +1a2 +> goes +${SPROG} diff: Diffing mod2-2 +Index: mod2-2/file2-2 +=================================================================== +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v +retrieving revision 1\.1 +diff -r1\.1 file2-2 +1a2 +> down" + + dotest multiroot-commit-1 "${testcvs} commit -m actually" \ +"${CPROG} commit: Examining \. +${CPROG} commit: Examining mod1-1 +${CPROG} commit: Examining mod1-2 +${CPROG} commit: Examining mod2-2/mod1-2 +${CVSROOT1_DIRNAME}/mod1-1/file1-1,v <-- mod1-1/file1-1 +new revision: 1.2; previous revision: 1.1 +${CVSROOT1_DIRNAME}/mod1-2/file1-2,v <-- mod1-2/file1-2 +new revision: 1.2; previous revision: 1.1 +${CPROG} commit: Examining mod1-2/mod2-2 +${CPROG} commit: Examining mod2-1 +${CPROG} commit: Examining mod2-2 +${CVSROOT2_DIRNAME}/mod2-1/file2-1,v <-- mod2-1/file2-1 +new revision: 1.2; previous revision: 1.1 +${CVSROOT2_DIRNAME}/mod2-2/file2-2,v <-- mod2-2/file2-2 +new revision: 1.2; previous revision: 1.1" + + dotest multiroot-update-2 "${testcvs} update" \ +"${CPROG} update: Updating \. +${CPROG} update: Updating mod1-1 +${CPROG} update: Updating mod1-2 +${CPROG} update: Updating mod2-2/mod1-2 +U mod2-2/mod1-2/file1-2 +${CPROG} update: Updating mod1-2/mod2-2 +U mod1-2/mod2-2/file2-2 +${CPROG} update: Updating mod2-1 +${CPROG} update: Updating mod2-2" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating mod1-1 +${SPROG} update: Updating mod1-2 +${SPROG} update: Updating mod2-2 +${SPROG} update: Updating mod2-2/mod1-2 +P mod2-2/mod1-2/file1-2 +${SPROG} update: Updating mod1-2 +${SPROG} update: Updating mod1-2/mod2-2 +P mod1-2/mod2-2/file2-2 +${SPROG} update: Updating mod2-1 +${SPROG} update: Updating mod2-2" + + dotest multiroot-tag-1 "${testcvs} tag cattle" \ +"${SPROG} tag: Tagging \. +${SPROG} tag: Tagging mod1-1 +T mod1-1/file1-1 +${SPROG} tag: Tagging mod1-2 +T mod1-2/file1-2 +${SPROG} tag: Tagging mod2-2/mod1-2 +${SPROG} tag: Tagging mod1-2/mod2-2 +T mod1-2/mod2-2/file2-2 +${SPROG} tag: Tagging mod2-1 +T mod2-1/file2-1 +${SPROG} tag: Tagging mod2-2" \ +"${SPROG} tag: Tagging \. +${SPROG} tag: Tagging mod1-1 +T mod1-1/file1-1 +${SPROG} tag: Tagging mod1-2 +T mod1-2/file1-2 +${SPROG} tag: Tagging mod2-2 +${SPROG} tag: Tagging mod2-2/mod1-2 +${SPROG} tag: Tagging mod1-2 +${SPROG} tag: Tagging mod1-2/mod2-2 +T mod1-2/mod2-2/file2-2 +${SPROG} tag: Tagging mod2-1 +T mod2-1/file2-1 +${SPROG} tag: Tagging mod2-2" + + echo anotherfile1-1 > mod1-1/anotherfile1-1 + echo anotherfile2-1 > mod2-1/anotherfile2-1 + echo anotherfile1-2 > mod2-2/mod1-2/anotherfile1-2 + echo anotherfile2-2 > mod1-2/mod2-2/anotherfile2-2 + + if $remote; then + cd mod1-1 + dotest multiroot-add-1ar "${testcvs} add anotherfile1-1" \ +"${SPROG} add: scheduling file .anotherfile1-1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cd ../mod2-1 + dotest multiroot-add-1br "${testcvs} add anotherfile2-1" \ +"${SPROG} add: scheduling file .anotherfile2-1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cd ../mod2-2/mod1-2 + dotest multiroot-add-1cr "${testcvs} add anotherfile1-2" \ +"${SPROG} add: scheduling file .anotherfile1-2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cd ../../mod1-2/mod2-2 + dotest multiroot-add-1dr "${testcvs} add anotherfile2-2" \ +"${SPROG} add: scheduling file .anotherfile2-2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cd ../.. + else + dotest multiroot-add-1 "${testcvs} add mod1-1/anotherfile1-1 mod2-1/anotherfile2-1 mod2-2/mod1-2/anotherfile1-2 mod1-2/mod2-2/anotherfile2-2" \ +"${SPROG} add: scheduling file .mod1-1/anotherfile1-1. for addition +${SPROG} add: scheduling file .mod2-1/anotherfile2-1. for addition +${SPROG} add: scheduling file .mod2-2/mod1-2/anotherfile1-2. for addition +${SPROG} add: scheduling file .mod1-2/mod2-2/anotherfile2-2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + fi + + dotest multiroot-status-1 "${testcvs} status -v" \ +"${SPROG} status: Examining \. +${SPROG} status: Examining mod1-1 +=================================================================== +File: anotherfile1-1 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file1-1 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod1-2 +=================================================================== +File: file1-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod2-2/mod1-2 +=================================================================== +File: anotherfile1-2 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file1-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod1-2/mod2-2 +=================================================================== +File: anotherfile2-2 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file2-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod2-1 +=================================================================== +File: anotherfile2-1 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file2-1 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod2-2 +=================================================================== +File: file2-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2)" \ +"${SPROG} status: Examining \. +${SPROG} status: Examining mod1-1 +=================================================================== +File: anotherfile1-1 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file1-1 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod1-2 +=================================================================== +File: file1-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod2-2 +${SPROG} status: Examining mod2-2/mod1-2 +=================================================================== +File: anotherfile1-2 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file1-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod1-2 +${SPROG} status: Examining mod1-2/mod2-2 +=================================================================== +File: anotherfile2-2 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file2-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod2-1 +=================================================================== +File: anotherfile2-1 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file2-1 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2) + +${SPROG} status: Examining mod2-2 +=================================================================== +File: file2-2 Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v + Commit Identifier: ${commitid} + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + cattle (revision: 1\.2)" + + dotest multiroot-commit-2 "${testcvs} commit -m reading" \ +"${CPROG} commit: Examining \. +${CPROG} commit: Examining mod1-1 +${CPROG} commit: Examining mod1-2 +${CPROG} commit: Examining mod2-2/mod1-2 +${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v <-- mod1-1/anotherfile1-1 +initial revision: 1\.1 +${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v <-- mod2-2/mod1-2/anotherfile1-2 +initial revision: 1\.1 +${CPROG} commit: Examining mod1-2/mod2-2 +${CPROG} commit: Examining mod2-1 +${CPROG} commit: Examining mod2-2 +${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v <-- mod1-2/mod2-2/anotherfile2-2 +initial revision: 1\.1 +${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v <-- mod2-1/anotherfile2-1 +initial revision: 1\.1" + + dotest multiroot-update-3 "${testcvs} update" \ +"${CPROG} update: Updating \. +${CPROG} update: Updating mod1-1 +${CPROG} update: Updating mod1-2 +U mod1-2/anotherfile1-2 +${CPROG} update: Updating mod2-2/mod1-2 +${CPROG} update: Updating mod1-2/mod2-2 +${CPROG} update: Updating mod2-1 +${CPROG} update: Updating mod2-2 +U mod2-2/anotherfile2-2" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating mod1-1 +${SPROG} update: Updating mod1-2 +U mod1-2/anotherfile1-2 +${SPROG} update: Updating mod2-2 +${SPROG} update: Updating mod2-2/mod1-2 +${SPROG} update: Updating mod1-2 +${SPROG} update: Updating mod1-2/mod2-2 +${SPROG} update: Updating mod2-1 +${SPROG} update: Updating mod2-2 +U mod2-2/anotherfile2-2" + + dotest multiroot-log-1 "${testcvs} log" \ +"${SPROG} log: Logging \. +${SPROG} log: Logging mod1-1 + +RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v +Working file: mod1-1/anotherfile1-1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v +Working file: mod1-1/file1-1 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +is +============================================================================= +${SPROG} log: Logging mod1-2 + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v +Working file: mod1-2/anotherfile1-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v +Working file: mod1-2/file1-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +is +============================================================================= +${SPROG} log: Logging mod2-2/mod1-2 + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v +Working file: mod2-2/mod1-2/anotherfile1-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v +Working file: mod2-2/mod1-2/file1-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +is +============================================================================= +${SPROG} log: Logging mod1-2/mod2-2 + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v +Working file: mod1-2/mod2-2/anotherfile2-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v +Working file: mod1-2/mod2-2/file2-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +anyone +============================================================================= +${SPROG} log: Logging mod2-1 + +RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v +Working file: mod2-1/anotherfile2-1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v +Working file: mod2-1/file2-1 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +anyone +============================================================================= +${SPROG} log: Logging mod2-2 + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v +Working file: mod2-2/anotherfile2-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v +Working file: mod2-2/file2-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +anyone +=============================================================================" \ +"${SPROG} log: Logging \. +${SPROG} log: Logging mod1-1 + +RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v +Working file: mod1-1/anotherfile1-1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v +Working file: mod1-1/file1-1 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +is +============================================================================= +${SPROG} log: Logging mod1-2 + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v +Working file: mod1-2/anotherfile1-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v +Working file: mod1-2/file1-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +is +============================================================================= +${SPROG} log: Logging mod2-2 +${SPROG} log: Logging mod2-2/mod1-2 + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v +Working file: mod2-2/mod1-2/anotherfile1-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v +Working file: mod2-2/mod1-2/file1-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +is +============================================================================= +${SPROG} log: Logging mod1-2 +${SPROG} log: Logging mod1-2/mod2-2 + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v +Working file: mod1-2/mod2-2/anotherfile2-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v +Working file: mod1-2/mod2-2/file2-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +anyone +============================================================================= +${SPROG} log: Logging mod2-1 + +RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v +Working file: mod2-1/anotherfile2-1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v +Working file: mod2-1/file2-1 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +anyone +============================================================================= +${SPROG} log: Logging mod2-2 + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v +Working file: mod2-2/anotherfile2-2 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +reading +============================================================================= + +RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v +Working file: mod2-2/file2-2 +head: 1\.2 +branch: +locks: strict +access list: +symbolic names: + cattle: 1\.2 +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.2 +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; +actually +---------------------------- +revision 1\.1 +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +anyone +=============================================================================" + + + # After the simple cases, let's execute some commands which + # refer to parts of our checked-out tree (e.g. "cvs update + # mod1-1 mod2-2") + + dokeep + + # clean up after ourselves + cd .. + rm -r 1 + + # clean up our repositories + rm -rf ${CVSROOT1_DIRNAME} ${CVSROOT2_DIRNAME} + ;; + + + + multiroot2) + # More multiroot tests. In particular, nested directories. + + if $proxy; then + # don't even try + continue + fi + + CVSROOT1_DIRNAME=${TESTDIR}/root1 + CVSROOT2_DIRNAME=${TESTDIR}/root2 + CVSROOT1=`newroot $CVSROOT1_DIRNAME` + CVSROOT2=`newroot $CVSROOT2_DIRNAME` + + dotest multiroot2-1 "${testcvs} -d ${CVSROOT1} init" "" + dotest multiroot2-2 "${testcvs} -d ${CVSROOT2} init" "" + + mkdir imp-dir; cd imp-dir + echo file1 >file1 + mkdir sdir + echo sfile >sdir/sfile + mkdir sdir/ssdir + echo ssfile >sdir/ssdir/ssfile + dotest_sort multiroot2-3 \ +"${testcvs} -d ${CVSROOT1} import -m import-to-root1 dir1 vend rel" " + +N dir1/file1 +N dir1/sdir/sfile +N dir1/sdir/ssdir/ssfile +No conflicts created by this import +${SPROG} import: Importing ${TESTDIR}/root1/dir1/sdir +${SPROG} import: Importing ${TESTDIR}/root1/dir1/sdir/ssdir" + cd sdir + dotest_sort multiroot2-4 \ +"${testcvs} -d ${CVSROOT2} import -m import-to-root2 sdir vend2 rel2" " + +N sdir/sfile +N sdir/ssdir/ssfile +No conflicts created by this import +${SPROG} import: Importing ${TESTDIR}/root2/sdir/ssdir" + cd ../.. + + mkdir 1; cd 1 + # Get TopLevelAdmin-like behavior. + dotest multiroot2-5 "${testcvs} -d ${CVSROOT1} -q co -l ." + dotest multiroot2-5 "${testcvs} -d ${CVSROOT1} -q co dir1" \ +"U dir1/file1 +U dir1/sdir/sfile +U dir1/sdir/ssdir/ssfile" + cd dir1 + dotest multiroot2-6 "${testcvs} -Q release -d sdir" "" + dotest multiroot2-7 "${testcvs} -d ${CVSROOT2} -q co sdir" \ +"U sdir/sfile +U sdir/ssdir/ssfile" + cd .. + # This has one subtle effect - it deals with Entries.Log + # so that the next test doesn't get trace messages for + # Entries.Log + dotest multiroot2-8 "${testcvs} update" \ +"${CPROG} update: Updating \. +${CPROG} update: Updating dir1 +${CPROG} update: Updating dir1/sdir +${CPROG} update: Updating dir1/sdir/ssdir" \ +"${SPROG} update: Updating \. +${SPROG} update: Updating dir1 +${SPROG} update: Updating dir1 +${SPROG} update: Updating dir1/sdir +${SPROG} update: Updating dir1/sdir/ssdir" + # Two reasons we don't run this on the server: (1) the server + # also prints some trace messages, and (2) the server trace + # messages are subject to out-of-order bugs (this one is hard + # to work around). + if $remote; then :; else + dotest multiroot2-9a "${testcvs} -t update" \ +" *-> main: Session ID is ${commitid} + *-> main loop with CVSROOT=${TESTDIR}/root1 + *-> parse_config ($TESTDIR/root1) + *-> do_update ((null), (null), (null), 1, 0, 0, 0, 0, 0, 3, (null), (null), (null), (null), (null), 1, (null)) + *-> Write_Template (\., ${TESTDIR}/root1) +${CPROG} update: Updating \. + *-> Reader_Lock(${TESTDIR}/root1) + *-> Simple_Lock_Cleanup() + *-> Write_Template (dir1, ${TESTDIR}/root1/dir1) +${CPROG} update: Updating dir1 + *-> Reader_Lock(${TESTDIR}/root1/dir1) + *-> Simple_Lock_Cleanup() + *-> main loop with CVSROOT=${TESTDIR}/root2 + *-> parse_config ($TESTDIR/root2) + *-> do_update ((null), (null), (null), 1, 0, 0, 0, 0, 0, 3, (null), (null), (null), (null), (null), 1, (null)) + *-> Write_Template (dir1/sdir, ${TESTDIR}/root2/dir1/sdir) +${CPROG} update: Updating dir1/sdir + *-> Reader_Lock(${TESTDIR}/root2/sdir) + *-> Simple_Lock_Cleanup() + *-> Write_Template (dir1/sdir/ssdir, ${TESTDIR}/root2/sdir/ssdir) +${CPROG} update: Updating dir1/sdir/ssdir + *-> Reader_Lock(${TESTDIR}/root2/sdir/ssdir) + *-> Simple_Lock_Cleanup() + *-> Lock_Cleanup() + *-> Simple_Lock_Cleanup()" + fi + + dotest multiroot2-9 "${testcvs} -q tag tag1" \ +"T dir1/file1 +T dir1/sdir/sfile +T dir1/sdir/ssdir/ssfile" + echo "change it" >>dir1/file1 + echo "change him too" >>dir1/sdir/sfile + dotest multiroot2-10 "${testcvs} -q ci -m modify" \ +"$TESTDIR/root1/dir1/file1,v <-- dir1/file1 +new revision: 1\.2; previous revision: 1\.1 +$TESTDIR/root2/sdir/sfile,v <-- dir1/sdir/sfile +new revision: 1\.2; previous revision: 1\.1" + dotest multiroot2-11 "${testcvs} -q tag tag2" \ +"T dir1/file1 +T dir1/sdir/sfile +T dir1/sdir/ssdir/ssfile" + dotest_fail multiroot2-12 \ +"${testcvs} -q diff -u -r tag1 -r tag2" \ +"Index: dir1/file1 +=================================================================== +RCS file: ${TESTDIR}/root1/dir1/file1,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.2 +diff -u -r1\.1\.1\.1 -r1\.2 +--- dir1/file1 ${RFCDATE} 1\.1\.1\.1 +${PLUS}${PLUS}${PLUS} dir1/file1 ${RFCDATE} 1\.2 +@@ -1 ${PLUS}1,2 @@ + file1 +${PLUS}change it +Index: dir1/sdir/sfile +=================================================================== +RCS file: ${TESTDIR}/root2/sdir/sfile,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.2 +diff -u -r1\.1\.1\.1 -r1\.2 +--- dir1/sdir/sfile ${RFCDATE} 1\.1\.1\.1 +${PLUS}${PLUS}${PLUS} dir1/sdir/sfile ${RFCDATE} 1\.2 +@@ -1 ${PLUS}1,2 @@ + sfile +${PLUS}change him too" + + if $keep; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + + # clean up after ourselves + cd .. + rm -r imp-dir 1 + + # clean up our repositories + rm -rf root1 root2 + ;; + + + + multiroot3) + # More multiroot tests. Directories are side-by-side, not nested. + # Not drastically different from multiroot but it covers somewhat + # different stuff. + + if $proxy; then + # don't even try + continue + fi + + CVSROOT1=`newroot ${TESTDIR}/root1` + CVSROOT2=`newroot ${TESTDIR}/root2` + + mkdir 1; cd 1 + dotest multiroot3-1 "${testcvs} -d ${CVSROOT1} init" "" + dotest multiroot3-2 "${testcvs} -d ${CVSROOT1} -q co -l ." "" + mkdir dir1 + dotest multiroot3-3 "${testcvs} add dir1" \ +"Directory ${TESTDIR}/root1/dir1 added to the repository" + dotest multiroot3-4 "${testcvs} -d ${CVSROOT2} init" "" + rm -r CVS + dotest multiroot3-5 "${testcvs} -d ${CVSROOT2} -q co -l ." "" + mkdir dir2 + + # OK, the problem is that CVS/Entries doesn't look quite right, + # I suppose because of the "rm -r". Then again, why *should* it + # look right? CVS/Root can only point to a single location, but + # we expect CVS/Entries to hold entries for two repositories? It + # just plain isn't part of the filespec yet. + # + # Use the quick and dirty fix. + echo "D/dir1////" >CVS/Entries + echo "D/dir2////" >>CVS/Entries + + dotest multiroot3-7 "${testcvs} add dir2" \ +"Directory ${TESTDIR}/root2/dir2 added to the repository" + + touch dir1/file1 dir2/file2 + if $remote; then + # Trying to add them both in one command doesn't work, + # because add.c doesn't do multiroot (it doesn't use recurse.c). + # Furthermore, it can't deal with the parent directory + # having a different root from the child, hence the cd. + cd dir1 + dotest multiroot3-8 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + cd .. + dotest multiroot3-8a "${testcvs} add dir2/file2" \ +"${SPROG} add: scheduling file .dir2/file2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + else + dotest multiroot3-8 "${testcvs} add dir1/file1 dir2/file2" \ +"${SPROG} add: scheduling file .dir1/file1. for addition +${SPROG} add: scheduling file .dir2/file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + fi + + dotest multiroot3-9 "${testcvs} -q ci -m add-them" \ +"$TESTDIR/root2/dir2/file2,v <-- dir2/file2 +initial revision: 1\.1 +$TESTDIR/root1/dir1/file1,v <-- dir1/file1 +initial revision: 1\.1" + + # That this is an error is good - we are asking CVS to do + # something which doesn't make sense. + dotest_fail multiroot3-10 \ +"${testcvs} -q -d ${CVSROOT1} diff dir1/file1 dir2/file2" \ +"${SPROG} diff: failed to create lock directory for .${TESTDIR}/root1/dir2' (${TESTDIR}/root1/dir2/#cvs.lock): No such file or directory +${SPROG} diff: failed to obtain dir lock in repository .${TESTDIR}/root1/dir2' +${SPROG} \[diff aborted\]: read lock failed - giving up" + + # This one is supposed to work. + dotest multiroot3-11 "${testcvs} -q diff dir1/file1 dir2/file2" "" + + # make sure we can't access across repositories + # FIXCVS: we probably shouldn't even create the local directories + # in this case, but we do, so deal with it. + mkdir 1a + cd 1a + dotest_fail multiroot3-12 \ +"$testcvs -d $CVSROOT1 -q co ../root2/dir2" \ +"$CPROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\." \ +"$SPROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\. +$CPROG \[checkout aborted\]: end of file from server (consult above messages if any)" + dotest_fail multiroot3-13 \ +"$testcvs -d $CVSROOT2 -q co ../root1/dir1" \ +"$CPROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root1/dir1'\." \ +"$SPROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root1/dir1'\. +$CPROG \[checkout aborted\]: end of file from server (consult above messages if any)" + dotest_fail multiroot3-14 \ +"$testcvs -d $CVSROOT1 -q co ./../root2/dir2" \ +"$CPROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root2/dir2'\." \ +"$SPROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root2/dir2'\. +$CPROG \[checkout aborted\]: end of file from server (consult above messages if any)" + dotest_fail multiroot3-15 \ +"$testcvs -d $CVSROOT2 -q co ./../root1/dir1" \ +"$CPROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\." \ +"$SPROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\. +$CPROG \[checkout aborted\]: end of file from server (consult above messages if any)" + dotest_fail multiroot3-16 \ +"$testcvs -d $CVSROOT1 -q co -p ../root2/dir2" \ +"$CPROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\." \ +"$SPROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\. +$CPROG \[checkout aborted\]: end of file from server (consult above messages if any)" + dotest_fail multiroot3-17 \ +"$testcvs -d $CVSROOT1 -q co -p ./../root1/dir1" \ +"$CPROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\." \ +"$SPROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\. +$CPROG \[checkout aborted\]: end of file from server (consult above messages if any)" + + cd ../.. + + if $keep; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + + rm -r 1 + rm -rf ${TESTDIR}/root1 ${TESTDIR}/root2 + unset CVSROOT1 + unset CVSROOT2 + ;; + + + + multiroot4) + # More multiroot tests, in particular we have two roots with + # similarly-named directories and we try to see that CVS can + # keep them separate. + + if $proxy; then + # don't even try + continue + fi + + CVSROOT1=`newroot ${TESTDIR}/root1` + CVSROOT2=`newroot ${TESTDIR}/root2` + + mkdir 1; cd 1 + dotest multiroot4-1 "${testcvs} -d ${CVSROOT1} init" "" + dotest multiroot4-2 "${testcvs} -d ${CVSROOT1} -q co -l ." "" + mkdir dircom + dotest multiroot4-3 "${testcvs} add dircom" \ +"Directory ${TESTDIR}/root1/dircom added to the repository" + cd dircom + touch file1 + dotest multiroot4-4 "${testcvs} add file1" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest multiroot4-5 "${testcvs} -q ci -m add" \ +"$TESTDIR/root1/dircom/file1,v <-- file1 +initial revision: 1\.1" + cd ../.. + mkdir 2; cd 2 + dotest multiroot4-6 "${testcvs} -d ${CVSROOT2} init" "" + dotest multiroot4-7 "${testcvs} -d ${CVSROOT2} -q co -l ." "" + mkdir dircom + dotest multiroot4-8 "${testcvs} add dircom" \ +"Directory ${TESTDIR}/root2/dircom added to the repository" + cd dircom + touch file2 + dotest multiroot4-9 "${testcvs} add file2" \ +"${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest multiroot4-10 "${testcvs} -q ci -m add" \ +"$TESTDIR/root2/dircom/file2,v <-- file2 +initial revision: 1\.1" + + cd ../.. + cd 1/dircom + # This may look contrived; the real world example which inspired + # it was that a user was changing from local to remote. Cases + # like switching servers (among those mounting the same + # repository) and so on would also look the same. + mkdir sdir2 + dotest multiroot4-11 "${testcvs} -d ${CVSROOT2} add sdir2" \ +"Directory ${TESTDIR}/root2/dircom/sdir2 added to the repository" + + dotest multiroot4-12 "${testcvs} -q update" "" + cd .. + dotest multiroot4-13 "${testcvs} -q update dircom" "" + cd .. + + rm -r 1 2 + rm -rf ${TESTDIR}/root1 ${TESTDIR}/root2 + unset CVSROOT1 + unset CVSROOT2 + ;; + + + + rmroot) + # When the Entries/Root file is removed from an existing + # workspace, CVS should assume $CVSROOT instead + # + # Right now only checking that CVS exits normally on an + # update once CVS/Root is deleted + # + # There was a time when this would core dump when run in + # client/server mode + + mkdir 1; cd 1 + dotest rmroot-setup-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest rmroot-setup-2 "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd first-dir + touch file1 file2 + dotest rmroot-setup-3 "${testcvs} add file1 file2" \ +"${SPROG} add: scheduling file .file1. for addition +${SPROG} add: scheduling file .file2. for addition +${SPROG} add: use .${SPROG} commit. to add these files permanently" + dotest rmroot-setup-4 "${testcvs} -q commit -minit" \ +"$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 +initial revision: 1\.1 +$CVSROOT_DIRNAME/first-dir/file2,v <-- file2 +initial revision: 1\.1" + rm CVS/Root + dotest rmroot-1 "${testcvs} -q update" '' + + dokeep + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir + ;; + + + + reposmv) + # More tests of repositories and specifying them. + # Similar to crerepos but that test is probably getting big + # enough. + + if $proxy; then + # don't even try + continue + fi + + CVSROOT1=`newroot ${TESTDIR}/root1` + CVSROOT_MOVED=`newroot ${TESTDIR}/root-moved` + + dotest reposmv-setup-1 "${testcvs} -d ${CVSROOT1} init" "" + mkdir imp-dir; cd imp-dir + echo file1 >file1 + dotest reposmv-setup-2 \ +"${testcvs} -d ${CVSROOT1} import -m add dir1 vendor release" \ +"N dir1/file1 + +No conflicts created by this import" + cd .. + + mkdir 1; cd 1 + dotest reposmv-1 "${testcvs} -d ${CVSROOT1} -Q co dir1" "" + mv ${TESTDIR}/root1 ${TESTDIR}/root-moved + cd dir1 + + # If we didn't have a relative repository, get one now. + dotest reposmv-1a "cat CVS/Repository" \ +"${TESTDIR}/root1/dir1" "dir1" + echo dir1 >CVS/Repository + + # There were some duplicated warnings and such; only test + # for the part of the error message which makes sense. + # + # FIXCVS then FIXME + # Now the duplicated error messages only occur on some platforms, + # including, apparently, NetBSD 1.6.1, RedHat Linux 7.3, whatever + # kernel that is using, and Solaris 9. These platforms somehow + # decide to call Name_Root() up to four times, via do_recursion, but + # I'm not sure of the rest of the details. Other platforms, + # including Fedora Core 1 (Linux 2.4.22-1.2199.nptl), RH Linux 9 + # (Linux 2.4.20-37.9.legacy), and probably AIX 3.4, Solaris 8, + # BSD/OS 4.2, & IRIX 6.5 only call Name_Root() once as a result of + # this test. + # + # Bug: "skipping directory " without filename. + if $remote; then + dotest_fail reposmv-2r "${testcvs} update" \ +"Cannot access ${TESTDIR}/root1/CVSROOT +No such file or directory" + else + dotest reposmv-2 "$testcvs update" \ +"$DOTSTAR$CPROG update: in directory \.: +$CPROG update: ignoring CVS/Root because it specifies a non-existent repository $TESTDIR/root1 +$CPROG update: Updating \. +$DOTSTAR$CPROG update: cannot open directory $CVSROOT_DIRNAME/dir1: No such file or directory +$CPROG update: skipping directory " + fi + + # CVS/Root overrides $CVSROOT + if $remote; then + CVSROOT_save=${CVSROOT} + CVSROOT=:fork:${TESTDIR}/root-moved; export CVSROOT + dotest_fail reposmv-3r "${testcvs} update" \ +"Cannot access ${TESTDIR}/root1/CVSROOT +No such file or directory" + CVSROOT=${CVSROOT_save}; export CVSROOT + else + CVSROOT_save=$CVSROOT + CVSROOT=$TESTDIR/root-moved; export CVSROOT + dotest reposmv-3 "$testcvs update" \ +"$DOTSTAR$CPROG update: in directory \.: +$CPROG update: ignoring CVS/Root because it specifies a non-existent repository $TESTDIR/root1 +$CPROG update: Updating \.$DOTSTAR" + CVSROOT=$CVSROOT_save; export CVSROOT + fi + + if $remote; then + CVSROOT_save=${CVSROOT} + CVSROOT=:fork:${TESTDIR}/root-none; export CVSROOT + dotest_fail reposmv-4r "${testcvs} update" \ +"Cannot access ${TESTDIR}/root1/CVSROOT +No such file or directory" + CVSROOT=${CVSROOT_save}; export CVSROOT + else + # CVS/Root doesn't seem to quite completely override $CVSROOT + # Bug? Not necessarily a big deal if it only affects error + # messages. + CVSROOT_save=${CVSROOT} + CVSROOT=${TESTDIR}/root-none; export CVSROOT + dotest_fail reposmv-4 "${testcvs} update" \ +"${CPROG} update: in directory \.: +${CPROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1 +${CPROG} \[update aborted\]: ${TESTDIR}/root-none/CVSROOT: No such file or directory" + CVSROOT=${CVSROOT_save}; export CVSROOT + fi + + # -d overrides CVS/Root + # + # Oddly enough, with CVS 1.10 I think this didn't work for + # local (that is, it would appear that CVS/Root would not + # get used, but would produce an error if it didn't exist). + dotest reposmv-5 "${testcvs} -d ${CVSROOT_MOVED} update" \ +"${SPROG} update: Updating \." + + # TODO: could also test various other things, like what if the + # user removes CVS/Root (which is legit). Or another set of + # tests would be if both repositories exist but we want to make + # sure that CVS is using the correct one. + + cd ../.. + rm -r imp-dir 1 + rm -rf root1 root2 + unset CVSROOT1 + ;; + + + + pserver) + # Test basic pserver functionality. + if $remote; then + if test -n "$remotehost"; then + # Don't even try. (The issue is getting servercvs & testcvs + # set correctly for the following tests. Some expect one access + # method and some another, which in $remotehost mode, means that + # sometimes the executables must run on one platform and + # sometimes another.) + continue + fi + save_servercvs=$servercvs + servercvs=$testcvs + # First set SystemAuth=no. Not really necessary, I don't + # think, but somehow it seems like the clean thing for + # the testsuite. + mkdir 1; cd 1 + dotest pserver-1 "$testcvs -Q co CVSROOT" "" + cd CVSROOT + echo "SystemAuth=no" >>config + dotest pserver-2 "$testcvs -q ci -m config-it" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + cat >$CVSROOT_DIRNAME/CVSROOT/passwd <<EOF +testme:q6WV9d2t848B2:$username +dontroot:q6WV9d2t848B2:root +anonymous::$username +$username: +willfail: :whocares +EOF + dotest_fail pserver-3 "$servercvs pserver" \ +"error 0 Server configuration missing --allow-root in inetd.conf" <<EOF +BEGIN AUTH REQUEST +$CVSROOT_DIRNAME +testme +Ay::'d +END AUTH REQUEST +EOF + + # Confirm that not sending a newline during auth cannot constitute + # a denial-of-service attack. This assumes that PATH_MAX is less + # than 65536 bytes. If PATH_MAX is larger than 65535 bytes, this + # test could hang indefinitely. + ${AWK} 'BEGIN { printf "0123456789abcdef" }' </dev/null >garbageseg + echo "BEGIN AUTH REQUEST" >garbageinput + i=0 + while test $i -lt 64; do + cat <garbageseg >>garbageseg2 + i=`expr $i + 1` + done + i=0 + while test $i -lt 64; do + cat <garbageseg2 >>garbageinput + i=`expr $i + 1` + done + dotest_fail pserver-auth-no-dos \ +"${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"$CPROG \\[pserver aborted\\]: error reading from net while validating pserver: Not enough space" \ +"$CPROG \\[pserver aborted\\]: error reading from net while validating pserver: Cannot allocate memory" <garbageinput + unset i + rm garbageseg garbageseg2 garbageinput + + # Sending the Root and noop before waiting for the + # "I LOVE YOU" is bogus, but hopefully we can get + # away with it. + dotest pserver-4 "$servercvs --allow-root=$CVSROOT_DIRNAME pserver" \ +"$DOTSTAR LOVE YOU +ok" <<EOF +BEGIN AUTH REQUEST +$CVSROOT_DIRNAME +testme +Ay::'d +END AUTH REQUEST +Root $CVSROOT_DIRNAME +noop +EOF + + dotest_fail pserver-4.2 \ +"$servercvs --allow-root=$CVSROOT_DIRNAME pserver" \ +"error 0: root not allowed" <<EOF +BEGIN AUTH REQUEST +$CVSROOT_DIRNAME +dontroot +Ay::'d +END AUTH REQUEST +EOF + + dotest pserver-5 "$servercvs --allow-root=$CVSROOT_DIRNAME pserver" \ +"$DOTSTAR LOVE YOU +E Protocol error: Root says \"$TESTDIR/1\" but pserver says \"$CVSROOT_DIRNAME\" +error " <<EOF +BEGIN AUTH REQUEST +$CVSROOT_DIRNAME +testme +Ay::'d +END AUTH REQUEST +Root $TESTDIR/1 +noop +EOF + + dotest pserver-5a "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +E Protocol error: init says \"${TESTDIR}/2\" but pserver says \"${CVSROOT_DIRNAME}\" +error " <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +init ${TESTDIR}/2 +EOF + dotest_fail pserver-5b "test -d ${TESTDIR}/2" '' + + dotest pserver-5c "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +E init xxx must be an absolute pathname +error " <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +init xxx +EOF + dotest_fail pserver-5d "test -d xxx" '' + + dotest_fail pserver-6 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"I HATE YOU" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d^b?hd +END AUTH REQUEST +EOF + + dotest_fail pserver-7 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"I HATE YOU" <<EOF +BEGIN VERIFICATION REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d^b?hd +END VERIFICATION REQUEST +EOF + + dotest pserver-8 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU" <<EOF +BEGIN VERIFICATION REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END VERIFICATION REQUEST +EOF + +# Tests pserver-9 through pserver-13 are about empty passwords + + # Test empty password (both sides) for aliased user + dotest pserver-9 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +anonymous +A +END AUTH REQUEST +EOF + + # Test empty password (server side only) for aliased user + dotest pserver-10 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +anonymous +Aanythingwouldworkhereittrulydoesnotmatter +END AUTH REQUEST +EOF + + # Test empty (both sides) password for non-aliased user + dotest pserver-11 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +A +END AUTH REQUEST +EOF + + # Test empty (server side only) password for non-aliased user + dotest pserver-12 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +Anypasswordwouldworkwhynotthisonethen +END AUTH REQUEST +EOF + + # Test failure of whitespace password + dotest_fail pserver-13 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} HATE YOU" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +willfail +Amquiteunabletocomeupwithinterestingpasswordsanymore +END AUTH REQUEST +EOF + + # The following tests are for read-only access + + # Check that readers can only read, everyone else can write + + echo anonymous >$CVSROOT_DIRNAME/CVSROOT/readers + + dotest pserver-14 "$servercvs --allow-root=$CVSROOT_DIRNAME pserver" \ +"$DOTSTAR LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +$CVSROOT_DIRNAME +anonymous +Ay::'d +END AUTH REQUEST +Root $CVSROOT_DIRNAME +version +EOF + + dotest pserver-15 "$servercvs --allow-root=$CVSROOT_DIRNAME pserver" \ +"$DOTSTAR LOVE YOU +E $CPROG \\[server aborted\\]: .init. requires write access to the repository +error " <<EOF +BEGIN AUTH REQUEST +$CVSROOT_DIRNAME +anonymous +Ay::'d +END AUTH REQUEST +init $CVSROOT_DIRNAME +EOF + + dotest pserver-16 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-17 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + dotest pserver-18 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-19 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +Anything +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + # Check that writers can write, everyone else can only read + # even if not listed in readers + + cat >${CVSROOT_DIRNAME}/CVSROOT/writers <<EOF +testme +EOF + + dotest pserver-20 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +anonymous +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-21 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +E $CPROG \\[server aborted\\]: .init. requires write access to the repository +error " <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +anonymous +Ay::'d +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + dotest pserver-22 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-23 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + dotest pserver-24 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-25 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +E $CPROG \\[server aborted\\]: .init. requires write access to the repository +error " <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +Anything +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + # Should work the same without readers + + rm ${CVSROOT_DIRNAME}/CVSROOT/readers + + dotest pserver-26 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +anonymous +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-27 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +E $CPROG \\[server aborted\\]: .init. requires write access to the repository +error " <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +anonymous +Ay::'d +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + dotest pserver-28 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-29 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + dotest pserver-30 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +M Concurrent Versions System (CVS) .* +ok" <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +Ay::'d +END AUTH REQUEST +Root ${CVSROOT_DIRNAME} +version +EOF + + dotest pserver-31 "${servercvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ +"${DOTSTAR} LOVE YOU +E $CPROG \\[server aborted\\]: .init. requires write access to the repository +error " <<EOF +BEGIN AUTH REQUEST +${CVSROOT_DIRNAME} +${username} +Anything +END AUTH REQUEST +init ${CVSROOT_DIRNAME} +EOF + + # pserver used to try and print from the NULL pointer + # in this error message in this case + dotest_fail pserver-bufinit "${servercvs} pserver" \ +"$CPROG \[pserver aborted\]: unexpected EOF encountered during authentication" </dev/null + + # Clean up. + dotest pserver-cleanup-1 "${testcvs} -q up -pr1.1 config >config" "" + dotest pserver-cleanup-2 "${testcvs} -q ci -m config-it" \ +"$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +$SPROG commit: Rebuilding administrative file database" + + dokeep + cd ../.. + rm -r 1 + restore_adm + servercvs=$save_servercvs + fi # skip the whole thing for local + ;; + + + + server) + # Some tests of the server (independent of the client). + if $remote; then + save_servercvs=$servercvs + servercvs=$testcvs + dotest server-1 "${servercvs} server" \ +"E Protocol error: Root request missing +error " <<EOF +Directory bogus +mumble/bar +update +EOF + + # Could also test for relative pathnames here (so that crerepos-6a + # and crerepos-6b can use :fork:). + dotest server-2 "${servercvs} server" "ok" <<EOF +Set OTHER=variable +Set MYENV=env-value +init ${TESTDIR}/crerepos +EOF + dotest server-3 "test -d ${TESTDIR}/crerepos/CVSROOT" "" + + # Now some tests of gzip-file-contents (used by jCVS). + ${AWK} 'BEGIN { \ +printf "%c%c%c%c%c%c.6%c%c+I-.%c%c%c%c5%c;%c%c%c%c", \ +31, 139, 8, 64, 5, 7, 64, 3, 225, 2, 64, 198, 185, 5, 64, 64, 64}' \ + </dev/null | ${TR} '\100' '\000' >gzipped.dat + # Note that the CVS client sends "-b 1.1.1", and this + # test doesn't. But the server also defaults to that. + cat <<EOF >session.dat +Root ${TESTDIR}/crerepos +UseUnchanged +gzip-file-contents 3 +Argument -m +Argument msg +Argumentx +Argument dir1 +Argument tag1 +Argument tag2 +Directory . +${TESTDIR}/crerepos +Modified file1 +u=rw,g=r,o=r +z25 +EOF + cat gzipped.dat >>session.dat + echo import >>session.dat + dotest server-4 "${servercvs} server" \ +"M N dir1/file1 +M +M No conflicts created by this import +M +ok" <session.dat + dotest server-5 \ +"${testcvs} -q -d ${TESTDIR}/crerepos co -p dir1/file1" "test" + + # OK, here are some notify tests. + dotest server-6 "${servercvs} server" \ +"Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Fri May 7 13:21:09 1999 -0000 myhost some-work-dir EUC +noop +EOF + # Sending the second "noop" before waiting for the output + # from the first is bogus but hopefully we can get away + # with it. + dotest server-7 "${servercvs} server" \ +"M file1 $username Fri May 7 13:21:09 1999 -0000 myhost some-work-dir +Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok +M file1 $username Fri May 7 13:21:09 1999 -0000 myhost some-work-dir +Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Fri May 7 13:21:09 1999 -0000 myhost some-work-dir EUC +noop +Notify file1 +E The 57th day of Discord in the YOLD 3165 myhost some-work-dir EUC +noop +EOF + + # OK, now test a few error conditions. + # FIXCVS: should give "error" and no "Notified", like server-9 + dotest server-8 "${servercvs} server" \ +"M file1 $username The 57th day of Discord in the YOLD 3165 myhost some-work-dir +E $CPROG server: invalid character in editor value +Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Setting Orange, the 52th day of Discord in the YOLD 3165 myhost some-work-dir EUC +noop +EOF + + dotest server-9 "${servercvs} server" \ +"E Protocol error; misformed Notify request +error " <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Setting Orange+57th day of Discord myhost some-work-dir EUC +noop +EOF + + # First demonstrate an interesting quirk in the protocol. + # The "watchers" request selects the files to operate based + # on files which exist in the working directory. So if we + # don't send "Entry" or the like, it won't do anything. + # Wants to be documented in cvsclient.texi... + dotest server-10 "${servercvs} server" "ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +watchers +EOF + # See if "watchers" and "editors" display the right thing. + dotest server-11 "${servercvs} server" \ +"M file1 ${username} tedit tunedit tcommit +ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Entry /file1/1.1//// +watchers +EOF + dotest server-12 "${servercvs} server" \ +"M file1 ${username} The 57th day of Discord in the YOLD 3165 myhost some-work-dir +ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Entry /file1/1.1//// +editors +EOF + + # Now do an unedit. + dotest server-13 "${servercvs} server" \ +"Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +U 7 May 1999 15:00 -0000 myhost some-work-dir EUC +noop +EOF + + # Now try "watchers" and "editors" again. + dotest server-14 "${servercvs} server" "ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +watchers +EOF + dotest server-15 "${servercvs} server" "ok" <<EOF +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +editors +EOF + + # Test that the global `-l' option is ignored nonfatally. + dotest server-16 "${testcvs} server" \ +"E $CPROG server: WARNING: global \`-l' option ignored\. +ok" <<EOF +Global_option -l +noop +EOF + + # There used to be some exploits based on malformed Entry requests + dotest server-17 "$testcvs server" \ +"E protocol error: Malformed Entry +error " <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos/dir1 +Entry X/file1/1.1//// +noop +EOF + + dotest server-18 "$testcvs server" \ +"E protocol error: Malformed Entry +error " <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos/dir1 +Entry /CC/CC/CC +noop +EOF + + # Check that the config file may be set from the command line. + # But first verify the default config produces no error messages. + dotest server-19 "$testcvs server" \ +"ok" <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos +noop +EOF + echo THIS-CONFIG-OPTION-IS-BAD=XXX >$TESTDIR/newconfig + dotest_fail server-20 "$testcvs server -c $TESTDIR/newconfig" \ +"E $SPROG \[server aborted\]: Invalid path to config file specified: \`$TESTDIR/newconfig'" <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos +noop +EOF + dotest_fail server-21 \ +"$testcvs server -c /etc/cvs/this-shouldnt-exist" \ +"E $SPROG \[server aborted\]: Failed to resolve path: \`/etc/cvs/this-shouldnt-exist': No such file or directory" <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos +noop +EOF + + # Now make sure that the config file can't be set via the user's + # .cvsrc. + echo server -c $TESTDIR/newconfig >$HOME/.cvsrc + dotest server-22 "$testcvs server" \ +"ok" <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos +noop +EOF + + dokeep + rm -rf $TESTDIR/crerepos + rm gzipped.dat session.dat + rm $TESTDIR/newconfig $HOME/.cvsrc + servercvs=$save_servercvs + fi # skip the whole thing for local + ;; + + + + server2) + # More server tests, in particular testing that various + # possible security holes are plugged. + if $remote; then + if test -n "$remotehost"; then + # Don't even try. (The issue is getting servercvs & testcvs + # set correctly for the following tests. Some expect one access + # method and some another, which in $remotehost mode, means that + # sometimes the executables must run on one platform and + # sometimes another.) + continue + fi + save_servercvs=$servercvs + servercvs=$testcvs + dotest server2-1 "${servercvs} server" \ +"E protocol error: directory '${CVSROOT_DIRNAME}/\.\./dir1' not within root '${CVSROOT_DIRNAME}' +error " <<EOF +Root ${CVSROOT_DIRNAME} +Directory . +${CVSROOT_DIRNAME}/../dir1 +noop +EOF + + dotest server2-2 "${servercvs} server" \ +"E protocol error: directory '${CVSROOT_DIRNAME}dir1' not within root '${CVSROOT_DIRNAME}' +error " <<EOF +Root ${CVSROOT_DIRNAME} +Directory . +${CVSROOT_DIRNAME}dir1 +noop +EOF + + dotest 2-3 "${servercvs} server" \ +"E protocol error: directory '${TESTDIR}' not within root '${CVSROOT_DIRNAME}' +error " <<EOF +Root ${CVSROOT_DIRNAME} +Directory . +${TESTDIR} +noop +EOF + + # OK, now a few tests for the rule that one cannot pass a + # filename containing a slash to Modified, Is-modified, + # Notify, Questionable, or Unchanged. For completeness + # we'd try them all. For lazyness/conciseness we don't. + dotest server2-4 "${servercvs} server" \ +"E protocol error: directory 'foo/bar' not within current directory +error " <<EOF +Root ${CVSROOT_DIRNAME} +Directory . +${CVSROOT_DIRNAME} +Unchanged foo/bar +noop +EOF + servercvs=$save_servercvs + fi + ;; + + + + client) + # Some tests of the client (independent of the server). + if $remote; then :; else + remoteonly client + continue + fi + + if $proxy; then + # Skip these tests in proxy mode since they assume we are not + # writing through a proxy server. There is no writeproxy-client + # test currently. The writeproxy & writeproxy-noredirect tests + # test the writeproxy server. + notproxy client + continue + fi + + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +# This is admittedly a bit cheezy, in the sense that we make lots +# of assumptions about what the client is going to send us. +# We don't mention Repository, because current clients don't require it. +# Sending these at our own pace, rather than waiting for the client to +# make the requests, is bogus, but hopefully we can get away with it. +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "M special message" +echo "Created first-dir/" +echo "$CVSROOT_DIRNAME/first-dir/file1" +echo "/file1/1.1///" +echo "u=rw,g=rw,o=rw" +echo "4" +echo "xyz" +echo "ok" +cat >/dev/null +EOF + # Cygwin. Pthffffffffft! + if test -n "$remotehost"; then + $CVS_RSH $remotehost "chmod +x $TESTDIR/serveme" + else + chmod +x $TESTDIR/serveme + fi + save_CVS_SERVER=$CVS_SERVER + CVS_SERVER=$TESTDIR/serveme; export CVS_SERVER + mkdir 1; cd 1 + dotest_fail client-1 "$testcvs -q co first-dir" \ +"$CPROG \[checkout aborted\]: This server does not support the global -q option$DOTSTAR" + dotest client-2 "$testcvs co first-dir" "special message" + + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "M merge-it" +echo "Copy-file ./" +echo "$CVSROOT_DIRNAME/first-dir/file1" +echo "$TESTDIR/bogus/.#file1.1.1" +echo "Merged ./" +echo "$CVSROOT_DIRNAME/first-dir/file1" +echo "/file1/1.2///" +echo "u=rw,g=rw,o=rw" +echo "4" +echo "abd" +echo "ok" +cat >/dev/null +EOF + cd first-dir + mkdir $TESTDIR/bogus + # The ${DOTSTAR} is to match a potential "broken pipe" if the + # client exits before the server script sends everything + dotest_fail client-3 "$testcvs update" \ +"merge-it +$CPROG \[update aborted\]: protocol error: Copy-file tried to specify director$DOTSTAR" + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "M merge-it" +echo "Copy-file ./" +echo "$CVSROOT_DIRNAME/first-dir/file1" +echo ".#file1.1.1" +echo "Merged ./" +echo "$CVSROOT_DIRNAME/first-dir/file1" +echo "/file1/1.2///" +echo "u=rw,g=rw,o=rw" +echo "4" +echo "abc" +echo "ok" +cat >/dev/null +EOF + dotest client-4 "$testcvs update" "merge-it" + dotest client-5 "cat .#file1.1.1" "xyz" + dotest client-6 "cat CVS/Entries" "/file1/1.2/[A-Za-z0-9 :]*// +D" + dotest client-7 "cat file1" "abc" + + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "M OK, whatever" +echo "ok" +cat >$TESTDIR/client.tmp +EOF + chmod u=rw,go= file1 + # By specifying the time zone in local time, we don't + # know exactly how that will translate to GMT. + dotest client-8 "$testcvs update -D 99-10-04" "OK, whatever" + # String 2 below is Cygwin again - ptoooey. + dotest client-9 "cat $TESTDIR/client.tmp" \ +"Root $CVSROOT_DIRNAME +Valid-responses [-a-zA-Z ]* +valid-requests +Argument -D +Argument [34] Oct 1999 [0-9][0-9]:00:00 -0000 +Argument -- +Directory \. +$CVSROOT_DIRNAME/first-dir +Entry /file1/1\.2/// +Modified file1 +u=rw,g=,o= +4 +abc +update" \ +"Root $CVSROOT_DIRNAME +Valid-responses [-a-zA-Z ]* +valid-requests +Argument -D +Argument [34] Oct 1999 [0-9][0-9]:00:00 -0000 +Argument -- +Directory \. +$CVSROOT_DIRNAME/first-dir +Entry /file1/1\.2/// +Modified file1 +u=rw,g=r,o=r +4 +abc +update" + + # The following test tests what was a potential client exploit in + # CVS versions 1.11.14 and CVS versions 1.12.6 and earlier. This + # exploit would allow a trojan server to create arbitrary files, + # anywhere the user had write permissions, even outside of the + # user's sandbox. + cat >$HOME/.bashrc <<EOF +#!$TESTSHELL +# This is where login scripts would usually be +# stored. +EOF + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Rcs-diff $HOME/" +echo "$HOME/.bashrc" +echo "/.bashrc/73.50///" +echo "u=rw,g=rw,o=rw" +echo "20" +echo "a1 1" +echo "echo 'gotcha!'" +echo "ok" +cat >/dev/null +EOF + + # If I don't run the following sleep between the above cat and + # the following calls to dotest, sometimes the serveme file isn't + # completely written yet by the time CVS tries to execute it, + # causing the shell to intermittantly report syntax errors (usually + # early EOF). There's probably a new race condition here, but this + # works. + # + # Incidentally, I can reproduce this behavior with Linux 2.4.20 and + # Bash 2.05 or Bash 2.05b. + sleep 1 + dotest_fail client-10 "$testcvs update" \ +"$CPROG update: Server attempted to update a file via an invalid pathname: +$CPROG \[update aborted\]: \`$HOME/.bashrc'\." + + # A second try at a client exploit. This one never actually + # failed in the past, but I thought it wouldn't hurt to add a test. + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Rcs-diff ./" +echo "$HOME/.bashrc" +echo "/.bashrc/73.50///" +echo "u=rw,g=rw,o=rw" +echo "20" +echo "a1 1" +echo "echo 'gotcha!'" +echo "ok" +cat >/dev/null +EOF + sleep 1 + dotest_fail client-11 "$testcvs update" \ +"$CPROG \[update aborted\]: patch original file \./\.bashrc does not exist" + + # A third try at a client exploit. This one did used to fail like + # client-10. + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Rcs-diff ../../home/" +echo "../../.bashrc" +echo "/.bashrc/73.50///" +echo "u=rw,g=rw,o=rw" +echo "20" +echo "a1 1" +echo "echo 'gotcha!'" +echo "ok" +cat >/dev/null +EOF + sleep 1 + dotest_fail client-12 "$testcvs update" \ +"$CPROG update: Server attempted to update a file via an invalid pathname: +$CPROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." + + # Try the same exploit using the Created response. + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Created $HOME/" +echo "$HOME/.bashrc" +echo "/.bashrc/73.50///" +echo "u=rw,g=rw,o=rw" +echo "26" +echo "#! $TESTSHELL" +echo "echo 'gotcha!'" +echo "ok" +cat >/dev/null +EOF + sleep 1 + dotest_fail client-13 "$testcvs update" \ +"$CPROG update: Server attempted to update a file via an invalid pathname: +$CPROG \[update aborted\]: \`$HOME/.bashrc'\." + + # Now try using the Update-existing response + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Update-existing ../../home/" +echo "../../home/.bashrc" +echo "/.bashrc/73.50///" +echo "u=rw,g=rw,o=rw" +echo "26" +echo "#! $TESTSHELL" +echo "echo 'gotcha!'" +echo "ok" +cat >/dev/null +EOF + sleep 1 + dotest_fail client-14 "$testcvs update" \ +"$CPROG update: Server attempted to update a file via an invalid pathname: +$CPROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." + + # Try the same exploit using the Merged response. + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Merged $HOME/" +echo "$HOME/.bashrc" +echo "/.bashrc/73.50///" +echo "u=rw,g=rw,o=rw" +echo "26" +echo "#! $TESTSHELL" +echo "echo 'gotcha!'" +echo "ok" +cat >/dev/null +EOF + sleep 1 + dotest_fail client-15 "$testcvs update" \ +"$CPROG update: Server attempted to update a file via an invalid pathname: +$CPROG \[update aborted\]: \`$HOME/.bashrc'\." + + # Now try using the Updated response + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Updated ../../home/" +echo "../../home/.bashrc" +echo "/.bashrc/73.50///" +echo "u=rw,g=rw,o=rw" +echo "26" +echo "#! $TESTSHELL" +echo "echo 'gotcha!'" +echo "ok" +cat >/dev/null +EOF + sleep 1 + dotest_fail client-16 "$testcvs update" \ +"$CPROG update: Server attempted to update a file via an invalid pathname: +$CPROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." + + # Try the same exploit using the Copy-file response. + # As far as I know, Copy-file was never exploitable either. + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update" +echo "ok" +echo "Created ." +echo "./innocuous" +echo "/innocuous/73.50///" +echo "u=rw,g=rw,o=rw" +echo "26" +echo "#! $TESTSHELL" +echo "echo 'gotcha!'" +echo "Copy-file ." +echo "./innocuous" +echo "$HOME/innocuous" +echo "ok" +cat >/dev/null +EOF + sleep 1 + dotest_fail client-18 "$testcvs update" \ +"$CPROG \[update aborted\]: protocol error: Copy-file tried to specify directory" + + # And verify that none of the exploits was successful. + dotest client-19 "cat $HOME/.bashrc" \ +"#!$TESTSHELL +# This is where login scripts would usually be +# stored\." + + # Check that the client detects redirect loops. + cat >$TESTDIR/serveme <<EOF +#!$TESTSHELL +echo "Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set Gssapi-authenticate expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version" +echo "ok" +echo "Redirect $CVSROOT" + +# Eat up data from the client to avoid broken pipe errors. +cat >/dev/null +EOF + echo newstuff >file1 + sleep 1 + dotest_fail client-20 "$testcvs ci" \ +"$CPROG commit: Examining \. +$CPROG \[commit aborted\]: \`Redirect' loop detected\. Server misconfiguration$QUESTION" + + dokeep + cd ../.. + rm -r 1 + rmdir $TESTDIR/bogus + rm $TESTDIR/serveme $HOME/.bashrc + CVS_SERVER=$save_CVS_SERVER; export CVS_SERVER + ;; + + + + dottedroot) + # Check that a CVSROOT with a "." in the name will work. + + if $proxy; then + # don't even try + continue + fi + + CVSROOT_save=${CVSROOT} + CVSROOT_DIRNAME_save=${CVSROOT_DIRNAME} + CVSROOT_DIRNAME=${TESTDIR}/cvs.root + CVSROOT=`newroot ${CVSROOT_DIRNAME}` + + dotest dottedroot-init-1 "${testcvs} init" "" + mkdir dir1 + mkdir dir1/dir2 + echo version1 >dir1/dir2/file1 + cd dir1 + dotest dottedroot-1 "${testcvs} import -m '' module1 AUTHOR INITIAL" \ +"${SPROG} import: Importing ${CVSROOT_DIRNAME}/module1/dir2 +N module1/dir2/file1 + +No conflicts created by this import" + cd .. + + # This is the test that used to cause an assertion failure + # in recurse.c:do_recursion(). + dotest dottedroot-2 "${testcvs} co -rINITIAL module1" \ +"${SPROG} checkout: Updating module1 +${SPROG} checkout: Updating module1/dir2 +U module1/dir2/file1" + + dokeep + + rm -rf ${CVSROOT_DIRNAME} + rm -r dir1 module1 + CVSROOT_DIRNAME=${CVSROOT_DIRNAME_save} + CVSROOT=${CVSROOT_save} + ;; + + + + fork) + # Test that the server defaults to the correct executable in :fork: + # mode. See the note in the TODO at the end of this file about this. + # + # This test and client should be left after all other references to + # CVS_SERVER are removed from this script. + # + # The client series of tests already tests that CVS_SERVER is + # working, but that test might be better here. + if $remote; then + if test -n "$remotehost"; then + # Don't even try. If our caller specified a remotehost, our + # access method has been determined anyhow. + continue + fi + mkdir fork; cd fork + save_CVS_SERVER=$CVS_SERVER + unset CVS_SERVER + # So looking through $PATH for cvs won't work... + echo "echo junk" >cvs + chmod a+x cvs + save_PATH=$PATH; PATH=.:$PATH + # The second error message below is for testing clients without + # server support. + if ${testcvs_server_support}; then + dotest fork-1 "$testcvs -d:fork:$CVSROOT_DIRNAME version" \ +'Client: \(.*\) +Server: \1' + else + dotest_fail fork-1-noss \ +"$testcvs -d:fork:$CVSROOT_DIRNAME version" \ +"Client: .* +Server: ${CPROG} version: You must set the CVS_SERVER environment variable when +${CPROG} version: using the :fork: access method\. +${CPROG} \[version aborted\]: This CVS was not compiled with server support\." + fi + + CVS_SERVER=${save_CVS_SERVER}; export CVS_SERVER + unset save_CVS_SERVER + PATH=$save_PATH; unset save_PATH + + dokeep + cd .. + rm -r fork + fi + ;; + + + + commit-add-missing) + # Make sure that a commit fails when a `cvs add'ed file has + # been removed from the working directory. + + mkdir 1; cd 1 + module=c-a-m + echo > unused-file + dotest commit-add-missing-1 \ + "$testcvs -Q import -m. $module X Y" '' + + file=F + # Check it out and tag it. + dotest commit-add-missing-2 "$testcvs -Q co $module" '' + cd $module + dotest commit-add-missing-3 "$testcvs -Q tag -b B" '' + echo v1 > $file + dotest commit-add-missing-4 "$testcvs -Q add $file" '' + rm -f $file + dotest_fail commit-add-missing-5 "$testcvs -Q ci -m. $file" \ +"${SPROG} commit: Up-to-date check failed for .$file' +${SPROG} \[commit aborted\]: correct above errors first!" + + dotest + cd ../.. + rm -rf 1 + modify_repo rm -rf $CVSROOT_DIRNAME/$module + ;; + + + + commit-d) + # Check that top-level commits work when CVS/Root + # is overridden by cvs -d. + + mkdir -p 1/subdir; cd 1 + touch file1 subdir/file2 + dotest commit-d-1 "$testcvs -Q import -m. c-d-c X Y" "" + dotest commit-d-2 "$testcvs -Q co c-d-c" "" + cd c-d-c + echo change >>file1; echo another change >>subdir/file2 + # Changing working root, then override with -d + echo nosuchhost:/cvs > CVS/Root + dotest commit-d-3 "$testcvs -q -d '$CVSROOT' commit -m." \ +"$CVSROOT_DIRNAME/c-d-c/file1,v <-- file1 +new revision: 1.2; previous revision: 1.1 +$CVSROOT_DIRNAME/c-d-c/subdir/file2,v <-- subdir/file2 +new revision: 1.2; previous revision: 1.1" + + dokeep + cd ../.. + rm -rf 1 cvsroot/c-d-c + ;; + + + + template) + # Check that the CVS/Template directory is being + # properly created. + modify_repo mkdir -p $CVSROOT_DIRNAME/first/subdir + modify_repo mkdir $CVSROOT_DIRNAME/second + mkdir template; cd template + + # check that no CVS/Template is created for an empty rcsinfo + # Note: For cvs clients with no Clear-template response, the + # CVS/Template file will exist and be zero bytes in length. + dotest template-empty-1 "${testcvs} -Q co first" '' + dotest template-empty-2 \ +"test ! -s first/CVS/Template" '' + dotest template-empty-3 \ +"test ! -s first/subdir/CVS/Template" '' + rm -fr first + + # create some template files + echo 'CVS: the default template' > ${TESTDIR}/template/temp.def + echo 'CVS: the first template' > ${TESTDIR}/template/temp.first + echo 'CVS: the subdir template' > ${TESTDIR}/template/temp.subdir + + dotest template-rcsinfo-1 "${testcvs} -Q co CVSROOT" '' + cd CVSROOT + echo DEFAULT ${TESTDIR}/template/temp.def >>rcsinfo + dotest template-rcsinfo-2 "$testcvs -Q ci -m." + # Make sure we get the update without a commit. + dotest template-rcsinfo-3 "${testcvs} -Q ci -m." '' + # Did the CVSROOT/CVS/Template file get the updated version? + if $remote; then + dotest template-rcsinfo-4r \ +"cmp CVS/Template ${TESTDIR}/template/temp.def" '' + else + dotest template-rcsinfo-4 \ +"test ! -f CVS/Template" '' + fi + echo "^first/subdir ${TESTDIR}/template/temp.subdir" >>rcsinfo + echo "^first ${TESTDIR}/template/temp.first" >>rcsinfo + dotest template-rcsinfo-4.1 "${testcvs} -Q ci -m. rcsinfo" + # Did the CVSROOT/CVS/Template file get the updated version? + if $remote; then + dotest template-rcsinfo-5r \ +"cmp CVS/Template ${TESTDIR}/template/temp.def" '' + else + dotest template-rcsinfo-5 \ +"test ! -f CVS/Template" '' + fi + cd .. + + # Now checkout the first and second modules and see + # if the proper template has been provided for each + dotest template-first "${testcvs} co first second" \ +"${SPROG} checkout: Updating first +${SPROG} checkout: Updating first/subdir +${SPROG} checkout: Updating second" + + if $remote; then + # When in client/server CVS/Template must exist + dotest template-first-r-1 "test -f first/CVS/Template" '' + dotest template-first-r-2 "test -f first/subdir/CVS/Template" '' + dotest template-first-r-3 "test -f second/CVS/Template" '' + # The value of the CVS/Template should be equal to the + # file called out in the rcsinfo file. + dotest template-first-r-4 \ +"cmp first/CVS/Template ${TESTDIR}/template/temp.first" '' + dotest template-first-r-5 \ +"cmp first/subdir/CVS/Template ${TESTDIR}/template/temp.subdir" '' + dotest template-first-r-6 \ +"cmp second/CVS/Template ${TESTDIR}/template/temp.def" '' + else + # When in local mode CVS/Template must NOT exist + dotest_fail template-first-1 "test -f first/CVS/Template" '' + dotest_fail template-first-2 "test -f first/subdir/CVS/Template" '' + dotest_fail template-first-3 "test -f second/CVS/Template" '' + fi + + # Next, create a new subdirectory and see if it gets the + # correct template or not + cd second + mkdir otherdir + dotest template-add-1 "${testcvs} add otherdir" \ +"Directory ${CVSROOT_DIRNAME}/second/otherdir added to the repository" + if $remote; then + dotest template-add-2r \ +"cmp otherdir/CVS/Template ${TESTDIR}/template/temp.def" '' + else + dotest_fail template-add-2 "test -f otherdir/CVS/Template" '' + fi + cd .. + + # Update the remote template. Then see if doing an + # update of a checked out tree will properly update + # the CVS/Template files. + echo 'CVS: Line two' >> ${TESTDIR}/template/temp.def + echo 'CVS: Line two' >> ${TESTDIR}/template/temp.first + echo 'CVS: Line two' >> ${TESTDIR}/template/temp.subdir + dotest template-second "${testcvs} update first second" \ +"${SPROG} update: Updating first +${SPROG} update: Updating first/subdir +${SPROG} update: Updating second +${SPROG} update: Updating second/otherdir" + + if $remote; then + dotest template-second-r-1 \ +"cmp first/CVS/Template ${TESTDIR}/template/temp.first" '' + dotest template-second-r-2 \ +"cmp first/subdir/CVS/Template ${TESTDIR}/template/temp.subdir" '' + dotest template-second-r-3 \ +"cmp second/CVS/Template ${TESTDIR}/template/temp.def" '' + dotest template-second-r-4 \ +"cmp second/otherdir/CVS/Template ${TESTDIR}/template/temp.def" '' + else + # When in local mode CVS/Template must NOT exist + dotest_fail template-second-1 "test -f CVS/Template" '' + dotest_fail template-second-2 "test -f subdir/CVS/Template" '' + dotest_fail template-second-3 "test -f second/CVS/Template" '' + dotest_fail template-second-4 \ +"test -f second/otherdir/CVS/Template" '' + fi + # Update the remote template with a zero-length template + : > ${TESTDIR}/template/temp.def + dotest template-third-1 "${testcvs} update second" \ +"${SPROG} update: Updating second +${SPROG} update: Updating second/otherdir" + + if $remote; then + dotest_fail template-third-r-2 "test -s second/CVS/Template" '' + dotest_fail template-third-r-3 "test -s second/otherdir/CVS/Template" '' + else + dotest_fail template-third-2 "test -f second/CVS/Template" '' + dotest_fail template-third-3 \ +"test -f second/otherdir/CVS/Template" '' + fi + + # fun with remote protocols and tags + if $remote; then + cd second + echo hello > file1 + dotest template-tag-r-1 "${testcvs} -Q add file1" '' + dotest template-tag-r-2 "${testcvs} -Q commit -madd file1" + dotest template-tag-r-3 "${testcvs} -q tag tag" 'T file1' + rm ${CVSROOT_DIRNAME}/CVSROOT/val-tags + cd .. + rm -fr second + dotest template-tag-r-4 "${testcvs} -Q co -rtag second" '' + fi + + cd CVSROOT + dotest template-norcsinfo-1 "${testcvs} up" \ +"${SPROG} update: Updating \." + # Did the CVSROOT/CVS/Template file get the updated version? + if $remote; then + dotest template-norcsinfo-r-2 \ +"cmp CVS/Template ${TESTDIR}/template/temp.def" '' + else + dotest_fail template-norcsinfo-2 "test -f CVS/Template" '' + fi + + : > rcsinfo + dotest template-norcsinfo-3 "${testcvs} -Q ci -m. rcsinfo" + # Did the CVSROOT/CVS/Template file get the updated version? + # The file should be gone or of zero length. + dotest template-norcsinfo-4 \ +"test ! -s CVS/Template" '' + cd .. + + dotest template-norcsinfo-5 "${testcvs} update first" \ +"${SPROG} update: Updating first +${SPROG} update: Updating first/subdir" + + # Note: For cvs clients with no Clear-template response, the + # CVS/Template file will exist and be zero bytes in length. + dotest template-norcsinfo-6 \ +"test ! -s first/CVS/Template" '' + dotest template-norcsinfo-7 \ +"test ! -s first/subdir/CVS/Template" '' + + dokeep + + # cleanup + modify_repo rm -rf $CVSROOT_DIRNAME/first $CVSROOT_DIRNAME/second + restore_adm + cd .. + rm -rf template + ;; + + + + writeproxy) + # Various tests for a read-only CVS mirror set up as a write-proxy + # for a central server. + # + # These tests are only meaningful in client/server mode. + if $remote; then :; else + remoteonly writeproxy + continue + fi + + if $noredirect; then + notnoredirect writeproxy + continue + fi + + require_rsync + if test $? -eq 77; then + skip writeproxy "$skipreason" + continue + fi + + PRIMARY_CVSROOT_DIRNAME_save=$PRIMARY_CVSROOT_DIRNAME + PRIMARY_CVSROOT_save=$PRIMARY_CVSROOT + PRIMARY_CVSROOT_DIRNAME=$TESTDIR/primary_cvsroot + PRIMARY_CVSROOT=`newroot $PRIMARY_CVSROOT_DIRNAME` + SECONDARY_CVSROOT_DIRNAME_save=$SECONDARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_save=$SECONDARY_CVSROOT + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot + SECONDARY_CVSROOT=`newroot $SECONDARY_CVSROOT_DIRNAME` + + # Initialize the primary repository + dotest writeproxy-init-1 "$testcvs -d$PRIMARY_CVSROOT init" + mkdir writeproxy; cd writeproxy + mkdir primary; cd primary + dotest writeproxy-init-2 "$testcvs -Qd$PRIMARY_CVSROOT co CVSROOT" + cd CVSROOT + cat >>loginfo <<EOF +ALL (cat >/dev/null; echo %R) >$TESTDIR/referrer +ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME +EOF + cat >>config <<EOF +PrimaryServer=$PRIMARY_CVSROOT +EOF + dotest writeproxy-init-3 \ +"$testcvs -Q ci -mconfigure-writeproxy" + + # Quickly verify that the server can resolve symlinks when + # determining whether it is the primary. + # This shouldn't actually change the repository. + save_CVS_SERVER=$CVS_SERVER + ln -s $PRIMARY_CVSROOT_DIRNAME $TESTDIR/primary_link + dotest writeproxy-0 "$CVS_SERVER server" \ +"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version +ok +ok +ok" \ +<< EOF +Root $TESTDIR/primary_link +Valid-responses ok error Valid-requests Redirect Checked-in New-entry Checksum Copy-file Updated Created Update-existing Merged Patched Rcs-diff Mode Mod-time Removed Remove-entry Set-static-directory Clear-static-directory Set-sticky Clear-sticky Edit-file Template Clear-template Notified Module-expansion Wrapper-rcsOption M Mbinary E F MT +valid-requests +UseUnchanged +Command-prep commit +Global_option -q +Global_option -Q +Argument -m +Argument configure-writeproxy +Argument -- +Directory . +CVSROOT +Entry /checkoutlist/1.1/// +Modified checkoutlist +u=rw,g=rw,o=r +495 +# The "checkoutlist" file is used to support additional version controlled +# administrative files in \$CVSROOT/CVSROOT, such as template files. +# +# The first entry on a line is a filename which will be checked out from +# the corresponding RCS file in the \$CVSROOT/CVSROOT directory. +# The remainder of the line is an error message to use if the file cannot +# be checked out. +# +# File format: +# +# [<whitespace>]<filename>[<whitespace><error message>]<end-of-line> +# +# comment lines begin with '#' +ci +EOF + rm $TESTDIR/primary_link + + # And now the secondary. + $RSYNC -gopr $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME + + # Checkout from secondary + # + # For now, move the primary root out of the way to satisfy + # ourselves that the data is coming from the secondary. + mv $PRIMARY_CVSROOT_DIRNAME $TESTDIR/save-root + cd ../.. + mkdir secondary; cd secondary + dotest writeproxy-1 "$testcvs -qd$SECONDARY_CVSROOT co CVSROOT" \ +"U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg" + + # Confirm data present + cd CVSROOT + dotest writeproxy-2 "grep rsync loginfo" \ +"ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME" + dotest writeproxy-3 "grep PrimaryServer config" \ +"${DOTSTAR} +PrimaryServer=$PRIMARY_CVSROOT" + + # Checkin to secondary + cd .. + dotest writeproxy-4 "$testcvs -Qd$SECONDARY_CVSROOT co -ldtop ." + cd top + mkdir firstdir + + # Have to move the primary root back before we can perform write + # operations. + mv $TESTDIR/save-root $PRIMARY_CVSROOT_DIRNAME + + dotest writeproxy-5 "$testcvs -Q add firstdir" + cd firstdir + echo now you see me >file1 + dotest writeproxy-6 "$testcvs -Q add file1" + dotest writeproxy-6a "grep file1 CVS/Entries >/dev/null" + dotest writeproxy-7 "$testcvs -Q ci -mfirst-file file1" + + # Verify that the server got the correct referrer. + # + # This happens even when using a :fork:ed server because CVS is + # hardcoded to support only :ext: servers. + # + # This test meaningfully detects that a referrer was passed in fork + # mode because the only time the referrer string can be altered from + # its original state is when the server sends a Referrer response. + # If the client were not parsing and resending the referrer, this + # string would still match $SECONDARY_CVSROOT_DIRNAME. + dotest writeproxy-7a "cat $TESTDIR/referrer" \ +":ext:$username@$hostname$SECONDARY_CVSROOT_DIRNAME" + + # Make sure the sync took place + dotest writeproxy-7b "$testcvs -Q up" + + # Checkout from primary + cd ../../../primary + dotest writeproxy-8 "$testcvs -qd$PRIMARY_CVSROOT co firstdir" \ +"U firstdir/file1" + + # Confirm data present + # - This test indirectly confirms that the commit did not take + # place on the secondary. + cd firstdir + dotest writeproxy-9 "cat file1" "now you see me" + + # Commit to primary + echo now you see me again >file1 + dotest writeproxy-10 "$testcvs -Q ci -medit file1" + + # Update from secondary + cd ../../secondary/top/firstdir + dotest writeproxy-11 "$testcvs -q up" \ +"U file1" + + # Confirm data present + dotest writeproxy-12 "cat file1" "now you see me again" + + # Test a failing rsync + cd ../../CVSROOT + sed \$d <loginfo >tmp + mv tmp loginfo + echo >>loginfo \ +"ALL echo >&2 'Im rsync and I encountered an error!'; cat >/dev/null; exit 1" + dotest writeproxy-init-13 "$testcvs -Q ci -mbreak-rsync" \ +"Im rsync and I encountered an error!" + echo "# a comment" >>loginfo + dotest writeproxy-13 "$testcvs -Q ci -mtest-broken-rsync" \ +"Im rsync and I encountered an error!" + touch loginfo + dotest_fail writeproxy-14 "$testcvs up" \ +"$SPROG update: Updating \. +$SPROG \[update aborted\]: could not find desired version 1\.4 in $PRIMARY_CVSROOT_DIRNAME/CVSROOT/loginfo,v" + + dokeep + cd ../../.. + rm -r writeproxy $TESTDIR/referrer + rm -rf $PRIMARY_CVSROOT_DIRNAME $SECONDARY_CVSROOT_DIRNAME + PRIMARY_CVSROOT_DIRNAME=$PRIMARY_CVSROOT_DIRNAME_save + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save + SECONDARY_CVSROOT=$SECONDARY_CVSROOT_save + ;; + + + + writeproxy-noredirect) + # Various tests for a read-only CVS mirror set up as a write-proxy + # for a central server. + # + # These tests are only meaningful in client/server mode. + # + # These tests are a few simple tests for a writeproxy setup with a + # client that can't handle the `Redirect' response. Mostly they + # parallel the "writeproxy" tests but, in the style of the "server", + # "server2", "pserver", and related tests, they bypass the CVS client + # for write commands by piping data into a server on STDIN to mimic + # a client that cannot handle the `Redirect' response. + if $remote; then :; else + remoteonly writeproxy-noredirect + continue + fi + + require_rsync + if test $? -eq 77; then + skip writeproxy-noredirect "$skipreason" + continue + fi + + PRIMARY_CVSROOT_DIRNAME_save=$PRIMARY_CVSROOT_DIRNAME + PRIMARY_CVSROOT_save=$PRIMARY_CVSROOT + PRIMARY_CVSROOT_DIRNAME=$TESTDIR/primary_cvsroot + PRIMARY_CVSROOT=`newroot $PRIMARY_CVSROOT_DIRNAME` + SECONDARY_CVSROOT_DIRNAME_save=$SECONDARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot + + # Initialize the primary repository + dotest writeproxy-noredirect-init-1 \ +"$testcvs -d'$PRIMARY_CVSROOT' init" + mkdir writeproxy-noredirect; cd writeproxy-noredirect + mkdir primary; cd primary + dotest writeproxy-noredirect-init-2 \ +"$testcvs -Qd'$PRIMARY_CVSROOT' co CVSROOT" + cd CVSROOT + cat >>loginfo <<EOF +ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME +EOF + cat >>config <<EOF +PrimaryServer=$PRIMARY_CVSROOT +EOF + dotest writeproxy-noredirect-init-3 \ +"$testcvs -Q ci -mconfigure-writeproxy" + + # And now the secondary. + $RSYNC -gopr $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME + + CVS_SERVER_save=$CVS_SERVER + CVS_SERVER_secondary=$TESTDIR/writeproxy-secondary-wrapper + CVS_SERVER=$CVS_SERVER_secondary + + # Wrap the CVS server to allow --primary-root to be set by the + # secondary. + cat <<EOF >$TESTDIR/writeproxy-secondary-wrapper +#! $TESTSHELL +CVS_SERVER=$TESTDIR/writeproxy-primary-wrapper +export CVS_SERVER + +# No need to check the PID of the last client since we are testing with +# Redirect disabled. +proot_arg="--allow-root $SECONDARY_CVSROOT_DIRNAME" +exec $servercvs \$proot_arg "\$@" +EOF + cat <<EOF >$TESTDIR/writeproxy-primary-wrapper +#! $TESTSHELL +#CVS_SERVER_LOG=/tmp/cvsprimarylog +exec $servercvs "\$@" +EOF + + chmod a+x $TESTDIR/writeproxy-secondary-wrapper \ + $TESTDIR/writeproxy-primary-wrapper + + # Checkout from secondary + # + # It may look like we are checking out from the primary here, but + # in fork mode, the deciding factor is the PrimaryServer translation + # above. + # + # When the primary and secondary hostname were different, the server + # the client is talking directly to is more obvious. + # + # For now, move the primary root out of the way to satisfy + # ourselves that the data is coming from the secondary. + mv $PRIMARY_CVSROOT_DIRNAME $TESTDIR/save-root + cd ../.. + mkdir secondary; cd secondary + dotest writeproxy-noredirect-1 \ +"$testcvs -qd'$PRIMARY_CVSROOT' co CVSROOT" \ +"U CVSROOT/checkoutlist +U CVSROOT/commitinfo +U CVSROOT/config +U CVSROOT/cvswrappers +U CVSROOT/loginfo +U CVSROOT/modules +U CVSROOT/notify +U CVSROOT/postadmin +U CVSROOT/postproxy +U CVSROOT/posttag +U CVSROOT/postwatch +U CVSROOT/preproxy +U CVSROOT/rcsinfo +U CVSROOT/taginfo +U CVSROOT/verifymsg" + + # Confirm data present + cd CVSROOT + dotest writeproxy-noredirect-2 "grep rsync loginfo" \ +"ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME" + dotest writeproxy-noredirect-3 "grep PrimaryServer config" \ +"${DOTSTAR} +PrimaryServer=$PRIMARY_CVSROOT" + + # Checkin to secondary + cd .. + dotest writeproxy-noredirect-4 \ +"$testcvs -Qd'$PRIMARY_CVSROOT' co -ldtop ." + cd top + mkdir firstdir + + # Have to move the primary root back before we can perform write + # operations. + mv $TESTDIR/save-root $PRIMARY_CVSROOT_DIRNAME + + dotest writeproxy-noredirect-5 "$CVS_SERVER server" \ +"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version +ok +ok +ok +Clear-template firstdir/ +firstdir/ +ok" \ +<< EOF +Root $PRIMARY_CVSROOT_DIRNAME +Valid-responses ok error Valid-requests Checked-in New-entry Checksum Copy-file Updated Created Update-existing Merged Patched Rcs-diff Mode Mod-time Removed Remove-entry Set-static-directory Clear-static-directory Set-sticky Clear-sticky Template Clear-template Notified Module-expansion Wrapper-rcsOption M Mbinary E F MT +valid-requests +UseUnchanged +Command-prep add +Global_option -q +Global_option -Q +wrapper-sendme-rcsOptions +Argument -- +Directory firstdir +firstdir +Directory . + +Argument firstdir +add +EOF + + # Gotta update the workspace ourselves since we bypassed the client. + cp -R CVS firstdir/CVS + echo "firstdir" >firstdir/CVS/Repository + + cd firstdir + echo now you see me >file1 + dotest writeproxy-noredirect-6 "$CVS_SERVER server" \ +"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version +ok +ok +ok +Checked-in \./ +firstdir/file1 +/file1/0/// +ok" \ +<< EOF +Root $PRIMARY_CVSROOT_DIRNAME +Valid-responses ok error Valid-requests Checked-in New-entry Checksum Copy-file Updated Created Update-existing Merged Patched Rcs-diff Mode Mod-time Removed Remove-entry Set-static-directory Clear-static-directory Set-sticky Clear-sticky Template Clear-template Notified Module-expansion Wrapper-rcsOption M Mbinary E F MT +valid-requests +UseUnchanged +Command-prep add +Global_option -q +Global_option -Q +wrapper-sendme-rcsOptions +Argument -- +Directory . +firstdir +Is-modified file1 +Argument file1 +add +EOF + + # Have to add it to the workspace ourselves again since we are + # bypassing the client. + echo /file1/0/dummy+timestamp// >>CVS/Entries + + dotest writeproxy-noredirect-7 "$CVS_SERVER server" \ +"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version +ok +ok +Mode u=rw,g=rw,o=r +Checked-in \./ +firstdir/file1 +/file1/1\.1/// +ok" \ +<< EOF +Root $PRIMARY_CVSROOT_DIRNAME +Valid-responses ok error Valid-requests Checked-in New-entry Checksum Copy-file Updated Created Update-existing Merged Patched Rcs-diff Mode Mod-time Removed Remove-entry Set-static-directory Clear-static-directory Set-sticky Clear-sticky Template Clear-template Notified Module-expansion Wrapper-rcsOption M Mbinary E F MT +valid-requests +UseUnchanged +Command-prep commit +Global_option -q +Global_option -Q +Argument -m +Argument first-file +Argument -- +Directory . +firstdir +Entry /file1/0/+modified// +Modified file1 +u=rw,g=rw,o=r +15 +now you see me +Argument file1 +ci +EOF + + # Have to add it to the workspace ourselves again since we are + # bypassing the client. + echo D >CVS/Entries + echo /file1/1.1/dummy+timestamp// >>CVS/Entries + + # Make sure the sync took place + dotest writeproxy-noredirect-7a "$testcvs -Q up" + + CVS_SERVER=$servercvs + # Checkout from primary + cd ../../../primary + dotest writeproxy-noredirect-8 \ +"$testcvs -qd'$PRIMARY_CVSROOT' co firstdir" \ +"U firstdir/file1" + + # Confirm data present + # - This test indirectly confirms that the commit did not take + # place on the secondary. + cd firstdir + dotest writeproxy-noredirect-9 "cat file1" "now you see me" + + # Commit to primary + echo now you see me again >file1 + dotest writeproxy-noredirect-10 "$testcvs -Q ci -medit file1" + + CVS_SERVER=$CVS_SERVER_secondary + # Update from secondary + cd ../../secondary/top/firstdir + dotest writeproxy-noredirect-11 "$testcvs -q up" "U file1" + + # Confirm data present + dotest writeproxy-noredirect-12 "cat file1" "now you see me again" + + dokeep + cd ../../../.. + rm -r writeproxy-noredirect + rm -rf $PRIMARY_CVSROOT_DIRNAME $SECONDARY_CVSROOT_DIRNAME + rm $TESTDIR/writeproxy-secondary-wrapper \ + $TESTDIR/writeproxy-primary-wrapper + CVS_SERVER=$CVS_SERVER_save + PRIMARY_CVSROOT_DIRNAME=$PRIMARY_CVSROOT_DIRNAME_save + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save + ;; + + + + writeproxy-ssh) + # Various tests for a read-only CVS mirror set up as a write-proxy + # for a central server accessed via the :ext: method. + # + # Mostly these tests are intended to set up for the final test which + # verifies that the server registers the referrer. + if $remote; then :; else + remoteonly writeproxy-ssh + continue + fi + + if $noredirect; then + notnoredirect writeproxy-ssh + continue + fi + + require_rsh "$CVS_RSH" + if test $? -eq 77; then + skip writeproxy-ssh "$skipreason" + continue + fi + + require_rsync + if test $? -eq 77; then + skip writeproxy-ssh "$skipreason" + continue + fi + + # Save old roots. + PRIMARY_CVSROOT_DIRNAME_save=$PRIMARY_CVSROOT_DIRNAME + PRIMARY_CVSROOT_save=$PRIMARY_CVSROOT + SECONDARY_CVSROOT_DIRNAME_save=$SECONDARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_save=$SECONDARY_CVSROOT + + # Set new roots. + PRIMARY_CVSROOT_DIRNAME=$TESTDIR/primary_cvsroot + PRIMARY_CVSROOT=:ext:$host$PRIMARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot + SECONDARY_CVSROOT=":ext;Redirect=yes:$host$SECONDARY_CVSROOT_DIRNAME" + + # Initialize the primary repository + dotest writeproxy-ssh-init-1 "$testcvs -d$PRIMARY_CVSROOT init" + mkdir writeproxy-ssh; cd writeproxy-ssh + mkdir primary; cd primary + dotest writeproxy-ssh-init-2 "$testcvs -Qd$PRIMARY_CVSROOT co CVSROOT" + cd CVSROOT + cat >>loginfo <<EOF +ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME +EOF + cat >>loginfo <<EOF +ALL echo Referrer=%R; cat >/dev/null +EOF + cat >>config <<EOF +PrimaryServer=$PRIMARY_CVSROOT +EOF + dotest writeproxy-ssh-init-3 \ +"$testcvs -Q ci -mconfigure-writeproxy-ssh" \ +"Referrer=NONE" + + # And now the secondary. + $RSYNC -gopr $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME + + # Checkout from secondary + # + # For now, move the primary root out of the way to satisfy + # ourselves that the data is coming from the secondary. + mv $PRIMARY_CVSROOT_DIRNAME $TESTDIR/save-root + + # Checkin to secondary + cd ../.. + save_CVSROOT=$CVSROOT + CVSROOT=$SECONDARY_CVSROOT + export CVSROOT + dotest writeproxy-ssh-1 "$testcvs -Q co -ldtop ." + CVSROOT=$save_CVSROOT + export CVSROOT + cd top + mkdir firstdir + + # Have to move the primary root back before we can perform write + # operations. + mv $TESTDIR/save-root $PRIMARY_CVSROOT_DIRNAME + + dotest writeproxy-ssh-2 "$testcvs -Q add firstdir" \ +"Referrer=:ext:$username@$hostname$SECONDARY_CVSROOT_DIRNAME" + + cd firstdir + echo now you see me >file1 + dotest writeproxy-ssh-3 "$testcvs -Q add file1" + dotest writeproxy-ssh-4 "$testcvs -Q ci -mfirst-file file1" \ +"Referrer=:ext:$username@$hostname$SECONDARY_CVSROOT_DIRNAME" + + dokeep + cd ../../.. + rm -r writeproxy-ssh + rm -rf $PRIMARY_CVSROOT_DIRNAME $SECONDARY_CVSROOT_DIRNAME + PRIMARY_CVSROOT_DIRNAME=$PRIMARY_CVSROOT_DIRNAME_save + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save + SECONDARY_CVSROOT=$SECONDARY_CVSROOT_save + ;; + + + + writeproxy-ssh-noredirect) + # Various tests for a read-only CVS mirror set up as a write-proxy + # for a central server accessed via the :ext: method. + # + # Mostly these tests are intended to set up for the final test which + # verifies that the server registers the referrer. + if $remote; then :; else + remoteonly writeproxy-ssh-noredirect + continue + fi + + require_rsh "$CVS_RSH" + if test $? -eq 77; then + skip writeproxy-ssh-noredirect "$skipreason" + continue + fi + + require_rsync + if test $? -eq 77; then + skip writeproxy-ssh-noredirect "$skipreason" + continue + fi + + # Save old roots. + PRIMARY_CVSROOT_DIRNAME_save=$PRIMARY_CVSROOT_DIRNAME + PRIMARY_CVSROOT_save=$PRIMARY_CVSROOT + SECONDARY_CVSROOT_DIRNAME_save=$SECONDARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_save=$SECONDARY_CVSROOT + + # Set new roots. + PRIMARY_CVSROOT_DIRNAME=$TESTDIR/primary_cvsroot + PRIMARY_CVSROOT=:ext:$host$PRIMARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot + SECONDARY_CVSROOT=":ext;Redirect=no:$host$PRIMARY_CVSROOT_DIRNAME" + + # Initialize the primary repository + dotest writeproxy-ssh-noredirect-init-1 \ +"$testcvs -d$PRIMARY_CVSROOT init" + mkdir writeproxy-ssh-noredirect; cd writeproxy-ssh-noredirect + mkdir primary; cd primary + dotest writeproxy-ssh-noredirect-init-2 \ +"$testcvs -Qd$PRIMARY_CVSROOT co CVSROOT" + cd CVSROOT + cat >>loginfo <<EOF +ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME +EOF + cat >>loginfo <<EOF +ALL echo Referrer=%R; cat >/dev/null +EOF + cat >>config <<EOF +PrimaryServer=$PRIMARY_CVSROOT +EOF + dotest writeproxy-ssh-noredirect-init-3 \ +"$testcvs -Q ci -mconfigure-writeproxy-ssh-noredirect" \ +"Referrer=NONE" + + # And now the secondary. + $RSYNC -gopr $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME + + # Wrap the CVS server to allow --primary-root to be set by the + # secondary. + cat <<EOF >$TESTDIR/writeproxy-secondary-wrapper +#! $TESTSHELL +CVS_SERVER=$TESTDIR/writeproxy-primary-wrapper +export CVS_SERVER + +# No need to check the PID of the last client since we are testing with +# Redirect disabled. +proot_arg="--allow-root=$SECONDARY_CVSROOT_DIRNAME" +exec $CVS_SERVER \$proot_arg "\$@" +EOF + cat <<EOF >$TESTDIR/writeproxy-primary-wrapper +#! $TESTSHELL +if test -n "\$CVS_SERVER_LOG"; then + CVS_SERVER_LOG=$TMPDIR/cvsprimarylog; export CVS_SERVER_LOG +fi +exec $CVS_SERVER "\$@" +EOF + + CVS_SERVER_save=$CVS_SERVER + CVS_SERVER_secondary=$TESTDIR/writeproxy-secondary-wrapper + CVS_SERVER=$CVS_SERVER_secondary + + chmod a+x $TESTDIR/writeproxy-secondary-wrapper \ + $TESTDIR/writeproxy-primary-wrapper + + # Checkout from secondary + # + # For now, move the primary root out of the way to satisfy + # ourselves that the data is coming from the secondary. + mv $PRIMARY_CVSROOT_DIRNAME $TESTDIR/save-root + + # Checkin to secondary + cd ../.. + dotest writeproxy-ssh-noredirect-1 \ +"$testcvs -qd '$SECONDARY_CVSROOT' co -ldtop ." + + cd top + mkdir firstdir + + # Have to move the primary root back before we can perform write + # operations. + mv $TESTDIR/save-root $PRIMARY_CVSROOT_DIRNAME + + dotest writeproxy-ssh-noredirect-2 "$testcvs -Q add firstdir" \ +"Referrer=NONE" + + cd firstdir + echo now you see me >file1 + dotest writeproxy-ssh-noredirect-3 "$testcvs -Q add file1" + dotest writeproxy-ssh-noredirect-4 \ +"$testcvs -Q ci -mfirst-file file1" \ +"Referrer=NONE" + + dokeep + cd ../../.. + rm -r writeproxy-ssh-noredirect + rm -rf $PRIMARY_CVSROOT_DIRNAME $SECONDARY_CVSROOT_DIRNAME + PRIMARY_CVSROOT_DIRNAME=$PRIMARY_CVSROOT_DIRNAME_save + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save + SECONDARY_CVSROOT=$SECONDARY_CVSROOT_save + rm $TESTDIR/writeproxy-secondary-wrapper \ + $TESTDIR/writeproxy-primary-wrapper + CVS_SERVER=$CVS_SERVER_save + ;; + + + + trace) + # Check that there are no core dumps lurking in the trace + # options. + + # Perform some cleanup for normalized testing... + rm ${CVSROOT_DIRNAME}/CVSROOT/history + rm -f ${CVSROOT_DIRNAME}/CVSROOT/cvsignore + rm -f ${CVSROOT_DIRNAME}/CVSROOT/cvsignore,v + + # checkout the trace option + + mkdir trace && cd trace + mkdir imp && cd imp + touch file1 + + dotest_sort trace-1 "${testcvs} -t -t -t init" \ +" *-> Lock_Cleanup() + *-> RCS_checkout (checkoutlist,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (commitinfo,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (config,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (cvswrappers,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (loginfo,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (modules,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (notify,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (postadmin,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (postproxy,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (posttag,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (postwatch,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (preproxy,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (rcsinfo,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (taginfo,v, , , , \.#[0-9][0-9]*) + *-> RCS_checkout (verifymsg,v, , , , \.#[0-9][0-9]*) + *-> Simple_Lock_Cleanup() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#[0-9][0-9]*) + *-> unlink_file(\.#checkoutlist) + *-> unlink_file(\.#commitinfo) + *-> unlink_file(\.#config) + *-> unlink_file(\.#cvswrappers) + *-> unlink_file(\.#loginfo) + *-> unlink_file(\.#modules) + *-> unlink_file(\.#notify) + *-> unlink_file(\.#postadmin) + *-> unlink_file(\.#postproxy) + *-> unlink_file(\.#posttag) + *-> unlink_file(\.#postwatch) + *-> unlink_file(\.#preproxy) + *-> unlink_file(\.#rcsinfo) + *-> unlink_file(\.#taginfo) + *-> unlink_file(\.#verifymsg) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} )" \ +" + *-> Forking server: ${CVS_SERVER} server + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> CVS_SERVER_SLEEP not set\. +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> RCS_checkout (checkoutlist,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (commitinfo,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (config,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (cvswrappers,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (loginfo,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (modules,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (notify,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (postadmin,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (postproxy,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (posttag,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (postwatch,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (preproxy,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (rcsinfo,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (taginfo,v, , , , \.#[0-9][0-9]*) +S -> RCS_checkout (verifymsg,v, , , , \.#[0-9][0-9]*) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> do_cvs_command (init) +S -> remove_locks() +S -> remove_locks() +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#[0-9][0-9]*) +S -> unlink_file(\.#checkoutlist) +S -> unlink_file(\.#commitinfo) +S -> unlink_file(\.#config) +S -> unlink_file(\.#cvswrappers) +S -> unlink_file(\.#loginfo) +S -> unlink_file(\.#modules) +S -> unlink_file(\.#notify) +S -> unlink_file(\.#postadmin) +S -> unlink_file(\.#postproxy) +S -> unlink_file(\.#posttag) +S -> unlink_file(\.#postwatch) +S -> unlink_file(\.#preproxy) +S -> unlink_file(\.#rcsinfo) +S -> unlink_file(\.#taginfo) +S -> unlink_file(\.#verifymsg)" \ + + dotest_sort trace-2 \ +"${testcvs} -t -t -t import -mimport trace MYVENDOR version-1" \ +" + + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) + *-> Simple_Lock_Cleanup() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> safe_location( where=(null) ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +N trace/file1 +No conflicts created by this import" \ +" + + + *-> Forking server: ${CVS_SERVER} server + *-> Sending file \`file1' to server + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +N trace/file1 +No conflicts created by this import +S -> CVS_SERVER_SLEEP not set\. +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (import) +S -> remove_locks() +S -> remove_locks() +S -> safe_location( where=(null) ) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify()" + + cd .. + rm -fr imp + + dotest_sort trace-3 "${testcvs} -t -t -t co trace" \ +" *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *local=0, which=3, aflag=0, + *locktype=1, update_preload=trace + *-> Create_Admin + *-> Create_Admin (\., trace, ${CVSROOT_DIRNAME}/trace, , , 0, 0, 1) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, , , file1) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Register(file1, 1\.1\.1\.1, ${DATE}, , ) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Write_Template (trace, ${CVSROOT_DIRNAME}/trace) + *-> chmod(file1,[0-7][0-7]*) + *-> do_module (trace, Updating, NULL, NULL) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> safe_location( where=(null) ) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(\./CVS/Entries\.Static) + *-> unlink_file(\./CVS/Tag) + *-> unlink_file(CVS/Entries\.Log) + *-> unlink_file_dir(CVS/,,file1) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +U trace/file1 +${SPROG} checkout: Updating trace" \ +" + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *local=0, which=3, aflag=0, + *locktype=1, update_preload=trace + *-> Create_Admin + *-> Create_Admin (trace, trace, ${CVSROOT_DIRNAME}/trace, , , 0, 0, 1) + *-> Forking server: ${CVS_SERVER} server + *-> Register(file1, 1\.1\.1\.1, ${DATE}, , ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(\.new\.file1,file1) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> safe_location( where=(null) ) + *-> unlink_file(CVS/Entries\.Log) + *-> unlink_file(CVS/Entries\.Static) + *-> unlink_file(CVS/Tag) + *-> unlink_file(CVS/Template) + *-> unlink_file(trace/CVS/Tag) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> CVS_SERVER_SLEEP not set\. +S -> Create_Admin +S -> Create_Admin (\., trace, ${CVSROOT_DIRNAME}/trace, , , 0, 0, 1) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/rcsinfo, trace, ALL) +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, , , (function)) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Register(file1, 1\.1\.1\.1, , , ) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Write_Template (trace, ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (\., ${CVSROOT_DIRNAME}) +S -> dirswitch (\., ${CVSROOT_DIRNAME}) +S -> do_cvs_command (checkout) +S -> do_module (trace, Updating, NULL, NULL) +S -> do_module (trace, Updating, NULL, NULL) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> remove_locks() +S -> remove_locks() +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> safe_location( where=(null) ) +S -> serve_directory (\.) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_register(file1, 1\.1\.1\.1, , , , , ) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(\./CVS/Entries\.Static) +S -> unlink_file(\./CVS/Tag) +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +U trace/file1 +${SPROG} checkout: Updating trace" + + cd trace + mkdir subdir + dotest_sort trace-4 "${testcvs} -t -t -t add subdir" \ +" *-> Create_Admin + *-> Create_Admin (\., subdir, ${CVSROOT_DIRNAME}/trace/subdir, , , 0, 0, 1) + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace/subdir, ALL) + *-> Simple_Lock_Cleanup() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> unlink_file(\./CVS/Tag) + *-> unlink_file(${CVSROOT_DIRNAME}/trace/subdir/CVS/fileattr) + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +Directory ${CVSROOT_DIRNAME}/trace/subdir added to the repository" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *-> Create_Admin + *-> Create_Admin (subdir, subdir, ${CVSROOT_DIRNAME}/trace/subdir, , , 0, 0, 1) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(CVS/Entries\.Backup,CVS/Entries) +${DOTSTAR} *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) +${DOTSTAR} *-> unlink_file(CVS/Template) + *-> unlink_file(subdir/CVS/Tag) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${DOTSTAR}Directory ${CVSROOT_DIRNAME}/trace/subdir added to the repository +S -> CVS_SERVER_SLEEP not set\. +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace/subdir, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/rcsinfo, trace/subdir, ALL) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Write_Template (subdir, ${CVSROOT_DIRNAME}/trace/subdir) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (subdir, ${CVSROOT_DIRNAME}/trace/subdir) +S -> do_cvs_command (add) +S -> remove_locks() +S -> remove_locks() +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> serve_directory (subdir) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> unlink_file(${CVSROOT_DIRNAME}/trace/subdir/CVS/fileattr) +S -> unlink_file(CVS/Entries\.Log) +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} )" + touch file2 + dotest_sort trace-5 "${testcvs} -t -t -t add file2" \ +" *-> Lock_Cleanup() + *-> Register(file2, 0, Initial file2, , ) + *-> Simple_Lock_Cleanup() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${SPROG} add: scheduling file \`file2' for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Register(file2, 0, dummy timestamp, , ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(CVS/Entries\.Backup,CVS/Entries) +${DOTSTAR} *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) +${DOTSTAR} *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${DOTSTAR}S -> CVS_SERVER_SLEEP not set\. +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Register(file2, 0, Initial file2, , ) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (add) +S -> remove_locks() +S -> remove_locks() +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_register(file2, 0, Initial file2, , , , ) +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${SPROG} add: scheduling file \`file2' for addition +${SPROG} add: use \`${SPROG} commit' to add this file permanently" + dotest_sort trace-6 "${testcvs} -t -t -t ci -mnew-file file2" \ +" *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=2, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/commitinfo, trace, ALL) + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) + *-> Promotable_Lock () + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file2,v, 1, , , (function)) + *-> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file2,v, 1, (null), , file2 ) + *-> Register(file2, 1\.1, ${DATE}, , ) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_tree_promotably (1, argv, 0, 1, 0) + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_lock(${CVSROOT_DIRNAME}/trace) + *-> rcs_cleanup() + *-> readers_exist (${CVSROOT_DIRNAME}/trace) + *-> remove_locks() + *-> remove_locks() + *-> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) + *-> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 0) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Base/file2) + *-> unlink_file(CVS/Entries\.Log) + *-> unlink_file(CVS/file2,t) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${CVSROOT_DIRNAME}/trace/file2,v <-- file2 +initial revision: 1\.1" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=2, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Register(file2, 1\.1, ${DATE}, , ) + *-> Sending file \`file2' to server + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Base/file2) + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${CVSROOT_DIRNAME}/trace/file2,v <-- file2 +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/commitinfo, trace, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) +S -> Promotable_Lock () +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file2,v, 1, , , (function)) +S -> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file2,v, 1, (null), , file2 ) +S -> Register(file2, 1\.1, ${DATE}, , ) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (commit) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_tree_promotably (1, argv, 0, 1, 0) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_lock(${CVSROOT_DIRNAME}/trace) +S -> rcs_cleanup() +S -> readers_exist (${CVSROOT_DIRNAME}/trace) +S -> remove_locks() +S -> remove_locks() +S -> remove_locks() +S -> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) +S -> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file2) +S -> server_pathname_check (file2) +S -> server_pathname_check (file2) +S -> server_register(file2, 1\.1, ${DATE}, , , , ) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 0) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(CVS/Entries\.Log) +S -> unlink_file(CVS/file2,t) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +initial revision: 1\.1" + dotest_sort trace-7 "${testcvs} -t -t -t tag bp" \ +" *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in= ) + *dosrcs=1, repository_in= ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=1, update_preload=(null) + *locktype=2, update_preload=(null) + *local_specified=0, mname=(null), msg=(null) ) + *mwhere=(null), mfile=(null), shorten=0, + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/taginfo, trace, ALL) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.\*, (null)) + *-> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file1, ${CVSROOT_DIRNAME}/trace/file1,v ) + *-> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file2, ${CVSROOT_DIRNAME}/trace/file2,v ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace/subdir) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) + *-> rcs_cleanup() + *-> readers_exist (${CVSROOT_DIRNAME}/trace) + *-> readers_exist (${CVSROOT_DIRNAME}/trace/subdir) + *-> remove_locks() + *-> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) + *-> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> rtag_proc ( argc=1, argv=${PFMT}, xwhere=(null), + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +T file1 +T file2 +${SPROG} tag: Tagging \. +${SPROG} tag: Tagging subdir" \ +" + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in= ) + *dosrcs=1, repository_in= ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + *locktype=2, update_preload=(null) + *local_specified=0, mname=(null), msg=(null) ) + *mwhere=(null), mfile=(null), shorten=0, + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/taginfo, trace, ALL) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.\*, (null)) +S -> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file1, ${CVSROOT_DIRNAME}/trace/file1,v ) +S -> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file2, ${CVSROOT_DIRNAME}/trace/file2,v ) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (subdir, ${CVSROOT_DIRNAME}/trace/subdir) +S -> do_cvs_command (tag) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace/subdir) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) +S -> rcs_cleanup() +S -> readers_exist (${CVSROOT_DIRNAME}/trace) +S -> readers_exist (${CVSROOT_DIRNAME}/trace/subdir) +S -> remove_locks() +S -> remove_locks() +S -> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) +S -> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> rtag_proc ( argc=1, argv=${PFMT}, xwhere=(null), +S -> serve_directory (\.) +S -> serve_directory (\.) +S -> serve_directory (subdir) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(CVS/Entries\.Log) +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +T file1 +T file2 +${SPROG} tag: Tagging \. +${SPROG} tag: Tagging subdir" + + dotest_sort trace-8 "${testcvs} -t -t -t tag -b branch1" \ +" *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in= ) + *dosrcs=1, repository_in= ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=1, update_preload=(null) + *locktype=2, update_preload=(null) + *local_specified=0, mname=(null), msg=(null) ) + *mwhere=(null), mfile=(null), shorten=0, + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/taginfo, trace, ALL) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.\*, (null)) + *-> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file1, ${CVSROOT_DIRNAME}/trace/file1,v ) + *-> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file2, ${CVSROOT_DIRNAME}/trace/file2,v ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace/subdir) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) + *-> rcs_cleanup() + *-> readers_exist (${CVSROOT_DIRNAME}/trace) + *-> readers_exist (${CVSROOT_DIRNAME}/trace/subdir) + *-> remove_locks() + *-> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) + *-> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) + *-> rtag_proc ( argc=1, argv=${PFMT}, xwhere=(null), + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +T file1 +T file2 +${SPROG} tag: Tagging \. +${SPROG} tag: Tagging subdir" \ +" + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in= ) + *dosrcs=1, repository_in= ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + *locktype=2, update_preload=(null) + *local_specified=0, mname=(null), msg=(null) ) + *mwhere=(null), mfile=(null), shorten=0, + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/taginfo, trace, ALL) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.\*, (null)) +S -> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file1, ${CVSROOT_DIRNAME}/trace/file1,v ) +S -> check_fileproc ( ${CVSROOT_DIRNAME}/trace, file2, ${CVSROOT_DIRNAME}/trace/file2,v ) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (subdir, ${CVSROOT_DIRNAME}/trace/subdir) +S -> do_cvs_command (tag) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace/subdir) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) +S -> rcs_cleanup() +S -> readers_exist (${CVSROOT_DIRNAME}/trace) +S -> readers_exist (${CVSROOT_DIRNAME}/trace/subdir) +S -> remove_locks() +S -> remove_locks() +S -> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) +S -> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> rtag_proc ( argc=1, argv=${PFMT}, xwhere=(null), +S -> serve_directory (\.) +S -> serve_directory (\.) +S -> serve_directory (subdir) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(CVS/Entries\.Log) +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +T file1 +T file2 +${SPROG} tag: Tagging \. +${SPROG} tag: Tagging subdir" + dotest_sort trace-9 "${testcvs} -t -t -t log" \ +" + + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=(null) ) + *local=0, which=7, aflag=0, + *locktype=1, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + MYVENDOR: 1\.1\.1 + bp: 1\.1 + bp: 1\.1\.1\.1 + branch1: 1\.1\.0\.2 + branch1: 1\.1\.1\.1\.0\.2 + version-1: 1\.1\.1\.1 +---------------------------- +---------------------------- +---------------------------- +============================================================================= +============================================================================= +Initial revision +RCS file: ${CVSROOT_DIRNAME}/trace/file1,v +RCS file: ${CVSROOT_DIRNAME}/trace/file2,v +Working file: file1 +Working file: file2 +access list: +access list: +branch: +branch: 1\.1\.1 +branches: 1\.1\.1; +${SPROG} log: Logging \. +${SPROG} log: Logging subdir +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +description: +description: +head: 1\.1 +head: 1\.1 +import +keyword substitution: kv +keyword substitution: kv +locks: strict +locks: strict +new-file +revision 1\.1 +revision 1\.1 +revision 1\.1\.1\.1 +symbolic names: +symbolic names: +total revisions: 1; selected revisions: 1 +total revisions: 2; selected revisions: 2" \ +" + + + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=7, aflag=0, + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + MYVENDOR: 1\.1\.1 + bp: 1\.1 + bp: 1\.1\.1\.1 + branch1: 1\.1\.0\.2 + branch1: 1\.1\.1\.1\.0\.2 + version-1: 1\.1\.1\.1 +---------------------------- +---------------------------- +---------------------------- +============================================================================= +============================================================================= +Initial revision +RCS file: ${CVSROOT_DIRNAME}/trace/file1,v +RCS file: ${CVSROOT_DIRNAME}/trace/file2,v +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> dirswitch (subdir, ${CVSROOT_DIRNAME}/trace/subdir) +S -> do_cvs_command (log) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> remove_locks() +S -> remove_locks() +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> serve_directory (\.) +S -> serve_directory (subdir) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(CVS/Entries\.Log) +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +Working file: file1 +Working file: file2 +access list: +access list: +branch: +branch: 1\.1\.1 +branches: 1\.1\.1; +${SPROG} log: Logging \. +${SPROG} log: Logging subdir +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}0 -0; commitid: ${commitid}; +date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; +description: +description: +head: 1\.1 +head: 1\.1 +import +keyword substitution: kv +keyword substitution: kv +locks: strict +locks: strict +new-file +revision 1\.1 +revision 1\.1 +revision 1\.1\.1\.1 +symbolic names: +symbolic names: +total revisions: 1; selected revisions: 1 +total revisions: 2; selected revisions: 2" + + dotest_sort trace-10 "${testcvs} -t -t -t annotate file1" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in= ) + *local=0, which=1, aflag=0, + *locktype=1, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> do_recursion ( frame=${PFMT} ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +Annotations for file1" \ +" + + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in= ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +Annotations for file1 +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (annotate) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> remove_locks() +S -> remove_locks() +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} )" + + dotest_sort \ +trace-11 "${testcvs} -t -t -t rtag -r bp -b branch2 trace" \ +" *aflag=0, repository=${CVSROOT_DIRNAME}/trace ) + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *local=0, which=6, aflag=0, + *local=0, which=6, aflag=0, + *local=0, which=6, aflag=0, + *locktype=1, update_preload=(null) + *locktype=1, update_preload=trace + *locktype=2, update_preload=trace + *local_specified=0, mname=trace, msg=Tagging ) + *mwhere=(null), mfile=(null), shorten=0, + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/taginfo, trace, ALL) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, (null)) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.\*, (null)) + *-> check_fileproc ( ${CVSROOT_DIRNAME}/trace, trace/file1, ${CVSROOT_DIRNAME}/trace/file1,v ) + *-> check_fileproc ( ${CVSROOT_DIRNAME}/trace, trace/file2, ${CVSROOT_DIRNAME}/trace/file2,v ) + *-> do_module (trace, Tagging, NULL, branch2) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace/subdir) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) + *-> rcs_cleanup() + *-> readers_exist (${CVSROOT_DIRNAME}/trace) + *-> readers_exist (${CVSROOT_DIRNAME}/trace/subdir) + *-> remove_locks() + *-> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) + *-> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) + *-> rtag_proc ( argc=1, argv=${PFMT}, xwhere=(null), + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> tag_check_valid ( name=bp, argc=0, argv=${PFMT}, local=0, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${SPROG} rtag: Tagging trace +${SPROG} rtag: Tagging trace/subdir" \ +" + *aflag=0, repository=${CVSROOT_DIRNAME}/trace ) + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *local=0, which=6, aflag=0, + *local=0, which=6, aflag=0, + *local=0, which=6, aflag=0, + *locktype=1, update_preload=(null) + *locktype=1, update_preload=trace + *locktype=2, update_preload=trace + *local_specified=0, mname=trace, msg=Tagging ) + *mwhere=(null), mfile=(null), shorten=0, + *-> Forking server: ${CVS_SERVER} server + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/taginfo, trace, ALL) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace/subdir) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, (null)) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.\*, (null)) +S -> check_fileproc ( ${CVSROOT_DIRNAME}/trace, trace/file1, ${CVSROOT_DIRNAME}/trace/file1,v ) +S -> check_fileproc ( ${CVSROOT_DIRNAME}/trace, trace/file2, ${CVSROOT_DIRNAME}/trace/file2,v ) +S -> do_cvs_command (rtag) +S -> do_module (trace, Tagging, NULL, branch2) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace/subdir) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) +S -> rcs_cleanup() +S -> readers_exist (${CVSROOT_DIRNAME}/trace) +S -> readers_exist (${CVSROOT_DIRNAME}/trace/subdir) +S -> remove_locks() +S -> remove_locks() +S -> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) +S -> rename(${CVSROOT_DIRNAME}/trace/,file2,,${CVSROOT_DIRNAME}/trace/file2,v) +S -> rtag_proc ( argc=1, argv=${PFMT}, xwhere=(null), +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> tag_check_valid ( name=bp, argc=0, argv=${PFMT}, local=0, +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${SPROG} rtag: Tagging trace +${SPROG} rtag: Tagging trace/subdir" + + dotest_sort trace-12 "${testcvs} -t -t -t status file1" \ +" + + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *locktype=1, update_preload=(null) + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/trace/file1,v + Sticky Date: (none) + Sticky Options: (none) + Sticky Tag: (none) + Working revision: 1\.1\.1\.1 ${DATE} + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> do_recursion ( frame=${PFMT} ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +=================================================================== +File: file1 *Status: Up-to-date" \ +" + + + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/trace/file1,v + Sticky Date: (none) + Sticky Options: (none) + Sticky Tag: (none) + Working revision: 1\.1\.1\.1 + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +=================================================================== +File: file1 *Status: Up-to-date +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (status) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> remove_locks() +S -> remove_locks() +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} )" + + echo foo >> file1 + dotest_sort trace-13 "${testcvs} -t -t -t up -C file1" \ +" *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=(null) ) + *local=0, which=3, aflag=0, + *locktype=1, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, , , (function)) + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, , , file1) + *-> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, (null), , file1 ) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Register(file1, 1\.1\.1\.1, ${DATE}, , ) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> chmod(file1,[0-7][0-7]*) + *-> copy(file1,\.#file1\.1\.1\.1\.1) + *-> do_recursion ( frame=${PFMT} ) + *-> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> rename(file1,CVS/,,file1) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) + *-> unlink_file_dir(CVS/,,file1) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +(Locally modified file1 moved to \.#file1\.1\.1\.1\.1) +U file1" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=3, aflag=0, + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Register(file1, 1\.1\.1\.1, ${DATE}, , ) + *-> copy(file1,\.#file1\.1\.1\.1\.1) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(\.new\.file1,file1) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +(Locally modified file1 moved to \.#file1\.1\.1\.1\.1) +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, , , (function)) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Register(file1, 1\.1\.1\.1, M, , ) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (update) +S -> do_recursion ( frame=${PFMT} ) +S -> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> remove_locks() +S -> remove_locks() +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> server_register(file1, 1\.1\.1\.1, M, , , , ) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +U file1" + echo foo >> file1 + dotest_sort trace-14 "${testcvs} -t -t -t ci -madd-data file1" \ +" *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=2, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/commitinfo, trace, ALL) + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) + *-> Promotable_Lock () + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, , , , (function)) + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1, , -ko, ${tempname}) + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, , , (function)) + *-> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file1,v, (null), (null), , file1 ) + *-> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, (null), , file1 ) + *-> Register(file1, 1\.2, ${DATE}, , ) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_tree_promotably (1, argv, 0, 1, 0) + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_lock(${CVSROOT_DIRNAME}/trace) + *-> rcs_cleanup() + *-> readers_exist (${CVSROOT_DIRNAME}/trace) + *-> remove_locks() + *-> remove_locks() + *-> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 0) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(${tempname}) + *-> unlink_file(${tempname}) + *-> unlink_file(CVS/Base/file1) + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${CVSROOT_DIRNAME}/trace/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=2, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Register(file1, 1\.2, ${DATE}, , ) + *-> Sending file \`file1' to server + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Base/file1) + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${CVSROOT_DIRNAME}/trace/file1,v <-- file1 +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/commitinfo, trace, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) +S -> Promotable_Lock () +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, , , , (function)) +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1, , -ko, ${tempname}) +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, , , (function)) +S -> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file1,v, (null), (null), , file1 ) +S -> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, (null), , file1 ) +S -> Register(file1, 1\.2, ${DATE}, , ) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (commit) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_tree_promotably (1, argv, 0, 1, 0) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_lock(${CVSROOT_DIRNAME}/trace) +S -> rcs_cleanup() +S -> readers_exist (${CVSROOT_DIRNAME}/trace) +S -> remove_locks() +S -> remove_locks() +S -> remove_locks() +S -> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> server_pathname_check (file1) +S -> server_pathname_check (file1) +S -> server_register(file1, 1\.2, ${DATE}, , , , ) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 0) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(${tempname}) +S -> unlink_file(${tempname}) +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +new revision: 1\.2; previous revision: 1\.1" + + dotest_fail_sort trace-15 "${testcvs} -t -t -t diff -r1.1 file1" \ +" *aflag=0, repository= ) + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=(null) ) + *local=0, which=7, aflag=0, + *locktype=1, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1, , , ${tempname}) + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , , (function)) + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , , ${tempname}) + *-> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file1,v, 1\.1, 1\.2, , file1 ) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> diff_file_nodiff (file1, 3) + *-> do_recursion ( frame=${PFMT} ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> tag_check_valid ( name=1\.1, argc=1, argv=${PFMT}, local=0, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +0a1 +=================================================================== +> foo +Index: file1 +RCS file: ${CVSROOT_DIRNAME}/trace/file1,v +diff -r1\.1 -r1\.2 +retrieving revision 1\.1 +retrieving revision 1\.2" \ +" + *aflag=0, repository= ) + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=7, aflag=0, + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +0a1 +=================================================================== +> foo +Index: file1 +RCS file: ${CVSROOT_DIRNAME}/trace/file1,v +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1, , , ${tempname}) +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , , (function)) +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , , ${tempname}) +S -> RCS_cmp_file( ${CVSROOT_DIRNAME}/trace/file1,v, 1\.1, 1\.2, , file1 ) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> diff_file_nodiff (file1, 3) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (diff) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> remove_locks() +S -> remove_locks() +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> tag_check_valid ( name=1\.1, argc=1, argv=${PFMT}, local=0, +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +diff -r1\.1 -r1\.2 +retrieving revision 1\.1 +retrieving revision 1\.2" + + dotest_sort trace-16 "${testcvs} -t -t -t rdiff -rbp trace/file1" \ +" *aflag=0, repository=${CVSROOT_DIRNAME}/trace ) + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *local=0, which=6, aflag=0, + *locktype=1, update_preload=trace + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, bp, , ${tempname}) + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , , ${tempname}) + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> do_module (trace/file1, Patching, NULL, NULL) + *-> do_recursion ( frame=${PFMT} ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> patch_proc ( (null), (null), (null), 0, 0, trace/file1, Patching ) + *-> remove_locks() + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> tag_check_valid ( name=bp, argc=1, argv=${PFMT}, local=0, + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +\*\*\* 0 \*\*\*\* +\*\*\* trace/file1:1\.1\.1\.1 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +${PLUS} foo +--- 1 ---- +--- trace/file1 ${DATE} +Index: trace/file1 +diff -c trace/file1:1\.1\.1\.1 trace/file1:1\.2" \ +" + *aflag=0, repository=${CVSROOT_DIRNAME}/trace ) + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=${CVSROOT_DIRNAME}/trace ) + *local=0, which=6, aflag=0, + *locktype=1, update_preload=trace + *-> Forking server: ${CVS_SERVER} server + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +\*\*\* 0 \*\*\*\* +\*\*\* trace/file1:1\.1\.1\.1 ${DATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +${PLUS} foo +--- 1 ---- +--- trace/file1 ${DATE} +Index: trace/file1 +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.1\.1\.1, bp, , ${tempname}) +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , , ${tempname}) +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> do_cvs_command (rdiff) +S -> do_module (trace/file1, Patching, NULL, NULL) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> patch_proc ( (null), (null), (null), 0, 0, trace/file1, Patching ) +S -> remove_locks() +S -> remove_locks() +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> tag_check_valid ( name=bp, argc=1, argv=${PFMT}, local=0, +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +diff -c trace/file1:1\.1\.1\.1 trace/file1:1\.2" + + dotest_sort trace-17 "${testcvs} -t -t -t rm -f file1" \ +" *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *locktype=1, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Reader_Lock(${CVSROOT_DIRNAME}/trace) + *-> Register(file1, -1\.2, ${DATE}, , ) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> do_recursion ( frame=${PFMT} ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_simple_remove() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${SPROG} remove: scheduling \`file1' for removal +${SPROG} remove: use \`${SPROG} commit' to remove this file permanently" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=1, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Register(file1, -1\.2, dummy timestamp, , ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Reader_Lock(${CVSROOT_DIRNAME}/trace) +S -> Register(file1, -1\.2, , , ) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (remove) +S -> do_recursion ( frame=${PFMT} ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_simple_remove() +S -> remove_locks() +S -> remove_locks() +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> server_register(file1, -1\.2, , , , , ) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(CVS/Entries\.Log) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${SPROG} remove: scheduling \`file1' for removal +${SPROG} remove: use \`${SPROG} commit' to remove this file permanently" + + dotest_sort trace-18 "${testcvs} -t -t -t ci -mremove file1" \ +" *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=2, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Lock_Cleanup() + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/commitinfo, trace, ALL) + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) + *-> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) + *-> Promotable_Lock () + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, , , , file1) + *-> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , -ko, ${tempname}) + *-> Scratch_Entry(file1) + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, #cvs.rfl\.${hostname}\.[0-9][0-9]*) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_tree_promotably (1, argv, 0, 1, 0) + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_lock(${CVSROOT_DIRNAME}/trace) + *-> rcs_cleanup() + *-> readers_exist (${CVSROOT_DIRNAME}/trace) + *-> remove_locks() + *-> remove_locks() + *-> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) + *-> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) + *-> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 0) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(${tempname}) + *-> unlink_file(${tempname}) + *-> unlink_file(CVS/Entries\.Log) + *-> unlink_file(file1) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${CVSROOT_DIRNAME}/trace/file1,v <-- file1 +new revision: delete; previous revision: 1\.2" \ +" + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *dosrcs=1, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=2, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Scratch_Entry(file1) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> rename(CVS/Entries\.Backup,CVS/Entries) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file(CVS/Entries\.Log) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +${CVSROOT_DIRNAME}/trace/file1,v <-- file1 +S -> CVS_SERVER_SLEEP not set\. +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Leaving do_recursion ( frame=${PFMT} ) +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/commitinfo, trace, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/loginfo, trace, ALL) +S -> Parse_Info (${CVSROOT_DIRNAME}/CVSROOT/verifymsg, trace, not ALL) +S -> Promotable_Lock () +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, , , , file1) +S -> RCS_checkout (${CVSROOT_DIRNAME}/trace/file1,v, 1\.2, , -ko, ${tempname}) +S -> Scratch_Entry(file1) +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs.pfl\.${hostname}\.[0-9][0-9]*) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs.pfl\.${hostname}\.[0-9][0-9]*) +S -> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, #cvs.rfl\.${hostname}\.[0-9][0-9]*) +S -> dirswitch (\., ${CVSROOT_DIRNAME}/trace) +S -> do_cvs_command (commit) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> do_recursion ( frame=${PFMT} ) +S -> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) +S -> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_name (${CVSROOT_DIRNAME}/trace, ) +S -> lock_simple_remove() +S -> lock_simple_remove() +S -> lock_tree_promotably (1, argv, 0, 1, 0) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_exists (${CVSROOT_DIRNAME}/trace) +S -> promotable_lock(${CVSROOT_DIRNAME}/trace) +S -> rcs_cleanup() +S -> readers_exist (${CVSROOT_DIRNAME}/trace) +S -> remove_locks() +S -> remove_locks() +S -> remove_locks() +S -> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) +S -> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) +S -> rename(${CVSROOT_DIRNAME}/trace/,file1,,${CVSROOT_DIRNAME}/trace/file1,v) +S -> rename(CVS/Entries\.Backup,CVS/Entries) +S -> serve_directory (\.) +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_pathname_check (file1) +S -> server_pathname_check (file1) +S -> server_pathname_check (file1) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 0) +S -> set_lock (${CVSROOT_DIRNAME}/trace, 1) +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> unlink_file(${tempname}) +S -> unlink_file(${tempname}) +S -> unlink_file(CVS/Entries\.Log) +S -> unlink_file(file1) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +done +new revision: delete; previous revision: 1\.2" + + # SGI IRIX seems to have problems with the stdout and stderr + # mix for this test, so separate them. + dotest_sort trace-19 "${testcvs} -t -t -t history file1 2>stderr19" \ +"O ${ISODATE} ${username} trace =trace= ${TESTDIR}/trace/\*" \ +"O ${ISODATE} ${username} trace =trace= <remote>/\*" + dotest_sort trace-19stderr "sort < stderr19" \ +" *-> Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> remove_locks() + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} )" \ +" + *-> Forking server: ${CVS_SERVER} server + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +S -> CVS_SERVER_SLEEP not set\. +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> do_cvs_command (history) +S -> remove_locks() +S -> remove_locks() +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify()" + rm stderr19 + + cd .. + dotest_sort \ +trace-20 "echo yes | ${testcvs} -t -t -t release -d trace" \ +" *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *locktype=2, update_preload=(null) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Lock_Cleanup() + *-> Lock_Cleanup() + *-> Promotable_Lock () + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> Simple_Lock_Cleanup() + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.\*, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.\*, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> _lock_exists (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.\*, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace) + *-> lock_dir_for_write (${CVSROOT_DIRNAME}/trace/subdir) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.lock) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.pfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.rfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, #cvs\.wfl\.${hostname}\.[0-9][0-9]*) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_name (${CVSROOT_DIRNAME}/trace/subdir, ) + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_simple_remove() + *-> lock_tree_promotably (0, argv, 0, 1, 0) + *-> main loop with CVSROOT=${CVSROOT_DIRNAME} + *-> parse_cvsroot ( ${CVSROOT_DIRNAME} ) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) + *-> promotable_exists (${CVSROOT_DIRNAME}/trace/subdir) + *-> promotable_lock(${CVSROOT_DIRNAME}/trace) + *-> promotable_lock(${CVSROOT_DIRNAME}/trace/subdir) + *-> readers_exist (${CVSROOT_DIRNAME}/trace) + *-> readers_exist (${CVSROOT_DIRNAME}/trace/subdir) + *-> remove_locks() + *-> remove_locks() + *-> run_popen(${testcvs} -n -q -d ${CVSROOT_DIRNAME} update,r) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 0) + *-> set_lock (${CVSROOT_DIRNAME}/trace, 1) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 0) + *-> set_lock (${CVSROOT_DIRNAME}/trace/subdir, 1) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file_dir(trace) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +Are you sure you want to release (and delete) directory \`trace': *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +You have \[0\] altered files in this repository\." \ +" + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *callerdat=${PFMT}, argc=0, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, + *dosrcs=0, repository_in=(null) ) + *dosrcs=0, repository_in=(null) ) + *local=0, which=1, aflag=0, + *local=0, which=1, aflag=0, + *locktype=0, update_preload=(null) + *locktype=0, update_preload=(null) + *-> Forking server: ${CVS_SERVER} server + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> Leaving do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> do_recursion ( frame=${PFMT} ) + *-> main loop with CVSROOT=${CVSROOT} + *-> parse_cvsroot ( ${CVSROOT} ) + *-> run_popen(${testcvs} -n -q -d ${CVSROOT} update,r) + *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, + *-> unlink_file_dir(trace) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +Are you sure you want to release (and delete) directory \`trace': *-> start_recursion ( fileproc=${PFMT}, filesdoneproc=${PFMT}, +S -> CVS_SERVER_SLEEP not set\. +S -> Lock_Cleanup() +S -> Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> Simple_Lock_Cleanup() +S -> do_cvs_command (release) +S -> fopen(${CVSROOT_DIRNAME}/CVSROOT/history,a) +S -> remove_locks() +S -> remove_locks() +S -> server_cleanup() +S -> server_cleanup() +S -> server_notify() +S -> server_notify() +S -> server_notify() +You have \[0\] altered files in this repository\." + + dokeep + cd .. + rm -fr trace + modify_repo rm -fr $CVSROOT_DIRNAME/trace + ;; + + + + *) + echo $what is not the name of a test -- ignored + ;; + esac + + # Sanity check sanity.sh. :) + # + # Test our exit directory so that tests that exit in an incorrect directory + # are noticed during single test runs. + # + # FIXME? + # Sparc Solaris 9 is dereferencing paths here as if /bin/pwd were + # called when /tmp is a symlink. This might be a new problem with this + # test, but since this was recently tested I think it more likely to be + # A Solaris issue. + if test "x$TESTDIR" != "x`pwd`"; then + fail "cleanup: PWD != TESTDIR (\``pwd`' != \`$TESTDIR')" + fi + + # Test that the last test didn't overwrite any write proxy configuration + # which may be in place. + if $proxy; then + problem=false + for file in \ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT/config \ + $CVSROOT_DIRNAME/CVSROOT/config \ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT/loginfo \ + $CVSROOT_DIRNAME/CVSROOT/loginfo \ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT/postadmin \ + $CVSROOT_DIRNAME/CVSROOT/postadmin \ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT/posttag \ + $CVSROOT_DIRNAME/CVSROOT/posttag \ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT/postwatch \ + $CVSROOT_DIRNAME/CVSROOT/postwatch; do + if cmp $file $TESTDIR/`basename $file`-clean >/dev/null 2>&1; then + :; + else + echo "\`$file' and \`$TESTDIR/`basename $file`-clean' differ." \ + >>$LOGFILE + problem=: + fi + done + if $problem; then + fail "cleanup: write proxy configuration not preserved" + fi + fi + + if $remote && test "$servercvs_orig" != "$servercvs" >/dev/null 2>&1; then + fail "test slagged \$servercvs" + fi + + # Reset val-tags to a pristine state. + if test -s $CVSROOT_DIRNAME/CVSROOT/val-tags; then + modify_repo ":" > $CVSROOT_DIRNAME/CVSROOT/val-tags + fi + verify_tmp_empty "post $what" + +done # The big loop + +# Set up summary data for output. +skippedoutput= +warningsoutput= +extendedinfo= +if test $skipped -ne 0; then + skippedoutput="$skipped test group" + if test $skipped -ne 1; then + skippedoutput="${skippedoutput}s" + fi + skippedoutput="$skippedoutput skipped" +fi +if test $warnings -ne 0; then + warningsoutput="$warnings test" + if test $warnings -ne 1; then + warningsoutput="${warningsoutput}s" + fi + warningsoutput="$warningsoutput passed with warnings" +fi +if test -n "$skippedoutput" || test -n "$warningsoutput"; then + extendedinfo=" (" + if test -n "$skippedoutput"; then + extendedinfo="$extendedinfo$skippedoutput" + fi + if test -n "$skippedoutput" && test -n "$warningsoutput"; then + extendedinfo="$extendedinfo and " + fi + if test -n "$warningsoutput"; then + extendedinfo="$extendedinfo$warningsoutput" + fi + extendedinfo="$extendedinfo)" +fi + +echo "OK, all $passed tests passed$extendedinfo." + +# TODO: +# * Test `cvs update -d foo' (where foo does not exist). +# * Test `cvs update foo bar' (where foo and bar are both from the +# same directory in the repository). Suppose one is a branch--make +# sure that both directories get updated with the respective correct +# thing. +# * `cvs update ../foo'. Also ../../foo ./../foo foo/../../bar /foo/bar +# foo/.././../bar foo/../bar etc. +# * Test all flags in modules file. +# Test that ciprog gets run both on checkin in that directory, or a +# higher-level checkin which recurses into it. +# * Test operations on a directory that contains other directories but has +# no files of its own. +# * -t global option +# * cvs rm followed by cvs add or vice versa (with no checkin in between). +# * cvs rm twice (should be a nice error message). +# * -P option to checkout--(a) refrains from checking out new empty dirs, +# (b) prunes empty dirs already there. +# * Test that cvs -d `hostname`:${TESTDIR}/non/existent co foo +# gives an appropriate error (e.g. +# Cannot access ${TESTDIR}/non-existent/CVSROOT +# No such file or directory). +# (like basica-9, but for remote). +# * Test ability to send notifications in response to watches. (currently +# hard to test because CVS doesn't send notifications if username is the +# same). +# * Test the contents of adm files other than Root and Repository. +# Entries seems the next most important thing. +# * Test the following compatibility issues: +# - The filler fields in "D" entries in CVS/Entries get preserved +# (per cvs.texinfo). +# - Unrecognized entry types in CVS/Entries get ignored (looks like +# this needs to be documented in cvs.texinfo, but is not) +# - Test that unrecognized files in CVS directories (e.g. CVS/Foobar) +# are ignored (per cvs.texinfo). +# - Test 'cvs history' with symlinks in the path to the working directory. +# - Remove most of the CVS_SERVER stuff after a reasonable amount of time. +# The "fork" & "client" series of tests should be left. 4/2/00, CVS +# 1.11.0.1 was altered so that it would default to program_name (set from +# argv[0]) rather than "cvs", but I'd like this script to work on legacy +# versions of CVS for awhile. +# - Testsuite doesn't work with usernames over eight characters in length. +# Fix it. +# End of TODO list. + +# Exit if keep set +dokeep + +# Remove the test directory, but first change out of it. +if $TIMING; then + echo "exiting without removing test dir in order to preserve timing information." +else + cd `dirname $TESTDIR` + rm -rf $TESTDIR +fi + +# end of sanity.sh |