summaryrefslogtreecommitdiff
path: root/src/sanity.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/sanity.sh')
-rwxr-xr-xsrc/sanity.sh35660
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