"Fossies" - the Fresh Open Source Software Archive

Member "cvs-1.11.23/src/sanity.sh" (7 May 2008, 968602 Bytes) of package /linux/misc/old/cvs-1.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bash source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 #! /bin/sh
    2 :
    3 #   sanity.sh -- a growing testsuite for cvs.
    4 #
    5 # The copyright notice said: "Copyright (C) 1992, 1993 Cygnus Support"
    6 # I'm not adding new copyright notices for new years as our recent 
    7 # practice has been to include copying terms without copyright notices.
    8 #
    9 # This program is free software; you can redistribute it and/or modify
   10 # it under the terms of the GNU General Public License as published by
   11 # the Free Software Foundation; either version 2, or (at your option)
   12 # any later version.
   13 #
   14 # This program is distributed in the hope that it will be useful,
   15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17 # GNU General Public License for more details.
   18 #
   19 # Original Author: K. Richard Pixley
   20 
   21 # usage:
   22 usage ()
   23 {
   24     echo "Usage: `basename $0` --help"
   25     echo "Usage: `basename $0` [-eklrv] [-f FROM-TEST] [-h HOSTNAME] CVS-TO-TEST [TESTS-TO-RUN...]"
   26 }
   27 
   28 exit_usage ()
   29 {
   30     usage 1>&2
   31     exit 2
   32 }
   33 
   34 exit_help ()
   35 {
   36     usage
   37     echo
   38     echo "-H|--help     Display this text."
   39     echo "-e|--skipfail Treat tests that would otherwise be nonfatally skipped"
   40     echo "              for reasons like missing tools as failures, exiting"
   41     echo "              with an error message.  Also treat warnings as"
   42     echo "              failures."
   43     echo "-f FROM-TEST  Run TESTS-TO-RUN, skipping all tests in the list before"
   44     echo "              FROM-TEST."
   45     echo "-h HOSTNAME   Use :ext:HOSTNAME to run remote tests rather than"
   46     echo "              :fork:.  Implies --remote and assumes that \$TESTDIR"
   47     echo "              resolves to the same directory on both the client and"
   48     echo "              the server."
   49     echo "-k|--keep     Try to keep directories created by individual tests"
   50     echo "              around, exiting after the first test which supports"
   51     echo "              --keep."
   52     echo "-l|--link-root"
   53     echo "              Test CVS using a symlink to a real CVSROOT."
   54     echo "-r|--remote   Test remote instead of local cvs."
   55     echo "-v|--verbose  List test names as they are executed."
   56     echo
   57     echo "CVS-TO-TEST   The path to the CVS executable to be tested."
   58     echo "TESTS-TO-RUN  The names of the tests to run (defaults to all tests)."
   59     exit 2
   60 }
   61 
   62 # See TODO list at end of file.
   63 
   64 # required to make this script work properly.
   65 unset CVSREAD
   66 
   67 # This will cause malloc to run slower but should also catch some common errors
   68 # when CVS is linked with glibc 2.x.
   69 MALLOC_CHECK_=2; export MALLOC_CHECK_
   70 
   71 # We want to invoke a predictable set of i18n behaviors, not whatever
   72 # the user running this script might have set.
   73 # In particular:
   74 #   'sort' and tabs and spaces (LC_COLLATE).
   75 #   Messages from getopt (LC_MESSAGES) (in the future, CVS itself might 
   76 #     also alter its messages based on LC_MESSAGES).
   77 LANG=C
   78 export LANG
   79 LC_ALL=C
   80 export LC_ALL
   81 
   82 
   83 #
   84 # Initialize the test counts.
   85 #
   86 passed=0
   87 skipped=0
   88 warnings=0
   89 
   90 
   91 
   92 #
   93 # read our options
   94 #
   95 unset fromtest
   96 unset remotehost
   97 keep=false
   98 linkroot=false
   99 remote=false
  100 skipfail=false
  101 verbose=false
  102 while getopts ef:h:Hklrv-: option ; do
  103     # convert the long opts to short opts
  104     if test x$option = x-;  then
  105     case "$OPTARG" in
  106         [hH]|[hH][eE]|[hH][eE][lL]|[hH][eE][lL][pP])
  107         option=H;
  108         OPTARG=
  109         ;;
  110         [kK]|[kK][eE]|[kK][eE][eE]|[kK][eE][eE][pP])
  111         option=k;
  112         OPTARG=
  113         ;;
  114         l|li|lin|link|link-|link-r]|link-ro|link-roo|link-root)
  115         option=l;
  116         OPTARG=
  117         ;;
  118         [rR]|[rR][eE]|[rR][eE][mM]|[rR][eE][mM][oO]|[rR][eE][mM][oO][tT]|[rR][eE][mM][oO][tT][eE])
  119         option=k;
  120         OPTARG=
  121         ;;
  122         s|sk|ski|skip|skipf|skipfa|skipfai|skipfail)
  123         option=e
  124         OPTARG=
  125         ;;
  126         v|ve|ver|verb|verbo|verbos|verbose)
  127         option=v
  128         OPTARG=
  129         ;;
  130         *)
  131         option=\?
  132         OPTARG=
  133     esac
  134     fi
  135     case "$option" in
  136     e)
  137         skipfail=:
  138         ;;
  139     f)
  140         fromtest="$OPTARG"
  141         ;;
  142     h)
  143         # Set a remotehost to run the remote tests on via :ext:
  144         # Implies `-r' and assumes that $TESTDIR resolves to the same
  145         # directory on the client and the server.
  146         remotehost="$OPTARG"
  147         remote=:
  148         ;;
  149     H)
  150         exit_help
  151         ;;
  152     k)
  153         # The -k (keep) option will eventually cause all the tests to
  154         # leave around the contents of the /tmp directory; right now only
  155         # some implement it.  Not originally intended to be useful with
  156         # more than one test, but this should work if each test uses a
  157         # uniquely named dir (use the name of the test).
  158         keep=:
  159         ;;
  160     l)
  161         linkroot=:
  162         ;;
  163     r)
  164         remote=:
  165         ;;
  166     v)
  167         verbose=:
  168         ;;
  169     \?)
  170         exit_usage
  171         ;;
  172     esac
  173 done
  174 
  175 # boot the arguments we used above
  176 while test $OPTIND -gt 1 ; do
  177     shift
  178     OPTIND=`expr $OPTIND - 1`
  179 done
  180 
  181 # Use full path for CVS executable, so that CVS_SERVER gets set properly
  182 # for remote.
  183 case $1 in
  184 "")
  185   exit_usage
  186   ;;
  187 /*)
  188   testcvs=$1
  189   ;;
  190 *)
  191   testcvs=`pwd`/$1
  192   ;;
  193 esac
  194 shift
  195 
  196 # If $remotehost is set, warn if $TESTDIR isn't since we are pretty sure
  197 # that its default value of `/tmp/cvs-sanity' will not resolve to the same
  198 # directory on two different machines.
  199 if test -n "$remotehost" && test -z "$TESTDIR"; then
  200     echo "WARNING: CVS server hostname is set and \$TESTDIR is not.  If" >&2
  201     echo "$remotehost is not the local machine, then it is unlikely that" >&2
  202     echo "the default value assigned to \$TESTDIR will resolve to the same" >&2
  203     echo "directory on both this client and the CVS server." >&2
  204 fi
  205 
  206 
  207 
  208 ###
  209 ### GUTS
  210 ###
  211 
  212 # "debugger"
  213 #set -x
  214 
  215 echo 'This test should produce no other output than this message, and a final "OK".'
  216 echo '(Note that the test can take an hour or more to run and periodically stops'
  217 echo 'for as long as one minute.  Do not assume there is a problem just because'
  218 echo 'nothing seems to happen for a long time.  If you cannot live without'
  219 echo 'running status, use the -v option or try the command:'
  220 echo "\`tail -f check.log' from another window.)"
  221 
  222 # Regexp to match what CVS will call itself in output that it prints.
  223 # FIXME: we don't properly quote this--if the name contains . we'll
  224 # just spuriously match a few things; if the name contains other regexp
  225 # special characters we are probably in big trouble.
  226 PROG=`basename ${testcvs}`
  227 
  228 # Match the hostname
  229 hostname="[-_.a-zA-Z0-9]*"
  230 
  231 # Regexp to match the name of a temporary file (from cvs_temp_name).
  232 # This appears in certain diff output.
  233 tempname="[-a-zA-Z0-9/.%_]*"
  234 
  235 # Regexp to match a date in RFC822 format (as amended by RFC1123).
  236 RFCDATE="[a-zA-Z0-9 ][a-zA-Z0-9 ]* [0-9:][0-9:]* -0000"
  237 RFCDATE_EPOCH="1 Jan 1970 00:00:00 -0000"
  238 
  239 # Regexp to match a date in standard Unix format as used by rdiff
  240 # FIXCVS: There's no reason for rdiff to use a different date format
  241 # than diff does
  242 DATE="[a-zA-Z]* [a-zA-Z]* [ 1-3][0-9] [0-9:]* [0-9]*"
  243 
  244 # Which directories should Which and find_tool search for executables?
  245 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
  246 
  247 # Do not assume that `type -p cmd` is portable
  248 # Usage: Which [-a] [-x|-f|-r] prog [$SEARCHPATH:/with/directories:/to/search]
  249 Which() {
  250   # Optional first argument for file type, defaults to -x.
  251   # Second argument is the file or directory to be found.
  252   # Third argument is the PATH to search.
  253   # By default, print only the first file that matches,
  254   # -a will cause all matches to be printed.
  255   notevery=:
  256   if [ "x$1" = "x-a" ]; then notevery=false; shift; fi
  257   case "$1" in
  258     -*) t=$1; shift ;;
  259     *) t=-x ;;
  260   esac
  261   case "$1" in
  262     # FIXME: Someday this may need to be fixed
  263     # to deal better with C:\some\path\to\ssh values...
  264     /*) test $t $1 && echo $1 ;;
  265     *) for d in `IFS=:; echo ${2-$SEARCHPATH}`
  266        do
  267          test $t $d/$1 && { echo $d/$1; if $notevery; then break; fi; }
  268        done
  269        ;;
  270   esac
  271 }
  272 
  273 
  274 # On cygwin32, we may not have /bin/sh.
  275 if test -r /bin/sh; then
  276   TESTSHELL="/bin/sh"
  277 else
  278   TESTSHELL=`Which -f sh`
  279   if test ! -r "$TESTSHELL"; then
  280     TESTSHELL="/bin/sh"
  281   fi
  282 fi
  283 
  284 # FIXME: try things (what things? checkins?) without -m.
  285 #
  286 # Some of these tests are written to expect -Q.  But testing with
  287 # -Q is kind of bogus, it is not the way users actually use CVS (usually).
  288 # So new tests probably should invoke ${testcvs} directly, rather than ${CVS}.
  289 # and then they've obviously got to do something with the output....
  290 #
  291 CVS="${testcvs} -Q"
  292 
  293 LOGFILE=`pwd`/check.log
  294 
  295 # Save the previous log in case the person running the tests decides
  296 # they want to look at it.  The extension ".plog" is chosen for consistency
  297 # with dejagnu.
  298 if test -f check.log; then
  299     mv check.log check.plog
  300 fi
  301 
  302 # Create the log file so check.log can be tailed almost immediately after
  303 # this script is started.  Otherwise it can take up to a minute or two before
  304 # the log file gets created when $remotehost is specified on some systems,
  305 # which makes for a lot of failed `tail -f' attempts.
  306 touch check.log
  307 
  308 # Workaround any X11Forwarding by ssh. Otherwise this text:
  309 #   Warning: No xauth data; using fake authentication data for X11 forwarding.
  310 # has been known to end up in the test results below
  311 # causing the test to fail.
  312 [ -n "$DISPLAY" ] && unset DISPLAY
  313   
  314 # The default value of /tmp/cvs-sanity for TESTDIR is dubious,
  315 # because it loses if two people/scripts try to run the tests
  316 # at the same time.  Some possible solutions:
  317 # 1.  Use /tmp/cvs-test$$.  One disadvantage is that the old
  318 #     cvs-test* directories would pile up, because they wouldn't
  319 #     necessarily get removed.
  320 # 2.  Have everyone/everything running the testsuite set
  321 #     TESTDIR to some appropriate directory.
  322 # 3.  Have the default value of TESTDIR be some variation of
  323 #     `pwd`/cvs-sanity.  The biggest problem here is that we have
  324 #     been fairly careful to test that CVS prints in messages the
  325 #     actual pathnames that we pass to it, rather than a different
  326 #     pathname for the same directory, as may come out of `pwd`.
  327 #     So this would be lost if everything was `pwd`-based.  I suppose
  328 #     if we wanted to get baroque we could start making symlinks
  329 #     to ensure the two are different.
  330 : ${CVS_RSH=rsh}; export CVS_RSH
  331 if test -n "$remotehost"; then
  332         # We need to set $tmp on the server since $TMPDIR is compared against
  333     # messages generated by the server.
  334     tmp=`$CVS_RSH $remotehost 'cd /tmp; /bin/pwd || pwd' 2>/dev/null`
  335     if test $? != 0; then
  336         echo "$CVS_RSH $remotehost failed." >&2
  337         exit 1
  338     fi
  339 else
  340     tmp=`(cd /tmp; /bin/pwd || pwd) 2>/dev/null`
  341 fi
  342 
  343 # Now:
  344 #   1) Set TESTDIR if it's not set already
  345 #   2) Remove any old test remnants
  346 #   3) Create $TESTDIR
  347 #   4) Normalize TESTDIR with `cd && (/bin/pwd || pwd)`
  348 #      (This will match CVS output later)
  349 : ${TESTDIR=$tmp/cvs-sanity}
  350 # clean any old remnants (we need the chmod because some tests make
  351 # directories read-only)
  352 if test -d ${TESTDIR}; then
  353     chmod -R a+wx ${TESTDIR}
  354     rm -rf ${TESTDIR}
  355 fi
  356 # These exits are important.  The first time I tried this, if the `mkdir && cd`
  357 # failed then the build directory would get blown away.  Some people probably
  358 # wouldn't appreciate that.
  359 mkdir ${TESTDIR} || exit 1
  360 cd ${TESTDIR} || exit 1
  361 # Ensure $TESTDIR is absolute
  362 if echo "${TESTDIR}" |grep '^[^/]'; then
  363     # Don't resolve this unless we have to.  This keeps symlinks intact.  This
  364     # is important at least when testing using -h $remotehost, because the same
  365     # value for $TESTDIR must resolve to the same directory on the client and
  366     # the server and we likely used Samba, and possibly symlinks, to do this.
  367     TESTDIR=`(/bin/pwd || pwd) 2>/dev/null`
  368 fi
  369 
  370 if test -z "${TESTDIR}" || echo "${TESTDIR}" |grep '^[^/]'; then
  371     echo "Unable to resolve TESTDIR to an absolute directory." >&2
  372     exit 1
  373 fi
  374 cd ${TESTDIR}
  375 
  376 # Now set $TMPDIR if the user hasn't overridden it.
  377 #
  378 # We use a $TMPDIR under $TESTDIR by default so that two tests may be run at
  379 # the same time without bumping heads without requiring the user to specify
  380 # more than $TESTDIR.  See the test for leftover cvs-serv* directories near the
  381 # end of this script at the end of "The big loop".
  382 : ${TMPDIR=$TESTDIR/tmp}
  383 export TMPDIR
  384 if test -d $TMPDIR; then :; else
  385     mkdir $TMPDIR
  386 fi
  387 
  388 # Make sure various tools work the way we expect, or try to find
  389 # versions that do.
  390 : ${AWK=awk}
  391 : ${EXPR=expr}
  392 : ${ID=id}
  393 : ${TR=tr}
  394 
  395 # Keep track of tools that are found, but do NOT work as we hope
  396 # in order to avoid them in future
  397 badtools=
  398 set_bad_tool ()
  399 {
  400    badtools=$badtools:$1
  401 }
  402 is_bad_tool ()
  403 {
  404    case ":$badtools:" in *:$1:*) return 0 ;; *) return 1 ; esac
  405 }
  406 
  407 version_test ()
  408 {
  409   vercmd=$1
  410   verbad=:
  411   if RES=`$vercmd --version </dev/null 2>&1`; then
  412     if test "X$RES" != "X--version" && test "X$RES" != "X" ; then
  413       echo "$RES"
  414       verbad=false
  415     fi
  416   fi
  417   if $verbad; then
  418     echo "The command \`$vercmd' does not support the --version option."
  419   fi
  420   # It does not really matter that --version is not supported
  421   return 0
  422 }
  423 
  424 # Try to find a tool that satisfies all of the tests.
  425 # Usage: list:of:colon:separated:alternatives test1 test2 test3 test4...
  426 # Example: find_tool awk:gawk:nawk awk_tooltest1 awk_tooltest2
  427 find_tool ()
  428 {
  429   default_TOOL=$1
  430   echo find_tool: ${1+"$@"} >>$LOGFILE
  431   cmds="`IFS=:; echo $1`"; shift; tooltests="${1+$@}"
  432   if test -z "$tooltests"; then tooltests=version_test; fi
  433   clist=; for cmd in $cmds; do clist="$clist `Which -a $cmd`"; done
  434   # Make sure the default tool is just the first real command name
  435   for default_TOOL in $clist `IFS=:; echo $default_TOOL`; do break; done
  436   TOOL=""
  437   for trytool in $clist ; do
  438     pass=:
  439     for tooltest in $tooltests; do
  440       result=`eval $tooltest $trytool`
  441       rc=$?
  442       echo "Running $tooltest $trytool" >>$LOGFILE
  443       if test -n "$result"; then
  444     echo "$result" >>$LOGFILE
  445       fi
  446       if test "$rc" = "0"; then
  447         echo "PASS: $tooltest $trytool" >>$LOGFILE
  448       elif test "$rc" = "77"; then
  449         echo "MARGINAL: $tooltest $trytool; rc=$rc" >>$LOGFILE
  450         TOOL=$trytool
  451     pass=false
  452       else
  453         set_bad_tool $trytool
  454         echo "FAIL: $tooltest $trytool; rc=$rc" >>$LOGFILE
  455     pass=false
  456       fi
  457     done
  458     if $pass; then
  459       echo $trytool
  460       return 0
  461     fi
  462   done
  463   if test -n "$TOOL"; then
  464     echo "Notice: The default version of \`$default_TOOL' is defective." >>$LOGFILE
  465     echo "using \`$TOOL' and hoping for the best." >>$LOGFILE
  466     echo "Notice: The default version of \`$default_TOOL' is defective." >&2
  467     echo "using \`$TOOL' and hoping for the best." >&2
  468     echo $TOOL
  469   else
  470     echo $default_TOOL
  471   fi
  472 }  
  473 
  474 id_tool_test ()
  475 {
  476   id=$1
  477   if $id -u >/dev/null 2>&1 && $id -un >/dev/null 2>&1; then
  478     return 0
  479   else
  480     echo "Running these tests requires an \`id' program that understands the"
  481     echo "-u and -n flags.  Make sure that such an id (GNU, or many but not"
  482     echo "all vendor-supplied versions) is in your path."
  483     return 1
  484   fi
  485 }
  486 
  487 ID=`find_tool id version_test id_tool_test`
  488 echo "Using ID=$ID" >>$LOGFILE
  489 
  490 # You can't run CVS as root; print a nice error message here instead
  491 # of somewhere later, after making a mess.
  492 for pass in false :; do
  493   case "`$ID -u 2>/dev/null`" in
  494     "0")
  495       echo "Test suite does not work correctly when run as root" >&2
  496       exit 1
  497       ;;
  498 
  499     *)
  500       break
  501       ;;
  502   esac
  503 done
  504 
  505 # Cause NextStep 3.3 users to lose in a more graceful fashion.
  506 expr_tooltest1 ()
  507 {
  508 expr=$1
  509 if $expr 'abc
  510 def' : 'abc
  511 def' >/dev/null; then
  512   # good, it works
  513   return 0
  514 else
  515   echo 'Running these tests requires an "expr" program that can handle'
  516   echo 'multi-line patterns.  Make sure that such an expr (GNU, or many but'
  517   echo 'not all vendor-supplied versions) is in your path.'
  518   return 1
  519 fi
  520 }
  521 
  522 # Warn SunOS, SysVr3.2, etc., users that they may be partially losing
  523 # if we can't find a GNU expr to ease their troubles...
  524 expr_tooltest2 ()
  525 {
  526 expr=$1
  527 if $expr 'a
  528 b' : 'a
  529 c' >/dev/null; then
  530   echo 'WARNING: you are using a version of expr that does not correctly'
  531   echo 'match multi-line patterns.  Some tests may spuriously pass or fail.'
  532   echo 'You may wish to make sure GNU expr is in your path.'
  533   return 1
  534 else
  535   return 0
  536 fi
  537 }
  538 
  539 expr_create_bar ()
  540 {
  541 echo 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >${TESTDIR}/foo
  542 cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar
  543 cat ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar >${TESTDIR}/foo
  544 cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar
  545 rm -f ${TESTDIR}/foo
  546 }
  547 
  548 expr_tooltest3 ()
  549 {
  550 expr=$1
  551 # More SunOS lossage...
  552 test ! -f ${TESTDIR}/bar && expr_create_bar
  553 if $expr "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then
  554   : good, it works
  555 else
  556   echo 'WARNING: you are using a version of expr that does not correctly'
  557   echo 'match large patterns.  Some tests may spuriously pass or fail.'
  558   echo 'You may wish to make sure GNU expr is in your path.'
  559   return 1
  560 fi
  561 if $expr "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then
  562   echo 'WARNING: you are using a version of expr that does not correctly'
  563   echo 'match large patterns.  Some tests may spuriously pass or fail.'
  564   echo 'You may wish to make sure GNU expr is in your path.'
  565   return 1
  566 fi
  567 # good, it works
  568 return 0
  569 }
  570 
  571 # That we should have to do this is total bogosity, but GNU expr
  572 # version 1.9.4-1.12 uses the emacs definition of "$" instead of the unix
  573 # (e.g. SunOS 4.1.3 expr) one.  Rumor has it this will be fixed in the
  574 # next release of GNU expr after 1.12 (but we still have to cater to the old
  575 # ones for some time because they are in many linux distributions).
  576 ENDANCHOR="$"
  577 expr_set_ENDANCHOR ()
  578 {
  579 expr=$1
  580 ENDANCHOR="$"
  581 if $expr 'abc
  582 def' : 'abc$' >/dev/null; then
  583   ENDANCHOR='\'\'
  584    echo "Notice: An ENDANCHOR of dollar does not work."
  585    echo "Using a workaround for GNU expr versions 1.9.4 thru 1.12"
  586 fi
  587 return 0
  588 }
  589 
  590 # Work around another GNU expr (version 1.10-1.12) bug/incompatibility.
  591 # "." doesn't appear to match a newline (it does with SunOS 4.1.3 expr).
  592 # Note that the workaround is not a complete equivalent of .* because
  593 # the first parenthesized expression in the regexp must match something
  594 # in order for expr to return a successful exit status.
  595 # Rumor has it this will be fixed in the
  596 # next release of GNU expr after 1.12 (but we still have to cater to the old
  597 # ones for some time because they are in many linux distributions).
  598 DOTSTAR='.*'
  599 expr_set_DOTSTAR ()
  600 {
  601 expr=$1
  602 DOTSTAR='.*'
  603 if $expr 'abc
  604 def' : "a${DOTSTAR}f" >/dev/null; then
  605   : good, it works
  606 else
  607   DOTSTAR='\(.\|
  608 \)*'
  609   echo "Notice: DOTSTAR changed from sane \`.*' value to \`$DOTSTAR\`"
  610   echo "to workaround GNU expr version 1.10 thru 1.12 bug where \`.'"
  611   echo "does not match a newline."
  612 fi
  613 return 0
  614 }
  615 
  616 # Now that we have DOTSTAR, make sure it works with big matches
  617 expr_tooltest_DOTSTAR ()
  618 {
  619 expr=$1
  620 test ! -f ${TESTDIR}/bar && expr_create_bar
  621 if $expr "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then
  622   # good, it works
  623   return 0
  624 else
  625   echo 'WARNING: you are using a version of expr that does not correctly'
  626   echo 'match large patterns.  Some tests may spuriously pass or fail.'
  627   echo 'You may wish to make sure GNU expr is in your path.'
  628   return 77
  629 fi
  630 }
  631 
  632 # FreeBSD 5.2 and 6.1 support 'expr [-e] expression' 
  633 # They get confused unless '--' is used before the expressions
  634 # when those expressions begin with a '-' character, such as the
  635 # output of an ls -l command. The EXPR_COMPAT environment variable may
  636 # be used to go back to the non-POSIX behavior as an alternative.
  637 # (GNU expr appears to accept the '--' argument and work correctly or
  638 # not have it and still get the results we want.)
  639 exprDASHDASH='false'
  640 expr_set_DASHDASH ()
  641 {
  642 expr=$1
  643 exprDASHDASH='false'
  644 # Not POSIX, but works on a lot of expr versions.
  645 if $expr "-rw-rw-r--" : "-rw-rw-r--" >/dev/null 2>&1; then
  646   # good, it works
  647   return 0
  648 else
  649   # Do things in the POSIX manner.
  650   if $expr -- "-rw-rw-r--" : "-rw-rw-r--" >/dev/null 2>&1; then
  651     exprDASHDASH=':'
  652     return 0
  653   else
  654     echo 'WARNING: Your $expr does not correctly handle'
  655     echo 'leading "-" characters in regular expressions to'
  656     echo 'be matched. You may wish to see if there is an'
  657     echo 'environment variable or other setting to allow'
  658     echo 'POSIX functionality to be enabled.'
  659     return 77
  660   fi
  661 fi
  662 }
  663 
  664 
  665 EXPR=`find_tool ${EXPR}:gexpr \
  666   version_test expr_tooltest1 expr_tooltest2 expr_tooltest3 \
  667 expr_set_ENDANCHOR expr_set_DOTSTAR expr_tooltest_DOTSTAR`
  668 
  669 # Set the ENDANCHOR and DOTSTAR for the chosen expr version.
  670 expr_set_ENDANCHOR ${EXPR} >/dev/null
  671 expr_tooltest_DOTSTAR ${EXPR} >/dev/null
  672 
  673 # Is $EXPR a POSIX or non-POSIX implementation
  674 # with regard to command-line arguments?
  675 expr_set_DASHDASH ${EXPR}
  676 $exprDASHDASH && EXPR="$EXPR --"
  677 
  678 echo "Using EXPR=$EXPR" >>$LOGFILE
  679 echo "Using ENDANCHOR=$ENDANCHOR" >>$LOGFILE
  680 echo "Using DOTSTAR=$DOTSTAR" >>$LOGFILE
  681 
  682 # Cleanup
  683 rm -f ${TESTDIR}/bar
  684 
  685 # Work around yet another GNU expr (version 1.10) bug/incompatibility.
  686 # "+" is a special character, yet for unix expr (e.g. SunOS 4.1.3)
  687 # it is not.  I doubt that POSIX allows us to use \+ and assume it means
  688 # (non-special) +, so here is another workaround
  689 # Rumor has it this will be fixed in the
  690 # next release of GNU expr after 1.12 (but we still have to cater to the old
  691 # ones for some time because they are in many linux distributions).
  692 PLUS='+'
  693 if $EXPR 'a +b' : "a ${PLUS}b" >/dev/null; then
  694   : good, it works
  695 else
  696   PLUS='\+'
  697 fi
  698 
  699 # Likewise, for ?
  700 QUESTION='?'
  701 if $EXPR 'a?b' : "a${QUESTION}b" >/dev/null; then
  702   : good, it works
  703 else
  704   QUESTION='\?'
  705 fi
  706 
  707 # Now test the username to make sure it contains only valid characters
  708 username=`$ID -un`
  709 if $EXPR "${username}" : "${username}" >/dev/null; then
  710   : good, it works
  711 else
  712   echo "Test suite does not work correctly when run by a username" >&2
  713   echo "containing regular expression meta-characters." >&2
  714   exit 1
  715 fi
  716 
  717 # Only 8 characters of $username appear in some output.
  718 if test `echo $username |wc -c` -gt 8; then
  719   username8=`echo $username |sed 's/^\(........\).*/\1/'`
  720 else
  721   username8=$username
  722 fi
  723 
  724 # Rarely, we need to match any username, not just the name of the user
  725 # running this test.
  726 #
  727 # I'm not really sure what characters should be here.  a-zA-Z obviously.
  728 # People complained when 0-9 were not allowed in usernames.  Other than that
  729 # I'm not sure.
  730 anyusername="[-a-zA-Z0-9][-a-zA-Z0-9]*"
  731 
  732 # now make sure that tr works on NULs
  733 tr_tooltest1 ()
  734 {
  735 tr=$1
  736 if $EXPR `echo "123" | $tr '2' '\0'` : "123" >/dev/null 2>&1; then
  737   echo 'Warning: you are using a version of tr which does not correctly'
  738   echo 'handle NUL bytes.  Some tests may spuriously pass or fail.'
  739   echo 'You may wish to make sure GNU tr is in your path.'
  740   return 77
  741 fi
  742 # good, it works
  743 return 0
  744 }
  745 
  746 TR=`find_tool ${TR}:gtr version_test tr_tooltest1`
  747 echo "Using TR=$TR" >>$LOGFILE
  748 
  749 # Awk testing
  750 
  751 awk_tooltest1 ()
  752 {
  753 awk=$1
  754 $awk 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' </dev/null >abc
  755 if $EXPR "`cat abc`" : \
  756 'one
  757 two
  758 three
  759 four
  760 five
  761 six'; then
  762   rm abc
  763   return 0
  764 else
  765   rm abc
  766   echo "Notice: awk BEGIN clause or printf is not be working properly."
  767   return 1
  768 fi
  769 }
  770 
  771 # Format item %c check
  772 awk_tooltest2 ()
  773 {
  774 awk=$1
  775 $awk 'BEGIN { printf "%c%c%c", 2, 3, 4 }' </dev/null \
  776   | ${TR} '\002\003\004' '123' >abc
  777 if $EXPR "`cat abc`" : "123" ; then
  778   : good, found it
  779 else
  780   echo "Notice: awk format %c string may not be working properly."
  781   rm abc
  782   return 77
  783 fi
  784 rm abc
  785 return 0
  786 }
  787 
  788 AWK=`find_tool gawk:nawk:awk version_test awk_tooltest1 awk_tooltest2`
  789 echo "Using AWK=$AWK" >>$LOGFILE
  790 
  791 # Test that $1 works as a remote shell.  If so, set $host, $CVS_RSH, &
  792 # $save_CVS_RSH to match and return 0.  Otherwise, set $skipreason and return
  793 # 77.
  794 depends_on_rsh ()
  795 {
  796   host=${remotehost-"`hostname`"}
  797   result=`$1 $host 'echo test'`
  798   rc=$?
  799   if test $? != 0 || test "x$result" != "xtest"; then
  800     skipreason="\`$1 $host' failed rc=$rc result=$result"
  801     return 77
  802   fi
  803 
  804   save_CVS_RSH=$CVS_RSH
  805   CVS_RSH=$1; export CVS_RSH
  806   return 0
  807 }
  808 
  809 # Find a usable SSH.  When a usable ssh is found, set $host, $CVS_RSH, and
  810 # $save_CVS_RSH and return 0.  Otherwise, set $skipreason and return 77.
  811 depends_on_ssh ()
  812 {
  813   case "$CVS_RSH" in
  814     *ssh*|*putty*)
  815       tryssh=`Which $CVS_RSH`
  816       if [ ! -n "$tryssh" ]; then
  817     skipreason="Unable to find CVS_RSH=$CVS_RSH executable"
  818     return 77
  819       elif [ ! -x "$tryssh" ]; then
  820     skipreason="Unable to execute $tryssh program"
  821     return 77
  822       fi
  823       ;;
  824     *)
  825       # Look in the user's PATH for "ssh"
  826       tryssh=`Which ssh`
  827       if test ! -r "$tryssh"; then
  828     skipreason="Unable to find ssh program"
  829     return 77
  830       fi
  831       ;;
  832   esac
  833 
  834   depends_on_rsh "$tryssh"
  835   return $?
  836 }
  837 
  838 pass ()
  839 {
  840   echo "PASS: $1" >>${LOGFILE}
  841   passed=`expr $passed + 1`
  842 }
  843 
  844 # Like skip(), but don't fail when $skipfail is set.
  845 skip_always ()
  846 {
  847   echo "SKIP: $1${2+ ($2)}" >>$LOGFILE
  848   skipped=`expr $skipped + 1`
  849 }
  850 
  851 skip ()
  852 {
  853   if $skipfail; then
  854     fail "$1${2+ ($2)}"
  855   else
  856     echo "SKIP: $1${2+ ($2)}" >>$LOGFILE
  857   fi
  858   skipped=`expr $skipped + 1`
  859 }
  860 
  861 warn ()
  862 {
  863   if $skipfail; then
  864     fail "$1${2+ ($2)}"
  865   else
  866     echo "WARNING: $1${2+ ($2)}" >>$LOGFILE
  867   fi
  868   warnings=`expr $warnings + 1`
  869 }
  870 
  871 # Convenience function for skipping tests run only in local mode.
  872 localonly ()
  873 {
  874   skip_always $1 "only tested in local mode"
  875 }
  876 
  877 fail ()
  878 {
  879   echo "FAIL: $1" | tee -a ${LOGFILE}
  880   echo "*** Please see the \`TESTS' and \`check.log' files for more information." >&2
  881   # This way the tester can go and see what remnants were left
  882   exit 1
  883 }
  884 
  885 verify_tmp_empty ()
  886 {
  887   # Test our temp directory for cvs-serv* directories and cvsXXXXXX temp
  888   # files.  We would like to not leave any behind.
  889   if $remote && ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
  890     # A true value means ls found files/directories with these names.
  891     # Give the server some time to finish, then retry.
  892     sleep 1
  893     if ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
  894       warn "$1" "Found cvs-serv* directories in $TMPDIR."
  895       # The above will exit if $skipfail
  896       rm -rf $TMPDIR/cvs-serv*
  897     fi
  898   fi
  899   if ls $TMPDIR/cvs?????? >/dev/null 2>&1; then
  900     # A true value means ls found files/directories with these names.
  901     warn "$1" "Found cvsXXXXXX temp files in $TMPDIR."
  902     # The above will exit if $skipfail
  903     rm -f ls $TMPDIR/cvs??????
  904   fi
  905 }
  906 
  907 # Restore changes to CVSROOT admin files.
  908 restore_adm ()
  909 {
  910     rm -rf $CVSROOT_DIRNAME/CVSROOT
  911     cp -Rp $TESTDIR/CVSROOT.save $CVSROOT_DIRNAME/CVSROOT
  912 }
  913 
  914 # See dotest and dotest_fail for explanation (this is the parts
  915 # of the implementation common to the two).
  916 dotest_internal ()
  917 {
  918   if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$3${ENDANCHOR}" >/dev/null; then
  919     # Why, I hear you ask, do we write this to the logfile
  920     # even when the test passes?  The reason is that the test
  921     # may give us the regexp which we were supposed to match,
  922     # but sometimes it may be useful to look at the exact
  923     # text which was output.  For example, suppose one wants
  924     # to grep for a particular warning, and make _sure_ that
  925     # CVS never hits it (even in cases where the tests might
  926     # match it with .*).  Or suppose one wants to see the exact
  927     # date format output in a certain case (where the test will
  928     # surely use a somewhat non-specific pattern).
  929     cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
  930     pass "$1"
  931     verify_tmp_empty "$1"
  932   # expr can't distinguish between "zero characters matched" and "no match",
  933   # so special-case it.
  934   elif test -z "$3" && test ! -s ${TESTDIR}/dotest.tmp; then
  935     pass "$1"
  936     verify_tmp_empty "$1"
  937   elif test x"$4" != x; then
  938     if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$4${ENDANCHOR}" >/dev/null; then
  939       cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
  940       pass "$1"
  941       verify_tmp_empty "$1"
  942     else
  943       echo "** expected: " >>${LOGFILE}
  944       echo "$3" >>${LOGFILE}
  945       echo "$3" > ${TESTDIR}/dotest.ex1
  946       echo "** or: " >>${LOGFILE}
  947       echo "$4" >>${LOGFILE}
  948       echo "$4" > ${TESTDIR}/dotest.ex2
  949       echo "** got: " >>${LOGFILE}
  950       cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
  951       fail "$1"
  952     fi
  953   else
  954     echo "** expected: " >>${LOGFILE}
  955     echo "$3" >>${LOGFILE}
  956     echo "$3" > ${TESTDIR}/dotest.exp
  957     echo "** got: " >>${LOGFILE}
  958     cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
  959     fail "$1"
  960   fi
  961 }
  962 
  963 dotest_all_in_one ()
  964 {
  965   if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \
  966          "`cat ${TESTDIR}/dotest.exp`" >/dev/null; then
  967     return 0
  968   fi
  969   return 1
  970 }
  971 
  972 # WARNING: this won't work with REs that match newlines....
  973 #
  974 dotest_line_by_line ()
  975 {
  976   line=1
  977   while [ $line -le `wc -l <${TESTDIR}/dotest.tmp` ] ; do
  978     if $EXPR "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" : \
  979        "`sed -n ${line}p ${TESTDIR}/dotest.exp`" >/dev/null; then
  980       :
  981     elif test -z "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" &&
  982        test -z "`sed -n ${line}p ${TESTDIR}/dotest.exp`"; then
  983       :
  984     else
  985       echo "Line $line:" >> ${LOGFILE}
  986       echo "**** expected: " >>${LOGFILE}
  987       sed -n ${line}p ${TESTDIR}/dotest.exp >>${LOGFILE}
  988       echo "**** got: " >>${LOGFILE}
  989       sed -n ${line}p ${TESTDIR}/dotest.tmp >>${LOGFILE}
  990       unset line
  991       return 1
  992     fi
  993     line=`expr $line + 1`
  994   done
  995   unset line
  996   return 0
  997 }
  998 
  999 # If you are having trouble telling which line of a multi-line
 1000 # expression is not being matched, replace calls to dotest_internal()
 1001 # with calls to this function:
 1002 #
 1003 dotest_internal_debug ()
 1004 {
 1005   if test -z "$3"; then
 1006     if test -s ${TESTDIR}/dotest.tmp; then
 1007       echo "** expected: " >>${LOGFILE}
 1008       echo "$3" >>${LOGFILE}
 1009       echo "$3" > ${TESTDIR}/dotest.exp
 1010       rm -f ${TESTDIR}/dotest.ex2
 1011       echo "** got: " >>${LOGFILE}
 1012       cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
 1013       fail "$1"
 1014     else
 1015       pass "$1"
 1016       verify_tmp_empty "$1"
 1017     fi
 1018   else
 1019     echo "$3" > ${TESTDIR}/dotest.exp
 1020     if dotest_line_by_line "$1" "$2"; then
 1021       pass "$1"
 1022       verify_tmp_empty "$1"
 1023     else
 1024       if test x"$4" != x; then
 1025     mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex1
 1026     echo "$4" > ${TESTDIR}/dotest.exp
 1027     if dotest_line_by_line "$1" "$2"; then
 1028       pass "$1"
 1029       verify_tmp_empty "$1"
 1030     else
 1031       mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex2
 1032       echo "** expected: " >>${LOGFILE}
 1033       echo "$3" >>${LOGFILE}
 1034       echo "** or: " >>${LOGFILE}
 1035       echo "$4" >>${LOGFILE}
 1036       echo "** got: " >>${LOGFILE}
 1037       cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
 1038       fail "$1"
 1039     fi
 1040       else
 1041     echo "** expected: " >>${LOGFILE}
 1042     echo "$3" >>${LOGFILE}
 1043     echo "** got: " >>${LOGFILE}
 1044     cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
 1045     fail "$1"
 1046       fi
 1047     fi
 1048   fi
 1049 }
 1050 
 1051 # Usage:
 1052 #  dotest TESTNAME COMMAND OUTPUT [OUTPUT2]
 1053 # TESTNAME is the name used in the log to identify the test.
 1054 # COMMAND is the command to run; for the test to pass, it exits with
 1055 # exitstatus zero.
 1056 # OUTPUT is a regexp which is compared against the output (stdout and
 1057 # stderr combined) from the test.  It is anchored to the start and end
 1058 # of the output, so should start or end with ".*" if that is what is desired.
 1059 # Trailing newlines are stripped from the command's actual output before
 1060 # matching against OUTPUT.
 1061 # If OUTPUT2 is specified and the output matches it, then it is also
 1062 # a pass (partial workaround for the fact that some versions of expr
 1063 # lack \|).
 1064 dotest ()
 1065 {
 1066   rm -f ${TESTDIR}/dotest.ex? 2>&1
 1067   eval "$2" >${TESTDIR}/dotest.tmp 2>&1
 1068   status=$?
 1069   if test "$status" != 0; then
 1070     cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
 1071     echo "exit status was $status" >>${LOGFILE}
 1072     fail "$1"
 1073   fi
 1074   dotest_internal "$@"
 1075 }
 1076 
 1077 # Like dotest except only 2 args and result must exactly match stdin
 1078 dotest_lit ()
 1079 {
 1080   rm -f ${TESTDIR}/dotest.ex? 2>&1
 1081   eval "$2" >${TESTDIR}/dotest.tmp 2>&1
 1082   status=$?
 1083   if test "$status" != 0; then
 1084     cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
 1085     echo "exit status was $status" >>${LOGFILE}
 1086     fail "$1"
 1087   fi
 1088   cat >${TESTDIR}/dotest.exp
 1089   if cmp ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.tmp >/dev/null 2>&1; then
 1090     pass "$1"
 1091     verify_tmp_empty "$1"
 1092   else
 1093     echo "** expected: " >>${LOGFILE}
 1094     cat ${TESTDIR}/dotest.exp >>${LOGFILE}
 1095     echo "** got: " >>${LOGFILE}
 1096     cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
 1097     fail "$1"
 1098   fi
 1099 }
 1100 
 1101 # Like dotest except exitstatus should be nonzero.
 1102 dotest_fail ()
 1103 {
 1104   rm -f ${TESTDIR}/dotest.ex? 2>&1
 1105   eval "$2" >${TESTDIR}/dotest.tmp 2>&1
 1106   status=$?
 1107   if test "$status" = 0; then
 1108     cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
 1109     echo "exit status was $status" >>${LOGFILE}
 1110     fail "$1"
 1111   fi
 1112   dotest_internal "$@"
 1113 }
 1114 
 1115 # Like dotest except output is sorted.
 1116 dotest_sort ()
 1117 {
 1118   rm -f ${TESTDIR}/dotest.ex? 2>&1
 1119   eval "$2" >${TESTDIR}/dotest.tmp1 2>&1
 1120   status=$?
 1121   if test "$status" != 0; then
 1122     cat ${TESTDIR}/dotest.tmp1 >>${LOGFILE}
 1123     echo "exit status was $status" >>${LOGFILE}
 1124     fail "$1"
 1125   fi
 1126   ${TR} '   ' ' ' < ${TESTDIR}/dotest.tmp1 | sort > ${TESTDIR}/dotest.tmp
 1127   dotest_internal "$@"
 1128 }
 1129 
 1130 # A function for fetching the timestamp of a revison of a file
 1131 getrlogdate () {
 1132     ${testcvs} -n rlog -N ${1+"$@"} |
 1133     while read token value; do
 1134     case "$token" in
 1135     date:)
 1136         echo $value | sed "s,;.*,,"
 1137         break;
 1138             ;;
 1139     esac
 1140     done
 1141 }
 1142 
 1143 # Avoid picking up any stray .cvsrc, etc., from the user running the tests
 1144 mkdir home
 1145 HOME=${TESTDIR}/home; export HOME
 1146 
 1147 # Make sure this variable is not defined to anything that would
 1148 # change the format of rcs dates.  Otherwise people using e.g.,
 1149 # RCSINIT=-zLT get lots of spurious failures.
 1150 RCSINIT=; export RCSINIT
 1151 
 1152 # Remaining arguments are the names of tests to run.
 1153 #
 1154 # The testsuite is broken up into (hopefully manageably-sized)
 1155 # independently runnable tests, so that one can quickly get a result
 1156 # from a cvs or testsuite change, and to facilitate understanding the
 1157 # tests.
 1158 
 1159 if test x"$*" = x; then
 1160     # Basic/miscellaneous functionality
 1161     tests="version basica basicb basicc basic1 deep basic2"
 1162     tests="${tests} parseroot parseroot2 files spacefiles commit-readonly"
 1163     tests="${tests} commit-add-missing"
 1164     tests="$tests add-restricted"
 1165     tests="${tests} status"
 1166     # Branching, tagging, removing, adding, multiple directories
 1167     tests="${tests} rdiff rdiff-short"
 1168     tests="${tests} rdiff2 diff diffnl death death2 death-rtag"
 1169     tests="${tests} rm-update-message rmadd rmadd2 rmadd3 resurrection"
 1170     tests="${tests} dirs dirs2 branches branches2 tagc tagf "
 1171     tests="${tests} tag-log tag-space"
 1172     tests="${tests} rcslib multibranch import importb importc import-CVS"
 1173     tests="$tests import-quirks"
 1174     tests="${tests} update-p import-after-initial branch-after-import"
 1175     tests="${tests} join join2 join3 join4 join5 join6 join7 join8 join9"
 1176     tests="${tests} join-readonly-conflict join-admin join-admin-2"
 1177     tests="${tests} join-rm"
 1178     tests="${tests} new newb conflicts conflicts2 conflicts3 conflicts4"
 1179     tests="${tests} clean"
 1180     # Checking out various places (modules, checkout -d, &c)
 1181     tests="${tests} modules modules2 modules3 modules4 modules5 modules6"
 1182     tests="${tests} modules7 mkmodules co-d"
 1183     tests="${tests} cvsadm emptydir abspath abspath2 toplevel toplevel2"
 1184         tests="${tests} rstar-toplevel trailingslashes checkout_repository"
 1185     # Log messages, error messages.
 1186     tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg opterrmsg"
 1187     # Watches, binary files, history browsing, &c.
 1188     tests="${tests} devcom devcom2 devcom3 watch4 watch5 watch6"
 1189     tests="${tests} unedit-without-baserev"
 1190     tests="${tests} ignore ignore-on-branch binfiles binfiles2 binfiles3"
 1191     tests="${tests} mcopy binwrap binwrap2"
 1192     tests="${tests} binwrap3 mwrap info taginfo config"
 1193     tests="${tests} serverpatch log log2 logopt ann ann-id"
 1194     # Repository Storage (RCS file format, CVS lock files, creating
 1195     # a repository without "cvs init", &c).
 1196     tests="${tests} crerepos crerepos-extssh rcs rcs2 rcs3 rcs4 rcs5 rcs6"
 1197     tests="$tests lockfiles backuprecover"
 1198     tests="${tests} sshstdio"
 1199     # More history browsing, &c.
 1200     tests="${tests} history"
 1201     tests="${tests} big modes modes2 modes3 stamps"
 1202     # PreservePermissions stuff: permissions, symlinks et al.
 1203     # tests="${tests} perms symlinks symlinks2 hardlinks"
 1204     # More tag and branch tests, keywords.
 1205     tests="${tests} sticky keyword keywordlog keywordname keyword2"
 1206     tests="${tests} head tagdate multibranch2 tag8k"
 1207     # "cvs admin", reserved checkouts.
 1208     tests="${tests} admin reserved"
 1209     # Nuts and bolts of diffing/merging (diff library, &c)
 1210     tests="${tests} diffmerge1 diffmerge2"
 1211     # Release of multiple directories
 1212     tests="${tests} release"
 1213     tests="${tests} recase"
 1214     # Multiple root directories and low-level protocol tests.
 1215     tests="${tests} multiroot multiroot2 multiroot3 multiroot4"
 1216     tests="$tests rmroot reposmv pserver server server2 server3"
 1217     tests="$tests client client2"
 1218     tests="${tests} dottedroot fork commit-d"
 1219 else
 1220     tests="$*"
 1221 fi
 1222 
 1223 # Now check the -f argument for validity.
 1224 if test -n "$fromtest"; then
 1225     # Don't allow spaces - they are our delimiters in tests
 1226     count=0
 1227     for sub in $fromtest; do
 1228       count=`expr $count + 1`
 1229     done
 1230     if test $count != 1; then
 1231         echo "No such test \`$fromtest'." >&2
 1232         exit 2
 1233     fi
 1234     # make sure it is in $tests
 1235     case " $tests " in
 1236         *" $fromtest "*)
 1237             ;;
 1238         *)
 1239             echo "No such test \`$fromtest'." >&2
 1240             exit 2
 1241             ;;
 1242     esac
 1243 fi
 1244 
 1245 
 1246 
 1247 # a simple function to compare directory contents
 1248 #
 1249 # Returns: 0 for same, 1 for different
 1250 #
 1251 directory_cmp ()
 1252 {
 1253     OLDPWD=`pwd`
 1254     DIR_1=$1
 1255     DIR_2=$2
 1256 
 1257     cd $DIR_1
 1258     find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d1
 1259 
 1260     # go back where we were to avoid symlink hell...
 1261     cd $OLDPWD
 1262     cd $DIR_2
 1263     find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d2
 1264 
 1265     if diff $TESTDIR/dc$$d1 $TESTDIR/dc$$d2 >/dev/null 2>&1
 1266     then
 1267         :
 1268     else
 1269         return 1
 1270     fi
 1271     cd $OLDPWD
 1272     while read a
 1273     do
 1274         if test -f $DIR_1/"$a" ; then
 1275             cmp -s $DIR_1/"$a" $DIR_2/"$a"
 1276             if test $? -ne 0 ; then
 1277                 return 1
 1278             fi
 1279         fi
 1280     done < $TESTDIR/dc$$d1
 1281     rm -f $TESTDIR/dc$$*
 1282     return 0
 1283 }
 1284 
 1285 
 1286 
 1287 #
 1288 # The following 4 functions are used by the diffmerge1 test case.  They set up,
 1289 # respectively, the four versions of the files necessary:
 1290 #
 1291 #   1.  Ancestor revisions.
 1292 #   2.  "Your" changes.
 1293 #   3.  "My" changes.
 1294 #   4.  Expected merge result.
 1295 #
 1296 
 1297 # Create ancestor revisions for diffmerge1
 1298 diffmerge_create_older_files() {
 1299       # This test case was supplied by Noah Friedman:
 1300       cat >testcase01 <<EOF
 1301 // Button.java
 1302 
 1303 package random.application;
 1304 
 1305 import random.util.*;
 1306 
 1307 public class Button
 1308 {
 1309   /* Instantiates a Button with origin (0, 0) and zero width and height.
 1310    * You must call an initializer method to properly initialize the Button.
 1311    */
 1312   public Button ()
 1313   {
 1314     super ();
 1315 
 1316     _titleColor = Color.black;
 1317     _disabledTitleColor = Color.gray;
 1318     _titleFont = Font.defaultFont ();
 1319   }
 1320 
 1321   /* Convenience constructor for instantiating a Button with
 1322    * bounds x, y, width, and height.  Equivalent to
 1323    *     foo = new Button ();
 1324    *     foo.init (x, y, width, height);
 1325    */
 1326   public Button (int x, int y, int width, int height)
 1327   {
 1328     this ();
 1329     init (x, y, width, height);
 1330   }
 1331 }
 1332 EOF
 1333 
 1334       # This test case was supplied by Jacob Burckhardt:
 1335       cat >testcase02 <<EOF
 1336 a
 1337 a
 1338 a
 1339 a
 1340 a
 1341 EOF
 1342 
 1343       # This test case was supplied by Karl Tomlinson who also wrote the
 1344       # patch which lets CVS correctly handle this and several other cases:
 1345       cat >testcase03 <<EOF
 1346 x
 1347 s
 1348 a
 1349 b
 1350 s
 1351 y
 1352 EOF
 1353 
 1354       # This test case was supplied by Karl Tomlinson:
 1355       cat >testcase04 <<EOF
 1356 s
 1357 x
 1358 m
 1359 m
 1360 x
 1361 s
 1362 v
 1363 s
 1364 x
 1365 m
 1366 m
 1367 x
 1368 s
 1369 EOF
 1370 
 1371       # This test case was supplied by Karl Tomlinson:
 1372       cat >testcase05 <<EOF
 1373 s
 1374 x
 1375 m
 1376 m
 1377 x
 1378 x
 1379 x
 1380 x
 1381 x
 1382 x
 1383 x
 1384 x
 1385 x
 1386 x
 1387 s
 1388 s
 1389 s
 1390 s
 1391 s
 1392 s
 1393 s
 1394 s
 1395 s
 1396 s
 1397 v
 1398 EOF
 1399 
 1400       # This test case was supplied by Jacob Burckhardt:
 1401       cat >testcase06 <<EOF
 1402 g
 1403 
 1404 
 1405 
 1406 
 1407 
 1408 
 1409 
 1410 
 1411 
 1412 
 1413 
 1414 i
 1415 EOF
 1416 
 1417       # This test is supposed to verify that the horizon lines are the same
 1418       # for both 2-way diffs, but unfortunately, it does not fail with the
 1419       # old version of cvs.  However, Karl Tomlinson still thought it would
 1420       # be good to test it anyway:
 1421       cat >testcase07 <<EOF
 1422 h
 1423 f
 1424 
 1425 
 1426 
 1427 
 1428 
 1429 
 1430 
 1431 
 1432 
 1433 g
 1434 r
 1435 
 1436 
 1437 
 1438 i
 1439 
 1440 
 1441 
 1442 
 1443 
 1444 
 1445 
 1446 
 1447 
 1448 
 1449 i
 1450 EOF
 1451 
 1452       # This test case was supplied by Jacob Burckhardt:
 1453       cat >testcase08 <<EOF
 1454 Both changes move this line to the end of the file.
 1455 
 1456 no
 1457 changes
 1458 here
 1459 
 1460 First change will delete this line.
 1461 
 1462 First change will also delete this line.
 1463 
 1464     no
 1465     changes
 1466     here
 1467 
 1468 Second change will change it here.
 1469 
 1470         no
 1471         changes
 1472         here
 1473 EOF
 1474 
 1475       # This test case was supplied by Jacob Burckhardt.  Note that I do not
 1476       # think cvs has ever failed with this case, but I include it anyway,
 1477       # since I think it is a hard case.  It is hard because Peter Miller's
 1478       # fmerge utility fails on it:
 1479       cat >testcase09 <<EOF
 1480 m
 1481 a
 1482 {
 1483 }
 1484 b
 1485 {
 1486 }
 1487 EOF
 1488 
 1489       # This test case was supplied by Martin Dorey and simplified by Jacob
 1490       # Burckhardt:
 1491       cat >testcase10 <<EOF
 1492 
 1493     petRpY ( MtatRk );
 1494     fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG );
 1495 
 1496     MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek );
 1497     OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep );
 1498 
 1499     Bloke_GttpfIRte_MtpeaL ( &acI );
 1500 MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep )
 1501 {
 1502     fV ( Y < 16 )
 1503     {
 1504         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 1505                                                       Y * jfle_Uecopd_MfJe_fY_Mectopk,
 1506                                 jfle_Uecopd_MfJe_fY_Mectopk,
 1507                                 nRVVep ) );
 1508     }
 1509     elke
 1510     {
 1511         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 1512                                                  ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk,
 1513                                 jfle_Uecopd_MfJe_fY_Mectopk,
 1514                                 nRVVep ) );
 1515     }
 1516 
 1517 }
 1518 
 1519 
 1520 /****************************************************************************
 1521 *                                                                           *
 1522 *   Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY )                      *
 1523 *                                                                           *
 1524 ****************************************************************************/
 1525 
 1526 MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep )
 1527 {
 1528 MTGTXM MtatRk = Zy;
 1529 
 1530     MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep );
 1531 
 1532     petRpY ( MtatRk );
 1533 
 1534 }
 1535     HfkQipfte ( waYdle,                 /*  waYdle                         */
 1536                 waYdleFok,              /*  ZVVket VpoL ktapt oV dfkQ      */
 1537                 (coYkt RfYt8*) nRVVep,  /*  nRVVep                         */
 1538                 0,                      /*  MRrepVlRoRk KfxoYfkL           */
 1539                 beYgtz                  /*  nEtek to Apfte                 */
 1540               );
 1541 
 1542     petRpY ( Zy );
 1543 }
 1544 EOF
 1545 }
 1546 
 1547 # Create "your" revisions for diffmerge1
 1548 diffmerge_create_your_files() {
 1549       # remove the Button() method
 1550       cat >testcase01 <<\EOF
 1551 // Button.java
 1552 
 1553 package random.application;
 1554 
 1555 import random.util.*;
 1556 
 1557 public class Button
 1558 {
 1559   /* Instantiates a Button with origin (0, 0) and zero width and height.
 1560    * You must call an initializer method to properly initialize the Button.
 1561    */
 1562   public Button ()
 1563   {
 1564     super ();
 1565 
 1566     _titleColor = Color.black;
 1567     _disabledTitleColor = Color.gray;
 1568     _titleFont = Font.defaultFont ();
 1569   }
 1570 }
 1571 EOF
 1572 
 1573       cat >testcase02 <<\EOF
 1574 y
 1575 a
 1576 a
 1577 a
 1578 a
 1579 EOF
 1580 
 1581       cat >testcase03 <<\EOF
 1582 x
 1583 s
 1584 a
 1585 b
 1586 s
 1587 b
 1588 s
 1589 y
 1590 EOF
 1591 
 1592       cat >testcase04 <<\EOF
 1593 s
 1594 m
 1595 s
 1596 v
 1597 s
 1598 m
 1599 s
 1600 EOF
 1601 
 1602       cat >testcase05 <<\EOF
 1603 v
 1604 s
 1605 m
 1606 s
 1607 s
 1608 s
 1609 s
 1610 s
 1611 s
 1612 s
 1613 s
 1614 s
 1615 s
 1616 v
 1617 EOF
 1618 
 1619       # Test case 6 and test case 7 both use the same input files, but they
 1620       # order the input files differently.  In one case, a certain file is
 1621       # used as the older file, but in the other test case, that same file
 1622       # is used as the file which has changes.  I could have put echo
 1623       # commands here, but since the echo lines would be the same as those
 1624       # in the previous function, I decided to save space and avoid repeating
 1625       # several lines of code.  Instead, I merely swap the files:
 1626       mv testcase07 tmp
 1627       mv testcase06 testcase07
 1628       mv tmp testcase06
 1629 
 1630       # Make the date newer so that cvs thinks that the files are changed:
 1631       touch testcase06 testcase07
 1632 
 1633       cat >testcase08 <<\EOF
 1634 no
 1635 changes
 1636 here
 1637 
 1638 First change has now added this in.
 1639 
 1640     no
 1641     changes
 1642     here
 1643 
 1644 Second change will change it here.
 1645 
 1646         no
 1647         changes
 1648         here
 1649 
 1650 Both changes move this line to the end of the file.
 1651 EOF
 1652 
 1653       cat >testcase09 <<\EOF
 1654 
 1655 m
 1656 a
 1657 {
 1658 }
 1659 b
 1660 {
 1661 }
 1662 c
 1663 {
 1664 }
 1665 EOF
 1666 
 1667       cat >testcase10 <<\EOF
 1668 
 1669     fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK;
 1670 
 1671     petRpY ( MtatRk );
 1672     fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG );
 1673 
 1674     fV ( jfle_Uecopd_KRLIep < 16 )
 1675     {
 1676         MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep );
 1677     }
 1678     elke
 1679     {
 1680         MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI );
 1681         fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG );
 1682 
 1683         MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek );
 1684         OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep );
 1685 
 1686     Bloke_GttpfIRte_MtpeaL ( &acI );
 1687 MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep )
 1688 {
 1689 MTGTXM MtatRk = Zy;
 1690 
 1691     fV ( Y < 16 )
 1692     {
 1693         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 1694                                                       Y * jfle_Uecopd_MfJe_fY_Mectopk,
 1695                                 jfle_Uecopd_MfJe_fY_Mectopk,
 1696                                 nRVVep ) );
 1697     }
 1698     elke
 1699     {
 1700         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 1701                                                  ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk,
 1702                                 jfle_Uecopd_MfJe_fY_Mectopk,
 1703                                 nRVVep ) );
 1704     }
 1705 
 1706     petRpY ( MtatRk );
 1707 
 1708 }
 1709 
 1710 
 1711 /****************************************************************************
 1712 *                                                                           *
 1713 *   Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY )                      *
 1714 *                                                                           *
 1715 ****************************************************************************/
 1716 
 1717 MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep )
 1718 {
 1719 MTGTXM MtatRk = Zy;
 1720 
 1721     MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep );
 1722 
 1723     petRpY ( MtatRk );
 1724 
 1725 }
 1726     HfkQipfte ( waYdle,                 /*  waYdle                         */
 1727                 waYdleFok,              /*  ZVVket VpoL ktapt oV dfkQ      */
 1728                 (coYkt RfYt8*) nRVVep,  /*  nRVVep                         */
 1729                 0,                      /*  MRrepVlRoRk KfxoYfkL           */
 1730                 beYgtz                  /*  nEtek to Apfte                 */
 1731               );
 1732 
 1733     petRpY ( Zy );
 1734 }
 1735 
 1736 EOF
 1737 }
 1738 
 1739 # Create "my" revisions for diffmerge1
 1740 diffmerge_create_my_files() {
 1741           # My working copy still has the Button() method, but I
 1742       # comment out some code at the top of the class.
 1743       cat >testcase01 <<\EOF
 1744 // Button.java
 1745 
 1746 package random.application;
 1747 
 1748 import random.util.*;
 1749 
 1750 public class Button
 1751 {
 1752   /* Instantiates a Button with origin (0, 0) and zero width and height.
 1753    * You must call an initializer method to properly initialize the Button.
 1754    */
 1755   public Button ()
 1756   {
 1757     super ();
 1758 
 1759     // _titleColor = Color.black;
 1760     // _disabledTitleColor = Color.gray;
 1761     // _titleFont = Font.defaultFont ();
 1762   }
 1763 
 1764   /* Convenience constructor for instantiating a Button with
 1765    * bounds x, y, width, and height.  Equivalent to
 1766    *     foo = new Button ();
 1767    *     foo.init (x, y, width, height);
 1768    */
 1769   public Button (int x, int y, int width, int height)
 1770   {
 1771     this ();
 1772     init (x, y, width, height);
 1773   }
 1774 }
 1775 EOF
 1776 
 1777       cat >testcase02 <<\EOF
 1778 a
 1779 a
 1780 a
 1781 a
 1782 m
 1783 EOF
 1784 
 1785       cat >testcase03 <<\EOF
 1786 x
 1787 s
 1788 c
 1789 s
 1790 b
 1791 s
 1792 y
 1793 EOF
 1794 
 1795       cat >testcase04 <<\EOF
 1796 v
 1797 s
 1798 x
 1799 m
 1800 m
 1801 x
 1802 s
 1803 v
 1804 s
 1805 x
 1806 m
 1807 m
 1808 x
 1809 s
 1810 v
 1811 EOF
 1812 
 1813       # Note that in test case 5, there are no changes in the "mine"
 1814       # section, which explains why there is no command here which writes to
 1815       # file testcase05.
 1816 
 1817       # no changes for testcase06
 1818 
 1819       # The two branches make the same changes:
 1820       cp ../yours/testcase07 .
 1821 
 1822       cat >testcase08 <<\EOF
 1823 no
 1824 changes
 1825 here
 1826 
 1827 First change will delete this line.
 1828 
 1829 First change will also delete this line.
 1830 
 1831     no
 1832     changes
 1833     here
 1834 
 1835 Second change has now changed it here.
 1836 
 1837         no
 1838         changes
 1839         here
 1840 
 1841 Both changes move this line to the end of the file.
 1842 EOF
 1843 
 1844       cat >testcase09 <<\EOF
 1845 m
 1846 a
 1847 {
 1848 }
 1849 b
 1850 {
 1851 }
 1852 c
 1853 {
 1854 }
 1855 EOF
 1856 
 1857       cat >testcase10 <<\EOF
 1858 
 1859     petRpY ( MtatRk );
 1860     fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG );
 1861 
 1862     MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek );
 1863     OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep );
 1864 
 1865     Bloke_GttpfIRte_MtpeaL ( &acI );
 1866 MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep )
 1867 {
 1868     fV ( Y < 16 )
 1869     {
 1870         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 1871                                                       Y * jfle_Uecopd_MfJe_fY_Mectopk,
 1872                                 jfle_Uecopd_MfJe_fY_Mectopk,
 1873                                 nRVVep ) );
 1874     }
 1875     elke
 1876     {
 1877         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 1878                                                  ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk,
 1879                                 jfle_Uecopd_MfJe_fY_Mectopk,
 1880                                 nRVVep ) );
 1881     }
 1882 
 1883 }
 1884 
 1885 
 1886 /****************************************************************************
 1887 *                                                                           *
 1888 *   Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY )                      *
 1889 *                                                                           *
 1890 ****************************************************************************/
 1891 
 1892 MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep )
 1893 {
 1894 MTGTXM MtatRk = Zy;
 1895 
 1896     MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep );
 1897 
 1898     petRpY ( MtatRk );
 1899 
 1900 }
 1901     HfkQipfte ( waYdle,                 /*  waYdle                         */
 1902                 waYdleFok,              /*  ZVVket VpoL ktapt oV dfkQ      */
 1903                 (coYkt RfYt8*) nRVVep,  /*  nRVVep                         */
 1904                 beYgtz                  /*  nEtek to Apfte                 */
 1905               );
 1906 
 1907     petRpY ( Zy );
 1908 }
 1909 
 1910 EOF
 1911 }
 1912 
 1913 # Create expected results of merge for diffmerge1
 1914 diffmerge_create_expected_files() {
 1915       cat >testcase01 <<\EOF
 1916 // Button.java
 1917 
 1918 package random.application;
 1919 
 1920 import random.util.*;
 1921 
 1922 public class Button
 1923 {
 1924   /* Instantiates a Button with origin (0, 0) and zero width and height.
 1925    * You must call an initializer method to properly initialize the Button.
 1926    */
 1927   public Button ()
 1928   {
 1929     super ();
 1930 
 1931     // _titleColor = Color.black;
 1932     // _disabledTitleColor = Color.gray;
 1933     // _titleFont = Font.defaultFont ();
 1934   }
 1935 }
 1936 EOF
 1937 
 1938       cat >testcase02 <<\EOF
 1939 y
 1940 a
 1941 a
 1942 a
 1943 m
 1944 EOF
 1945 
 1946       cat >testcase03 <<\EOF
 1947 x
 1948 s
 1949 c
 1950 s
 1951 b
 1952 s
 1953 b
 1954 s
 1955 y
 1956 EOF
 1957 
 1958       cat >testcase04 <<\EOF
 1959 v
 1960 s
 1961 m
 1962 s
 1963 v
 1964 s
 1965 m
 1966 s
 1967 v
 1968 EOF
 1969 
 1970       # Since there are no changes in the "mine" section, just take exactly
 1971       # the version in the "yours" section:
 1972       cp ../yours/testcase05 .
 1973 
 1974       cp ../yours/testcase06 .
 1975 
 1976       # Since the two branches make the same changes, the result should be
 1977       # the same as both branches.  Here, I happen to pick yours to copy from,
 1978       # but I could have also picked mine, since the source of the copy is
 1979       # the same in either case.  However, the mine has already been
 1980       # altered by the update command, so don't use it.  Instead, use the
 1981       # yours section which has not had an update on it and so is unchanged:
 1982       cp ../yours/testcase07 .
 1983 
 1984       cat >testcase08 <<\EOF
 1985 no
 1986 changes
 1987 here
 1988 
 1989 First change has now added this in.
 1990 
 1991     no
 1992     changes
 1993     here
 1994 
 1995 Second change has now changed it here.
 1996 
 1997         no
 1998         changes
 1999         here
 2000 
 2001 Both changes move this line to the end of the file.
 2002 EOF
 2003 
 2004       cat >testcase09 <<\EOF
 2005 
 2006 m
 2007 a
 2008 {
 2009 }
 2010 b
 2011 {
 2012 }
 2013 c
 2014 {
 2015 }
 2016 EOF
 2017 
 2018       cat >testcase10 <<\EOF
 2019 
 2020     fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK;
 2021 
 2022     petRpY ( MtatRk );
 2023     fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG );
 2024 
 2025     fV ( jfle_Uecopd_KRLIep < 16 )
 2026     {
 2027         MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep );
 2028     }
 2029     elke
 2030     {
 2031         MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI );
 2032         fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG );
 2033 
 2034         MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek );
 2035         OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep );
 2036 
 2037     Bloke_GttpfIRte_MtpeaL ( &acI );
 2038 MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep )
 2039 {
 2040 MTGTXM MtatRk = Zy;
 2041 
 2042     fV ( Y < 16 )
 2043     {
 2044         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 2045                                                       Y * jfle_Uecopd_MfJe_fY_Mectopk,
 2046                                 jfle_Uecopd_MfJe_fY_Mectopk,
 2047                                 nRVVep ) );
 2048     }
 2049     elke
 2050     {
 2051         petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep +
 2052                                                  ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk,
 2053                                 jfle_Uecopd_MfJe_fY_Mectopk,
 2054                                 nRVVep ) );
 2055     }
 2056 
 2057     petRpY ( MtatRk );
 2058 
 2059 }
 2060 
 2061 
 2062 /****************************************************************************
 2063 *                                                                           *
 2064 *   Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY )                      *
 2065 *                                                                           *
 2066 ****************************************************************************/
 2067 
 2068 MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep )
 2069 {
 2070 MTGTXM MtatRk = Zy;
 2071 
 2072     MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep );
 2073 
 2074     petRpY ( MtatRk );
 2075 
 2076 }
 2077     HfkQipfte ( waYdle,                 /*  waYdle                         */
 2078                 waYdleFok,              /*  ZVVket VpoL ktapt oV dfkQ      */
 2079                 (coYkt RfYt8*) nRVVep,  /*  nRVVep                         */
 2080                 beYgtz                  /*  nEtek to Apfte                 */
 2081               );
 2082 
 2083     petRpY ( Zy );
 2084 }
 2085 
 2086 EOF
 2087 }
 2088 
 2089 
 2090 
 2091 # Echo a new CVSROOT based on $1, $remote, and $remotehost
 2092 newroot() {
 2093   if $remote; then
 2094     if test -n "$remotehost"; then
 2095       echo :ext:$remotehost$1
 2096     else
 2097       echo :fork:$1
 2098     fi
 2099   else
 2100     echo $1
 2101   fi
 2102 }
 2103 
 2104 
 2105 
 2106 # Set up CVSROOT (the crerepos tests will test operating without CVSROOT set).
 2107 #
 2108 # Currently we test :fork: and :ext: (see crerepos test).  There is a
 2109 # known difference between the two in modes-15 (see comments there).
 2110 #
 2111 # :ext: can be tested against a remote machine if:
 2112 #
 2113 #    1. $remotehost is set using the `-h' option to this script.
 2114 #    2. ${CVS_RSH=rsh} $remotehost works.
 2115 #    3. The path to $TESTDIR is the same on both machines (symlinks are okay)
 2116 #    4. The path to $testcvs is the same on both machines (symlinks are okay)
 2117 #       or $CVS_SERVER is overridden in this script's environment to point to
 2118 #       a working CVS exectuable on the remote machine.
 2119 #
 2120 # Testing :pserver: would be hard (inetd issues).  (How about using tcpserver
 2121 # and some high port number?  DRP)
 2122 
 2123 # Allow CVS_SERVER to be overridden.  This facilitates constructs like
 2124 # testing a local case-insensitive client against a remote case
 2125 # sensitive server and visa versa.
 2126 : ${CVS_SERVER=$testcvs}; export CVS_SERVER
 2127 
 2128 # Use a name which will be different than CVSROOT on case insensitive
 2129 # filesystems (e.g., HFS+)
 2130 CVSROOTDIR=cvsrootdir
 2131 if $linkroot; then
 2132     mkdir ${TESTDIR}/realcvsroot
 2133     ln -s realcvsroot ${TESTDIR}/${CVSROOTDIR}
 2134 fi
 2135 CVSROOT_DIRNAME=${TESTDIR}/${CVSROOTDIR}
 2136 CVSROOT=`newroot $CVSROOT_DIRNAME`; export CVSROOT
 2137 
 2138 
 2139 
 2140 ###
 2141 ### Init the repository.
 2142 ###
 2143 dotest init-1 "$testcvs -d$CVSROOT_DIRNAME init"
 2144 
 2145 # Copy the admin files for restore_adm.
 2146 cp -Rp $CVSROOT_DIRNAME/CVSROOT $TESTDIR/CVSROOT.save
 2147 
 2148 
 2149 
 2150 ###
 2151 ### The tests
 2152 ###
 2153 if $remote; then
 2154     localonly init-2
 2155     localonly init-3
 2156 else
 2157     dotest init-2 "$testcvs init"
 2158     dotest_fail init-3 "$testcvs -d $CVSROOT/sdir init" \
 2159 "$PROG \[init aborted\]: Cannot initialize repository under existing CVSROOT: \`$CVSROOT_DIRNAME'"
 2160 fi
 2161 
 2162 
 2163 
 2164 ### The big loop
 2165 for what in $tests; do
 2166     if test -n "$fromtest" ; then
 2167         if test $fromtest = $what ; then
 2168         unset fromtest
 2169         else
 2170         continue
 2171         fi
 2172     fi
 2173 
 2174     if $verbose; then
 2175         echo "$what:"
 2176     fi
 2177 
 2178     case $what in
 2179 
 2180     version)
 2181       # We've had cases where the version command started dumping core,
 2182       # so we might as well test it
 2183       dotest version-1 "${testcvs} --version" \
 2184 '
 2185 Concurrent Versions System (CVS) [0-9.]*.*
 2186 
 2187 Copyright (C) [0-9]* Free Software Foundation, Inc.
 2188 
 2189 Senior active maintainers include Larry Jones, Derek R. Price,
 2190 and Mark D. Baushke.  Please see the AUTHORS and README files from the CVS
 2191 distribution kit for a complete list of contributors and copyrights.
 2192 
 2193 CVS may be copied only under the terms of the GNU General Public License,
 2194 a copy of which can be found with the CVS distribution kit.
 2195 
 2196 Specify the --help option for further information about CVS'
 2197 
 2198       if $remote; then
 2199         dotest version-2r "${testcvs} version" \
 2200 'Client: Concurrent Versions System (CVS) [0-9p.]* (client/server)
 2201 Server: Concurrent Versions System (CVS) [0-9p.]* (client/server)'
 2202       else
 2203         dotest version-2 "${testcvs} version" \
 2204 'Concurrent Versions System (CVS) [0-9.]*.*'
 2205       fi
 2206       ;;
 2207 
 2208     basica)
 2209       # Similar in spirit to some of the basic1, and basic2
 2210       # tests, but hopefully a lot faster.  Also tests operating on
 2211       # files two directories down *without* operating on the parent dirs.
 2212 
 2213       # Tests basica-0a and basica-0b provide the equivalent of the:
 2214       #    mkdir ${CVSROOT_DIRNAME}/first-dir
 2215       # used by many of the tests.  It is "more official" in the sense
 2216       # that is does everything through CVS; the reason most of the
 2217       # tests don't use it is mostly historical.
 2218       mkdir 1; cd 1
 2219       dotest basica-0a "${testcvs} -q co -l ." ''
 2220       mkdir first-dir
 2221       dotest basica-0b "${testcvs} add first-dir" \
 2222 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 2223       cd ..
 2224       rm -r 1
 2225 
 2226       dotest basica-1 "${testcvs} -q co first-dir" ''
 2227       cd first-dir
 2228 
 2229       # Test a few operations, to ensure they gracefully do
 2230       # nothing in an empty directory.
 2231       dotest basica-1a0 "${testcvs} -q update" ''
 2232       dotest basica-1a1 "${testcvs} -q diff -c" ''
 2233       dotest basica-1a2 "${testcvs} -q status" ''
 2234       dotest basica-1a3 "${testcvs} -q update ." ''
 2235       dotest basica-1a4 "${testcvs} -q update ./" ''
 2236 
 2237       mkdir sdir
 2238       # Remote CVS gives the "cannot open CVS/Entries" error, which is
 2239       # clearly a bug, but not a simple one to fix.
 2240       dotest basica-1a10 "${testcvs} -n add sdir" \
 2241 "Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" \
 2242 "${PROG} add: cannot open CVS/Entries for reading: No such file or directory
 2243 Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository"
 2244       dotest_fail basica-1a11 \
 2245         "test -d ${CVSROOT_DIRNAME}/first-dir/sdir" ''
 2246       dotest basica-2 "${testcvs} add sdir" \
 2247 "Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository"
 2248       cd sdir
 2249       mkdir ssdir
 2250       dotest basica-3 "${testcvs} add ssdir" \
 2251 "Directory ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir added to the repository"
 2252       cd ssdir
 2253       echo ssfile >ssfile
 2254 
 2255       # Trying to commit it without a "cvs add" should be an error.
 2256       # The "use `cvs add' to create an entry" message is the one
 2257       # that I consider to be more correct, but local cvs prints the
 2258       # "nothing known" message and noone has gotten around to fixing it.
 2259       dotest_fail basica-notadded "${testcvs} -q ci ssfile" \
 2260 "${PROG} [a-z]*: use .${PROG} add. to create an entry for ssfile
 2261 ${PROG}"' \[[a-z]* aborted\]: correct above errors first!' \
 2262 "${PROG}"' [a-z]*: nothing known about `ssfile'\''
 2263 '"${PROG}"' \[[a-z]* aborted\]: correct above errors first!'
 2264 
 2265       dotest basica-4 "${testcvs} add ssfile" \
 2266 "${PROG}"' add: scheduling file `ssfile'\'' for addition
 2267 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 2268       dotest_fail basica-4a "${testcvs} tag tag0 ssfile" \
 2269 "${PROG} tag: nothing known about ssfile
 2270 ${PROG} "'\[tag aborted\]: correct the above errors first!'
 2271       cd ../..
 2272       dotest basica-5 "${testcvs} -q ci -m add-it" \
 2273 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2274 done
 2275 Checking in sdir/ssdir/ssfile;
 2276 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2277 initial revision: 1\.1
 2278 done"
 2279       dotest_fail basica-5a \
 2280         "${testcvs} -q tag BASE sdir/ssdir/ssfile" \
 2281 "${PROG} tag: Attempt to add reserved tag name BASE
 2282 ${PROG} \[tag aborted\]: failed to set tag BASE to revision 1\.1 in ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v"
 2283       dotest basica-5b "${testcvs} -q tag NOT_RESERVED" \
 2284 'T sdir/ssdir/ssfile'
 2285 
 2286       dotest basica-6 "${testcvs} -q update" ''
 2287       echo "ssfile line 2" >>sdir/ssdir/ssfile
 2288       dotest_fail basica-6.2 "${testcvs} -q diff -c" \
 2289 "Index: sdir/ssdir/ssfile
 2290 ===================================================================
 2291 RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2292 retrieving revision 1\.1
 2293 diff -c -r1\.1 ssfile
 2294 \*\*\* sdir/ssdir/ssfile    ${RFCDATE}  1\.1
 2295 --- sdir/ssdir/ssfile   ${RFCDATE}
 2296 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 2297 \*\*\* 1 \*\*\*\*
 2298 --- 1,2 ----
 2299   ssfile
 2300 ${PLUS} ssfile line 2"
 2301       dotest_fail basica-6.3 "${testcvs} -q diff -c -rBASE" \
 2302 "Index: sdir/ssdir/ssfile
 2303 ===================================================================
 2304 RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2305 retrieving revision 1\.1
 2306 diff -c -r1\.1 ssfile
 2307 \*\*\* sdir/ssdir/ssfile    ${RFCDATE}  1\.1
 2308 --- sdir/ssdir/ssfile   ${RFCDATE}
 2309 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 2310 \*\*\* 1 \*\*\*\*
 2311 --- 1,2 ----
 2312   ssfile
 2313 ${PLUS} ssfile line 2"
 2314       dotest_fail basica-6.4 "${testcvs} -q diff -c -rBASE -C3isacrowd" \
 2315 "Index: sdir/ssdir/ssfile
 2316 ===================================================================
 2317 RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2318 retrieving revision 1\.1
 2319 diff -c -C 3isacrowd -r1\.1 ssfile
 2320 ${PROG} diff: invalid context length argument"
 2321       dotest basica-7 "${testcvs} -q ci -m modify-it" \
 2322 "Checking in sdir/ssdir/ssfile;
 2323 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2324 new revision: 1\.2; previous revision: 1\.1
 2325 done"
 2326       dotest_fail basica-nonexist "${testcvs} -q ci nonexist" \
 2327 "${PROG}"' [a-z]*: nothing known about `nonexist'\''
 2328 '"${PROG}"' \[[a-z]* aborted\]: correct above errors first!'
 2329       dotest basica-8 "${testcvs} -q update ." ''
 2330 
 2331       # Test the -f option to ci
 2332       cd sdir/ssdir
 2333       dotest basica-8a0 "${testcvs} -q ci -m not-modified ssfile" ''
 2334       dotest basica-8a "${testcvs} -q ci -f -m force-it" \
 2335 "Checking in ssfile;
 2336 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2337 new revision: 1\.3; previous revision: 1\.2
 2338 done"
 2339       dotest basica-8a1 "${testcvs} -q ci -m bump-it -r 2.0" \
 2340 "Checking in ssfile;
 2341 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2342 new revision: 2\.0; previous revision: 1\.3
 2343 done"
 2344       dotest basica-8a1a "${testcvs} -q ci -m bump-it -r 2.9" \
 2345 "Checking in ssfile;
 2346 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2347 new revision: 2\.9; previous revision: 2\.0
 2348 done"
 2349       # Test string-based revion number increment rollover
 2350       dotest basica-8a1b "${testcvs} -q ci -m bump-it -f -r 2" \
 2351 "Checking in ssfile;
 2352 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2353 new revision: 2\.10; previous revision: 2\.9
 2354 done"
 2355       dotest basica-8a1c "${testcvs} -q ci -m bump-it -r 2.99" \
 2356 "Checking in ssfile;
 2357 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2358 new revision: 2\.99; previous revision: 2\.10
 2359 done"
 2360       # Test string-based revion number increment rollover
 2361       dotest basica-8a1d "${testcvs} -q ci -m bump-it -f -r 2" \
 2362 "Checking in ssfile;
 2363 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2364 new revision: 2\.100; previous revision: 2\.99
 2365 done"
 2366       dotest basica-8a1e "${testcvs} -q ci -m bump-it -r 2.1099" \
 2367 "Checking in ssfile;
 2368 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2369 new revision: 2\.1099; previous revision: 2\.100
 2370 done"
 2371       # Test string-based revion number increment rollover
 2372       dotest basica-8a1f "${testcvs} -q ci -m bump-it -f -r 2" \
 2373 "Checking in ssfile;
 2374 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2375 new revision: 2\.1100; previous revision: 2\.1099
 2376 done"
 2377       # -f should not be necessary, but it should be harmless.
 2378       # Also test the "-r 3" (rather than "-r 3.0") usage.
 2379       dotest basica-8a2 "${testcvs} -q ci -m bump-it -f -r 3" \
 2380 "Checking in ssfile;
 2381 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2382 new revision: 3\.1; previous revision: 2\.1100
 2383 done"
 2384 
 2385       # Test using -r to create a branch
 2386       dotest_fail basica-8a3 "${testcvs} -q ci -m bogus -r 3.0.0" \
 2387 "Checking in ssfile;
 2388 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2389 ${PROG} commit: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: can't find branch point 3\.0
 2390 ${PROG} commit: could not check in ssfile"
 2391       dotest basica-8a4 "${testcvs} -q ci -m valid -r 3.1.2" \
 2392 "Checking in ssfile;
 2393 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2394 new revision: 3\.1\.2\.1; previous revision: 3\.1
 2395 done"
 2396 
 2397       # Verify that this file remains unchanged since up -A should not
 2398       # change the contents here.
 2399       cp ssfile $TESTDIR/ssfile.sav
 2400       # now get rid of the sticky tag and go back to the trunk
 2401       dotest basica-8a5 "$testcvs -q up -A ./" '[UP] ssfile'
 2402       dotest basica-8a6 "cmp ssfile $TESTDIR/ssfile.sav"
 2403       rm $TESTDIR/ssfile.sav
 2404 
 2405       cd ../..
 2406       dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3"
 2407       dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd"
 2408 
 2409       # The .* here will normally be "No such file or directory",
 2410       # but if memory serves some systems (AIX?) have a different message.
 2411 :     dotest_fail basica-9 \
 2412         "${testcvs} -q -d ${TESTDIR}/nonexist update" \
 2413 "${PROG}: cannot access cvs root ${TESTDIR}/nonexist: .*"
 2414       dotest_fail basica-9 \
 2415         "${testcvs} -q -d ${TESTDIR}/nonexist update" \
 2416 "${PROG} \[[a-z]* aborted\]: ${TESTDIR}/nonexist/CVSROOT: .*"
 2417 
 2418       dotest basica-10 "${testcvs} annotate" \
 2419 '
 2420 Annotations for sdir/ssdir/ssfile
 2421 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 2422 1\.1          .'"$username8"' *[0-9a-zA-Z-]*.: ssfile
 2423 1\.2          .'"$username8"' *[0-9a-zA-Z-]*.: ssfile line 2'
 2424 
 2425       # Test resurrecting with strange revision numbers
 2426       cd sdir/ssdir
 2427       dotest basica-r1 "${testcvs} rm -f ssfile" \
 2428 "${PROG} remove: scheduling .ssfile. for removal
 2429 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 2430       dotest basica-r2 "${testcvs} -q ci -m remove" \
 2431 "Removing ssfile;
 2432 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2433 new revision: delete; previous revision: 3\.1
 2434 done"
 2435       dotest basica-r3 "${testcvs} -q up -p -r 3.1 ./ssfile >ssfile" ""
 2436       dotest basica-r4 "${testcvs} add ssfile" \
 2437 "${PROG} add: Re-adding file .ssfile. (in place of dead revision 3\.2)\.
 2438 ${PROG} add: use .${PROG} commit. to add this file permanently"
 2439       dotest basica-r5 "${testcvs} -q ci -m resurrect" \
 2440 "Checking in ssfile;
 2441 ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v  <--  ssfile
 2442 new revision: 3\.3; previous revision: 3\.2
 2443 done"
 2444       cd ../..
 2445 
 2446       # As long as we have a file with a few revisions, test
 2447       # a few "cvs admin -o" invocations.
 2448       cd sdir/ssdir
 2449       dotest_fail basica-o1 "${testcvs} admin -o 1.2::1.2" \
 2450 "${PROG} [a-z]*: while processing more than one file:
 2451 ${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision"
 2452       dotest basica-o2 "${testcvs} admin -o 1.2::1.2 ssfile" \
 2453 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2454 done"
 2455       dotest basica-o2a "${testcvs} admin -o 1.1::NOT_RESERVED ssfile" \
 2456 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2457 done"
 2458       dotest_fail basica-o2b "${testcvs} admin -o 1.1::NOT_EXIST ssfile" \
 2459 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2460 ${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: Revision NOT_EXIST doesn't exist.
 2461 ${PROG} admin: RCS file for .ssfile. not modified\."
 2462       dotest basica-o3 "${testcvs} admin -o 1.2::1.3 ssfile" \
 2463 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2464 done"
 2465       dotest basica-o4 "${testcvs} admin -o 3.1:: ssfile" \
 2466 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2467 deleting revision 3\.3
 2468 deleting revision 3\.2
 2469 done"
 2470       dotest basica-o5 "${testcvs} admin -o ::1.1 ssfile" \
 2471 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2472 done"
 2473       dotest basica-o5a "${testcvs} -n admin -o 1.2::3.1 ssfile" \
 2474 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2475 deleting revision 2\.1100
 2476 deleting revision 2\.1099
 2477 deleting revision 2\.100
 2478 deleting revision 2\.99
 2479 deleting revision 2\.10
 2480 deleting revision 2\.9
 2481 deleting revision 2\.0
 2482 deleting revision 1\.3
 2483 done"
 2484       dotest basica-o6 "${testcvs} admin -o 1.2::3.1 ssfile" \
 2485 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2486 deleting revision 2\.1100
 2487 deleting revision 2\.1099
 2488 deleting revision 2\.100
 2489 deleting revision 2\.99
 2490 deleting revision 2\.10
 2491 deleting revision 2\.9
 2492 deleting revision 2\.0
 2493 deleting revision 1\.3
 2494 done"
 2495       dotest basica-o6a "${testcvs} admin -o 3.1.2: ssfile" \
 2496 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2497 deleting revision 3\.1\.2\.1
 2498 done"
 2499       dotest basica-o7 "${testcvs} log -N ssfile" "
 2500 RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
 2501 Working file: ssfile
 2502 head: 3\.1
 2503 branch:
 2504 locks: strict
 2505 access list:
 2506 keyword substitution: kv
 2507 total revisions: 3; selected revisions: 3
 2508 description:
 2509 ----------------------------
 2510 revision 3\.1
 2511 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;  lines: ${PLUS}0 -0
 2512 bump-it
 2513 ----------------------------
 2514 revision 1\.2
 2515 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;  lines: ${PLUS}1 -0
 2516 modify-it
 2517 ----------------------------
 2518 revision 1\.1
 2519 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;
 2520 add-it
 2521 ============================================================================="
 2522       dotest basica-o8 "${testcvs} -q update -p -r 1.1 ./ssfile" "ssfile"
 2523       cd ../..
 2524 
 2525       cd ..
 2526 
 2527       rm -rf ${CVSROOT_DIRNAME}/first-dir
 2528       rm -r first-dir
 2529       ;;
 2530 
 2531     basicb)
 2532       # More basic tests, including non-branch tags and co -d.
 2533       mkdir 1; cd 1
 2534       dotest basicb-0a "${testcvs} -q co -l ." ''
 2535       touch topfile
 2536       dotest basicb-0b "${testcvs} add topfile" \
 2537 "${PROG} add: scheduling file .topfile. for addition
 2538 ${PROG} add: use .${PROG} commit. to add this file permanently"
 2539       dotest basicb-0c "${testcvs} -q ci -m add-it topfile" \
 2540 "RCS file: ${CVSROOT_DIRNAME}/topfile,v
 2541 done
 2542 Checking in topfile;
 2543 ${CVSROOT_DIRNAME}/topfile,v  <--  topfile
 2544 initial revision: 1\.1
 2545 done"
 2546       cd ..
 2547       rm -r 1
 2548       mkdir 2; cd 2
 2549       dotest basicb-0d "${testcvs} -q co -l ." "U topfile"
 2550       # Now test the ability to run checkout on an existing working
 2551       # directory without having it lose its mind.  I don't know
 2552       # whether this is tested elsewhere in sanity.sh.  A more elaborate
 2553       # test might also have modified files, make sure it works if
 2554       # the modules file was modified to add new directories to the
 2555       # module, and such.
 2556       dotest basicb-0d0 "${testcvs} -q co -l ." ""
 2557       mkdir first-dir
 2558       dotest basicb-0e "${testcvs} add first-dir" \
 2559 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 2560       cd ..
 2561       rm -r 2
 2562 
 2563       dotest basicb-1 "${testcvs} -q co first-dir" ''
 2564 
 2565       # The top-level CVS directory is not created by default.
 2566       # I'm leaving basicb-1a and basicb-1b untouched, mostly, in
 2567       # case we decide that the default should be reversed...
 2568 
 2569       dotest_fail basicb-1a "test -d CVS" ''
 2570 
 2571       dotest basicb-1c "cat first-dir/CVS/Repository" "first-dir"
 2572 
 2573       cd first-dir
 2574       # Note that the name Emptydir is chosen to test that CVS just
 2575       # treats it like any other directory name.  It should be
 2576       # special only when it is directly in $CVSROOT/CVSROOT.
 2577       mkdir Emptydir sdir2
 2578       dotest basicb-2 "${testcvs} add Emptydir sdir2" \
 2579 "Directory ${CVSROOT_DIRNAME}/first-dir/Emptydir added to the repository
 2580 Directory ${CVSROOT_DIRNAME}/first-dir/sdir2 added to the repository"
 2581       cd Emptydir
 2582       echo sfile1 starts >sfile1
 2583       dotest basicb-2a10 "${testcvs} -n add sfile1" \
 2584 "${PROG} add: scheduling file .sfile1. for addition
 2585 ${PROG} add: use .${PROG} commit. to add this file permanently"
 2586       dotest basicb-2a11 "${testcvs} status sfile1" \
 2587 "${PROG} status: use .${PROG} add. to create an entry for sfile1
 2588 ===================================================================
 2589 File: sfile1            Status: Unknown
 2590 
 2591    Working revision:    No entry for sfile1
 2592    Repository revision: No revision control file"
 2593       dotest basicb-3 "${testcvs} add sfile1" \
 2594 "${PROG} add: scheduling file .sfile1. for addition
 2595 ${PROG} add: use .${PROG} commit. to add this file permanently"
 2596       dotest basicb-3a1 "${testcvs} status sfile1" \
 2597 "===================================================================
 2598 File: sfile1            Status: Locally Added
 2599 
 2600    Working revision:    New file!
 2601    Repository revision: No revision control file
 2602    Sticky Tag:      (none)
 2603    Sticky Date:     (none)
 2604    Sticky Options:  (none)"
 2605 
 2606       cd ../sdir2
 2607       echo sfile2 starts >sfile2
 2608       dotest basicb-4 "${testcvs} add sfile2" \
 2609 "${PROG} add: scheduling file .sfile2. for addition
 2610 ${PROG} add: use .${PROG} commit. to add this file permanently"
 2611       dotest basicb-4a "${testcvs} -q ci CVS" \
 2612 "${PROG} [a-z]*: warning: directory CVS specified in argument
 2613 ${PROG} [a-z]*: but CVS uses CVS for its own purposes; skipping CVS directory"
 2614       cd ..
 2615       dotest basicb-5 "${testcvs} -q ci -m add" \
 2616 "RCS file: ${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v
 2617 done
 2618 Checking in Emptydir/sfile1;
 2619 ${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v  <--  sfile1
 2620 initial revision: 1\.1
 2621 done
 2622 RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v
 2623 done
 2624 Checking in sdir2/sfile2;
 2625 ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v  <--  sfile2
 2626 initial revision: 1\.1
 2627 done"
 2628       echo sfile1 develops >Emptydir/sfile1
 2629       dotest basicb-6 "${testcvs} -q ci -m modify" \
 2630 "Checking in Emptydir/sfile1;
 2631 ${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v  <--  sfile1
 2632 new revision: 1\.2; previous revision: 1\.1
 2633 done"
 2634       dotest basicb-7 "${testcvs} -q tag release-1" 'T Emptydir/sfile1
 2635 T sdir2/sfile2'
 2636       echo not in time for release-1 >sdir2/sfile2
 2637       dotest basicb-8 "${testcvs} -q ci -m modify-2" \
 2638 "Checking in sdir2/sfile2;
 2639 ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v  <--  sfile2
 2640 new revision: 1\.2; previous revision: 1\.1
 2641 done"
 2642       # See if CVS can correctly notice when an invalid numeric
 2643       # revision is specified.
 2644       # Commented out until we get around to fixing CVS
 2645 :     dotest basicb-8a0 "${testcvs} diff -r 1.5 -r 1.7 sfile2" 'error msg'
 2646       cd ..
 2647 
 2648       # Test that we recurse into the correct directory when checking
 2649       # for existing files, even if co -d is in use.
 2650       touch first-dir/extra
 2651       dotest basicb-cod-1 "${testcvs} -q co -d first-dir1 first-dir" \
 2652 'U first-dir1/Emptydir/sfile1
 2653 U first-dir1/sdir2/sfile2'
 2654       rm -r first-dir1
 2655 
 2656       rm -r first-dir
 2657 
 2658       # FIXME? basicb-9 used to check things out like this:
 2659       #   U newdir/Emptydir/sfile1
 2660       #   U newdir/sdir2/sfile2
 2661       # but that's difficult to do.  The whole "shorten" thing
 2662       # is pretty bogus, because it will break on things
 2663       # like "cvs co foo/bar baz/quux".  Unless there's some
 2664       # pretty detailed expansion and analysis of the command-line
 2665       # arguments, we shouldn't do "shorten" stuff at all.
 2666 
 2667       dotest basicb-9 \
 2668 "${testcvs} -q co -d newdir -r release-1 first-dir/Emptydir first-dir/sdir2" \
 2669 'U newdir/first-dir/Emptydir/sfile1
 2670 U newdir/first-dir/sdir2/sfile2'
 2671 
 2672       # basicb-9a and basicb-9b: see note about basicb-1a
 2673 
 2674       dotest_fail basicb-9a "test -d CVS" ''
 2675 
 2676       dotest basicb-9c "cat newdir/CVS/Repository" "\."
 2677       dotest basicb-9d "cat newdir/first-dir/CVS/Repository" \
 2678 "${CVSROOT_DIRNAME}/first-dir" \
 2679 "first-dir"
 2680       dotest basicb-9e "cat newdir/first-dir/Emptydir/CVS/Repository" \
 2681 "${CVSROOT_DIRNAME}/first-dir/Emptydir" \
 2682 "first-dir/Emptydir"
 2683       dotest basicb-9f "cat newdir/first-dir/sdir2/CVS/Repository" \
 2684 "${CVSROOT_DIRNAME}/first-dir/sdir2" \
 2685 "first-dir/sdir2"
 2686 
 2687       dotest basicb-10 "cat newdir/first-dir/Emptydir/sfile1 newdir/first-dir/sdir2/sfile2" \
 2688 "sfile1 develops
 2689 sfile2 starts"
 2690 
 2691       rm -r newdir
 2692 
 2693       # Hmm, this might be a case for CVSNULLREPOS, but CVS doesn't
 2694       # seem to deal with it...
 2695       if false; then
 2696       dotest basicb-11 "${testcvs} -q co -d sub1/sub2 first-dir" \
 2697 "U sub1/sub2/Emptydir/sfile1
 2698 U sub1/sub2/sdir2/sfile2"
 2699       cd sub1
 2700       dotest basicb-12 "${testcvs} -q update ./." ''
 2701       touch xx
 2702       dotest basicb-13 "${testcvs} add xx" fixme
 2703       cd ..
 2704       rm -r sub1
 2705       # to test: sub1/sub2/sub3
 2706       fi # end of tests commented out.
 2707 
 2708       # Create a second directory.
 2709       mkdir 1
 2710       cd 1
 2711       dotest basicb-14 "${testcvs} -q co -l ." 'U topfile'
 2712       mkdir second-dir
 2713       dotest basicb-15 "${testcvs} add second-dir" \
 2714 "Directory ${CVSROOT_DIRNAME}/second-dir added to the repository"
 2715       cd second-dir
 2716       touch aa
 2717       dotest basicb-16 "${testcvs} add aa" \
 2718 "${PROG} add: scheduling file .aa. for addition
 2719 ${PROG} add: use .${PROG} commit. to add this file permanently"
 2720       dotest basicb-17 "${testcvs} -q ci -m add" \
 2721 "RCS file: ${CVSROOT_DIRNAME}/second-dir/aa,v
 2722 done
 2723 Checking in aa;
 2724 ${CVSROOT_DIRNAME}/second-dir/aa,v  <--  aa
 2725 initial revision: 1\.1
 2726 done"
 2727       cd ..
 2728 
 2729       # Try to remove all revisions in a file.
 2730       dotest_fail basicb-o1 "${testcvs} admin -o1.1 topfile" \
 2731 "RCS file: ${CVSROOT_DIRNAME}/topfile,v
 2732 deleting revision 1\.1
 2733 ${PROG} \[admin aborted\]: attempt to delete all revisions"
 2734       dotest basicb-o2 "${testcvs} -q update -d first-dir" \
 2735 "U first-dir/Emptydir/sfile1
 2736 U first-dir/sdir2/sfile2"
 2737       dotest_fail basicb-o3 \
 2738 "${testcvs} admin -o1.1:1.2 first-dir/sdir2/sfile2" \
 2739 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v
 2740 deleting revision 1\.2
 2741 deleting revision 1\.1
 2742 ${PROG} \[admin aborted\]: attempt to delete all revisions"
 2743       cd ..
 2744       rm -r 1
 2745 
 2746       mkdir 1; cd 1
 2747       # Note that -H is an illegal option.
 2748       # I suspect that the choice between "illegal" and "invalid"
 2749       # depends on the user's environment variables, the phase
 2750       # of the moon (weirdness with optind), and who knows what else.
 2751       # I've been seeing "illegal"...
 2752       dotest_fail basicb-21 "${testcvs} -q admin -H" \
 2753 "admin: illegal option -- H
 2754 ${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information" \
 2755 "admin: invalid option -- H
 2756 ${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information"
 2757       cd ..
 2758       rmdir 1
 2759 
 2760       if $keep; then
 2761         echo Keeping ${TESTDIR} and exiting due to --keep
 2762         exit 0
 2763       fi
 2764 
 2765       rm -rf ${CVSROOT_DIRNAME}/first-dir
 2766       rm -rf ${CVSROOT_DIRNAME}/second-dir
 2767       rm -f ${CVSROOT_DIRNAME}/topfile,v
 2768       ;;
 2769 
 2770     basicc)
 2771       # More tests of basic/miscellaneous functionality.
 2772       mkdir 1; cd 1
 2773       dotest_fail basicc-1 "${testcvs} diff" \
 2774 "${PROG} [a-z]*: in directory \.:
 2775 ${PROG} \[[a-z]* aborted\]: there is no version here; run .${PROG} checkout. first"
 2776       dotest basicc-2 "${testcvs} -q co -l ." ''
 2777       mkdir first-dir second-dir
 2778       dotest basicc-3 "${testcvs} add first-dir second-dir" \
 2779 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository
 2780 Directory ${CVSROOT_DIRNAME}/second-dir added to the repository"
 2781       # Old versions of CVS often didn't create this top-level CVS
 2782       # directory in the first place.  I think that maybe the only
 2783       # way to get it to work currently is to let CVS create it,
 2784       # and then blow it away (don't complain if it does not
 2785       # exist).  But that is perfectly legal; people who are used
 2786       # to the old behavior especially may be interested.
 2787       # FIXME: this test is intended for the TopLevelAdmin=yes case;
 2788       # should adjust/move it accordingly.
 2789       rm -rf CVS
 2790       dotest basicc-4 "echo *" "first-dir second-dir"
 2791       dotest basicc-5 "${testcvs} update" \
 2792 "${PROG} update: Updating first-dir
 2793 ${PROG} update: Updating second-dir" \
 2794 "${PROG} update: Updating \.
 2795 ${PROG} update: Updating first-dir
 2796 ${PROG} update: Updating second-dir"
 2797 
 2798       cd first-dir
 2799       dotest basicc-6 "${testcvs} release -d" ""
 2800       dotest basicc-7 "test -d ../first-dir" ""
 2801       # The Linux 2.2 kernel lets you delete ".".  That's OK either way,
 2802       # the point is that CVS must not mess with anything *outside* "."
 2803       # the way that CVS 1.10 and older tried to.
 2804       dotest basicc-8 "${testcvs} -Q release -d ." \
 2805 "" "${PROG} release: deletion of directory \. failed: .*"
 2806       dotest basicc-9 "test -d ../second-dir" ""
 2807       # For CVS to make a syntactic check for "." wouldn't suffice.
 2808       # On Linux 2.2 systems, the cwd may be gone, so we recreate it
 2809           # to allow basicc-11 to actually happen 
 2810       if test ! -d ../first-dir; then
 2811         # Apparently `cd ..' doesn't work with Linux 2.2 & Bash 2.05b.
 2812         cd $TESTDIR/1
 2813         mkdir ./first-dir
 2814             cd ./first-dir
 2815       fi
 2816       dotest basicc-11 "${testcvs} -Q release -d ./." \
 2817 "" "${PROG} release: deletion of directory \./\. failed: .*"
 2818       dotest basicc-11a "test -d ../second-dir" ""
 2819 
 2820       cd ../..
 2821 
 2822       mkdir 2; cd 2
 2823       dotest basicc-12 "${testcvs} -Q co ." ""
 2824       # actual entries can be in either Entries or Entries.log, do
 2825       # an update to get them consolidated into Entries
 2826       dotest basicc-12a "${testcvs} -Q up" ""
 2827       dotest basicc-12b "cat CVS/Entries" \
 2828 "D/CVSROOT////
 2829 D/first-dir////
 2830 D/second-dir////"
 2831       dotest basicc-13 "echo *" "CVS CVSROOT first-dir second-dir"
 2832       dotest basicc-14 "${testcvs} -Q release first-dir second-dir" ""
 2833       # a normal release shouldn't affect the Entries file
 2834       dotest basicc-14b "cat CVS/Entries" \
 2835 "D/CVSROOT////
 2836 D/first-dir////
 2837 D/second-dir////"
 2838       # FIXCVS: but release -d probably should
 2839       dotest basicc-15 "${testcvs} -Q release -d first-dir second-dir" ""
 2840       dotest basicc-16 "echo *" "CVS CVSROOT"
 2841       dotest basicc-17 "cat CVS/Entries" \
 2842 "D/CVSROOT////
 2843 D/first-dir////
 2844 D/second-dir////"
 2845       # FIXCVS: if not, update should notice the missing directories
 2846       # and update Entries accordingly
 2847       dotest basicc-18 "${testcvs} -Q up" ""
 2848       dotest basicc-19 "cat CVS/Entries" \
 2849 "D/CVSROOT////
 2850 D/first-dir////
 2851 D/second-dir////"
 2852 
 2853       cd ..
 2854       rm -r 1 2
 2855       rm -rf ${CVSROOT_DIRNAME}/first-dir
 2856       ;;
 2857 
 2858     basic1)
 2859       # first dive - add a files, first singly, then in a group.
 2860       mkdir ${CVSROOT_DIRNAME}/first-dir
 2861       mkdir basic1; cd basic1
 2862       # check out an empty directory
 2863       dotest basic1-1 "${testcvs} -q co first-dir" ''
 2864 
 2865       cd first-dir
 2866       echo file2 >file2
 2867       echo file3 >file3
 2868       echo file4 >file4
 2869       echo file5 >file5
 2870 
 2871       dotest basic1-14-add-add "${testcvs} add file2 file3 file4 file5" \
 2872 "${PROG} add: scheduling file \`file2' for addition
 2873 ${PROG} add: scheduling file \`file3' for addition
 2874 ${PROG} add: scheduling file \`file4' for addition
 2875 ${PROG} add: scheduling file \`file5' for addition
 2876 ${PROG} add: use .${PROG} commit. to add these files permanently"
 2877       dotest basic1-15-add-add \
 2878 "${testcvs} -q update file2 file3 file4 file5" \
 2879 "A file2
 2880 A file3
 2881 A file4
 2882 A file5"
 2883       dotest basic1-16-add-add "${testcvs} -q update" \
 2884 "A file2
 2885 A file3
 2886 A file4
 2887 A file5"
 2888       dotest basic1-17-add-add "${testcvs} -q status" \
 2889 "===================================================================
 2890 File: file2             Status: Locally Added
 2891 
 2892    Working revision:    New file!
 2893    Repository revision: No revision control file
 2894    Sticky Tag:      (none)
 2895    Sticky Date:     (none)
 2896    Sticky Options:  (none)
 2897 
 2898 ===================================================================
 2899 File: file3             Status: Locally Added
 2900 
 2901    Working revision:    New file!
 2902    Repository revision: No revision control file
 2903    Sticky Tag:      (none)
 2904    Sticky Date:     (none)
 2905    Sticky Options:  (none)
 2906 
 2907 ===================================================================
 2908 File: file4             Status: Locally Added
 2909 
 2910    Working revision:    New file!
 2911    Repository revision: No revision control file
 2912    Sticky Tag:      (none)
 2913    Sticky Date:     (none)
 2914    Sticky Options:  (none)
 2915 
 2916 ===================================================================
 2917 File: file5             Status: Locally Added
 2918 
 2919    Working revision:    New file!
 2920    Repository revision: No revision control file
 2921    Sticky Tag:      (none)
 2922    Sticky Date:     (none)
 2923    Sticky Options:  (none)"
 2924       dotest basic1-18-add-add "${testcvs} -q log" \
 2925 "${PROG} log: file2 has been added, but not committed
 2926 ${PROG} log: file3 has been added, but not committed
 2927 ${PROG} log: file4 has been added, but not committed
 2928 ${PROG} log: file5 has been added, but not committed"
 2929       cd ..
 2930       dotest basic1-21-add-add "${testcvs} -q update" \
 2931 "A first-dir/file2
 2932 A first-dir/file3
 2933 A first-dir/file4
 2934 A first-dir/file5"
 2935       # FIXCVS?  Shouldn't this read first-dir/file2 instead of file2?
 2936       dotest basic1-22-add-add "${testcvs} log first-dir" \
 2937 "${PROG} log: Logging first-dir
 2938 ${PROG} log: file2 has been added, but not committed
 2939 ${PROG} log: file3 has been added, but not committed
 2940 ${PROG} log: file4 has been added, but not committed
 2941 ${PROG} log: file5 has been added, but not committed"
 2942       dotest basic1-23-add-add "${testcvs} status first-dir" \
 2943 "${PROG} status: Examining first-dir
 2944 ===================================================================
 2945 File: file2             Status: Locally Added
 2946 
 2947    Working revision:    New file!
 2948    Repository revision: No revision control file
 2949    Sticky Tag:      (none)
 2950    Sticky Date:     (none)
 2951    Sticky Options:  (none)
 2952 
 2953 ===================================================================
 2954 File: file3             Status: Locally Added
 2955 
 2956    Working revision:    New file!
 2957    Repository revision: No revision control file
 2958    Sticky Tag:      (none)
 2959    Sticky Date:     (none)
 2960    Sticky Options:  (none)
 2961 
 2962 ===================================================================
 2963 File: file4             Status: Locally Added
 2964 
 2965    Working revision:    New file!
 2966    Repository revision: No revision control file
 2967    Sticky Tag:      (none)
 2968    Sticky Date:     (none)
 2969    Sticky Options:  (none)
 2970 
 2971 ===================================================================
 2972 File: file5             Status: Locally Added
 2973 
 2974    Working revision:    New file!
 2975    Repository revision: No revision control file
 2976    Sticky Tag:      (none)
 2977    Sticky Date:     (none)
 2978    Sticky Options:  (none)"
 2979       dotest basic1-24-add-add "${testcvs} update first-dir" \
 2980 "${PROG} update: Updating first-dir
 2981 A first-dir/file2
 2982 A first-dir/file3
 2983 A first-dir/file4
 2984 A first-dir/file5"
 2985       dotest basic1-27-add-add "${testcvs} co first-dir" \
 2986 "${PROG} checkout: Updating first-dir
 2987 A first-dir/file2
 2988 A first-dir/file3
 2989 A first-dir/file4
 2990 A first-dir/file5"
 2991       cd first-dir
 2992       dotest basic1-14-add-ci \
 2993 "${testcvs} commit -m test file2 file3 file4 file5" \
 2994 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
 2995 done
 2996 Checking in file2;
 2997 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 2998 initial revision: 1\.1
 2999 done
 3000 RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v
 3001 done
 3002 Checking in file3;
 3003 ${CVSROOT_DIRNAME}/first-dir/file3,v  <--  file3
 3004 initial revision: 1\.1
 3005 done
 3006 RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v
 3007 done
 3008 Checking in file4;
 3009 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 3010 initial revision: 1\.1
 3011 done
 3012 RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v
 3013 done
 3014 Checking in file5;
 3015 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 3016 initial revision: 1\.1
 3017 done"
 3018       dotest basic1-15-add-ci \
 3019 "${testcvs} -q update file2 file3 file4 file5" ''
 3020       dotest basic1-16-add-ci "${testcvs} -q update" ''
 3021       dotest basic1-17-add-ci "${testcvs} -q status" \
 3022 "===================================================================
 3023 File: file2             Status: Up-to-date
 3024 
 3025    Working revision:    1\.1.*
 3026    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file2,v
 3027    Sticky Tag:      (none)
 3028    Sticky Date:     (none)
 3029    Sticky Options:  (none)
 3030 
 3031 ===================================================================
 3032 File: file3             Status: Up-to-date
 3033 
 3034    Working revision:    1\.1.*
 3035    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file3,v
 3036    Sticky Tag:      (none)
 3037    Sticky Date:     (none)
 3038    Sticky Options:  (none)
 3039 
 3040 ===================================================================
 3041 File: file4             Status: Up-to-date
 3042 
 3043    Working revision:    1\.1.*
 3044    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file4,v
 3045    Sticky Tag:      (none)
 3046    Sticky Date:     (none)
 3047    Sticky Options:  (none)
 3048 
 3049 ===================================================================
 3050 File: file5             Status: Up-to-date
 3051 
 3052    Working revision:    1\.1.*
 3053    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file5,v
 3054    Sticky Tag:      (none)
 3055    Sticky Date:     (none)
 3056    Sticky Options:  (none)"
 3057       # The "log" tests and friends probably already test the output 
 3058       # from log quite adequately.
 3059       # Note: using dotest fails here.  It seems to be related
 3060       # to the output being sufficiently large (Red Hat 4.1).
 3061       # dotest basic1-18-add-ci "${testcvs} log" "${DOTSTAR}"
 3062       if ${testcvs} -q log >>${LOGFILE}; then
 3063         pass basic1-18-add-ci
 3064       else
 3065         pass basic1-18-add-ci
 3066       fi
 3067       cd ..
 3068       dotest basic1-21-add-ci "${testcvs} -q update" ''
 3069       # See test basic1-18-add-ci for explanation of non-use of dotest.
 3070       if ${testcvs} -q log first-dir >>${LOGFILE}; then
 3071         pass basic1-22-add-ci
 3072       else
 3073         pass basic1-22-add-ci
 3074       fi
 3075       # At least for the moment I am going to consider 17-add-ci
 3076       # an adequate test of the output here.
 3077       # See test basic1-18-add-ci for explanation of non-use of dotest.
 3078       if ${testcvs} -q status first-dir >>${LOGFILE}; then
 3079         pass basic1-23-add-ci
 3080       else
 3081         pass basic1-23-add-ci
 3082       fi
 3083       dotest basic1-24-add-ci "${testcvs} -q update first-dir" ''
 3084       dotest basic1-27-add-ci "${testcvs} -q co first-dir" ''
 3085 
 3086       cd first-dir
 3087       rm file2 file3 file4 file5
 3088       dotest basic1-14-rm-rm "${testcvs} rm file2 file3 file4 file5" \
 3089 "${PROG} remove: scheduling .file2. for removal
 3090 ${PROG} remove: scheduling .file3. for removal
 3091 ${PROG} remove: scheduling .file4. for removal
 3092 ${PROG} remove: scheduling .file5. for removal
 3093 ${PROG} remove: use .${PROG} commit. to remove these files permanently"
 3094       # 15-rm-rm was commented out.  Why?
 3095       dotest basic1-15-rm-rm \
 3096 "${testcvs} -q update file2 file3 file4 file5" \
 3097 "R file2
 3098 R file3
 3099 R file4
 3100 R file5"
 3101       dotest basic1-16-rm-rm "${testcvs} -q update" \
 3102 "R file2
 3103 R file3
 3104 R file4
 3105 R file5"
 3106       dotest basic1-17-rm-rm "${testcvs} -q status" \
 3107 "===================================================================
 3108 File: no file file2     Status: Locally Removed
 3109 
 3110    Working revision:    -1\.1.*
 3111    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file2,v
 3112    Sticky Tag:      (none)
 3113    Sticky Date:     (none)
 3114    Sticky Options:  (none)
 3115 
 3116 ===================================================================
 3117 File: no file file3     Status: Locally Removed
 3118 
 3119    Working revision:    -1\.1.*
 3120    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file3,v
 3121    Sticky Tag:      (none)
 3122    Sticky Date:     (none)
 3123    Sticky Options:  (none)
 3124 
 3125 ===================================================================
 3126 File: no file file4     Status: Locally Removed
 3127 
 3128    Working revision:    -1\.1.*
 3129    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file4,v
 3130    Sticky Tag:      (none)
 3131    Sticky Date:     (none)
 3132    Sticky Options:  (none)
 3133 
 3134 ===================================================================
 3135 File: no file file5     Status: Locally Removed
 3136 
 3137    Working revision:    -1\.1.*
 3138    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file5,v
 3139    Sticky Tag:      (none)
 3140    Sticky Date:     (none)
 3141    Sticky Options:  (none)"
 3142       # Would be nice to test that real logs appear (with dead state
 3143       # and all), either here or someplace like log2 tests.
 3144       if ${testcvs} -q log >>${LOGFILE}; then
 3145         pass basic1-18-rm-rm
 3146       else
 3147         fail basic1-18-rm-rm
 3148       fi
 3149       cd ..
 3150       dotest basic1-21-rm-rm "${testcvs} -q update" \
 3151 "R first-dir/file2
 3152 R first-dir/file3
 3153 R first-dir/file4
 3154 R first-dir/file5"
 3155       if ${testcvs} -q log first-dir >>${LOGFILE}; then
 3156         pass basic1-22-rm-rm
 3157       else
 3158         fail basic1-22-rm-rm
 3159       fi
 3160       if ${testcvs} -q status first-dir >>${LOGFILE}; then
 3161         pass basic1-23-rm-rm
 3162       else
 3163         fail basic1-23-rm-rm
 3164       fi
 3165       dotest basic1-24-rm-rm "${testcvs} -q update first-dir" \
 3166 "R first-dir/file2
 3167 R first-dir/file3
 3168 R first-dir/file4
 3169 R first-dir/file5"
 3170       dotest basic1-27-rm-rm "${testcvs} -q co first-dir" \
 3171 "R first-dir/file2
 3172 R first-dir/file3
 3173 R first-dir/file4
 3174 R first-dir/file5"
 3175       cd first-dir
 3176       dotest basic1-14-rm-ci "${testcvs} -q commit -m test" \
 3177 "Removing file2;
 3178 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 3179 new revision: delete; previous revision: 1\.1
 3180 done
 3181 Removing file3;
 3182 ${CVSROOT_DIRNAME}/first-dir/file3,v  <--  file3
 3183 new revision: delete; previous revision: 1\.1
 3184 done
 3185 Removing file4;
 3186 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 3187 new revision: delete; previous revision: 1\.1
 3188 done
 3189 Removing file5;
 3190 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 3191 new revision: delete; previous revision: 1\.1
 3192 done"
 3193       dotest basic1-15-rm-ci \
 3194 "${testcvs} -q update file2 file3 file4 file5" ''
 3195       dotest basic1-16-rm-ci "${testcvs} -q update" ''
 3196       dotest basic1-17-rm-ci "${testcvs} -q status" ''
 3197       # Would be nice to test that real logs appear (with dead state
 3198       # and all), either here or someplace like log2 tests.
 3199       if ${testcvs} -q log >>${LOGFILE}; then
 3200         pass basic1-18-rm-ci
 3201       else
 3202         fail basic1-18-rm-ci
 3203       fi
 3204       cd ..
 3205       dotest basic1-21-rm-ci "${testcvs} -q update" ''
 3206       if ${testcvs} -q log first-dir >>${LOGFILE}; then
 3207         pass basic1-22-rm-ci
 3208       else
 3209         fail basic1-22-rm-ci
 3210       fi
 3211       if ${testcvs} -q status first-dir >>${LOGFILE}; then
 3212         pass basic1-23-rm-ci
 3213       else
 3214         fail basic1-23-rm-ci
 3215       fi
 3216       dotest basic1-24-rm-ci "${testcvs} -q update first-dir" ''
 3217       dotest basic1-27-rm-ci "${testcvs} -q co first-dir" ''
 3218       cd first-dir
 3219       # All the files are removed, so nothing gets tagged.
 3220       dotest basic1-28 "${testcvs} -q tag first-dive" ''
 3221       cd ..
 3222       cd ..
 3223 
 3224       if $keep; then
 3225         echo Keeping ${TESTDIR} and exiting due to --keep
 3226         exit 0
 3227       fi
 3228 
 3229       rm -r basic1
 3230       rm -rf ${CVSROOT_DIRNAME}/first-dir
 3231       ;;
 3232 
 3233     deep)
 3234       # Test the ability to operate on directories nested rather deeply.
 3235       mkdir ${CVSROOT_DIRNAME}/first-dir
 3236       dotest deep-1 "${testcvs} -q co first-dir" ''
 3237       cd first-dir
 3238       for i in dir1 dir2 dir3 dir4 dir5 dir6 dir7 dir8; do
 3239         mkdir $i
 3240         dotest deep-2-$i "${testcvs} add $i" \
 3241 "Directory ${CVSROOT_DIRNAME}/first-dir/dir1[/dir0-9]* added to the repository"
 3242         cd $i
 3243         echo file1 >file1
 3244         dotest deep-3-$i "${testcvs} add file1" \
 3245 "${PROG}"' add: scheduling file `file1'\'' for addition
 3246 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 3247       done
 3248       cd ../../../../../../../../..
 3249       dotest_lit deep-4 "${testcvs} -q ci -m add-them first-dir" <<HERE
 3250 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file1,v
 3251 done
 3252 Checking in first-dir/dir1/file1;
 3253 ${CVSROOT_DIRNAME}/first-dir/dir1/file1,v  <--  file1
 3254 initial revision: 1.1
 3255 done
 3256 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file1,v
 3257 done
 3258 Checking in first-dir/dir1/dir2/file1;
 3259 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file1,v  <--  file1
 3260 initial revision: 1.1
 3261 done
 3262 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/file1,v
 3263 done
 3264 Checking in first-dir/dir1/dir2/dir3/file1;
 3265 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/file1,v  <--  file1
 3266 initial revision: 1.1
 3267 done
 3268 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/file1,v
 3269 done
 3270 Checking in first-dir/dir1/dir2/dir3/dir4/file1;
 3271 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/file1,v  <--  file1
 3272 initial revision: 1.1
 3273 done
 3274 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/file1,v
 3275 done
 3276 Checking in first-dir/dir1/dir2/dir3/dir4/dir5/file1;
 3277 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/file1,v  <--  file1
 3278 initial revision: 1.1
 3279 done
 3280 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1,v
 3281 done
 3282 Checking in first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1;
 3283 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1,v  <--  file1
 3284 initial revision: 1.1
 3285 done
 3286 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file1,v
 3287 done
 3288 Checking in first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file1;
 3289 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file1,v  <--  file1
 3290 initial revision: 1.1
 3291 done
 3292 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v
 3293 done
 3294 Checking in first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1;
 3295 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v  <--  file1
 3296 initial revision: 1.1
 3297 done
 3298 HERE
 3299 
 3300       cd first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8
 3301       rm file1
 3302       dotest deep-4a0 "${testcvs} rm file1" \
 3303 "${PROG} remove: scheduling .file1. for removal
 3304 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 3305       dotest deep-4a1 "${testcvs} -q ci -m rm-it" "Removing file1;
 3306 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v  <--  file1
 3307 new revision: delete; previous revision: 1\.1
 3308 done"
 3309       cd ../../..
 3310       dotest deep-4a2 "${testcvs} -q update -P dir6/dir7" ''
 3311       # Should be using "test -e" if that is portable enough.
 3312       dotest_fail deep-4a3 "test -d dir6/dir7/dir8" ''
 3313 
 3314       # Test that if we remove the working directory, CVS does not
 3315       # recreate it.  (I realize that this behavior is what the
 3316       # users expect, but in the longer run we might want to
 3317       # re-think it.  The corresponding behavior for a file is that
 3318       # CVS *will* recreate it, and we might want to make it so
 3319       # that "cvs release -d" is the way to delete the directory
 3320       # and have it stay gone -kingdon, Oct1996).
 3321       rm -r dir6
 3322       dotest deep-4b0a "${testcvs} -q diff" ''
 3323       dotest deep-4b0b "${testcvs} -q ci" ''
 3324       dotest deep-4b1 "${testcvs} -q update" ''
 3325       dotest deep-4b2 "${testcvs} -q update -d -P" \
 3326 'U dir6/file1
 3327 U dir6/dir7/file1'
 3328 
 3329       # Test what happens if one uses -P when there are files removed
 3330       # but not committed.
 3331       cd dir6/dir7
 3332       dotest deep-rm1 "${testcvs} rm -f file1" \
 3333 "${PROG} remove: scheduling .file1. for removal
 3334 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 3335       cd ..
 3336       dotest deep-rm2 "${testcvs} -q update -d -P" 'R dir7/file1'
 3337       dotest deep-rm3 "test -d dir7" ''
 3338       dotest deep-rm4 "${testcvs} -q ci -m rm-it" "Removing dir7/file1;
 3339 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file1,v  <--  file1
 3340 new revision: delete; previous revision: 1\.1
 3341 done"
 3342       dotest deep-rm5 "${testcvs} -q update -d -P" ''
 3343       dotest_fail deep-rm6 "test -d dir7" ''
 3344 
 3345       # Test rm -f -R.
 3346       cd ../..
 3347       dotest deep-rm7 "${testcvs} rm -f -R dir5" \
 3348 "${PROG} remove: Removing dir5
 3349 ${PROG} remove: scheduling .dir5/file1. for removal
 3350 ${PROG} remove: Removing dir5/dir6
 3351 ${PROG} remove: scheduling .dir5/dir6/file1. for removal
 3352 ${PROG} remove: use .${PROG} commit. to remove these files permanently"
 3353       dotest deep-rm8 "${testcvs} -q ci -m rm-it" \
 3354 "Removing dir5/file1;
 3355 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/file1,v  <--  file1
 3356 new revision: delete; previous revision: 1\.1
 3357 done
 3358 Removing dir5/dir6/file1;
 3359 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1,v  <--  file1
 3360 new revision: delete; previous revision: 1\.1
 3361 done"
 3362       dotest deep-rm9 "${testcvs} -q update -d -P" ''
 3363       dotest_fail deep-rm10 "test -d dir5"
 3364 
 3365       cd ../../../../..
 3366 
 3367       if echo "yes" | ${testcvs} release -d first-dir >>${LOGFILE}; then
 3368         pass deep-5
 3369       else
 3370         fail deep-5
 3371       fi
 3372       rm -rf ${CVSROOT_DIRNAME}/first-dir
 3373       ;;
 3374 
 3375     basic2)
 3376         # Test rtag, import, history, various miscellaneous operations
 3377 
 3378         # NOTE: this section has reached the size and
 3379         # complexity where it is getting to be a good idea to
 3380         # add new tests to a new section rather than
 3381         # continuing to piggyback them onto the tests here.
 3382 
 3383         # First empty the history file
 3384         rm ${CVSROOT_DIRNAME}/CVSROOT/history
 3385         touch ${CVSROOT_DIRNAME}/CVSROOT/history
 3386 
 3387 ### XXX maybe should use 'cvs imprt -b1 -m new-module first-dir F F1' in an
 3388 ### empty directory to do this instead of hacking directly into $CVSROOT
 3389         mkdir ${CVSROOT_DIRNAME}/first-dir
 3390         dotest basic2-1 "${testcvs} -q co first-dir" ''
 3391         for i in first-dir dir1 dir2 ; do
 3392             if test ! -d $i ; then
 3393                 mkdir $i
 3394                 dotest basic2-2-$i "${testcvs} add $i" \
 3395 "Directory ${CVSROOT_DIRNAME}/.*/$i added to the repository"
 3396             fi
 3397 
 3398             cd $i
 3399 
 3400             for j in file6 file7; do
 3401                 echo $j > $j
 3402             done
 3403 
 3404             dotest basic2-3-$i "${testcvs} add file6 file7" \
 3405 "${PROG} add: scheduling file .file6. for addition
 3406 ${PROG} add: scheduling file .file7. for addition
 3407 ${PROG} add: use .${PROG} commit. to add these files permanently"
 3408 
 3409         done
 3410         cd ../../..
 3411         dotest basic2-4 "${testcvs} update first-dir" \
 3412 "${PROG} update: Updating first-dir
 3413 A first-dir/file6
 3414 A first-dir/file7
 3415 ${PROG} update: Updating first-dir/dir1
 3416 A first-dir/dir1/file6
 3417 A first-dir/dir1/file7
 3418 ${PROG} update: Updating first-dir/dir1/dir2
 3419 A first-dir/dir1/dir2/file6
 3420 A first-dir/dir1/dir2/file7"
 3421 
 3422         # fixme: doesn't work right for added files.
 3423         dotest basic2-5 "${testcvs} log first-dir" \
 3424 "${PROG} log: Logging first-dir
 3425 ${PROG} log: file6 has been added, but not committed
 3426 ${PROG} log: file7 has been added, but not committed
 3427 ${PROG} log: Logging first-dir/dir1
 3428 ${PROG} log: file6 has been added, but not committed
 3429 ${PROG} log: file7 has been added, but not committed
 3430 ${PROG} log: Logging first-dir/dir1/dir2
 3431 ${PROG} log: file6 has been added, but not committed
 3432 ${PROG} log: file7 has been added, but not committed"
 3433 
 3434         dotest basic2-6 "${testcvs} status first-dir" \
 3435 "${PROG} status: Examining first-dir
 3436 ===================================================================
 3437 File: file6             Status: Locally Added
 3438 
 3439    Working revision:    New file!
 3440    Repository revision: No revision control file
 3441    Sticky Tag:      (none)
 3442    Sticky Date:     (none)
 3443    Sticky Options:  (none)
 3444 
 3445 ===================================================================
 3446 File: file7             Status: Locally Added
 3447 
 3448    Working revision:    New file!
 3449    Repository revision: No revision control file
 3450    Sticky Tag:      (none)
 3451    Sticky Date:     (none)
 3452    Sticky Options:  (none)
 3453 
 3454 ${PROG} status: Examining first-dir/dir1
 3455 ===================================================================
 3456 File: file6             Status: Locally Added
 3457 
 3458    Working revision:    New file!
 3459    Repository revision: No revision control file
 3460    Sticky Tag:      (none)
 3461    Sticky Date:     (none)
 3462    Sticky Options:  (none)
 3463 
 3464 ===================================================================
 3465 File: file7             Status: Locally Added
 3466 
 3467    Working revision:    New file!
 3468    Repository revision: No revision control file
 3469    Sticky Tag:      (none)
 3470    Sticky Date:     (none)
 3471    Sticky Options:  (none)
 3472 
 3473 ${PROG} status: Examining first-dir/dir1/dir2
 3474 ===================================================================
 3475 File: file6             Status: Locally Added
 3476 
 3477    Working revision:    New file!
 3478    Repository revision: No revision control file
 3479    Sticky Tag:      (none)
 3480    Sticky Date:     (none)
 3481    Sticky Options:  (none)
 3482 
 3483 ===================================================================
 3484 File: file7             Status: Locally Added
 3485 
 3486    Working revision:    New file!
 3487    Repository revision: No revision control file
 3488    Sticky Tag:      (none)
 3489    Sticky Date:     (none)
 3490    Sticky Options:  (none)"
 3491 
 3492 # XXX why is this commented out???
 3493 #       if ${CVS} diff -u first-dir   >> ${LOGFILE} || test $? = 1 ; then
 3494 #           pass 34
 3495 #       else
 3496 #           fail 34
 3497 #       fi
 3498 
 3499         dotest basic2-8 "${testcvs} -q ci -m 'second dive' first-dir" \
 3500 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v
 3501 done
 3502 Checking in first-dir/file6;
 3503 ${CVSROOT_DIRNAME}/first-dir/file6,v  <--  file6
 3504 initial revision: 1\.1
 3505 done
 3506 RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v
 3507 done
 3508 Checking in first-dir/file7;
 3509 ${CVSROOT_DIRNAME}/first-dir/file7,v  <--  file7
 3510 initial revision: 1\.1
 3511 done
 3512 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v
 3513 done
 3514 Checking in first-dir/dir1/file6;
 3515 ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v  <--  file6
 3516 initial revision: 1\.1
 3517 done
 3518 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v
 3519 done
 3520 Checking in first-dir/dir1/file7;
 3521 ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v  <--  file7
 3522 initial revision: 1\.1
 3523 done
 3524 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v
 3525 done
 3526 Checking in first-dir/dir1/dir2/file6;
 3527 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v  <--  file6
 3528 initial revision: 1\.1
 3529 done
 3530 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v
 3531 done
 3532 Checking in first-dir/dir1/dir2/file7;
 3533 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v  <--  file7
 3534 initial revision: 1\.1
 3535 done"
 3536 
 3537         dotest basic2-9 "${testcvs} tag second-dive first-dir" \
 3538 "${PROG} tag: Tagging first-dir
 3539 T first-dir/file6
 3540 T first-dir/file7
 3541 ${PROG} tag: Tagging first-dir/dir1
 3542 T first-dir/dir1/file6
 3543 T first-dir/dir1/file7
 3544 ${PROG} tag: Tagging first-dir/dir1/dir2
 3545 T first-dir/dir1/dir2/file6
 3546 T first-dir/dir1/dir2/file7"
 3547 
 3548         # third dive - in bunch o' directories, add bunch o' files,
 3549         # delete some, change some.
 3550 
 3551         for i in first-dir dir1 dir2 ; do
 3552             cd $i
 3553 
 3554             # modify a file
 3555             echo file6 >>file6
 3556 
 3557             # delete a file
 3558             rm file7
 3559 
 3560             dotest basic2-10-$i "${testcvs} rm file7" \
 3561 "${PROG} remove: scheduling .file7. for removal
 3562 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 3563 
 3564             # and add a new file
 3565             echo file14 >file14
 3566 
 3567             dotest basic2-11-$i "${testcvs} add file14" \
 3568 "${PROG} add: scheduling file .file14. for addition
 3569 ${PROG} add: use .${PROG} commit. to add this file permanently"
 3570         done
 3571 
 3572         cd ../../..
 3573         dotest basic2-12 "${testcvs} update first-dir" \
 3574 "${PROG} update: Updating first-dir
 3575 A first-dir/file14
 3576 M first-dir/file6
 3577 R first-dir/file7
 3578 ${PROG} update: Updating first-dir/dir1
 3579 A first-dir/dir1/file14
 3580 M first-dir/dir1/file6
 3581 R first-dir/dir1/file7
 3582 ${PROG} update: Updating first-dir/dir1/dir2
 3583 A first-dir/dir1/dir2/file14
 3584 M first-dir/dir1/dir2/file6
 3585 R first-dir/dir1/dir2/file7"
 3586 
 3587         # FIXME: doesn't work right for added files
 3588         dotest basic2-13 "${testcvs} log first-dir" \
 3589 "${PROG} log: Logging first-dir
 3590 ${PROG} log: file14 has been added, but not committed
 3591 
 3592 RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v
 3593 Working file: first-dir/file6
 3594 head: 1\.1
 3595 branch:
 3596 locks: strict
 3597 access list:
 3598 symbolic names:
 3599     second-dive: 1\.1
 3600 keyword substitution: kv
 3601 total revisions: 1; selected revisions: 1
 3602 description:
 3603 ----------------------------
 3604 revision 1\.1
 3605 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;
 3606 second dive
 3607 =============================================================================
 3608 
 3609 RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v
 3610 Working file: first-dir/file7
 3611 head: 1\.1
 3612 branch:
 3613 locks: strict
 3614 access list:
 3615 symbolic names:
 3616     second-dive: 1\.1
 3617 keyword substitution: kv
 3618 total revisions: 1; selected revisions: 1
 3619 description:
 3620 ----------------------------
 3621 revision 1\.1
 3622 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;
 3623 second dive
 3624 =============================================================================
 3625 ${PROG} log: Logging first-dir/dir1
 3626 ${PROG} log: file14 has been added, but not committed
 3627 
 3628 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v
 3629 Working file: first-dir/dir1/file6
 3630 head: 1\.1
 3631 branch:
 3632 locks: strict
 3633 access list:
 3634 symbolic names:
 3635     second-dive: 1\.1
 3636 keyword substitution: kv
 3637 total revisions: 1; selected revisions: 1
 3638 description:
 3639 ----------------------------
 3640 revision 1\.1
 3641 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;
 3642 second dive
 3643 =============================================================================
 3644 
 3645 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v
 3646 Working file: first-dir/dir1/file7
 3647 head: 1\.1
 3648 branch:
 3649 locks: strict
 3650 access list:
 3651 symbolic names:
 3652     second-dive: 1\.1
 3653 keyword substitution: kv
 3654 total revisions: 1; selected revisions: 1
 3655 description:
 3656 ----------------------------
 3657 revision 1\.1
 3658 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;
 3659 second dive
 3660 =============================================================================
 3661 ${PROG} log: Logging first-dir/dir1/dir2
 3662 ${PROG} log: file14 has been added, but not committed
 3663 
 3664 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v
 3665 Working file: first-dir/dir1/dir2/file6
 3666 head: 1\.1
 3667 branch:
 3668 locks: strict
 3669 access list:
 3670 symbolic names:
 3671     second-dive: 1\.1
 3672 keyword substitution: kv
 3673 total revisions: 1; selected revisions: 1
 3674 description:
 3675 ----------------------------
 3676 revision 1\.1
 3677 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;
 3678 second dive
 3679 =============================================================================
 3680 
 3681 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v
 3682 Working file: first-dir/dir1/dir2/file7
 3683 head: 1\.1
 3684 branch:
 3685 locks: strict
 3686 access list:
 3687 symbolic names:
 3688     second-dive: 1\.1
 3689 keyword substitution: kv
 3690 total revisions: 1; selected revisions: 1
 3691 description:
 3692 ----------------------------
 3693 revision 1\.1
 3694 date: [0-9/]* [0-9:]*;  author: ${username};  state: Exp;
 3695 second dive
 3696 ============================================================================="
 3697 
 3698         dotest basic2-14 "${testcvs} status first-dir" \
 3699 "${PROG} status: Examining first-dir
 3700 ===================================================================
 3701 File: file14            Status: Locally Added
 3702 
 3703    Working revision:    New file!
 3704    Repository revision: No revision control file
 3705    Sticky Tag:      (none)
 3706    Sticky Date:     (none)
 3707    Sticky Options:  (none)
 3708 
 3709 ===================================================================
 3710 File: file6             Status: Locally Modified
 3711 
 3712    Working revision:    1\.1.*
 3713    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file6,v
 3714    Sticky Tag:      (none)
 3715    Sticky Date:     (none)
 3716    Sticky Options:  (none)
 3717 
 3718 ===================================================================
 3719 File: no file file7     Status: Locally Removed
 3720 
 3721    Working revision:    -1\.1.*
 3722    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/file7,v
 3723    Sticky Tag:      (none)
 3724    Sticky Date:     (none)
 3725    Sticky Options:  (none)
 3726 
 3727 ${PROG} status: Examining first-dir/dir1
 3728 ===================================================================
 3729 File: file14            Status: Locally Added
 3730 
 3731    Working revision:    New file!
 3732    Repository revision: No revision control file
 3733    Sticky Tag:      (none)
 3734    Sticky Date:     (none)
 3735    Sticky Options:  (none)
 3736 
 3737 ===================================================================
 3738 File: file6             Status: Locally Modified
 3739 
 3740    Working revision:    1\.1.*
 3741    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v
 3742    Sticky Tag:      (none)
 3743    Sticky Date:     (none)
 3744    Sticky Options:  (none)
 3745 
 3746 ===================================================================
 3747 File: no file file7     Status: Locally Removed
 3748 
 3749    Working revision:    -1\.1.*
 3750    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v
 3751    Sticky Tag:      (none)
 3752    Sticky Date:     (none)
 3753    Sticky Options:  (none)
 3754 
 3755 ${PROG} status: Examining first-dir/dir1/dir2
 3756 ===================================================================
 3757 File: file14            Status: Locally Added
 3758 
 3759    Working revision:    New file!
 3760    Repository revision: No revision control file
 3761    Sticky Tag:      (none)
 3762    Sticky Date:     (none)
 3763    Sticky Options:  (none)
 3764 
 3765 ===================================================================
 3766 File: file6             Status: Locally Modified
 3767 
 3768    Working revision:    1\.1.*
 3769    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v
 3770    Sticky Tag:      (none)
 3771    Sticky Date:     (none)
 3772    Sticky Options:  (none)
 3773 
 3774 ===================================================================
 3775 File: no file file7     Status: Locally Removed
 3776 
 3777    Working revision:    -1\.1.*
 3778    Repository revision: 1\.1    ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v
 3779    Sticky Tag:      (none)
 3780    Sticky Date:     (none)
 3781    Sticky Options:  (none)"
 3782 
 3783 # XXX why is this commented out?
 3784 #       if ${CVS} diff -u first-dir  >> ${LOGFILE} || test $? = 1 ; then
 3785 #           pass 42
 3786 #       else
 3787 #           fail 42
 3788 #       fi
 3789 
 3790         dotest basic2-16 "${testcvs} ci -m 'third dive' first-dir" \
 3791 "${PROG} [a-z]*: Examining first-dir
 3792 ${PROG} [a-z]*: Examining first-dir/dir1
 3793 ${PROG} [a-z]*: Examining first-dir/dir1/dir2
 3794 RCS file: ${CVSROOT_DIRNAME}/first-dir/file14,v
 3795 done
 3796 Checking in first-dir/file14;
 3797 ${CVSROOT_DIRNAME}/first-dir/file14,v  <--  file14
 3798 initial revision: 1\.1
 3799 done
 3800 Checking in first-dir/file6;
 3801 ${CVSROOT_DIRNAME}/first-dir/file6,v  <--  file6
 3802 new revision: 1\.2; previous revision: 1\.1
 3803 done
 3804 Removing first-dir/file7;
 3805 ${CVSROOT_DIRNAME}/first-dir/file7,v  <--  file7
 3806 new revision: delete; previous revision: 1\.1
 3807 done
 3808 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file14,v
 3809 done
 3810 Checking in first-dir/dir1/file14;
 3811 ${CVSROOT_DIRNAME}/first-dir/dir1/file14,v  <--  file14
 3812 initial revision: 1\.1
 3813 done
 3814 Checking in first-dir/dir1/file6;
 3815 ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v  <--  file6
 3816 new revision: 1\.2; previous revision: 1\.1
 3817 done
 3818 Removing first-dir/dir1/file7;
 3819 ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v  <--  file7
 3820 new revision: delete; previous revision: 1\.1
 3821 done
 3822 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file14,v
 3823 done
 3824 Checking in first-dir/dir1/dir2/file14;
 3825 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file14,v  <--  file14
 3826 initial revision: 1\.1
 3827 done
 3828 Checking in first-dir/dir1/dir2/file6;
 3829 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v  <--  file6
 3830 new revision: 1\.2; previous revision: 1\.1
 3831 done
 3832 Removing first-dir/dir1/dir2/file7;
 3833 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v  <--  file7
 3834 new revision: delete; previous revision: 1\.1
 3835 done"
 3836         dotest basic2-17 "${testcvs} -q update first-dir" ''
 3837 
 3838         dotest basic2-18 "${testcvs} tag third-dive first-dir" \
 3839 "${PROG} tag: Tagging first-dir
 3840 T first-dir/file14
 3841 T first-dir/file6
 3842 ${PROG} tag: Tagging first-dir/dir1
 3843 T first-dir/dir1/file14
 3844 T first-dir/dir1/file6
 3845 ${PROG} tag: Tagging first-dir/dir1/dir2
 3846 T first-dir/dir1/dir2/file14
 3847 T first-dir/dir1/dir2/file6"
 3848 
 3849         dotest basic2-19 "echo yes | ${testcvs} release -d first-dir" \
 3850 "You have \[0\] altered files in this repository\.
 3851 Are you sure you want to release (and delete) directory .first-dir.: "
 3852 
 3853         # end of third dive
 3854         dotest_fail basic2-20 "test -d first-dir" ""
 3855 
 3856         # now try some rtags
 3857 
 3858         # rtag HEADS
 3859         dotest basic2-21 "${testcvs} rtag rtagged-by-head first-dir" \
 3860 "${PROG} rtag: Tagging first-dir
 3861 ${PROG} rtag: Tagging first-dir/dir1
 3862 ${PROG} rtag: Tagging first-dir/dir1/dir2"
 3863         # The next test used to cause an assert failure
 3864         # something like:
 3865         # cvs: ./recurse.c:667: do_recursion: Assertion `repository != ((void *)0)' failed.
 3866         dotest basic2-21b "${testcvs} co -p -r rtagged-by-head first-dir/file6" \
 3867 "===================================================================
 3868 Checking out first-dir/file6
 3869 RCS:  $CVSROOT_DIRNAME/first-dir/file6,v
 3870 VERS: 1\.2
 3871 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3872 file6
 3873 file6"
 3874         # tag by tag
 3875         dotest basic2-22 "${testcvs} rtag -r rtagged-by-head rtagged-by-tag first-dir" \
 3876 "${PROG} rtag: Tagging first-dir
 3877 ${PROG} rtag: Tagging first-dir/dir1
 3878 ${PROG} rtag: Tagging first-dir/dir1/dir2"
 3879 
 3880         # tag by revision
 3881         dotest basic2-23 "${testcvs} rtag -r1.1 rtagged-by-revision first-dir" \
 3882 "${PROG} rtag: Tagging first-dir
 3883 ${PROG} rtag: Tagging first-dir/dir1
 3884 ${PROG} rtag: Tagging first-dir/dir1/dir2"
 3885 
 3886         # rdiff by revision
 3887         dotest basic2-24 "${testcvs} rdiff -r1.1 -rrtagged-by-head first-dir" \
 3888 "${PROG} rdiff: Diffing first-dir
 3889 Index: first-dir/file6
 3890 diff -c first-dir/file6:1\.1 first-dir/file6:1\.2
 3891 \*\*\* first-dir/file6:1\.1 ${DATE}
 3892 --- first-dir/file6 ${DATE}
 3893 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3894 \*\*\* 1 \*\*\*\*
 3895 --- 1,2 ----
 3896   file6
 3897 ${PLUS} file6
 3898 Index: first-dir/file7
 3899 diff -c first-dir/file7:1\.1 first-dir/file7:removed
 3900 \*\*\* first-dir/file7:1.1  ${DATE}
 3901 --- first-dir/file7 ${DATE}
 3902 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3903 \*\*\* 1 \*\*\*\*
 3904 - file7
 3905 --- 0 ----
 3906 ${PROG} rdiff: Diffing first-dir/dir1
 3907 Index: first-dir/dir1/file6
 3908 diff -c first-dir/dir1/file6:1\.1 first-dir/dir1/file6:1\.2
 3909 \*\*\* first-dir/dir1/file6:1\.1    ${DATE}
 3910 --- first-dir/dir1/file6    ${DATE}
 3911 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3912 \*\*\* 1 \*\*\*\*
 3913 --- 1,2 ----
 3914   file6
 3915 ${PLUS} file6
 3916 Index: first-dir/dir1/file7
 3917 diff -c first-dir/dir1/file7:1\.1 first-dir/dir1/file7:removed
 3918 \*\*\* first-dir/dir1/file7:1\.1    ${DATE}
 3919 --- first-dir/dir1/file7    ${DATE}
 3920 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3921 \*\*\* 1 \*\*\*\*
 3922 - file7
 3923 --- 0 ----
 3924 ${PROG} rdiff: Diffing first-dir/dir1/dir2
 3925 Index: first-dir/dir1/dir2/file6
 3926 diff -c first-dir/dir1/dir2/file6:1\.1 first-dir/dir1/dir2/file6:1\.2
 3927 \*\*\* first-dir/dir1/dir2/file6:1\.1   ${DATE}
 3928 --- first-dir/dir1/dir2/file6   ${DATE}
 3929 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3930 \*\*\* 1 \*\*\*\*
 3931 --- 1,2 ----
 3932   file6
 3933 ${PLUS} file6
 3934 Index: first-dir/dir1/dir2/file7
 3935 diff -c first-dir/dir1/dir2/file7:1\.1 first-dir/dir1/dir2/file7:removed
 3936 \*\*\* first-dir/dir1/dir2/file7:1\.1   ${DATE}
 3937 --- first-dir/dir1/dir2/file7   ${DATE}
 3938 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3939 \*\*\* 1 \*\*\*\*
 3940 - file7
 3941 --- 0 ----"
 3942         dotest basic2-24a "${testcvs} rdiff -l -r1.1 -rrtagged-by-head first-dir" \
 3943 "${PROG} rdiff: Diffing first-dir
 3944 Index: first-dir/file6
 3945 diff -c first-dir/file6:1\.1 first-dir/file6:1\.2
 3946 \*\*\* first-dir/file6:1\.1 ${DATE}
 3947 --- first-dir/file6 ${DATE}
 3948 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3949 \*\*\* 1 \*\*\*\*
 3950 --- 1,2 ----
 3951   file6
 3952 ${PLUS} file6
 3953 Index: first-dir/file7
 3954 diff -c first-dir/file7:1\.1 first-dir/file7:removed
 3955 \*\*\* first-dir/file7:1.1  ${DATE}
 3956 --- first-dir/file7 ${DATE}
 3957 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 3958 \*\*\* 1 \*\*\*\*
 3959 - file7
 3960 --- 0 ----"
 3961         # now export by rtagged-by-head and rtagged-by-tag and compare.
 3962         dotest basic2-25 "${testcvs} export -r rtagged-by-head -d 1dir first-dir" \
 3963 "${PROG} export: Updating 1dir
 3964 U 1dir/file14
 3965 U 1dir/file6
 3966 ${PROG} export: Updating 1dir/dir1
 3967 U 1dir/dir1/file14
 3968 U 1dir/dir1/file6
 3969 ${PROG} export: Updating 1dir/dir1/dir2
 3970 U 1dir/dir1/dir2/file14
 3971 U 1dir/dir1/dir2/file6"
 3972         dotest_fail basic2-25a "test -d 1dir/CVS"
 3973         dotest_fail basic2-25b "test -d 1dir/dir1/CVS"
 3974         dotest_fail basic2-25c "test -d 1dir/dir1/dir2/CVS"
 3975 
 3976         dotest basic2-26 "${testcvs} export -r rtagged-by-tag first-dir" \
 3977 "${PROG} export: Updating first-dir
 3978 U first-dir/file14
 3979 U first-dir/file6
 3980 ${PROG} export: Updating first-dir/dir1
 3981 U first-dir/dir1/file14
 3982 U first-dir/dir1/file6
 3983 ${PROG} export: Updating first-dir/dir1/dir2
 3984 U first-dir/dir1/dir2/file14
 3985 U first-dir/dir1/dir2/file6"
 3986         dotest_fail basic2-26a "test -d first-dir/CVS"
 3987         dotest_fail basic2-26b "test -d first-dir/dir1/CVS"
 3988         dotest_fail basic2-26c "test -d first-dir/dir1/dir2/CVS"
 3989 
 3990         dotest basic2-27 "directory_cmp 1dir first-dir"
 3991         rm -r 1dir first-dir
 3992 
 3993         # checkout by revision vs export by rtagged-by-revision and compare.
 3994         mkdir export-dir
 3995         dotest basic2-28 "${testcvs} export -rrtagged-by-revision -d export-dir first-dir" \
 3996 "${PROG} export: Updating export-dir
 3997 U export-dir/file14
 3998 U export-dir/file6
 3999 U export-dir/file7
 4000 ${PROG} export: Updating export-dir/dir1
 4001 U export-dir/dir1/file14
 4002 U export-dir/dir1/file6
 4003 U export-dir/dir1/file7
 4004 ${PROG} export: Updating export-dir/dir1/dir2
 4005 U export-dir/dir1/dir2/file14
 4006 U export-dir/dir1/dir2/file6
 4007 U export-dir/dir1/dir2/file7"
 4008         dotest_fail basic2-28a "test -d export-dir/CVS"
 4009         dotest_fail basic2-28b "test -d export-dir/dir1/CVS"
 4010         dotest_fail basic2-28c "test -d export-dir/dir1/dir2/CVS"
 4011 
 4012         dotest basic2-29 "${testcvs} co -r1.1 first-dir" \
 4013 "${PROG} checkout: Updating first-dir
 4014 U first-dir/file14
 4015 U first-dir/file6
 4016 U first-dir/file7
 4017 ${PROG} checkout: Updating first-dir/dir1
 4018 U first-dir/dir1/file14
 4019 U first-dir/dir1/file6
 4020 U first-dir/dir1/file7
 4021 ${PROG} checkout: Updating first-dir/dir1/dir2
 4022 U first-dir/dir1/dir2/file14
 4023 U first-dir/dir1/dir2/file6
 4024 U first-dir/dir1/dir2/file7"
 4025 
 4026         # directory copies are done in an oblique way in order to avoid a bug in sun's tmp filesystem.
 4027         mkdir first-dir.cpy ; (cd first-dir ; tar cf - . | (cd ../first-dir.cpy ; tar xf -))
 4028 
 4029         dotest basic2-30 "directory_cmp first-dir export-dir"
 4030 
 4031         # interrupt, while we've got a clean 1.1 here, let's import it
 4032         # into a couple of other modules.
 4033         cd export-dir
 4034         dotest_sort basic2-31 "${testcvs} import -m first-import second-dir first-immigration immigration1 immigration1_0" \
 4035 "
 4036 
 4037 N second-dir/dir1/dir2/file14
 4038 N second-dir/dir1/dir2/file6
 4039 N second-dir/dir1/dir2/file7
 4040 N second-dir/dir1/file14
 4041 N second-dir/dir1/file6
 4042 N second-dir/dir1/file7
 4043 N second-dir/file14
 4044 N second-dir/file6
 4045 N second-dir/file7
 4046 No conflicts created by this import
 4047 ${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1
 4048 ${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1/dir2"
 4049         cd ..
 4050 
 4051         dotest basic2-32 "${testcvs} export -r HEAD second-dir" \
 4052 "${PROG} export: Updating second-dir
 4053 U second-dir/file14
 4054 U second-dir/file6
 4055 U second-dir/file7
 4056 ${PROG} export: Updating second-dir/dir1
 4057 U second-dir/dir1/file14
 4058 U second-dir/dir1/file6
 4059 U second-dir/dir1/file7
 4060 ${PROG} export: Updating second-dir/dir1/dir2
 4061 U second-dir/dir1/dir2/file14
 4062 U second-dir/dir1/dir2/file6
 4063 U second-dir/dir1/dir2/file7"
 4064 
 4065         dotest basic2-33 "directory_cmp first-dir second-dir"
 4066 
 4067         rm -r second-dir
 4068 
 4069         rm -r export-dir first-dir
 4070         mkdir first-dir
 4071         (cd first-dir.cpy ; tar cf - . | (cd ../first-dir ; tar xf -))
 4072 
 4073         # update the top, cancelling sticky tags, retag, update other copy, compare.
 4074         cd first-dir
 4075         dotest basic2-34 "${testcvs} update -A -l *file*" \
 4076 "[UP] file6
 4077 ${PROG} update: file7 is no longer in the repository"
 4078 
 4079         # If we don't delete the tag first, cvs won't retag it.
 4080         # This would appear to be a feature.
 4081         dotest basic2-35 "${testcvs} tag -l -d rtagged-by-revision" \
 4082 "${PROG} tag: Untagging \.
 4083 D file14
 4084 D file6"
 4085         dotest basic2-36 "${testcvs} tag -l rtagged-by-revision" \
 4086 "${PROG} tag: Tagging \.
 4087 T file14
 4088 T file6"
 4089 
 4090         cd ..
 4091         mv first-dir 1dir
 4092         mv first-dir.cpy first-dir
 4093         cd first-dir
 4094 
 4095         dotest basic2-37 "${testcvs} -q diff -u" ''
 4096 
 4097         dotest basic2-38 "${testcvs} update" \
 4098 "${PROG} update: Updating .
 4099 ${PROG} update: Updating dir1
 4100 ${PROG} update: Updating dir1/dir2"
 4101 
 4102         cd ..
 4103 
 4104         #### FIXME: is this expected to work???  Need to investigate
 4105         #### and fix or remove the test.
 4106 #       dotest basic2-39 "directory_cmp 1dir first-dir"
 4107 
 4108         rm -r 1dir first-dir
 4109 
 4110         # Test the cvs history command.
 4111 
 4112         # The reason that there are two patterns rather than using
 4113         # \(${TESTDIR}\|<remote>\) is that we are trying to
 4114         # make this portable.  Perhaps at some point we should
 4115         # ditch that notion and require GNU expr (or dejagnu or....)
 4116         # since it seems to be so painful.
 4117 
 4118         # why are there two lines at the end of the local output
 4119         # which don't exist in the remote output?  would seem to be
 4120         # a CVS bug.
 4121         dotest basic2-64 "${testcvs} his -x TOFWUPCGMAR -a" \
 4122 "O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir           =first-dir= ${TESTDIR}/\*
 4123 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6     first-dir           == ${TESTDIR}
 4124 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7     first-dir           == ${TESTDIR}
 4125 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6     first-dir/dir1      == ${TESTDIR}
 4126 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7     first-dir/dir1      == ${TESTDIR}
 4127 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6     first-dir/dir1/dir2 == ${TESTDIR}
 4128 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7     first-dir/dir1/dir2 == ${TESTDIR}
 4129 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14    first-dir           == ${TESTDIR}
 4130 M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir           == ${TESTDIR}
 4131 R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7     first-dir           == ${TESTDIR}
 4132 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14    first-dir/dir1      == ${TESTDIR}
 4133 M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir/dir1      == ${TESTDIR}
 4134 R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7     first-dir/dir1      == ${TESTDIR}
 4135 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14    first-dir/dir1/dir2 == ${TESTDIR}
 4136 M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir/dir1/dir2 == ${TESTDIR}
 4137 R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7     first-dir/dir1/dir2 == ${TESTDIR}
 4138 F [0-9-]* [0-9:]* ${PLUS}0000 ${username}                     =first-dir= ${TESTDIR}/\*
 4139 T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\]
 4140 T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\]
 4141 T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\]
 4142 O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir           =first-dir= ${TESTDIR}/\*
 4143 U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir           == ${TESTDIR}/first-dir
 4144 W [0-9-]* [0-9:]* ${PLUS}0000 ${username}     file7     first-dir           == ${TESTDIR}/first-dir" \
 4145 "O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir           =first-dir= <remote>/\*
 4146 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6     first-dir           == <remote>
 4147 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7     first-dir           == <remote>
 4148 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6     first-dir/dir1      == <remote>
 4149 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7     first-dir/dir1      == <remote>
 4150 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6     first-dir/dir1/dir2 == <remote>
 4151 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7     first-dir/dir1/dir2 == <remote>
 4152 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14    first-dir           == <remote>
 4153 M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir           == <remote>
 4154 R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7     first-dir           == <remote>
 4155 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14    first-dir/dir1      == <remote>
 4156 M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir/dir1      == <remote>
 4157 R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7     first-dir/dir1      == <remote>
 4158 A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14    first-dir/dir1/dir2 == <remote>
 4159 M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir/dir1/dir2 == <remote>
 4160 R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7     first-dir/dir1/dir2 == <remote>
 4161 F [0-9-]* [0-9:]* ${PLUS}0000 ${username}                     =first-dir= <remote>/\*
 4162 T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\]
 4163 T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\]
 4164 T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\]
 4165 O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir           =first-dir= <remote>/\*
 4166 P [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6     first-dir           == <remote>
 4167 W [0-9-]* [0-9:]* ${PLUS}0000 ${username}     file7     first-dir           == <remote>"
 4168 
 4169         rm -rf ${CVSROOT_DIRNAME}/first-dir
 4170         rm -rf ${CVSROOT_DIRNAME}/second-dir
 4171         ;;
 4172 
 4173     parseroot)
 4174       mkdir 1; cd 1
 4175       # Test odd cases involving CVSROOT.  At the moment, that means we
 4176       # are testing roots with '/'s on the end, which CVS should parse off.
 4177       CVSROOT_save=${CVSROOT}
 4178       CVSROOT="${CVSROOT}/////"
 4179       dotest parseroot-1 "${testcvs} -q co CVSROOT/modules" \
 4180 "U CVSROOT/modules"
 4181       dotest parseroot-2 "${testcvs} -q ci -fmnull-change CVSROOT/modules" \
 4182 "Checking in CVSROOT/modules;
 4183 ${CVSROOT_DIRNAME}/CVSROOT/modules,v  <--  modules
 4184 new revision: 1\.2; previous revision: 1\.1
 4185 done
 4186 ${PROG} commit: Rebuilding administrative file database"
 4187 
 4188       if $remote; then
 4189         # I only test these when testing remote in case CVS was compiled
 4190         # without client support.
 4191 
 4192         # logout does not try to contact the server.
 4193         CVSROOT=":pserver;proxy=localhost;proxyport=8080:localhost/dev/null"
 4194         dotest parseroot-3r "$testcvs -d'$CVSROOT' logout" \
 4195 "$PROG logout: WARNING: Ignoring method options found in CVSROOT: \`proxy=localhost;proxyport=8080'\.
 4196 $PROG logout: Use CVS version 1\.12\.7 or later to handle method options\.
 4197 Logging out of :pserver:$username@localhost:2401/dev/null
 4198 $PROG logout: warning: failed to open $HOME/\.cvspass for reading: No such file or directory
 4199 $PROG logout: Entry not found\."
 4200       fi
 4201 
 4202       if $keep; then
 4203         echo Keeping $TESTDIR and exiting due to --keep
 4204         exit 0
 4205       fi
 4206 
 4207       CVSROOT=$CVSROOT_save
 4208       cd ..
 4209       rm -r 1
 4210       ;;
 4211 
 4212 
 4213 
 4214     files)
 4215       # Test of how we specify files on the command line
 4216       # (recurse.c and that sort of thing).  Vaguely similar to
 4217       # tests like basic* and deep.  See modules and such tests
 4218       # for what happens when we throw in modules and co -d, &c.
 4219 
 4220       # This particular test is fairly carefully crafted, to spot
 4221       # one particular issue with remote.
 4222       mkdir 1; cd 1
 4223       dotest files-1 "${testcvs} -q co -l ." ""
 4224       mkdir first-dir
 4225       dotest files-2 "${testcvs} add first-dir" \
 4226 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 4227       cd first-dir
 4228       touch tfile
 4229       dotest files-3 "${testcvs} add tfile" \
 4230 "${PROG} add: scheduling file .tfile. for addition
 4231 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4232       dotest files-4 "${testcvs} -q ci -m add" \
 4233 "RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v
 4234 done
 4235 Checking in tfile;
 4236 ${CVSROOT_DIRNAME}/first-dir/tfile,v  <--  tfile
 4237 initial revision: 1\.1
 4238 done"
 4239       dotest files-5 "${testcvs} -q tag -b C" "T tfile"
 4240       dotest files-6 "$testcvs -q update -r C" "U tfile"
 4241       mkdir dir
 4242       dotest files-7 "${testcvs} add dir" \
 4243 "Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository
 4244 --> Using per-directory sticky tag .C'"
 4245       cd dir
 4246       touch .file
 4247       dotest files-6 "${testcvs} add .file" \
 4248 "${PROG} add: scheduling file .\.file' for addition on branch .C.
 4249 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4250       mkdir sdir
 4251       dotest files-7 "${testcvs} add sdir" \
 4252 "Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir added to the repository
 4253 --> Using per-directory sticky tag .C'"
 4254       cd sdir
 4255       mkdir ssdir
 4256       dotest files-8 "${testcvs} add ssdir" \
 4257 "Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir added to the repository
 4258 --> Using per-directory sticky tag .C'"
 4259       cd ssdir
 4260       touch .file
 4261       dotest files-9 "${testcvs} add .file" \
 4262 "${PROG} add: scheduling file .\.file' for addition on branch .C.
 4263 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4264       cd ../..
 4265       dotest files-10 "${testcvs} -q ci -m test" \
 4266 "RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v
 4267 done
 4268 Checking in \.file;
 4269 ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v  <--  \.file
 4270 new revision: 1\.1\.2\.1; previous revision: 1\.1
 4271 done
 4272 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v
 4273 done
 4274 Checking in sdir/ssdir/\.file;
 4275 ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v  <--  \.file
 4276 new revision: 1\.1\.2\.1; previous revision: 1\.1
 4277 done"
 4278       dotest files-11 \
 4279 "${testcvs} commit -m test -f ./.file ./sdir/ssdir/.file" \
 4280 "Checking in \.file;
 4281 ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v  <--  \.file
 4282 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
 4283 done
 4284 Checking in \./sdir/ssdir/\.file;
 4285 ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v  <--  \.file
 4286 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
 4287 done"
 4288       if $remote; then
 4289         # FIXCVS:
 4290         # This is a bug, looks like that toplevel_repos cruft in
 4291         # client.c is coming back to haunt us.
 4292         # May want to think about the whole issue, toplevel_repos
 4293         # has always been crufty and trying to patch it up again
 4294         # might be a mistake.
 4295         dotest files-12 \
 4296 "${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \
 4297 "Checking in \./sdir/ssdir/\.file;
 4298 ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v  <--  \.file
 4299 new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
 4300 done"
 4301 
 4302         # Sync up the version numbers so that the rest of the
 4303         # tests don't need to expect different numbers based
 4304         # local or remote.
 4305         dotest files-12-workaround \
 4306 "${testcvs} commit -f -m test .file" \
 4307 "Checking in \.file;
 4308 ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v  <--  \.file
 4309 new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
 4310 done"
 4311       else
 4312         dotest files-12 \
 4313 "${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \
 4314 "Checking in \./sdir/ssdir/\.file;
 4315 ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v  <--  \.file
 4316 new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
 4317 done
 4318 Checking in \.file;
 4319 ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v  <--  \.file
 4320 new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
 4321 done"
 4322       fi
 4323       dotest files-13 \
 4324 "${testcvs} commit -fmtest ./sdir/../sdir/ssdir/..///ssdir/.file" \
 4325 "Checking in \./sdir/\.\./sdir/ssdir/\.\.///ssdir/\.file;
 4326 ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v  <--  \.file
 4327 new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3
 4328 done"
 4329       if $remote; then
 4330         dotest files-14 \
 4331 "${testcvs} commit -fmtest ../../first-dir/dir/.file" \
 4332 "Checking in \.\./\.\./first-dir/dir/\.file;
 4333 ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v  <--  .file
 4334 new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3
 4335 done"
 4336       else
 4337         dotest files-14 \
 4338 "${testcvs} commit -fmtest ../../first-dir/dir/.file" \
 4339 "Checking in \.\./\.\./first-dir/dir/\.file;
 4340 ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v  <--  \.file
 4341 new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3
 4342 done"
 4343       fi
 4344       cd ../../..
 4345 
 4346       rm -r 1
 4347       rm -rf ${CVSROOT_DIRNAME}/first-dir
 4348       ;;
 4349 
 4350     spacefiles)
 4351       # More filename tests, in particular spaces in file names.
 4352       # (it might be better to just change a few of the names in
 4353       # basica or some other test instead, always good to keep the
 4354       # testsuite concise).
 4355 
 4356       mkdir 1; cd 1
 4357       dotest spacefiles-1 "${testcvs} -q co -l ." ""
 4358       touch ./-c
 4359       dotest spacefiles-2 "${testcvs} add -- -c" \
 4360 "${PROG} add: scheduling file .-c. for addition
 4361 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4362       dotest spacefiles-3 "${testcvs} -q ci -m add" \
 4363 "RCS file: ${CVSROOT_DIRNAME}/-c,v
 4364 done
 4365 Checking in -c;
 4366 ${CVSROOT_DIRNAME}/-c,v  <--  -c
 4367 initial revision: 1\.1
 4368 done"
 4369       mkdir 'first dir'
 4370       dotest spacefiles-4 "${testcvs} add 'first dir'" \
 4371 "Directory ${CVSROOT_DIRNAME}/first dir added to the repository"
 4372       mkdir ./-b
 4373       dotest spacefiles-5 "${testcvs} add -- -b" \
 4374 "Directory ${CVSROOT_DIRNAME}/-b added to the repository"
 4375       cd 'first dir'
 4376       touch 'a file'
 4377       dotest spacefiles-6 "${testcvs} add 'a file'" \
 4378 "${PROG} add: scheduling file .a file. for addition
 4379 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4380       dotest spacefiles-7 "${testcvs} -q ci -m add" \
 4381 "RCS file: ${CVSROOT_DIRNAME}/first dir/a file,v
 4382 done
 4383 Checking in a file;
 4384 ${CVSROOT_DIRNAME}/first dir/a file,v  <--  a file
 4385 initial revision: 1\.1
 4386 done"
 4387       dotest spacefiles-8 "${testcvs} -q tag new-tag" "T a file"
 4388       cd ../..
 4389 
 4390       mkdir 2; cd 2
 4391       dotest spacefiles-10 "${testcvs} co -- -b" \
 4392 "${PROG} checkout: Updating -b"
 4393       dotest spacefiles-11 "${testcvs} -q co -- -c" "U \./-c"
 4394       rm ./-c
 4395       dotest spacefiles-13 "${testcvs} -q co 'first dir'" \
 4396 "U first dir/a file"
 4397       cd ..
 4398 
 4399       mkdir 3; cd 3
 4400       dotest spacefiles-14 "${testcvs} -q co 'first dir/a file'" \
 4401 "U first dir/a file"
 4402       cd ..
 4403 
 4404       rm -r 1 2 3
 4405       rm -rf "${CVSROOT_DIRNAME}/first dir"
 4406       rm -r ${CVSROOT_DIRNAME}/-b
 4407       rm -f ${CVSROOT_DIRNAME}/-c,v
 4408       ;;
 4409 
 4410     commit-readonly)
 4411       mkdir 1; cd 1
 4412       module=x
 4413 
 4414       : > junk
 4415       dotest commit-readonly-1 "$testcvs -Q import -m . $module X Y" ''
 4416       dotest commit-readonly-2 "$testcvs -Q co $module" ''
 4417       cd $module
 4418 
 4419       file=m
 4420 
 4421       # Include an rcs keyword to be expanded.
 4422       echo '$Id''$' > $file
 4423 
 4424       dotest commit-readonly-3 "$testcvs add $file" \
 4425 "${PROG} add: scheduling file .$file. for addition
 4426 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4427       dotest commit-readonly-4 "$testcvs -Q ci -m . $file" \
 4428 "RCS file: ${CVSROOT_DIRNAME}/$module/$file,v
 4429 done
 4430 Checking in $file;
 4431 ${CVSROOT_DIRNAME}/$module/$file,v  <--  $file
 4432 initial revision: 1\.1
 4433 done"
 4434 
 4435       echo line2 >> $file
 4436       # Make the file read-only.
 4437       chmod a-w $file
 4438 
 4439       dotest commit-readonly-5 "$testcvs -Q ci -m . $file" \
 4440 "Checking in $file;
 4441 ${CVSROOT_DIRNAME}/$module/$file,v  <--  $file
 4442 new revision: 1\.2; previous revision: 1\.1
 4443 done"
 4444 
 4445       cd ../..
 4446       rm -rf 1
 4447       rm -rf ${CVSROOT_DIRNAME}/$module
 4448       ;;
 4449 
 4450     status)
 4451         # This tests for a bug in the status command which failed to
 4452         # notice resolved conflicts.
 4453         mkdir status; cd status
 4454         dotest status-init-1 "${testcvs} -q co -l ." ""
 4455         mkdir first-dir
 4456         dotest status-init-2 "${testcvs} add first-dir" \
 4457 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 4458         cd first-dir
 4459         echo a line >tfile
 4460         dotest status-init-3 "${testcvs} add tfile" \
 4461 "${PROG} add: scheduling file .tfile. for addition
 4462 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4463         dotest status-init-4 "${testcvs} -q ci -m add" \
 4464 "RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v
 4465 done
 4466 Checking in tfile;
 4467 ${CVSROOT_DIRNAME}/first-dir/tfile,v  <--  tfile
 4468 initial revision: 1\.1
 4469 done"
 4470         cd ..
 4471         dotest status-init-5 "${testcvs} -q co -dsecond-dir first-dir" \
 4472 "U second-dir/tfile"
 4473         cd second-dir
 4474         echo some junk >>tfile
 4475         dotest status-init-6 "${testcvs} -q ci -maline" \
 4476 "Checking in tfile;
 4477 ${CVSROOT_DIRNAME}/first-dir/tfile,v  <--  tfile
 4478 new revision: 1\.2; previous revision: 1\.1
 4479 done"
 4480         cd ../first-dir
 4481         echo force a conflict >>tfile
 4482         dotest status-init-7 "${testcvs} -q up" \
 4483 "RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v
 4484 retrieving revision 1\.1
 4485 retrieving revision 1\.2
 4486 Merging differences between 1\.1 and 1\.2 into tfile
 4487 rcsmerge: warning: conflicts during merge
 4488 ${PROG} update: conflicts found in tfile
 4489 C tfile"
 4490 
 4491         # Now note our status
 4492         dotest status-1 "${testcvs} status tfile" \
 4493 "===================================================================
 4494 File: tfile             Status: Unresolved Conflict
 4495 
 4496    Working revision:    1\.2.*
 4497    Repository revision: 1\.2    ${CVSROOT_DIRNAME}/first-dir/tfile,v
 4498    Sticky Tag:      (none)
 4499    Sticky Date:     (none)
 4500    Sticky Options:  (none)"
 4501 
 4502         # touch the file, leaving conflict markers in place
 4503         # and note our status
 4504         touch tfile
 4505         dotest status-2 "${testcvs} status tfile" \
 4506 "===================================================================
 4507 File: tfile             Status: File had conflicts on merge
 4508 
 4509    Working revision:    1\.2.*
 4510    Repository revision: 1\.2    ${CVSROOT_DIRNAME}/first-dir/tfile,v
 4511    Sticky Tag:      (none)
 4512    Sticky Date:     (none)
 4513    Sticky Options:  (none)"
 4514 
 4515         # resolve the conflict
 4516         echo resolution >tfile
 4517         dotest status-3 "${testcvs} status tfile" \
 4518 "===================================================================
 4519 File: tfile             Status: Locally Modified
 4520 
 4521    Working revision:    1\.2.*
 4522    Repository revision: 1\.2    ${CVSROOT_DIRNAME}/first-dir/tfile,v
 4523    Sticky Tag:      (none)
 4524    Sticky Date:     (none)
 4525    Sticky Options:  (none)"
 4526 
 4527         # Check that there are no problems just using CVS/Root too.
 4528         save_CVSROOT=$CVSROOT
 4529         unset CVSROOT
 4530         dotest status-3a "${testcvs} status tfile" \
 4531 "===================================================================
 4532 File: tfile             Status: Locally Modified
 4533 
 4534    Working revision:    1\.2.*
 4535    Repository revision: 1\.2    ${CVSROOT_DIRNAME}/first-dir/tfile,v
 4536    Sticky Tag:      (none)
 4537    Sticky Date:     (none)
 4538    Sticky Options:  (none)"
 4539         CVSROOT=$save_CVSROOT
 4540         export CVSROOT
 4541 
 4542         # FIXCVS:
 4543         # Update is supposed to re-Register() the file when it
 4544         # finds resolved conflicts:
 4545         dotest status-4 "grep 'Result of merge' CVS/Entries" \
 4546 "/tfile/1\.2/Result of merge${PLUS}[a-zA-Z0-9 :]*//"
 4547 
 4548                 cd ..
 4549                 mkdir fourth-dir
 4550                 dotest status-init-8 "$testcvs add fourth-dir" \
 4551 "Directory $CVSROOT_DIRNAME/fourth-dir added to the repository"
 4552                 cd fourth-dir
 4553                 echo yet another line >t3file
 4554                 dotest status-init-9 "$testcvs add t3file" \
 4555 "$PROG add: scheduling file .t3file. for addition
 4556 $PROG add: use .$PROG commit. to add this file permanently"
 4557                 dotest status-init-10 "$testcvs -q ci -m add" \
 4558 "RCS file: $CVSROOT_DIRNAME/fourth-dir/t3file,v
 4559 done
 4560 Checking in t3file;
 4561 $CVSROOT_DIRNAME/fourth-dir/t3file,v  <--  t3file
 4562 initial revision: 1\.1
 4563 done"
 4564                 cd ../first-dir
 4565                 mkdir third-dir
 4566                 dotest status-init-11 "$testcvs add third-dir" \
 4567 "Directory $CVSROOT_DIRNAME/first-dir/third-dir added to the repository"
 4568                 cd third-dir
 4569                 echo another line >t2file
 4570                 dotest status-init-12 "$testcvs add t2file" \
 4571 "$PROG add: scheduling file .t2file. for addition
 4572 $PROG add: use .$PROG commit. to add this file permanently"
 4573                 dotest status-init-13 "$testcvs -q ci -m add" \
 4574 "RCS file: $CVSROOT_DIRNAME/first-dir/third-dir/t2file,v
 4575 done
 4576 Checking in t2file;
 4577 $CVSROOT_DIRNAME/first-dir/third-dir/t2file,v  <--  t2file
 4578 initial revision: 1\.1
 4579 done"
 4580                 dotest status-5 "$testcvs status ../tfile" \
 4581 "===================================================================
 4582 File: tfile             Status: Locally Modified
 4583 
 4584    Working revision:    1\.2.*
 4585    Repository revision: 1\.2    $CVSROOT_DIRNAME/first-dir/tfile,v
 4586    Sticky Tag:      (none)
 4587    Sticky Date:     (none)
 4588    Sticky Options:  (none)"
 4589                 dotest status-6 "$testcvs status ../../fourth-dir/t3file" \
 4590 "===================================================================
 4591 File: t3file            Status: Up-to-date
 4592 
 4593    Working revision:    1\.1.*
 4594    Repository revision: 1\.1    $CVSROOT_DIRNAME/fourth-dir/t3file,v
 4595    Sticky Tag:      (none)
 4596    Sticky Date:     (none)
 4597    Sticky Options:  (none)"
 4598 
 4599         if $keep; then
 4600             echo Keeping $TESTDIR and exiting due to --keep
 4601             exit 0
 4602         fi
 4603 
 4604         cd ../../..
 4605         rm -rf status
 4606         rm -rf $CVSROOT_DIRNAME/first-dir $CVSROOT_DIRNAME/fourth-dir
 4607         ;;
 4608 
 4609     rdiff)
 4610         # Test rdiff
 4611         # XXX for now this is just the most essential test...
 4612         cd ${TESTDIR}
 4613 
 4614         mkdir testimport
 4615         cd testimport
 4616         echo '$''Id$' > foo
 4617         echo '$''Name$' >> foo
 4618         echo '$''Id$' > bar
 4619         echo '$''Name$' >> bar
 4620         dotest_sort rdiff-1 \
 4621           "${testcvs} import -I ! -m test-import-with-keyword trdiff TRDIFF T1" \
 4622 '
 4623 
 4624 N trdiff/bar
 4625 N trdiff/foo
 4626 No conflicts created by this import'
 4627         dotest rdiff-2 \
 4628           "${testcvs} co -ko trdiff" \
 4629 "${PROG} checkout: Updating trdiff
 4630 U trdiff/bar
 4631 U trdiff/foo"
 4632         cd trdiff
 4633         echo something >> foo
 4634         dotest rdiff-3 \
 4635           "${testcvs} ci -m added-something foo" \
 4636 "Checking in foo;
 4637 ${CVSROOT_DIRNAME}/trdiff/foo,v  <--  foo
 4638 new revision: 1\.2; previous revision: 1\.1
 4639 done"
 4640         echo '#ident    "@(#)trdiff:$''Name$:$''Id$"' > new
 4641         echo "new file" >> new
 4642         dotest rdiff-4 \
 4643           "${testcvs} add -m new-file-description new" \
 4644 "${PROG} add: scheduling file \`new' for addition
 4645 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4646         dotest rdiff-5 \
 4647           "${testcvs} commit -m added-new-file new" \
 4648 "RCS file: ${CVSROOT_DIRNAME}/trdiff/new,v
 4649 done
 4650 Checking in new;
 4651 ${CVSROOT_DIRNAME}/trdiff/new,v  <--  new
 4652 initial revision: 1\.1
 4653 done"
 4654         dotest rdiff-6 \
 4655           "${testcvs} tag local-v0" \
 4656 "${PROG} tag: Tagging .
 4657 T bar
 4658 T foo
 4659 T new"
 4660         dotest rdiff-7 \
 4661           "${testcvs} status -v foo" \
 4662 "===================================================================
 4663 File: foo               Status: Up-to-date
 4664 
 4665    Working revision:    1\.2.*
 4666    Repository revision: 1\.2    ${CVSROOT_DIRNAME}/trdiff/foo,v
 4667    Sticky Tag:      (none)
 4668    Sticky Date:     (none)
 4669    Sticky Options:  -ko
 4670 
 4671    Existing Tags:
 4672     local-v0                    (revision: 1\.2)
 4673     T1                          (revision: 1\.1\.1\.1)
 4674     TRDIFF                      (branch: 1\.1\.1)"
 4675 
 4676         cd ..
 4677         rm -r trdiff
 4678 
 4679         dotest rdiff-8 \
 4680           "${testcvs} rdiff -r T1 -r local-v0 trdiff" \
 4681 "${PROG}"' rdiff: Diffing trdiff
 4682 Index: trdiff/foo
 4683 diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2
 4684 \*\*\* trdiff/foo:1\.1\.1\.1    '"${DATE}"'
 4685 --- trdiff/foo  '"${DATE}"'
 4686 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 4687 \*\*\* 1,2 \*\*\*\*
 4688 ! \$''Id: foo,v 1\.1\.1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$
 4689 ! \$''Name: T1 \$
 4690 --- 1,3 ----
 4691 ! \$''Id: foo,v 1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$
 4692 ! \$''Name: local-v0 \$
 4693 ! something
 4694 Index: trdiff/new
 4695 diff -c /dev/null trdiff/new:1\.1
 4696 \*\*\* /dev/null    '"${DATE}"'
 4697 --- trdiff/new  '"${DATE}"'
 4698 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 4699 \*\*\* 0 \*\*\*\*
 4700 --- 1,2 ----
 4701 '"${PLUS}"' #ident  "@(#)trdiff:\$''Name: local-v0 \$:\$''Id: new,v 1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$"
 4702 '"${PLUS}"' new file'
 4703 
 4704         if $keep; then
 4705           echo Keeping ${TESTDIR} and exiting due to --keep
 4706           exit 0
 4707         fi
 4708 
 4709         cd ..
 4710         rm -r testimport
 4711         rm -rf ${CVSROOT_DIRNAME}/trdiff
 4712         ;;
 4713 
 4714     rdiff-short)
 4715       # Test that the short patch behaves as expected
 4716       #   1) Added file.
 4717       #   2) Removed file.
 4718       #   3) Different revision number with no difference.
 4719       #   4) Different revision number with changes.
 4720       #   5) Against trunk.
 4721       #   6) Same revision number (no difference).
 4722       mkdir rdiff-short; cd rdiff-short
 4723       mkdir abc
 4724       dotest rdiff-short-init-1 \
 4725 "${testcvs} -q import -I ! -m initial-import abc vendor initial" \
 4726 '
 4727 No conflicts created by this import'
 4728 
 4729       dotest rdiff-short-init-2 "${testcvs} -q get abc" ''
 4730       cd abc
 4731       echo "abc" >file1.txt
 4732       dotest rdiff-short-init-3 "${testcvs} add file1.txt" \
 4733 "${PROG} add: scheduling file .file1\.txt' for addition
 4734 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4735       dotest rdiff-short-init-4 \
 4736 "${testcvs} commit -madd-file1 file1.txt" \
 4737 "RCS file: ${CVSROOT_DIRNAME}/abc/file1\.txt,v
 4738 done
 4739 Checking in file1\.txt;
 4740 ${CVSROOT_DIRNAME}/abc/file1\.txt,v  <--  file1\.txt
 4741 initial revision: 1\.1
 4742 done"
 4743       echo def >>file1.txt
 4744       dotest rdiff-short-init-5 \
 4745 "${testcvs} commit -mchange-file1 file1.txt" \
 4746 "Checking in file1\.txt;
 4747 ${CVSROOT_DIRNAME}/abc/file1\.txt,v  <--  file1\.txt
 4748 new revision: 1\.2; previous revision: 1\.1
 4749 done"
 4750       echo "abc" >file1.txt
 4751       dotest rdiff-short-init-6 \
 4752 "${testcvs} commit -mrestore-file1-rev1 file1.txt" \
 4753 "Checking in file1\.txt;
 4754 ${CVSROOT_DIRNAME}/abc/file1\.txt,v  <--  file1\.txt
 4755 new revision: 1\.3; previous revision: 1\.2
 4756 done"
 4757       dotest rdiff-short-init-7 \
 4758 "${testcvs} tag -r 1.1 tag1 file1.txt" \
 4759 "T file1\.txt"
 4760       dotest rdiff-short-init-8 \
 4761 "${testcvs} tag -r 1.2 tag2 file1.txt" \
 4762 "T file1\.txt"
 4763       dotest rdiff-short-init-9 \
 4764 "${testcvs} tag -r 1.3 tag3 file1.txt" \
 4765 "T file1\.txt"
 4766       echo "abc" >file2.txt
 4767       dotest rdiff-short-init-10 \
 4768 "${testcvs} add file2.txt" \
 4769 "${PROG} add: scheduling file .file2\.txt' for addition
 4770 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4771       dotest rdiff-add-remove-nodiff-init-11 \
 4772 "${testcvs} commit -madd-file2 file2.txt" \
 4773 "RCS file: ${CVSROOT_DIRNAME}/abc/file2\.txt,v
 4774 done
 4775 Checking in file2\.txt;
 4776 ${CVSROOT_DIRNAME}/abc/file2\.txt,v  <--  file2\.txt
 4777 initial revision: 1\.1
 4778 done"
 4779       dotest rdiff-short-init-12 \
 4780 "${testcvs} tag -r 1.1 tag4 file2.txt" \
 4781 "T file2\.txt"
 4782       dotest rdiff-short-init-13 \
 4783 "${testcvs} tag -r 1.1 tag5 file2.txt" \
 4784 "T file2\.txt"
 4785       cd ../..
 4786       rm -fr rdiff-short
 4787 
 4788       # 3) Different revision number with no difference.
 4789       dotest rdiff-short-no-real-change \
 4790 "${testcvs} -q rdiff -s -r tag1 -r tag3 abc"
 4791 
 4792       # 4) Different revision number with changes.
 4793       dotest rdiff-short-real-change \
 4794 "${testcvs} -q rdiff -s -r tag1 -r tag2 abc" \
 4795 'File abc/file1.txt changed from revision 1\.1 to 1\.2'
 4796 
 4797       # 1) Added file.
 4798       # 2) Removed file.
 4799       dotest_sort rdiff-short-remove-add \
 4800 "${testcvs} -q rdiff -s -r tag2 -r tag4 abc" \
 4801 'File abc/file1\.txt is removed; tag2 revision 1\.2
 4802 File abc/file2\.txt is new; tag4 revision 1\.1'
 4803 
 4804       # 6) Same revision number (no difference).
 4805       dotest rdiff-short-no-change \
 4806 "${testcvs} -q rdiff -s -r tag4 -r tag5 abc"
 4807 
 4808       # 5) Against trunk.
 4809       # Check that the messages change when we diff against the trunk
 4810       # rather than a tag or date.
 4811       dotest rdiff-short-against-trunk-1 \
 4812 "${testcvs} -q rdiff -s -rtag4 abc" \
 4813 "File abc/file1\.txt is new; current revision 1\.3"
 4814 
 4815       dotest rdiff-short-against-trunk-2 \
 4816 "${testcvs} -q rdiff -s -rtag2 abc" \
 4817 "File abc/file1\.txt changed from revision 1\.2 to 1\.3
 4818 File abc/file2\.txt is new; current revision 1\.1"
 4819 
 4820       rm -rf ${CVSROOT_DIRNAME}/abc
 4821       ;;
 4822 
 4823     rdiff2)
 4824       # Test for the segv problem reported by James Cribb
 4825       # Somewhere to work
 4826       mkdir rdiff2; cd rdiff2     
 4827       # Create a module "m" with files "foo" and "d/bar"
 4828       mkdir m; cd m
 4829       echo foo >foo
 4830       mkdir d
 4831       echo bar >d/bar
 4832       dotest_sort  rdiff2-1 \
 4833 "${testcvs} -q import -I ! -m initial-import m vendor initial" \
 4834 '
 4835 
 4836 N m/d/bar
 4837 N m/foo
 4838 No conflicts created by this import'
 4839 
 4840       cd ..
 4841       rm -r m
 4842       
 4843       # Remove "foo"
 4844       dotest rdiff2-2 "${testcvs} get m" \
 4845 "${PROG} checkout: Updating m
 4846 U m/foo
 4847 ${PROG} checkout: Updating m/d
 4848 U m/d/bar"
 4849       cd m
 4850       dotest rdiff2-3 "${testcvs} rm -f foo" \
 4851 "${PROG} remove: scheduling .foo. for removal
 4852 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 4853 
 4854       dotest rdiff2-4 "${testcvs} commit -m Removed foo" \
 4855 "Removing foo;
 4856 ${CVSROOT_DIRNAME}/m/foo,v  <--  foo
 4857 new revision: delete; previous revision: 1\.1\.1\.1
 4858 done"
 4859       
 4860       # Modify "d/bar"
 4861       echo foo >d/bar
 4862       dotest rdiff2-5 "${testcvs} commit -m Changed d/bar" \
 4863 "Checking in d/bar;
 4864 ${CVSROOT_DIRNAME}/m/d/bar,v  <--  bar
 4865 new revision: 1\.2; previous revision: 1\.1
 4866 done"
 4867       
 4868       # Crash before showing d/bar diffs
 4869       dotest_fail rdiff2-6 "${testcvs} rdiff -t m" \
 4870 "${PROG} rdiff: Diffing m
 4871 ${PROG} rdiff: Diffing m/d
 4872 Index: m/d/bar
 4873 diff -c m/d/bar:1\.1\.1\.1 m/d/bar:1\.2
 4874 \*\*\* m/d/bar:1\.1\.1\.1   ${DATE}
 4875 --- m/d/bar ${DATE}
 4876 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 4877 \*\*\* 1 \*\*\*\*
 4878 ! bar
 4879 --- 1 ----
 4880 ! foo"
 4881       if $keep; then
 4882         echo Keeping ${TESTDIR} and exiting due to --keep
 4883         exit 0
 4884       fi
 4885       cd ../..
 4886       rm -rf rdiff2
 4887       rm -rf ${CVSROOT_DIRNAME}/m
 4888       ;;
 4889 
 4890     diff)
 4891       # Various tests specific to the "cvs diff" command.
 4892       # Related tests:
 4893       #   death2: -N
 4894       #   rcslib: cvs diff and $Name.
 4895       #   rdiff: cvs rdiff.
 4896       #   diffmerge*: nuts and bolts (stuff within diff library)
 4897       mkdir 1; cd 1
 4898       dotest diff-1 "${testcvs} -q co -l ." ''
 4899       mkdir first-dir
 4900       dotest diff-2 "${testcvs} add first-dir" \
 4901 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 4902       cd first-dir
 4903 
 4904       # diff is anomalous.  Most CVS commands print the "nothing
 4905       # known" message (or worse yet, no message in some cases) but
 4906       # diff says "I know nothing".  Shrug.
 4907       dotest_fail diff-3 "${testcvs} diff xyzpdq" \
 4908 "${PROG} diff: I know nothing about xyzpdq"
 4909       touch abc
 4910       dotest diff-4 "${testcvs} add abc" \
 4911 "${PROG} add: scheduling file .abc. for addition
 4912 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4913       dotest diff-5 "${testcvs} -q ci -mtest" \
 4914 "RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 4915 done
 4916 Checking in abc;
 4917 ${CVSROOT_DIRNAME}/first-dir/abc,v  <--  abc
 4918 initial revision: 1\.1
 4919 done"
 4920       echo "extern int gethostname ();" >abc
 4921       dotest diff-6 "${testcvs} -q ci -mtest" \
 4922 "Checking in abc;
 4923 ${CVSROOT_DIRNAME}/first-dir/abc,v  <--  abc
 4924 new revision: 1\.2; previous revision: 1\.1
 4925 done"
 4926       echo "#include <winsock.h>" >abc
 4927       # check the behavior of the --ifdef=MACRO option
 4928       dotest_fail diff-7 "${testcvs} -q diff --ifdef=HAVE_WINSOCK_H" \
 4929 "Index: abc
 4930 ===================================================================
 4931 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 4932 retrieving revision 1\.2
 4933 diff --ifdef HAVE_WINSOCK_H -r1\.2 abc
 4934 #ifndef HAVE_WINSOCK_H
 4935 extern int gethostname ();
 4936 #else /\* HAVE_WINSOCK_H \*/
 4937 #include <winsock\.h>
 4938 #endif /\* HAVE_WINSOCK_H \*/"
 4939 
 4940       if $keep; then
 4941         echo Keeping ${TESTDIR} and exiting due to --keep
 4942         exit 0
 4943       fi
 4944 
 4945       cd ../..
 4946       rm -rf ${CVSROOT_DIRNAME}/first-dir
 4947       rm -r 1
 4948       ;;
 4949 
 4950     diffnl)
 4951       # Test handling of 'cvs diff' of files without newlines
 4952       mkdir 1; cd 1
 4953       dotest diffnl-000 "${testcvs} -q co -l ." ''
 4954       mkdir first-dir
 4955       dotest diffnl-001 "${testcvs} add first-dir" \
 4956 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 4957           cd first-dir
 4958 
 4959       ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' </dev/null >abc
 4960       dotest diffnl-002 "${testcvs} add abc" \
 4961 "${PROG} add: scheduling file .abc. for addition
 4962 ${PROG} add: use .${PROG} commit. to add this file permanently"
 4963           dotest diffnl-003 "${testcvs} -q ci -mtest" \
 4964 "RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 4965 done
 4966 Checking in abc;
 4967 ${CVSROOT_DIRNAME}/first-dir/abc,v  <--  abc
 4968 initial revision: 1\.1
 4969 done"
 4970 
 4971       # change to line near EOF
 4972       ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nsix")}' </dev/null >abc
 4973       dotest_fail diffnl-100 "${testcvs} diff abc" \
 4974 "Index: abc
 4975 ===================================================================
 4976 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 4977 retrieving revision 1\.1
 4978 diff -r1\.1 abc
 4979 5d4
 4980 < five"
 4981           dotest_fail diffnl-101 "${testcvs} diff -u abc" \
 4982 "Index: abc
 4983 ===================================================================
 4984 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 4985 retrieving revision 1\.1
 4986 diff -u -r1\.1 abc
 4987 --- abc ${RFCDATE}  1\.1
 4988 +++ abc ${RFCDATE}
 4989 @@ -2,5 +2,4 @@
 4990  two
 4991  three
 4992  four
 4993 -five
 4994  six
 4995 \\\\ No newline at end of file"
 4996           dotest diffnl-102 "${testcvs} -q ci -mtest abc" \
 4997 "Checking in abc;
 4998 ${CVSROOT_DIRNAME}/first-dir/abc,v  <--  abc
 4999 new revision: 1\.2; previous revision: 1\.1
 5000 done"
 5001 
 5002           # Change to last line
 5003       ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' </dev/null >abc
 5004           dotest_fail diffnl-200 "${testcvs} diff abc" \
 5005 "Index: abc
 5006 ===================================================================
 5007 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 5008 retrieving revision 1\.2
 5009 diff -r1\.2 abc
 5010 5c5
 5011 < six
 5012 \\\\ No newline at end of file
 5013 ---
 5014 > seven
 5015 \\\\ No newline at end of file"
 5016       dotest_fail diffnl-201 "${testcvs} diff -u abc" \
 5017 "Index: abc
 5018 ===================================================================
 5019 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 5020 retrieving revision 1\.2
 5021 diff -u -r1\.2 abc
 5022 --- abc ${RFCDATE}  1\.2
 5023 +++ abc ${RFCDATE}
 5024 @@ -2,4 +2,4 @@
 5025  two
 5026  three
 5027  four
 5028 -six
 5029 \\\\ No newline at end of file
 5030 +seven
 5031 \\\\ No newline at end of file"
 5032       dotest diffnl-202 "${testcvs} ci -mtest abc" \
 5033 "Checking in abc;
 5034 ${CVSROOT_DIRNAME}/first-dir/abc,v  <--  abc
 5035 new revision: 1\.3; previous revision: 1\.2
 5036 done"
 5037 
 5038       # Addition of newline
 5039       echo "one
 5040 two
 5041 three
 5042 four
 5043 seven" > abc
 5044       dotest_fail diffnl-300 "${testcvs} diff abc" \
 5045 "Index: abc
 5046 ===================================================================
 5047 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 5048 retrieving revision 1\.3
 5049 diff -r1\.3 abc
 5050 5c5
 5051 < seven
 5052 \\\\ No newline at end of file
 5053 ---
 5054 > seven"
 5055       dotest_fail diffnl-301 "${testcvs} diff -u abc" \
 5056 "Index: abc
 5057 ===================================================================
 5058 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 5059 retrieving revision 1\.3
 5060 diff -u -r1\.3 abc
 5061 --- abc ${RFCDATE}  1\.3
 5062 +++ abc ${RFCDATE}
 5063 @@ -2,4 +2,4 @@
 5064  two
 5065  three
 5066  four
 5067 -seven
 5068 \\\\ No newline at end of file
 5069 +seven"
 5070       dotest diffnl-302 "${testcvs} ci -mtest abc" \
 5071 "Checking in abc;
 5072 ${CVSROOT_DIRNAME}/first-dir/abc,v  <--  abc
 5073 new revision: 1\.4; previous revision: 1\.3
 5074 done"
 5075 
 5076       # Removal of newline
 5077       ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' </dev/null >abc
 5078       dotest_fail diffnl-400 "${testcvs} diff abc" \
 5079 "Index: abc
 5080 ===================================================================
 5081 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 5082 retrieving revision 1\.4
 5083 diff -r1\.4 abc
 5084 5c5
 5085 < seven
 5086 ---
 5087 > seven
 5088 \\\\ No newline at end of file"
 5089       dotest_fail diffnl-401 "${testcvs} diff -u abc" \
 5090 "Index: abc
 5091 ===================================================================
 5092 RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
 5093 retrieving revision 1\.4
 5094 diff -u -r1\.4 abc
 5095 --- abc ${RFCDATE}  1\.4
 5096 +++ abc ${RFCDATE}
 5097 @@ -2,4 +2,4 @@
 5098  two
 5099  three
 5100  four
 5101 -seven
 5102 +seven
 5103 \\\\ No newline at end of file"
 5104     
 5105       cd ../..
 5106       rm -r 1
 5107       rm -rf ${CVSROOT_DIRNAME}/first-dir
 5108       ;;
 5109 
 5110     death)
 5111         # next dive.  test death support.
 5112 
 5113         # NOTE: this section has reached the size and
 5114         # complexity where it is getting to be a good idea to
 5115         # add new death support tests to a new section rather
 5116         # than continuing to piggyback them onto the tests here.
 5117 
 5118         mkdir  ${CVSROOT_DIRNAME}/first-dir
 5119         if ${CVS} co first-dir  ; then
 5120             pass 65
 5121         else
 5122             fail 65
 5123         fi
 5124 
 5125         cd first-dir
 5126 
 5127         # Create a directory with only dead files, to make sure CVS
 5128         # doesn't get confused by it.
 5129         mkdir subdir
 5130         dotest 65a0 "${testcvs} add subdir" \
 5131 "Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository"
 5132         cd subdir
 5133         echo file in subdir >sfile
 5134         dotest 65a1 "${testcvs} add sfile" \
 5135 "${PROG}"' add: scheduling file `sfile'\'' for addition
 5136 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 5137         dotest 65a2 "${testcvs} -q ci -m add-it" \
 5138 "RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v
 5139 done
 5140 Checking in sfile;
 5141 ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v  <--  sfile
 5142 initial revision: 1\.1
 5143 done"
 5144         rm sfile
 5145         dotest 65a3 "${testcvs} rm sfile" \
 5146 "${PROG}"' remove: scheduling `sfile'\'' for removal
 5147 '"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently'
 5148         dotest 65a4 "${testcvs} -q ci -m remove-it" \
 5149 "Removing sfile;
 5150 ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v  <--  sfile
 5151 new revision: delete; previous revision: 1\.1
 5152 done"
 5153         cd ..
 5154         dotest 65a5 "${testcvs} -q update -P" ''
 5155         dotest_fail 65a6 "test -d subdir" ''
 5156 
 5157         # add a file.
 5158         touch file1
 5159         if ${CVS} add file1  2>> ${LOGFILE}; then
 5160             pass 66
 5161         else
 5162             fail 66
 5163         fi
 5164 
 5165         # commit
 5166         if ${CVS} ci -m test  >> ${LOGFILE} 2>&1; then
 5167             pass 67
 5168         else
 5169             fail 67
 5170         fi
 5171 
 5172         # remove
 5173         rm file1
 5174         if ${CVS} rm file1  2>> ${LOGFILE}; then
 5175             pass 68
 5176         else
 5177             fail 68
 5178         fi
 5179 
 5180         # commit
 5181         if ${CVS} ci -m test  >>${LOGFILE} ; then
 5182             pass 69
 5183         else
 5184             fail 69
 5185         fi
 5186 
 5187         dotest_fail 69a0 "test -f file1" ''
 5188         # get the old contents of file1 back
 5189         if ${testcvs} update -p -r 1.1 file1 >file1 2>>${LOGFILE}; then
 5190           pass 69a1
 5191         else
 5192           fail 69a1
 5193         fi
 5194         dotest 69a2 "cat file1" ''
 5195 
 5196         # create second file
 5197         touch file2
 5198         if ${CVS} add file1 file2  2>> ${LOGFILE}; then
 5199             pass 70
 5200         else
 5201             fail 70
 5202         fi
 5203 
 5204         # commit
 5205         if ${CVS} ci -m test  >> ${LOGFILE} 2>&1; then
 5206             pass 71
 5207         else
 5208             fail 71
 5209         fi
 5210 
 5211         # log
 5212         if ${CVS} log file1  >> ${LOGFILE}; then
 5213             pass 72
 5214         else
 5215             fail 72
 5216         fi
 5217 
 5218         # file4 will be dead at the time of branching and stay dead.
 5219         echo file4 > file4
 5220         dotest death-file4-add "${testcvs} add file4" \
 5221 "${PROG}"' add: scheduling file `file4'\'' for addition
 5222 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 5223         dotest death-file4-ciadd "${testcvs} -q ci -m add file4" \
 5224 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v
 5225 done
 5226 Checking in file4;
 5227 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 5228 initial revision: 1\.1
 5229 done"
 5230         rm file4
 5231         dotest death-file4-rm "${testcvs} remove file4" \
 5232 "${PROG}"' remove: scheduling `file4'\'' for removal
 5233 '"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently'
 5234         dotest death-file4-cirm "${testcvs} -q ci -m remove file4" \
 5235 "Removing file4;
 5236 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 5237 new revision: delete; previous revision: 1\.1
 5238 done"
 5239 
 5240         # Tag the branchpoint.
 5241         dotest death-72a "${testcvs} -q tag bp_branch1" 'T file1
 5242 T file2'
 5243 
 5244         # branch1
 5245         if ${CVS} tag -b branch1  ; then
 5246             pass 73
 5247         else
 5248             fail 73
 5249         fi
 5250 
 5251         # and move to the branch.
 5252         if ${CVS} update -r branch1  ; then
 5253             pass 74
 5254         else
 5255             fail 74
 5256         fi
 5257 
 5258         dotest_fail death-file4-3 "test -f file4" ''
 5259 
 5260         # add a file in the branch
 5261         echo line1 from branch1 >> file3
 5262         if ${CVS} add file3  2>> ${LOGFILE}; then
 5263             pass 75
 5264         else
 5265             fail 75
 5266         fi
 5267 
 5268         # commit
 5269         if ${CVS} ci -m test  >> ${LOGFILE} 2>&1; then
 5270             pass 76
 5271         else
 5272             fail 76
 5273         fi
 5274 
 5275         dotest death-76a0 \
 5276 "${testcvs} -q rdiff -r bp_branch1 -r branch1 first-dir" \
 5277 "Index: first-dir/file3
 5278 diff -c /dev/null first-dir/file3:1\.1\.2\.1
 5279 \*\*\* /dev/null    ${DATE}
 5280 --- first-dir/file3 ${DATE}
 5281 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5282 \*\*\* 0 \*\*\*\*
 5283 --- 1 ----
 5284 ${PLUS} line1 from branch1"
 5285         dotest death-76a1 \
 5286 "${testcvs} -q rdiff -r branch1 -r bp_branch1 first-dir" \
 5287 "Index: first-dir/file3
 5288 diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed
 5289 \*\*\* first-dir/file3:1\.1\.2\.1   ${DATE}
 5290 --- first-dir/file3 ${DATE}
 5291 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5292 \*\*\* 1 \*\*\*\*
 5293 - line1 from branch1
 5294 --- 0 ----"
 5295 
 5296         # remove
 5297         rm file3
 5298         if ${CVS} rm file3  2>> ${LOGFILE}; then
 5299             pass 77
 5300         else
 5301             fail 77
 5302         fi
 5303 
 5304         # commit
 5305         if ${CVS} ci -m test  >>${LOGFILE} ; then
 5306             pass 78
 5307         else
 5308             fail 78
 5309         fi
 5310 
 5311         # add again
 5312         echo line1 from branch1 >> file3
 5313         if ${CVS} add file3  2>> ${LOGFILE}; then
 5314             pass 79
 5315         else
 5316             fail 79
 5317         fi
 5318 
 5319         # commit
 5320         if ${CVS} ci -m test  >> ${LOGFILE} 2>&1; then
 5321             pass 80
 5322         else
 5323             fail 80
 5324         fi
 5325 
 5326         # change the first file
 5327         echo line2 from branch1 >> file1
 5328 
 5329         # commit
 5330         if ${CVS} ci -m test  >> ${LOGFILE} 2>&1; then
 5331             pass 81
 5332         else
 5333             fail 81
 5334         fi
 5335 
 5336         # remove the second
 5337         rm file2
 5338         if ${CVS} rm file2  2>> ${LOGFILE}; then
 5339             pass 82
 5340         else
 5341             fail 82
 5342         fi
 5343 
 5344         # commit
 5345         if ${CVS} ci -m test  >>${LOGFILE}; then
 5346             pass 83
 5347         else
 5348             fail 83
 5349         fi
 5350 
 5351         # back to the trunk.
 5352         if ${CVS} update -A  2>> ${LOGFILE}; then
 5353             pass 84
 5354         else
 5355             fail 84
 5356         fi
 5357 
 5358         dotest_fail death-file4-4 "test -f file4" ''
 5359 
 5360         if test -f file3 ; then
 5361             fail 85
 5362         else
 5363             pass 85
 5364         fi
 5365 
 5366         # join
 5367         dotest 86 "${testcvs} -q update -j branch1" \
 5368 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 5369 retrieving revision 1\.3
 5370 retrieving revision 1\.3\.2\.1
 5371 Merging differences between 1\.3 and 1\.3\.2\.1 into file1
 5372 ${PROG} update: scheduling file2 for removal
 5373 U file3"
 5374 
 5375         dotest_fail death-file4-5 "test -f file4" ''
 5376 
 5377         if test -f file3 ; then
 5378             pass 87
 5379         else
 5380             fail 87
 5381         fi
 5382 
 5383         # Make sure that we joined the correct change to file1
 5384         if echo line2 from branch1 | cmp - file1 >/dev/null; then
 5385             pass 87a
 5386         else
 5387             fail 87a
 5388         fi
 5389 
 5390         # update
 5391         if ${CVS} update  ; then
 5392             pass 88
 5393         else
 5394             fail 88
 5395         fi
 5396 
 5397         # commit
 5398         dotest 89 "${testcvs} -q ci -m test" \
 5399 "Checking in file1;
 5400 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 5401 new revision: 1\.4; previous revision: 1\.3
 5402 done
 5403 Removing file2;
 5404 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 5405 new revision: delete; previous revision: 1\.1
 5406 done
 5407 Checking in file3;
 5408 ${CVSROOT_DIRNAME}/first-dir/file3,v  <--  file3
 5409 new revision: 1\.2; previous revision: 1\.1
 5410 done"
 5411         cd ..
 5412         mkdir 2
 5413         cd 2
 5414         dotest 89a "${testcvs} -q co first-dir" 'U first-dir/file1
 5415 U first-dir/file3'
 5416         cd ..
 5417         rm -r 2
 5418         cd first-dir
 5419 
 5420         # remove first file.
 5421         rm file1
 5422         if ${CVS} rm file1  2>> ${LOGFILE}; then
 5423             pass 90
 5424         else
 5425             fail 90
 5426         fi
 5427 
 5428         # commit
 5429         if ${CVS} ci -m test  >>${LOGFILE}; then
 5430             pass 91
 5431         else
 5432             fail 91
 5433         fi
 5434 
 5435         if test -f file1 ; then
 5436             fail 92
 5437         else
 5438             pass 92
 5439         fi
 5440 
 5441         # typo; try to get to the branch and fail
 5442         dotest_fail 92.1a "${testcvs} update -r brnach1" \
 5443           "${PROG}"' \[update aborted\]: no such tag brnach1'
 5444         # Make sure we are still on the trunk
 5445         if test -f file1 ; then
 5446             fail 92.1b
 5447         else
 5448             pass 92.1b
 5449         fi
 5450         if test -f file3 ; then
 5451             pass 92.1c
 5452         else
 5453             fail 92.1c
 5454         fi
 5455 
 5456         # back to branch1
 5457         if ${CVS} update -r branch1  2>> ${LOGFILE}; then
 5458             pass 93
 5459         else
 5460             fail 93
 5461         fi
 5462 
 5463         dotest_fail death-file4-6 "test -f file4" ''
 5464 
 5465         if test -f file1 ; then
 5466             pass 94
 5467         else
 5468             fail 94
 5469         fi
 5470 
 5471         # and join
 5472         dotest 95 "$testcvs -q update -j HEAD" \
 5473 "$PROG update: file file1 has been removed in revision HEAD, but the destination is incompatibly modified
 5474 C file1
 5475 $PROG update: file file3 exists, but has been added in revision HEAD"
 5476 
 5477         dotest_fail death-file4-7 "test -f file4" ''
 5478 
 5479         # file2 should not have been recreated.  It was
 5480         # deleted on the branch, and has not been modified on
 5481         # the trunk.  That means that there have been no
 5482         # changes between the greatest common ancestor (the
 5483         # trunk version) and HEAD.
 5484         dotest_fail death-file2-1 "test -f file2" ''
 5485 
 5486         cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
 5487         ;;
 5488 
 5489     death2)
 5490       # More tests of death support.
 5491       mkdir ${CVSROOT_DIRNAME}/first-dir
 5492       dotest death2-1 "${testcvs} -q co first-dir" ''
 5493 
 5494       cd first-dir
 5495 
 5496       # Add two files on the trunk.
 5497       echo "first revision" > file1
 5498       echo "file4 first revision" > file4
 5499       dotest death2-2 "${testcvs} add file1 file4" \
 5500 "${PROG}"' add: scheduling file `file1'\'' for addition
 5501 '"${PROG}"' add: scheduling file `file4'\'' for addition
 5502 '"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
 5503 
 5504       dotest death2-3 "${testcvs} -q commit -m add" \
 5505 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 5506 done
 5507 Checking in file1;
 5508 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 5509 initial revision: 1\.1
 5510 done
 5511 RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v
 5512 done
 5513 Checking in file4;
 5514 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 5515 initial revision: 1\.1
 5516 done"
 5517 
 5518       # Make a branch and a non-branch tag.
 5519       dotest death2-4 "${testcvs} -q tag -b branch" \
 5520 'T file1
 5521 T file4'
 5522       dotest death2-5 "${testcvs} -q tag tag" \
 5523 'T file1
 5524 T file4'
 5525 
 5526       # Switch over to the branch.
 5527       dotest death2-6 "$testcvs -q update -r branch" \
 5528 '[UP] file1
 5529 [UP] file4'
 5530 
 5531       # Delete the file on the branch.
 5532       rm file1
 5533       dotest death2-7 "${testcvs} rm file1" \
 5534 "${PROG} remove: scheduling .file1. for removal
 5535 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 5536 
 5537       # Test diff of the removed file before it is committed.
 5538       dotest_fail death2-diff-1 "${testcvs} -q diff file1" \
 5539 "${PROG} diff: file1 was removed, no comparison available"
 5540 
 5541       dotest_fail death2-diff-2 "${testcvs} -q diff -N -c file1" \
 5542 "Index: file1
 5543 ===================================================================
 5544 RCS file: file1
 5545 diff -N file1
 5546 \*\*\* file1    ${RFCDATE}  [0-9.]*
 5547 --- /dev/null   ${RFCDATE_EPOCH}
 5548 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5549 \*\*\* 1 \*\*\*\*
 5550 - first revision
 5551 --- 0 ----"
 5552 
 5553       dotest death2-8 "${testcvs} -q ci -m removed" \
 5554 "Removing file1;
 5555 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 5556 new revision: delete; previous revision: 1\.1
 5557 done"
 5558 
 5559       # Test diff of a dead file.
 5560       dotest_fail death2-diff-3 \
 5561 "${testcvs} -q diff -r1.1 -rbranch -c file1" \
 5562 "${PROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\.
 5563 ${PROG} diff: No comparison available\.  Pass .-N. to .${PROG} diff.${QUESTION}"
 5564       # and in reverse
 5565       dotest_fail death2-diff-3a \
 5566 "${testcvs} -q diff -rbranch -r1.1 -c file1" \
 5567 "${PROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\.
 5568 ${PROG} diff: No comparison available\.  Pass .-N. to .${PROG} diff.${QUESTION}"
 5569 
 5570       dotest_fail death2-diff-4 \
 5571 "${testcvs} -q diff -r1.1 -rbranch -N -c file1" \
 5572 "Index: file1
 5573 ===================================================================
 5574 RCS file: file1
 5575 diff -N file1
 5576 \*\*\* file1    ${RFCDATE}  [0-9.]*
 5577 --- /dev/null   ${RFCDATE_EPOCH}
 5578 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5579 \*\*\* 1 \*\*\*\*
 5580 - first revision
 5581 --- 0 ----"
 5582       # and in reverse
 5583       dotest_fail death2-diff-4a \
 5584 "${testcvs} -q diff -rbranch -r1.1 -N -c file1" \
 5585 "Index: file1
 5586 ===================================================================
 5587 RCS file: file1
 5588 diff -N file1
 5589 \*\*\* /dev/null    ${RFCDATE_EPOCH}
 5590 --- file1   ${RFCDATE}  [0-9.]*
 5591 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5592 \*\*\* 0 \*\*\*\*
 5593 --- 1 ----
 5594 + first revision"
 5595 
 5596 
 5597       dotest_fail death2-diff-5 "${testcvs} -q diff -rtag -c ." \
 5598 "${PROG} diff: file1 no longer exists, no comparison available"
 5599 
 5600       dotest_fail death2-diff-6 "${testcvs} -q diff -rtag -N -c ." \
 5601 "Index: file1
 5602 ===================================================================
 5603 RCS file: file1
 5604 diff -N file1
 5605 \*\*\* file1    [-a-zA-Z0-9: ]* [0-9.]*
 5606 --- /dev/null   ${RFCDATE_EPOCH}
 5607 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5608 \*\*\* 1 \*\*\*\*
 5609 - first revision
 5610 --- 0 ----"
 5611 
 5612       # Test rdiff of a dead file.
 5613       dotest death2-rdiff-1 \
 5614 "${testcvs} -q rtag -rbranch rdiff-tag first-dir" ''
 5615 
 5616       dotest death2-rdiff-2 "${testcvs} -q rdiff -rtag -rbranch first-dir" \
 5617 "Index: first-dir/file1
 5618 diff -c first-dir/file1:1\.1 first-dir/file1:removed
 5619 \*\*\* first-dir/file1:1\.1 [a-zA-Z0-9: ]*
 5620 --- first-dir/file1 [a-zA-Z0-9: ]*
 5621 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5622 \*\*\* 1 \*\*\*\*
 5623 - first revision
 5624 --- 0 ----"
 5625 
 5626       # Readd the file to the branch.
 5627       echo "second revision" > file1
 5628       dotest death2-9 "${testcvs} add file1" \
 5629 "${PROG}"' add: file `file1'\'' will be added on branch `branch'\'' from version 1\.1\.2\.1
 5630 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 5631 
 5632       # Test diff of the added file before it is committed.
 5633       dotest_fail death2-diff-7 "${testcvs} -q diff file1" \
 5634 "${PROG} diff: file1 is a new entry, no comparison available"
 5635 
 5636       dotest_fail death2-diff-8 "${testcvs} -q diff -N -c file1" \
 5637 "Index: file1
 5638 ===================================================================
 5639 RCS file: file1
 5640 diff -N file1
 5641 \*\*\* /dev/null    ${RFCDATE_EPOCH}
 5642 --- file1   ${RFCDATE}
 5643 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5644 \*\*\* 0 \*\*\*\*
 5645 --- 1 ----
 5646 ${PLUS} second revision"
 5647 
 5648       dotest death2-10 "${testcvs} -q commit -m add" \
 5649 "Checking in file1;
 5650 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 5651 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
 5652 done"
 5653 
 5654       # Delete file4 from the branch
 5655       dotest death2-10a "${testcvs} rm -f file4" \
 5656 "${PROG} remove: scheduling .file4. for removal
 5657 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 5658       dotest death2-10b "${testcvs} -q ci -m removed" \
 5659 "Removing file4;
 5660 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 5661 new revision: delete; previous revision: 1\.1
 5662 done"
 5663 
 5664       # Back to the trunk.
 5665       dotest death2-11 "${testcvs} -q update -A" \
 5666 "[UP] file1
 5667 U file4"
 5668 
 5669       # Add another file on the trunk.
 5670       echo "first revision" > file2
 5671       dotest death2-12 "${testcvs} add file2" \
 5672 "${PROG}"' add: scheduling file `file2'\'' for addition
 5673 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 5674       dotest death2-13 "${testcvs} -q commit -m add" \
 5675 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
 5676 done
 5677 Checking in file2;
 5678 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 5679 initial revision: 1\.1
 5680 done"
 5681 
 5682       # Modify file4 on the trunk.
 5683       echo "new file4 revision" > file4
 5684       dotest death2-13a "${testcvs} -q commit -m mod" \
 5685 "Checking in file4;
 5686 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 5687 new revision: 1\.2; previous revision: 1\.1
 5688 done"
 5689 
 5690       # Back to the branch.
 5691       # The ``no longer in the repository'' message doesn't really
 5692       # look right to me, but that's what CVS currently prints for
 5693       # this case.
 5694       dotest death2-14 "${testcvs} -q update -r branch" \
 5695 "[UP] file1
 5696 ${PROG} update: file2 is no longer in the repository
 5697 ${PROG} update: file4 is no longer in the repository"
 5698 
 5699       # Add a file on the branch with the same name.
 5700       echo "branch revision" > file2
 5701       dotest death2-15 "${testcvs} add file2" \
 5702 "${PROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\''
 5703 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 5704       dotest death2-16 "${testcvs} -q commit -m add" \
 5705 "Checking in file2;
 5706 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 5707 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
 5708 done"
 5709 
 5710       # Add a new file on the branch.
 5711       echo "first revision" > file3
 5712       dotest death2-17 "${testcvs} add file3" \
 5713 "${PROG}"' add: scheduling file `file3'\'' for addition on branch `branch'\''
 5714 '"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
 5715       dotest death2-18 "${testcvs} -q commit -m add" \
 5716 "RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
 5717 done
 5718 Checking in file3;
 5719 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v  <--  file3
 5720 new revision: 1\.1\.2\.1; previous revision: 1\.1
 5721 done"
 5722 
 5723       # Test diff of a nonexistent tag
 5724       dotest_fail death2-diff-9 "${testcvs} -q diff -rtag -c file3" \
 5725 "${PROG} diff: tag tag is not in file file3"
 5726 
 5727       dotest_fail death2-diff-10 "${testcvs} -q diff -rtag -N -c file3" \
 5728 "Index: file3
 5729 ===================================================================
 5730 RCS file: file3
 5731 diff -N file3
 5732 \*\*\* /dev/null    ${RFCDATE_EPOCH}
 5733 --- file3   ${RFCDATE}  [0-9.]*
 5734 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5735 \*\*\* 0 \*\*\*\*
 5736 --- 1 ----
 5737 ${PLUS} first revision"
 5738 
 5739       dotest_fail death2-diff-11 "${testcvs} -q diff -rtag -c ." \
 5740 "Index: file1
 5741 ===================================================================
 5742 RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 5743 retrieving revision 1\.1
 5744 retrieving revision 1\.1\.2\.2
 5745 diff -c -r1\.1 -r1\.1\.2\.2
 5746 \*\*\* file1    ${RFCDATE}  [0-9.]*
 5747 --- file1   ${RFCDATE}  [0-9.]*
 5748 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5749 \*\*\* 1 \*\*\*\*
 5750 ! first revision
 5751 --- 1 ----
 5752 ! second revision
 5753 ${PROG} diff: tag tag is not in file file2
 5754 ${PROG} diff: tag tag is not in file file3
 5755 ${PROG} diff: file4 no longer exists, no comparison available"
 5756 
 5757       dotest_fail death2-diff-12 "${testcvs} -q diff -rtag -c -N ." \
 5758 "Index: file1
 5759 ===================================================================
 5760 RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 5761 retrieving revision 1\.1
 5762 retrieving revision 1\.1\.2\.2
 5763 diff -c -r1\.1 -r1\.1\.2\.2
 5764 \*\*\* file1    ${RFCDATE}  [0-9.]*
 5765 --- file1   ${RFCDATE}  [0-9.]*
 5766 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5767 \*\*\* 1 \*\*\*\*
 5768 ! first revision
 5769 --- 1 ----
 5770 ! second revision
 5771 Index: file2
 5772 ===================================================================
 5773 RCS file: file2
 5774 diff -N file2
 5775 \*\*\* /dev/null    ${RFCDATE_EPOCH}
 5776 --- file2   ${RFCDATE}  [0-9.]*
 5777 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5778 \*\*\* 0 \*\*\*\*
 5779 --- 1 ----
 5780 ${PLUS} branch revision
 5781 Index: file3
 5782 ===================================================================
 5783 RCS file: file3
 5784 diff -N file3
 5785 \*\*\* /dev/null    ${RFCDATE_EPOCH}
 5786 --- file3   ${RFCDATE}  [0-9.]*
 5787 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5788 \*\*\* 0 \*\*\*\*
 5789 --- 1 ----
 5790 ${PLUS} first revision
 5791 Index: file4
 5792 ===================================================================
 5793 RCS file: file4
 5794 diff -N file4
 5795 \*\*\* file4    ${RFCDATE}  [0-9.]*
 5796 --- /dev/null   ${RFCDATE_EPOCH}
 5797 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5798 \*\*\* 1 \*\*\*\*
 5799 - file4 first revision
 5800 --- 0 ----"
 5801 
 5802       # Switch to the nonbranch tag.
 5803       dotest death2-19 "${testcvs} -q update -r tag" \
 5804 "[UP] file1
 5805 ${PROG} update: file2 is no longer in the repository
 5806 ${PROG} update: file3 is no longer in the repository
 5807 U file4"
 5808 
 5809       dotest_fail death2-20 "test -f file2"
 5810 
 5811       # Make sure diff only reports appropriate files.
 5812       dotest_fail death2-diff-13 "${testcvs} -q diff -r rdiff-tag" \
 5813 "${PROG} diff: Tag rdiff-tag refers to a dead (removed) revision in file .file1.\.
 5814 ${PROG} diff: No comparison available\.  Pass .-N. to .${PROG} diff.${QUESTION}"
 5815 
 5816       dotest_fail death2-diff-14 "${testcvs} -q diff -r rdiff-tag -c -N" \
 5817 "Index: file1
 5818 ===================================================================
 5819 RCS file: file1
 5820 diff -N file1
 5821 \*\*\* /dev/null    ${RFCDATE_EPOCH}
 5822 --- file1   ${RFCDATE}  [0-9.]*
 5823 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 5824 \*\*\* 0 \*\*\*\*
 5825 --- 1 ----
 5826 ${PLUS} first revision"
 5827 
 5828       # now back to the trunk
 5829       dotest death2-21 "$testcvs -q update -A" \
 5830 '[UP] file1
 5831 U file2
 5832 U file4'
 5833 
 5834       # test merging with a dead file
 5835       dotest death2-22 "${testcvs} -q co first-dir" \
 5836 "U first-dir/file1
 5837 U first-dir/file2
 5838 U first-dir/file4"
 5839 
 5840       cd first-dir
 5841       dotest death2-23 "${testcvs} rm -f file4" \
 5842 "${PROG} remove: scheduling .file4. for removal
 5843 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 5844       dotest death2-24 "${testcvs} -q ci -m removed file4" \
 5845 "Removing file4;
 5846 ${CVSROOT_DIRNAME}/first-dir/file4,v  <--  file4
 5847 new revision: delete; previous revision: 1\.2
 5848 done"
 5849       cd ..
 5850       echo "new stuff" >file4
 5851       dotest_fail death2-25 "${testcvs} up file4" \
 5852 "${PROG} update: conflict: file4 is modified but no longer in the repository
 5853 C file4"
 5854 
 5855       cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
 5856       ;;
 5857 
 5858 
 5859 
 5860     death-rtag)
 5861       # This documents a bug in CVS that prevents rtag from tagging files
 5862       # in the Attic.
 5863       mkdir $CVSROOT_DIRNAME/death-rtag
 5864       dotest death-rtag-init-1 "$testcvs -Q co death-rtag"
 5865       cd death-rtag
 5866       echo "This is the file foo" > foo
 5867       echo "This is the file bar" > bar
 5868       dotest death-rtag-init-2 "$testcvs -Q add foo bar"
 5869       dotest death-rtag-init-3 "$testcvs -Q ci -m 'Add foo and bar.'" \
 5870 "RCS file: $CVSROOT_DIRNAME/death-rtag/bar,v
 5871 done
 5872 Checking in bar;
 5873 $CVSROOT_DIRNAME/death-rtag/bar,v  <--  bar
 5874 initial revision: 1\.[0-9]*
 5875 done
 5876 RCS file: $CVSROOT_DIRNAME/death-rtag/foo,v
 5877 done
 5878 Checking in foo;
 5879 $CVSROOT_DIRNAME/death-rtag/foo,v  <--  foo
 5880 initial revision: 1\.[0-9]*
 5881 done"
 5882       dotest death-rtag-init-5 "$testcvs -Q tag -b mybranch"
 5883 
 5884       dotest death-rtag-1 "$testcvs -q rtag -rmybranch willtag death-rtag"
 5885       dotest death-rtag-2 "$testcvs -Q rm -f foo"
 5886       dotest death-rtag-3 "$testcvs -Q ci -m 'Remove foo.'" \
 5887 "Removing foo;
 5888 $CVSROOT_DIRNAME/death-rtag/foo,v  <--  foo
 5889 new revision: delete; previous revision: 1\.[0-9]*
 5890 done"
 5891       # commit something on the branch so that the moving tag is visible.
 5892       dotest death-rtag-3.2 "$testcvs -Q up -rmybranch"
 5893       echo some branch content >>foo
 5894       echo some branch content >>bar
 5895       dotest death-rtag-3.3 "$testcvs -Q ci -m 'Change foo.'" \
 5896 "Checking in bar;
 5897 $CVSROOT_DIRNAME/death-rtag/bar,v  <--  bar
 5898 new revision: 1\.1\.2\.1; previous revision: 1\.1
 5899 done
 5900 Checking in foo;
 5901 $CVSROOT_DIRNAME/death-rtag/Attic/foo,v  <--  foo
 5902 new revision: 1\.1\.2\.1; previous revision: 1\.1
 5903 done"
 5904       dotest death-rtag-3.4 \
 5905 "$testcvs -q rtag -rmybranch wontmove death-rtag"
 5906       dotest death-rtag-3.5 "$testcvs -q rtag -F wontmove death-rtag"
 5907 
 5908       cd ..
 5909       # Removing -f below avoids this bug.
 5910       dotest death-rtag-4 "$testcvs -q rtag -frmybranch wonttag death-rtag"
 5911 
 5912       # When the bug existed, `wonttag' would not have been present in
 5913       # foo,v.
 5914       #
 5915       # A second bug prevented `wontmove' from moving from the branch to
 5916       # the dead revision on the trunk (death-rtag-3.4 & death-rtag-3.5).
 5917       dotest death-rtag-5 "$testcvs -q rlog death-rtag" \
 5918 "
 5919 RCS file: $CVSROOT_DIRNAME/death-rtag/bar,v
 5920 head: 1.[0-9]*
 5921 branch:
 5922 locks: strict
 5923 access list:
 5924 symbolic names:
 5925     wonttag: 1\.1\.2\.1
 5926     wontmove: 1\.1
 5927     willtag: 1\.1
 5928     mybranch: 1\.1.0\.2
 5929 keyword substitution: kv
 5930 $DOTSTAR
 5931 RCS file: $CVSROOT_DIRNAME/death-rtag/Attic/foo,v
 5932 head: 1.[0-9]*
 5933 branch:
 5934 locks: strict
 5935 access list:
 5936 symbolic names:
 5937     wonttag: 1\.1\.2\.1
 5938     wontmove: 1\.2
 5939     willtag: 1\.1
 5940     mybranch: 1\.1.0\.2
 5941 keyword substitution: kv
 5942 $DOTSTAR"
 5943 
 5944       if $keep; then
 5945         echo Keeping $TESTDIR and exiting due to --keep
 5946         exit 0
 5947       fi
 5948 
 5949       rm -r death-rtag
 5950       rm -rf $CVSROOT_DIRNAME/death-rtag
 5951       ;;
 5952 
 5953 
 5954 
 5955     rm-update-message)
 5956       # FIXME
 5957       # local CVS prints a warning message when update notices a missing
 5958       # file and client/server CVS doesn't.  These should be identical.
 5959       mkdir rm-update-message; cd rm-update-message
 5960       mkdir $CVSROOT_DIRNAME/rm-update-message
 5961       dotest rm-update-message-setup-1 "$testcvs -q co rm-update-message" ''
 5962       cd rm-update-message
 5963       file=x
 5964       echo >$file
 5965       dotest rm-update-message-setup-2 "$testcvs -q add $file" \
 5966 "${PROG} add: use .${PROG} commit. to add this file permanently"
 5967       dotest rm-update-message-setup-3 "$testcvs -q ci -mcreate $file" \
 5968 "RCS file: $CVSROOT_DIRNAME/rm-update-message/$file,v
 5969 done
 5970 Checking in $file;
 5971 $CVSROOT_DIRNAME/rm-update-message/$file,v  <--  $file
 5972 initial revision: 1\.1
 5973 done"
 5974 
 5975       rm $file
 5976       dotest rm-update-message-1 "$testcvs up $file" \
 5977 "${PROG} update: warning: $file was lost
 5978 U $file"
 5979 
 5980       cd ../..
 5981       if $keep; then :; else
 5982         rm -rf rm-update-message
 5983         rm -rf $CVSROOT_DIRNAME/rm-update-message
 5984       fi
 5985       ;;
 5986 
 5987     rmadd)
 5988       # More tests of adding and removing files.
 5989       # In particular ci -r.
 5990       # Other ci -r tests:
 5991       #   * editor-9: checking in a modified file,
 5992       #     where "ci -r" means a branch.
 5993       #   * basica-8a1: checking in a modified file with numeric revision.
 5994       #   * basica-8a2: likewise.
 5995       #   * keywordlog-4: adding a new file with numeric revision.
 5996       mkdir 1; cd 1
 5997       dotest rmadd-1 "${testcvs} -q co -l ." ''
 5998       mkdir first-dir
 5999       dotest rmadd-2 "${testcvs} add first-dir" \
 6000 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 6001       cd first-dir
 6002       echo first file1 >file1
 6003       dotest rmadd-3 "${testcvs} add file1" \
 6004 "${PROG} add: scheduling file .file1. for addition
 6005 ${PROG} add: use .${PROG} commit. to add this file permanently"
 6006 
 6007       dotest_fail rmadd-4 "${testcvs} -q ci -r 1.2.2.4 -m add" \
 6008 "${PROG} commit: cannot add file .file1' with revision .1\.2\.2\.4'; must be on trunk
 6009 ${PROG} \[commit aborted\]: correct above errors first!"
 6010       dotest_fail rmadd-5 "${testcvs} -q ci -r 1.2.2 -m add" \
 6011 "${PROG} commit: cannot add file .file1' with revision .1\.2\.2'; must be on trunk
 6012 ${PROG} \[commit aborted\]: correct above errors first!"
 6013       dotest_fail rmadd-6 "${testcvs} -q ci -r mybranch -m add" \
 6014 "${PROG} \[commit aborted\]: no such tag mybranch"
 6015 
 6016       # The thing with the trailing periods strikes me as a very
 6017       # bizarre behavior, but it would seem to be intentional
 6018       # (see commit.c).  It probably could go away....
 6019       dotest rmadd-7 "${testcvs} -q ci -r 7.... -m add" \
 6020 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 6021 done
 6022 Checking in file1;
 6023 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6024 initial revision: 7\.1
 6025 done"
 6026       if $remote; then
 6027         # I guess remote doesn't set a sticky tag in this case.
 6028         # Kind of odd, in the sense that rmadd-24a does set one
 6029         # both local and remote.
 6030         dotest_fail rmadd-7a "test -f CVS/Tag"
 6031         echo T7 >CVS/Tag
 6032       else
 6033         dotest rmadd-7a "cat CVS/Tag" "T7"
 6034       fi
 6035 
 6036       dotest rmadd-8 "${testcvs} -q tag -b mybranch" "T file1"
 6037       dotest rmadd-9 "${testcvs} -q tag mynonbranch" "T file1"
 6038 
 6039       touch file2
 6040       # The previous "cvs ci -r" set a sticky tag of '7'.  Seems a
 6041       # bit odd, and I guess commit.c (findmaxrev) makes '7' sticky
 6042       # tags unnecessary (?).  I kind of suspect that it should be
 6043       # saying "sticky tag is not a branch" like keywordlog-4b.
 6044       # Or something.
 6045       dotest rmadd-10 "${testcvs} add file2" \
 6046 "${PROG} add: scheduling file .file2. for addition on branch .7'
 6047 ${PROG} add: use .${PROG} commit. to add this file permanently"
 6048       # As in the previous example, CVS is confused....
 6049       dotest rmadd-11 "${testcvs} -q ci -m add" \
 6050 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
 6051 done
 6052 Checking in file2;
 6053 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 6054 initial revision: 7\.1
 6055 done"
 6056 
 6057       dotest rmadd-12 "${testcvs} -q update -A" ""
 6058       touch file3
 6059       dotest rmadd-13 "${testcvs} add file3" \
 6060 "${PROG} add: scheduling file .file3. for addition
 6061 ${PROG} add: use .${PROG} commit. to add this file permanently"
 6062       # Huh?  file2 is not up to date?  Seems buggy to me....
 6063       dotest_fail rmadd-14 "${testcvs} -q ci -r mybranch -m add" \
 6064 "${PROG} commit: Up-to-date check failed for .file2'
 6065 ${PROG} \[commit aborted\]: correct above errors first!"
 6066       # Whatever, let's not let file2 distract us....
 6067       dotest rmadd-15 "${testcvs} -q ci -r mybranch -m add file3" \
 6068 "RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
 6069 done
 6070 Checking in file3;
 6071 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v  <--  file3
 6072 new revision: 1\.1\.2\.1; previous revision: 1\.1
 6073 done"
 6074 
 6075       touch file4
 6076       dotest rmadd-16 "${testcvs} add file4" \
 6077 "${PROG} add: scheduling file .file4. for addition
 6078 ${PROG} add: use .${PROG} commit. to add this file permanently"
 6079       # Same "Up-to-date check" issues as in rmadd-14.
 6080       # The "no such tag" thing is due to the fact that we only
 6081       # update val-tags when the tag is used (might be more of a
 6082       # bug than a feature, I dunno).
 6083       dotest_fail rmadd-17 \
 6084 "${testcvs} -q ci -r mynonbranch -m add file4" \
 6085 "${PROG} \[commit aborted\]: no such tag mynonbranch"
 6086       # Try to make CVS write val-tags.
 6087       dotest rmadd-18 "${testcvs} -q update -p -r mynonbranch file1" \
 6088 "first file1"
 6089       # Oops, -p suppresses writing val-tags (probably a questionable
 6090       # behavior).
 6091       dotest_fail rmadd-19 \
 6092 "${testcvs} -q ci -r mynonbranch -m add file4" \
 6093 "${PROG} \[commit aborted\]: no such tag mynonbranch"
 6094       # Now make CVS write val-tags for real.
 6095       dotest rmadd-20 "$testcvs -q update -r mynonbranch file1" '[UP] file1'
 6096       # Oops - CVS isn't distinguishing between a branch tag and
 6097       # a non-branch tag.
 6098       dotest rmadd-21 \
 6099 "${testcvs} -q ci -r mynonbranch -m add file4" \
 6100 "RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file4,v
 6101 done
 6102 Checking in file4;
 6103 ${CVSROOT_DIRNAME}/first-dir/Attic/file4,v  <--  file4
 6104 new revision: 1\.1\.2\.1; previous revision: 1\.1
 6105 done"
 6106 
 6107       # OK, we add this one in a vanilla way, but then check in
 6108       # a modification with ci -r and sniff around for sticky tags.
 6109       echo file5 >file5
 6110       dotest rmadd-22 "${testcvs} add file5" \
 6111 "${PROG} add: scheduling file .file5. for addition
 6112 ${PROG} add: use .${PROG} commit. to add this file permanently"
 6113       if $remote; then
 6114         # Interesting bug (or missing feature) here.  findmaxrev
 6115         # gets the major revision from the Entries.  Well, remote
 6116         # doesn't send the entries for files which are not involved.
 6117         dotest rmadd-23r "${testcvs} -q ci -m add" \
 6118 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v
 6119 done
 6120 Checking in file5;
 6121 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 6122 initial revision: 1\.1
 6123 done"
 6124         dotest rmadd-23-workaroundr \
 6125 "${testcvs} -q ci -r 7 -m bump-it file5" \
 6126 "Checking in file5;
 6127 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 6128 new revision: 7\.1; previous revision: 1\.1
 6129 done"
 6130       else
 6131         dotest rmadd-23 "${testcvs} -q ci -m add" \
 6132 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v
 6133 done
 6134 Checking in file5;
 6135 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 6136 initial revision: 7\.1
 6137 done"
 6138       fi
 6139       echo change it >file5
 6140       dotest_fail rmadd-24 "${testcvs} -q ci -r 4.8 -m change file5" \
 6141 "Checking in file5;
 6142 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 6143 ${PROG} commit: ${CVSROOT_DIRNAME}/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1
 6144 ${PROG} commit: could not check in file5"
 6145       dotest rmadd-24a "${testcvs} -q ci -r 8.4 -m change file5" \
 6146 "Checking in file5;
 6147 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 6148 new revision: 8\.4; previous revision: 7\.1
 6149 done"
 6150       # I'm not really sure that a sticky tag make sense here.
 6151       # It seems to be longstanding behavior for what that is worth.
 6152       dotest rmadd-25 "${testcvs} status file5" \
 6153 "===================================================================
 6154 File: file5             Status: Up-to-date
 6155 
 6156    Working revision:    8\.4.*
 6157    Repository revision: 8\.4    ${CVSROOT_DIRNAME}/first-dir/file5,v
 6158    Sticky Tag:      8\.4
 6159    Sticky Date:     (none)
 6160    Sticky Options:  (none)"
 6161 
 6162       # now try forced revision with recursion
 6163       mkdir sub
 6164       dotest rmadd-26 "${testcvs} -q add sub" \
 6165 "Directory ${CVSROOT_DIRNAME}/first-dir/sub added to the repository"
 6166       echo hello >sub/subfile
 6167       dotest rmadd-27 "${testcvs} -q add sub/subfile" \
 6168 "${PROG} add: use .${PROG} commit. to add this file permanently"
 6169 
 6170       dotest rmadd-28 "${testcvs} -q ci -m. sub" \
 6171 "RCS file: ${CVSROOT_DIRNAME}/first-dir/sub/subfile,v
 6172 done
 6173 Checking in sub/subfile;
 6174 ${CVSROOT_DIRNAME}/first-dir/sub/subfile,v  <--  subfile
 6175 initial revision: 1\.1
 6176 done"
 6177 
 6178       # lose the branch
 6179       dotest rmadd-29 "$testcvs -q up -A" \
 6180 "[UP] file1
 6181 $PROG update: file3 is no longer in the repository
 6182 $PROG update: file4 is no longer in the repository"
 6183 
 6184       # -f disables recursion
 6185       dotest rmadd-30 "${testcvs} -q ci -f -r9 -m." \
 6186 "Checking in file1;
 6187 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6188 new revision: 9\.1; previous revision: 7\.1
 6189 done
 6190 Checking in file2;
 6191 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 6192 new revision: 9\.1; previous revision: 7\.1
 6193 done
 6194 Checking in file5;
 6195 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 6196 new revision: 9\.1; previous revision: 8\.4
 6197 done"
 6198 
 6199       # add -R to force recursion
 6200       dotest rmadd-31 "${testcvs} -q ci -f -r9 -R -m." \
 6201 "Checking in file1;
 6202 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6203 new revision: 9\.2; previous revision: 9\.1
 6204 done
 6205 Checking in file2;
 6206 ${CVSROOT_DIRNAME}/first-dir/file2,v  <--  file2
 6207 new revision: 9\.2; previous revision: 9\.1
 6208 done
 6209 Checking in file5;
 6210 ${CVSROOT_DIRNAME}/first-dir/file5,v  <--  file5
 6211 new revision: 9\.2; previous revision: 9\.1
 6212 done
 6213 Checking in sub/subfile;
 6214 ${CVSROOT_DIRNAME}/first-dir/sub/subfile,v  <--  subfile
 6215 new revision: 9\.1; previous revision: 1\.1
 6216 done"
 6217 
 6218       if $remote; then
 6219         # as noted above, remote doesn't set a sticky tag
 6220         :
 6221       else
 6222         dotest rmadd-32 "cat CVS/Tag" "T9"
 6223         dotest rmadd-33 "cat sub/CVS/Tag" "T9"
 6224       fi
 6225 
 6226       cd ../..
 6227       rm -r 1
 6228       rm -rf ${CVSROOT_DIRNAME}/first-dir
 6229       ;;
 6230 
 6231     rmadd2)
 6232       # Tests of undoing commits, including in the presence of
 6233       # adding and removing files.  See join for a list of -j tests.
 6234       mkdir 1; cd 1
 6235       dotest rmadd2-1 "${testcvs} -q co -l ." ''
 6236       mkdir first-dir
 6237       dotest rmadd2-2 "${testcvs} add first-dir" \
 6238 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 6239       cd first-dir
 6240       echo 'initial contents' >file1
 6241       dotest rmadd2-3 "${testcvs} add file1" \
 6242 "${PROG} add: scheduling file .file1. for addition
 6243 ${PROG} add: use .${PROG} commit. to add this file permanently"
 6244       dotest rmadd2-4 "${testcvs} -q ci -m add" \
 6245 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 6246 done
 6247 Checking in file1;
 6248 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6249 initial revision: 1\.1
 6250 done"
 6251       dotest rmadd2-4a "${testcvs} -Q tag tagone" ""
 6252       dotest rmadd2-5 "${testcvs} rm -f file1" \
 6253 "${PROG} remove: scheduling .file1. for removal
 6254 ${PROG} remove: use .${PROG} commit. to remove this file permanently"
 6255       dotest rmadd2-6 "${testcvs} -q ci -m remove" \
 6256 "Removing file1;
 6257 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6258 new revision: delete; previous revision: 1\.1
 6259 done"
 6260       dotest rmadd2-7 "${testcvs} -q update -j 1.2 -j 1.1 file1" "U file1"
 6261       dotest rmadd2-8 "${testcvs} -q ci -m readd" \
 6262 "Checking in file1;
 6263 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6264 new revision: 1\.3; previous revision: 1\.2
 6265 done"
 6266       echo 'new contents' >file1
 6267       dotest rmadd2-9 "${testcvs} -q ci -m modify" \
 6268 "Checking in file1;
 6269 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6270 new revision: 1\.4; previous revision: 1\.3
 6271 done"
 6272       dotest rmadd2-10 "${testcvs} -q update -j 1.4 -j 1.3 file1" \
 6273 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 6274 retrieving revision 1\.4
 6275 retrieving revision 1\.3
 6276 Merging differences between 1\.4 and 1\.3 into file1"
 6277       dotest rmadd2-11 "${testcvs} -q ci -m undo" \
 6278 "Checking in file1;
 6279 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6280 new revision: 1\.5; previous revision: 1\.4
 6281 done"
 6282       dotest rmadd2-12 "cat file1" "initial contents"
 6283       dotest rmadd2-13 "${testcvs} -q update -p -r 1.3" "initial contents"
 6284 
 6285       # Hmm, might be a bit odd that this works even if 1.3 is not
 6286       # the head.
 6287       dotest rmadd2-14 "${testcvs} -q update -j 1.3 -j 1.2 file1" \
 6288 "${PROG} update: scheduling file1 for removal"
 6289 
 6290       # Check that -p can get arbitrary revisions of a removed file
 6291       dotest rmadd2-14a "${testcvs} -q update -p" "initial contents"
 6292       dotest rmadd2-14b "${testcvs} -q update -p -r 1.5" "initial contents"
 6293       dotest rmadd2-14c "${testcvs} -q update -p -r 1.3" "initial contents"
 6294 
 6295       dotest rmadd2-15 "${testcvs} -q ci -m re-remove" \
 6296 "Removing file1;
 6297 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6298 new revision: delete; previous revision: 1\.5
 6299 done"
 6300       dotest rmadd2-16 "${testcvs} log -h file1" "
 6301 RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
 6302 Working file: file1
 6303 head: 1\.6
 6304 branch:
 6305 locks: strict
 6306 access list:
 6307 symbolic names:
 6308     tagone: 1\.1
 6309 keyword substitution: kv
 6310 total revisions: 6
 6311 ============================================================================="
 6312       dotest rmadd2-17 "${testcvs} status -v file1" \
 6313 "===================================================================
 6314 File: no file file1     Status: Up-to-date
 6315 
 6316    Working revision:    No entry for file1
 6317    Repository revision: 1\.6    ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
 6318 
 6319    Existing Tags:
 6320     tagone                      (revision: 1.1)"
 6321 
 6322       cd ../..
 6323 
 6324       rm -r 1
 6325       rm -rf ${CVSROOT_DIRNAME}/first-dir
 6326       ;;
 6327 
 6328     rmadd3)
 6329           # This test demonstrates that CVS notices that file1 exists rather
 6330       # that deleting or writing over it after:
 6331       #
 6332       #   cvs remove -f file1; touch file1; cvs add file1.
 6333       #
 6334           # According to the manual, this should work for:
 6335       #
 6336       #   rm file1; cvs remove file1; cvs add file1
 6337       #
 6338       # but in past version of CVS, new content in file1 would be
 6339       # erroneously deleted when file1 reappeared between the remove and
 6340       # the add.
 6341       #
 6342       # Later versions of CVS would refuse to perform the add, but still
 6343       # allow a subsequent local commit to erase the file from the
 6344       # workspace, possibly losing data.
 6345       mkdir 1; cd 1
 6346       dotest rmadd3-init1 "${testcvs} -q co -l ." ''
 6347       mkdir first-dir
 6348       dotest rmadd3-init2 "${testcvs} add first-dir" \
 6349 "Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
 6350       cd first-dir
 6351 
 6352       echo initial content for file1 >file1
 6353       dotest rmadd3-init3 "${testcvs} add file1" \
 6354 "${PROG} add: scheduling file \`file1' for addition
 6355 ${PROG} add: use '${PROG} commit' to add this file permanently"
 6356       dotest rmadd3-init4 "${testcvs} -q ci -m add" \
 6357 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
 6358 done
 6359 Checking in file1;
 6360 ${CVSROOT_DIRNAME}/first-dir/file1,v  <--  file1
 6361 initial revision: 1\.1
 6362 done"
 6363 
 6364       # Here begins the guts of this test, as detailed above.
 6365       dotest rmadd3-1 "${testcvs} rm -f file1" \
 6366 "${PROG} remove: scheduling \`file1' for removal
 6367 ${PROG} remove: use '${PROG} commit' to remove this file permanently"
 6368 
 6369           # Now recreate the file:
 6370       echo desired future contents for file1 >file1
 6371 
 6372       # And attempt to resurrect it at the same time:
 6373       dotest_fail rmadd3-2 "${testcvs} add file1" \
 6374 "${PROG} add: file1 should be removed and is still there (or is back again)"
 6375 
 6376       # Now prove that commit knows that it shouldn't erase files.
 6377       dotest_fail rmadd3-3 "${testcvs} -q ci -m." \
 6378 "$PROG commit: \`file1' should be removed and is still there (or is back again)
 6379 $PROG \[commit aborted\]: correct above errors first!"
 6380 
 6381       # Then these should pass too:
 6382       dotest rmadd3-4 "test -f file1"
 6383       dotest rmadd3-5 "cat file1" "desired future contents for file1"
 6384 
 6385       if $keep; then
 6386         echo Keeping ${TESTDIR} and exiting due to --keep
 6387         exit 0
 6388       fi
 6389 
 6390       cd ../..
 6391       rm -r 1
 6392       rm -rf ${CVSROOT_DIRNAME}/first-dir
 6393       ;;
 6394 
 6395     resurrection)
 6396       # This test tests a few file resurrection scenarios.
 6397       mkdir 1; cd 1
 6398       dotest resurrection-init1 "$testcvs -q co -l ." ''
 6399       mkdir first-dir
 6400       dotest resurrection-init2 "$testcvs add first-dir" \
 6401 "Directory $CVSROOT_DIRNAME/first-dir added to the repository"
 6402       cd first-dir
 6403 
 6404       echo initial content for file1 >file1
 6405       dotest resurrection-init3 "$testcvs add file1" \
 6406 "$PROG add: scheduling file \`file1' for addition
 6407 $PROG add: use '$PROG commit' to add this file permanently"
 6408       dotest resurrection-init4 "$testcvs -q ci -m add" \
 6409 "RCS file: $CVSROOT_DIRNAME/first-dir/file1,v
 6410 done
 6411 Checking in file1;
 6412 $CVSROOT_DIRNAME/first-dir/file1,v  <--  file1
 6413 initial revision: 1\.1
 6414 done"
 6415 
 6416       dotest resurrection-init5 "$testcvs -Q rm -f file1"
 6417 
 6418       # The first test is that `cvs add' will resurrect a file before its
 6419       # removal has been committed.
 6420       dotest_sort resurrection-1 "$testcvs add file1" \
 6421 "U file1
 6422 $PROG add: file1, version 1\.1, resurrected"
 6423       dotest resurrection-2 "$testcvs -Q diff file1" ""
 6424 
 6425       dotest resurrection-init6 "$testcvs -Q tag -b resurrection"
 6426       dotest resurrection-init7 "$testcvs -Q rm -f file1"
 6427       dotest resurrection-init8 "$testcvs -Q ci -mrm" \
 6428 "Removing file1;
 6429 $CVSROOT_DIRNAME/first-dir/file1,v  <--  file1
 6430 new revision: delete; previous revision: 1\.1
 6431 done"
 6432 
 6433       # The next test is that CVS will resurrect a committed removal.
 6434       dotest_sort resurrection-3 "$testcvs add file1" \
 6435 "U file1
 6436 $PROG add: Re-adding file \`file1' (in place of dead revision 1\.2)\.
 6437 $PROG add: Resurrecting file \`file1' from revision 1\.1\.
 6438 $PROG add: use 'cvs commit' to add this file permanently"
 6439       dotest resurrection-4 "$testcvs -q diff -r1.1 file1" ""
 6440       dotest resurrection-5 "$testcvs -q ci -mreadd" \
 6441 "Checking in file1;
 6442 $CVSROOT_DIRNAME/first-dir/file1,v  <--  file1
 6443 new revision: 1\.3; previous revision: 1\.2
 6444 done"
 6445 
 6446       dotest resurrection-init9 "$testcvs -Q up -rresurrection"
 6447       dotest resurrection-init10 "$testcvs -Q rm -f file1"
 6448       dotest resurrection-init11 "$testcvs -Q ci -mrm-on-resurrection" \
 6449 "Removing file1;
 6450 $CVSROOT_DIRNAME/first-dir/file1,v  <--  file1
 6451 new revision: delete; previous revision: 1\.1
 6452 done"
 6453 
 6454       # The next test is that CVS will resurrect a committed removal to a
 6455       # branch.
 6456       dotest_sort resurrection-6 "$testcvs add file1" \
 6457 "U file1
 6458 $PROG add: Resurrecting file \`file1' from revision 1\.1\.
 6459 $PROG add: file \`file1' will be added on branch \`resurrection' from version 1\.1\.2\.1
 6460 $PROG add: use 'cvs commit' to add this file permanently"
 6461       dotest resurrection-7 "$testcvs -Q diff -r1.1 file1" ""
 6462       dotest resurrection-8 "$testcvs -q ci -mreadd" \
 6463 "Checking in file1;
 6464 $CVSROOT_DIRNAME/first-dir/file1,v  <--  file1
 6465 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
 6466 done"
 6467 
 6468       # The next few tests verify that an attempted resurrection of a file
 6469       # with no previous revision on the trunk fails.
 6470       touch file2
 6471       dotest resurrection-9 "$testcvs -Q add file2"
 6472       dotest resurrection-10 "$testcvs -Q ci -mnew-file2" \
 6473 "RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file2,v
 6474 done
 6475 Checking in file2;
 6476 $CVSROOT_DIRNAME/first-dir/Attic/file2,v  <--  file2
 6477 new revision: 1\.1\.2\.1; previous revision: 1\.1
 6478 done"
 6479       dotest resurrection-11 "$testcvs -Q up -A"
 6480 
 6481       # This command once caused an assertion failure.
 6482       dotest resurrection-12 "$testcvs add file2" \
 6483 "$PROG add: File \`file2' has no previous revision to resurrect\."
 6484 
 6485       if $keep; then
 6486         echo Keeping $TESTDIR and exiting due to --keep
 6487         exit 0
 6488       fi
 6489 
 6490       cd ../..
 6491       rm -r 1
 6492       rm -rf $CVSROOT_DIRNAME/first-dir
 6493       ;;
 6494 
 6495     dirs)
 6496       # Tests related to removing and adding directories.
 6497       # See also:
 6498       #   conflicts (especially dir1 in conflicts-130): What happens if
 6499       #     directory exists in repository and a non-CVS-controlled
 6500       #     directory in the working directory?
 6501       #   conflicts3-15.  More cases, especially where CVS directory
 6502       #     exists but without CVS/Repository and friends.
 6503       #   conflicts3-22.  Similar to conflicts-130 but there is a file
 6504       #     in the directory.
 6505       #   dirs2.  Sort of similar to conflicts3-22 but somewhat different.
 6506       mkdir imp-dir; cd imp-dir
 6507       echo file1 >file1
 6508       mkdir sdir
 6509       echo sfile >sdir/sfile
 6510       dotest_sort dirs-1 \
 6511 "${testcvs} import -m import-it dir1 vend rel" "
 6512 
 6513 N dir1/file1
 6514 N dir1/sdir/sfile
 6515 No conflicts created by this import
 6516 ${PROG} import: Importing ${CVSROOT_DIRNAME}/dir1/sdir"
 6517       cd ..
 6518 
 6519       mkdir 1; cd 1
 6520       dotest dirs-2 "${testcvs} -Q co dir1" ""
 6521 
 6522       # Various CVS administrators are in the habit of removing
 6523       # the repository directory for things they don't want any
 6524       # more.  I've even been known to do it myself (on rare
 6525       # occasions).  Not the usual recommended practice, but we want
 6526       # to try to come up with some kind of reasonable/documented/sensible
 6527       # behavior.
 6528       rm -rf ${CVSROOT_DIRNAME}/dir1/sdir
 6529 
 6530       dotest dirs-3 "${testcvs} update" \
 6531 "${PROG} update: Updating dir1
 6532 ${PROG} update: Updating dir1/sdir
 6533 ${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
 6534 ${PROG} update: skipping directory dir1/sdir"
 6535       dotest dirs-3a "${testcvs} update -d" \
 6536 "${PROG} update*: Updating dir1
 6537 ${PROG} update: Updating dir1/sdir
 6538 ${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
 6539 ${PROG} update: skipping directory dir1/sdir"
 6540 
 6541       # If we say "yes", then CVS gives errors about not being able to
 6542       # create lock files.
 6543       # The fact that it says "skipping directory " rather than