diff options
author | peter <peter@FreeBSD.org> | 1998-03-10 13:40:57 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1998-03-10 13:40:57 +0000 |
commit | a194b78bd292dd13f17cfe65c12fb5dee1bb9392 (patch) | |
tree | 83716acb7a6188c846ca3328958e0a93b9701795 /contrib/cvs | |
parent | 39cd03a57045ca27b0e7323a52f287f7696fa947 (diff) | |
parent | 0c111e2b51cac7eead56494b30c5977e4ec9a8ea (diff) | |
download | FreeBSD-src-a194b78bd292dd13f17cfe65c12fb5dee1bb9392.zip FreeBSD-src-a194b78bd292dd13f17cfe65c12fb5dee1bb9392.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r34461,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/cvs')
47 files changed, 4003 insertions, 1853 deletions
diff --git a/contrib/cvs/ChangeLog b/contrib/cvs/ChangeLog index 6ff5bd1..82ea5ac 100644 --- a/contrib/cvs/ChangeLog +++ b/contrib/cvs/ChangeLog @@ -1,3 +1,29 @@ +1998-03-04 Jim Kingdon <kingdon@harvey.cyclic.com> + + * acconfig.h, configure.in: Add PRESERVE_PERMISSIONS_SUPPORT and + always define it. + * configure, config.h.in: Regenerated. + +Tue Feb 17 18:32:36 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Add memmove back to AC_REPLACE_FUNCS list. + * configure: Rebuild. + +1998-02-16 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TODO (190): Remove "failed to check out" from commit.c from + lists of error messages suppressed by -q; it no longer is. + +4 Feb 1998 Jim Kingdon + + * cvsnt.mak: The usual "because Visual C++ feels like it" + changes. These ones seem to have to do with reordering + files and release versus debug configurations, mainly. + +Fri Jan 30 10:37:40 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + * INSTALL: Update which version of CVS was tested with EMX. + 15 Jan 1998 W. L. Estes <wlestes@hamlet.uncg.edu> and Jim Kingdon <kingdon@harvey.cyclic.com> diff --git a/contrib/cvs/INSTALL b/contrib/cvs/INSTALL index c13948c..576f9a6 100644 --- a/contrib/cvs/INSTALL +++ b/contrib/cvs/INSTALL @@ -143,7 +143,7 @@ i386 family: Windows 95 (1.9 client and local) QNX (1.9.1 + patches for strippath() and va_list) OS/2 Version 3 using IBM C/C++ Tools 2.01 (1.8.86 + patches, client) - OS/2 Version 3 using EMX 0.9c (1.9.10 + patches, client) + OS/2 Version 3 using EMX 0.9c (1.9.22, client) OS/2 Version 3 using Watcom version ? (? - has this been tested?) m68k: Sun 3 running SunOS 4.1.1_U1 w/ bundled K&R /usr/5bin/cc (1.8.86+) diff --git a/contrib/cvs/TODO b/contrib/cvs/TODO index cddd580..cc40ab2 100644 --- a/contrib/cvs/TODO +++ b/contrib/cvs/TODO @@ -642,9 +642,6 @@ of -q; I don't know whether anyone has done a similar investigation of Rationale might be that we already printed another message elsewhere but why would it be necessary to avoid the extra message in such an uncommon case?) - commit.c: failed to check out `%s' (likewise; this one seems to be a - vestige from before RCS_checkout was internal. Take a look at how - RCS_checkout handles errors) commit.c: failed to commit dead revision for `%s' (likewise) remove.c: file `%s' still in working directory (see below about rm -f analogy) diff --git a/contrib/cvs/acconfig.h b/contrib/cvs/acconfig.h index 21c5fe7..8ccbf8f 100644 --- a/contrib/cvs/acconfig.h +++ b/contrib/cvs/acconfig.h @@ -20,6 +20,9 @@ /* Define if you have the connect function. */ #undef HAVE_CONNECT +/* Define if this system supports chown(), link(), and friends. */ +#undef PRESERVE_PERMISSIONS_SUPPORT + /* Define if you have memchr (always for CVS). */ #undef HAVE_MEMCHR diff --git a/contrib/cvs/config.h.in b/contrib/cvs/config.h.in index a492190..af42df6 100644 --- a/contrib/cvs/config.h.in +++ b/contrib/cvs/config.h.in @@ -90,6 +90,9 @@ /* Define if you have the connect function. */ #undef HAVE_CONNECT +/* Define if this system supports chown(), link(), and friends. */ +#undef PRESERVE_PERMISSIONS_SUPPORT + /* Define if you have memchr (always for CVS). */ #undef HAVE_MEMCHR diff --git a/contrib/cvs/configure b/contrib/cvs/configure index f79a25d..01c0ace 100755 --- a/contrib/cvs/configure +++ b/contrib/cvs/configure @@ -1782,7 +1782,7 @@ EOF fi -for ac_func in mkdir rename strstr dup2 strerror valloc waitpid vasprintf strtoul +for ac_func in mkdir rename strstr dup2 strerror valloc waitpid memmove vasprintf strtoul do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then @@ -3254,12 +3254,17 @@ EOF fi fi # enable_server +cat >> confdefs.h <<\EOF +#define PRESERVE_PERMISSIONS_SUPPORT 1 +EOF + + echo $ac_n "checking for cygwin32""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ccvs_cv_sys_cygwin32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 3263 "configure" +#line 3268 "configure" #include "confdefs.h" int main() { return 0; } @@ -3267,7 +3272,7 @@ int t() { return __CYGWIN32__; ; return 0; } EOF -if { (eval echo configure:3271: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ccvs_cv_sys_cygwin32=yes else diff --git a/contrib/cvs/configure.in b/contrib/cvs/configure.in index 292958d..b848ab6 100644 --- a/contrib/cvs/configure.in +++ b/contrib/cvs/configure.in @@ -63,7 +63,7 @@ AC_TYPE_MODE_T AC_TYPE_SIZE_T AC_TYPE_PID_T AC_STRUCT_ST_BLKSIZE -AC_REPLACE_FUNCS(mkdir rename strstr dup2 strerror valloc waitpid vasprintf strtoul) +AC_REPLACE_FUNCS(mkdir rename strstr dup2 strerror valloc waitpid memmove vasprintf strtoul) AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3) dnl @@ -340,6 +340,12 @@ if test "$ac_cv_func_crypt" = yes; then fi fi # enable_server +dnl For the moment we will assume that all systems which have +dnl the unixyness to run configure are unixy enough to do the +dnl PreservePermissions stuff. I have this sinking feeling that +dnl things won't be that simple, before long. +AC_DEFINE(PRESERVE_PERMISSIONS_SUPPORT) + dnl On cygwin32, we configure like a Unix system, but we use the dnl Windows support code in lib/fncase.c to handle the case dnl insensitive file system. We also need some support libraries. We diff --git a/contrib/cvs/contrib/ChangeLog b/contrib/cvs/contrib/ChangeLog index 3db22a5..e0d87e1 100644 --- a/contrib/cvs/contrib/ChangeLog +++ b/contrib/cvs/contrib/ChangeLog @@ -1,3 +1,7 @@ +Sat Feb 21 21:59:45 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (clean): Change "/bin/rm" to "rm". + Thu Aug 7 22:42:23 1997 Jim Kingdon <kingdon@harvey.cyclic.com> * pvcs_to_rcs: Remove RCS keywords. Remove $Log and move the data diff --git a/contrib/cvs/contrib/Makefile.in b/contrib/cvs/contrib/Makefile.in index 2a6e9a2..9997bd8 100644 --- a/contrib/cvs/contrib/Makefile.in +++ b/contrib/cvs/contrib/Makefile.in @@ -106,7 +106,7 @@ ls: .PHONY: ls clean: - /bin/rm -f *.o core + rm -f *.o core .PHONY: clean distclean: clean diff --git a/contrib/cvs/doc/ChangeLog b/contrib/cvs/doc/ChangeLog index 3fd4433..9a01d1b 100644 --- a/contrib/cvs/doc/ChangeLog +++ b/contrib/cvs/doc/ChangeLog @@ -1,3 +1,45 @@ +1998-03-04 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Special Files): Add notes about client/server CVS + and hard links across directories. + +1998-03-01 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Keeping a checked out copy): The magic loginfo + incantation isn't too likely to work except on unix. + +1998-02-23 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (user-defined logging): Double "@" literal. + +1998-02-18 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (user-defined logging): Add taginfo example. + +1998-02-04 Tim Pierce <twp@skepsis.com> + + * cvs.texinfo (config): PreservePermissions variable. + (Special Files): New. + (Editing files): Add note about PreservePermissions. + +Tue Feb 10 18:07:35 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Connection): New node. + + * cvsclient.texi (Protocol): Fix typo (lots -> lost). + +Sun Feb 8 21:39:22 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Invoking CVS): For admin -b, point to the section + where we talk about reverting to vendor branch. + + * cvs.texinfo (Invoking CVS, rdiff options): Document rdiff -V + option as obsolete, since it was made a fatal error some time ago. + + * cvs.texinfo (Invoking CVS): Add global options, keywords, and + keyword substitution modes. Wording fix in reference to --help + and Index. + Wed Jan 28 23:09:39 1998 Jim Kingdon <kingdon@harvey.cyclic.com> * cvs.texinfo (Excluding directories): Add index entry for "!". diff --git a/contrib/cvs/doc/cvs.texinfo b/contrib/cvs/doc/cvs.texinfo index e50a793..5558538 100644 --- a/contrib/cvs/doc/cvs.texinfo +++ b/contrib/cvs/doc/cvs.texinfo @@ -152,6 +152,7 @@ CVS and the Real World. * Keyword substitution:: CVS can include the revision inside the file * Tracking sources:: Tracking third-party sources * Builds:: Issues related to CVS and builds +* Special Files:: Devices, links and other non-regular files References. ----------- @@ -724,7 +725,7 @@ they should be in separate locations. @c /home/joe/sources. But this node is too long @c as it is; need a little reorganization... -@cindex :local: +@cindex :local:, setting up @sc{Cvs} can access a repository by a variety of means. It might be on the local computer, or it might be on a computer across the room or across the world. @@ -2058,8 +2059,8 @@ for example @file{/usr/local/bin/cvs-1.6}. There is no need to edit @code{inetd.conf} or start a @sc{cvs} server daemon. -@cindex :server: -@cindex :ext: +@cindex :server:, setting up +@cindex :ext:, setting up There are two access methods that you use in CVSROOT for rsh. @code{:server:} specifies an internal rsh client, which is supported only by some CVS ports. @@ -2284,7 +2285,7 @@ passwd} command. @cindex Login (subcommand) @cindex password client, using @cindex authenticated client, using -@cindex :pserver: +@cindex :pserver:, setting up Before connecting to the server, the client must @dfn{log in} with the command @code{cvs login}. Logging in verifies a password with the server, and also records @@ -2417,7 +2418,7 @@ security, get Kerberos. @cindex GSSAPI @cindex security, GSSAPI -@cindex :gserver: +@cindex :gserver:, setting up GSSAPI is a generic interface to network security systems such as Kerberos 5. If you have a working GSSAPI library, you can have @@ -2470,7 +2471,7 @@ cvs -d :gserver:chainsaw.yard.com:/usr/local/cvsroot checkout foo @cindex kerberos @cindex security, kerberos -@cindex :kserver: +@cindex :kserver:, setting up The easiest way to use kerberos is to use the kerberos @code{rsh}, as described in @ref{Connecting via rsh}. The main disadvantage of using rsh is that all the data @@ -4731,6 +4732,21 @@ pairs of @var{filename} @var{revision}. A non-zero exit of the filter program will cause the tag to be aborted. +Here is an example of using taginfo to log tag and rtag +commands. In the taginfo file put: + +@example +ALL /usr/local/cvsroot/CVSROOT/loggit +@end example + +Where @file{/usr/local/cvsroot/CVSROOT/loggit} contains the +following script: + +@example +#!/bin/sh +echo "$@@" >>/home/kingdon/cvsroot/CVSROOT/taglog +@end example + @node annotate @section Annotate command @cindex annotate (subcommand) @@ -5841,6 +5857,14 @@ receive notifications, she should specify @code{-a none}. The @var{files} and options are processed as for the @code{cvs watch} commands. +@strong{Caution:} If the @var{PreservePermissions} +option is enabled in the repository (@pxref{config}), +CVS will not change the permissions on any of the +@var{files}. The reason for this change is to ensure +that using @samp{cvs edit} does not interfere with the +ability to store file permissions in the CVS +repository. + @end deffn Normally when you are done with a set of changes, you @@ -6740,6 +6764,67 @@ is Odin (see @c can work with CVS. @c --------------------------------------------------------------------- +@node Special Files +@chapter Special Files + +In normal circumstances, CVS works only with regular +files. Every file in a project is assumed to be +persistent; it must be possible to open, read and close +them; and so on. CVS also ignores file permissions and +ownerships, leaving such issues to be resolved by the +developer at installation time. In other words, it is +not possible to "check in" a device into a repository; +if the device file cannot be opened, CVS will refuse to +handle it. Files also lose their ownerships and +permissions during repository transactions. + +If the configuration variable @var{PreservePermissions} +(@pxref{config}) is set in the repository, CVS will +preserve file permissions and ownership across +repository transactions, and will permit checkin and +checkout of special files and symbolic links. + +Using this option affects the behavior of CVS in +several ways. First, some of the new operations +supported by CVS are not accessible to all users. In +particular, file ownership and special file +characteristics may only be changed by the superuser. +When the @var{PreservePermissions} configuration +variable is set, therefore, users will have to be +`root' in order to perform CVS operations. + +A more subtle difference is that CVS considers a file +to have changed only if its contents have changed +(specifically, if the modification time of the working +file does not match that of the repository's file). +Therefore, if only the permissions or ownership have +changed, or if a device's major or minor numbers have +changed, CVS will not notice. In order to commit such +a change to the repository, you must force the commit +with @samp{cvs commit -f}. This also means that if a +file's permissions have changed and the repository file +is newer than the working copy, performing @samp{cvs +update} will silently change the permissions on the +working copy. + +It is worth noting that only regular files may +be merged, for reasons that hopefully are obvious. If +@samp{cvs update} or @samp{cvs checkout -j} attempts to +merge a symbolic link with a regular file, or two +device files for different kinds of devices, CVS will +report a conflict and refuse to perform the merge. At +the same time, @samp{cvs diff} will not report any +differences between these files, since no meaningful +textual comparisons can be made on files which contain +no text. + +The PreservePermissions features do not work with +client/server @sc{cvs}. Another limitation is that +hard links must be to other files within the same +directory; hard links across directories are not +supported. + +@c --------------------------------------------------------------------- @node CVS commands @appendix Guide to CVS commands @@ -9117,7 +9202,9 @@ you should probably not use @samp{-u}. @item -V @var{vn} Expand keywords according to the rules current in @sc{rcs} version @var{vn} (the expansion format changed with -@sc{rcs} version 5). +@sc{rcs} version 5). Note that this option is no +longer accepted. CVS will always expand keywords the +way that @sc{rcs} version 5 does. @end table @c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -9741,9 +9828,121 @@ description of the @samp{-I} option, and This appendix describes how to invoke @sc{cvs}, with references to where each command or feature is -described in detail. Other relevant references are the -@samp{--help}/@samp{-H} option to @sc{cvs} -(@pxref{Global options}) and @ref{Index}. +described in detail. For other references run the +@code{cvs --help} command, or see @ref{Index}. + +A @sc{cvs} command looks like: + +@example +cvs [ @var{global_options} ] @var{command} [ @var{command_options} ] [ @var{command_args} ] +@end example + +Global options: + +@table @code +@item --allow-root=@var{rootdir} +Specify legal @sc{cvsroot} directory (server only) (not +in @sc{cvs} 1.9 and older). See @ref{Password +authentication server}. + +@item -a +Authenticate all communication (client only) (not in @sc{cvs} +1.9 and older). See @ref{Global options}. + +@item -b +Specify RCS location (@sc{cvs} 1.9 and older). See +@ref{Global options}. + +@item -d @var{root} +Specify the @sc{cvsroot}. See @ref{Repository}. + +@item -e @var{editor} +Edit messages with @var{editor}. See @ref{Committing +your changes}. + +@item -f +Do not read the @file{~/.cvsrc} file. See @ref{Global +options}. + +@item -H +@itemx --help +Print a help message. See @ref{Global options}. + +@item -l +Do not log in CVSROOT/history file. See @ref{Global +options}. + +@item -n +Do not change any files. See @ref{Global options}. + +@item -Q +Cause the command to be really quiet. See @ref{Global options}. + +@item -q +Cause the command to be somewhat quiet. See @ref{Global options}. + +@item -r +Make new working files files read-only. See @ref{Global options}. + +@item -s @var{variable}=@var{value} +Set a user variable. See @ref{Variables}. + +@item -T @var{tempdir} +Put temporary files in @var{tempdir}. See @ref{Global +options}. + +@item -t +Trace @sc{cvs} execution. See @ref{Global options}. + +@item -v +@item --version +Display version and copyright information for @sc{cvs}. + +@item -w +Make new working files read-write. See @ref{Global +options}. + +@item -x +Encrypt all communication (client only). See +@ref{Global options}. + +@item -z @var{gzip-level} +Set the compression level (client only). +@c FIXME: what are the valid values for gzip-level. +@c And shouldn't this be documented in at least a +@c little bit of detail somewhere? + +@end table + +Keyword expansion modes (@pxref{Substitution modes}): + +@example +-kkv $@asis{}Id: file1,v 1.1 1993/12/09 03:21:13 joe Exp $ +-kkvl $@asis{}Id: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ +-kk $@asis{}Id$ +-kv file1,v 1.1 1993/12/09 03:21:13 joe Exp +-ko @i{no expansion} +-kb @i{no expansion, file is binary} +@end example + +Keywords (@pxref{Keyword list}): + +@example +$@asis{}Author: joe $ +$@asis{}Date: 1993/12/09 03:21:13 $ +$@asis{}Header: /home/files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ +$@asis{}Id: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ +$@asis{}Locker: harry $ +$@asis{}Name: snapshot_1_14 $ +$@asis{}RCSfile: file1,v $ +$@asis{}Revision: 1.1 $ +$@asis{}Source: /home/files/file1,v $ +$@asis{}State: Exp $ +$@asis{}Log: file1,v $ +Revision 1.1 1993/12/09 03:30:17 joe +Initial revision + +@end example @c The idea behind this table is that we want each item @c to be a sentence or two at most. Preferably a @@ -9752,6 +9951,8 @@ described in detail. Other relevant references are the @c In some cases refs to "foo options" are just to get @c this thing written quickly, not because the "foo @c options" node is really the best place to point. +Commands, command options, and command arguments: + @table @code @item add [@var{options}] [@var{files}@dots{}] Add a new file/directory. See @ref{Adding files}. @@ -9773,9 +9974,7 @@ Administration of history files in the repository. See @table @code @item -b[@var{rev}] -Set default branch. -@c FIXME: Should xref to a section which describes how -@c to use this with the vendor branch. +Set default branch. See @ref{Reverting local changes}. @item -c@var{string} Set comment leader. @@ -10209,7 +10408,7 @@ Top two diffs - last change made to the file. See Unidiff output format. See @ref{rdiff options}. @item -V @var{vers} -Use RCS Version @var{vers} for keyword expansion. See +Use RCS Version @var{vers} for keyword expansion (obsolete). See @ref{rdiff options}. @end table @@ -11493,7 +11692,7 @@ must be run in the background. @c out locks (I think) but I don't see many advantages @c of that and we might as well document something which @c works for multiple files. -Here is an example (this should all be on one line): +Here is an example for unix (this should all be on one line): @example ^cyclic-pages (date; cat; (sleep 2; cd /u/www/local-docs; @@ -11811,6 +12010,14 @@ for users in the system's user database if not found in pserver users must exist in @file{CVSROOT/passwd}. The default is @samp{yes}. For more on pserver, see @ref{Password authenticated}. + +@cindex PreservePermissions, in CVSROOT/config +@item PreservePermissions=@var{value} +Enable support for saving special device files, +symbolic links, file permissions and ownerships in the +repository. The default value is @samp{no}. +@xref{Special Files} for the full implications of using +this keyword. @end table @c --------------------------------------------------------------------- @@ -12060,6 +12267,7 @@ mentioned there. @menu * Error messages:: Partial list of CVS errors +* Connection:: Trouble making a connection to a CVS server * Other problems:: Problems not readily listed by error message @end menu @@ -12394,12 +12602,75 @@ exit 0 @c potentially confusing for the new user. @end table +@node Connection +@appendixsec Trouble making a connection to a CVS server + +This section concerns what to do if you are having +trouble making a connection to a @sc{cvs} server. If +you are running the @sc{cvs} command line client +running on Windows, first upgrade the client to +@sc{cvs} 1.9.12 or later. The error reporting in +earlier versions provided much less information about +what the problem was. If the client is non-Windows, +@sc{cvs} 1.9 should be fine. + +If the error messages are not sufficient to track down +the problem, the next steps depend largely on which +access method you are using. + +@table @code +@cindex :ext:, troubleshooting +@item :ext: +Try running the rsh program from the command line. For +example: "rsh servername cvs -v" should print @sc{cvs} +version information. If this doesn't work, you need to +fix it before you can worry about @sc{cvs} problems. + +@cindex :server:, troubleshooting +@item :server: +You don't need a command line rsh program to use this +access method, but if you have an rsh program around, +it may be useful as a debugging tool. Follow the +directions given for :ext:. + +@cindex :pserver:, troubleshooting +@item :pserver: +One good debugging tool is to "telnet servername +2401". After connecting, send any text (for example +"foo" followed by return). If @sc{cvs} is working +correctly, it will respond with + +@example +cvs [pserver aborted]: bad auth protocol start: foo +@end example + +If this fails to work, then make sure inetd is working +right. Change the invocation in inetd.conf to run the +echo program instead of cvs. For example: + +@example +2401 stream tcp nowait root /bin/echo echo hello +@end example + +After making that change and instructing inetd to +re-read its configuration file, "telnet servername +2401" should show you the text hello and then the +server should close the connection. If this doesn't +work, you need to fix it before you can worry about +@sc{cvs} problems. + +On AIX systems, the system will often have its own +program trying to use port 2401. This is AIX's problem +in the sense that port 2401 is registered for use with +@sc{cvs}. I hear that there is an AIX patch available +to address this problem. +@end table + @node Other problems @appendixsec Other common problems -Here is a list of problems which cannot be readily -looked up based on an error message. They are in no -particular order. +Here is a list of problems which do not fit into the +above categories. They are in no particular order. @itemize @bullet @item diff --git a/contrib/cvs/doc/cvsclient.texi b/contrib/cvs/doc/cvsclient.texi index 35fe39b..56577c2 100644 --- a/contrib/cvs/doc/cvsclient.texi +++ b/contrib/cvs/doc/cvsclient.texi @@ -309,7 +309,7 @@ out what the other supports before exchanging large amounts of data (such as file contents). @c Hmm, having 3 sections in this menu makes a certain amount of sense -@c but that structure gets lots in the printed manual (not sure about +@c but that structure gets lost in the printed manual (not sure about @c HTML). Perhaps there is a better way. @menu diff --git a/contrib/cvs/lib/ChangeLog b/contrib/cvs/lib/ChangeLog index 3d858ab..623c292 100644 --- a/contrib/cvs/lib/ChangeLog +++ b/contrib/cvs/lib/ChangeLog @@ -1,3 +1,25 @@ +1998-02-20 Jim Kingdon <kingdon@harvey.cyclic.com> + + * regex.c: Partial merge with version from emacs 20.2. Brings + over some trivial changes (whitespace and so on) (most such + changes I didn't bother with, for this time). Don't cast to int + before comparing old_regend[r] to regstart[r] (this is the point + of bothering; the old code was broken for 64 bit machines. + Reported by Paul Vixie). + +Tue Feb 17 18:33:26 1998 Ian Lance Taylor <ian@cygnus.com> + + * memmove.c: New file, resurrecting the old one. + * Makefile.in (SOURCES): Add memmove.c. + +1998-02-03 Tim Pierce <twp@skepsis.com> + + * system.h (CVS_LSTAT): New macro. + +Sat Feb 7 17:33:39 1998 Ian Lance Taylor <ian@cygnus.com> + + * getline.h (getstr): Declare. + 13 Jan 1998 Jim Kingdon * fncase.c: Include config.h before system.h. diff --git a/contrib/cvs/lib/Makefile.in b/contrib/cvs/lib/Makefile.in index 9c32d9f..92122c7 100644 --- a/contrib/cvs/lib/Makefile.in +++ b/contrib/cvs/lib/Makefile.in @@ -35,6 +35,7 @@ SOURCES = \ getopt1.c \ hostname.c \ md5.c \ + memmove.c \ mkdir.c \ regex.c \ rename.c \ diff --git a/contrib/cvs/lib/getline.h b/contrib/cvs/lib/getline.h index 30bcc25..d061b7c 100644 --- a/contrib/cvs/lib/getline.h +++ b/contrib/cvs/lib/getline.h @@ -11,5 +11,8 @@ int getline __PROTO ((char **_lineptr, size_t *_n, FILE *_stream)); +int + getstr __PROTO ((char **_lineptr, size_t *_n, FILE *_stream, + char _terminator, int _offset)); #endif /* _getline_h_ */ diff --git a/contrib/cvs/lib/regex.c b/contrib/cvs/lib/regex.c index ddeca2a..38b31f4 100644 --- a/contrib/cvs/lib/regex.c +++ b/contrib/cvs/lib/regex.c @@ -1,6 +1,5 @@ -/* Extended regular expression matching and search library, - version 0.12. - (Implements POSIX draft P10003.2/D11.2, except for +/* Extended regular expression matching and search library, version + 0.12. (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. @@ -39,10 +38,16 @@ #include "lisp.h" #include "buffer.h" + +/* Make syntax table lookup grant data in gl_state. */ +#define SYNTAX_ENTRY_VIA_PROPERTY + #include "syntax.h" +#include "charset.h" +#include "category.h" -/* Emacs uses `NULL' as a predicate. */ -#undef NULL +#define malloc xmalloc +#define free xfree #else /* not emacs */ @@ -160,7 +165,7 @@ init_syntax_once () /* We remove any previous definition of `SIGN_EXTEND_CHAR', since ours (we hope) works properly with all combinations of machines, compilers, `char' and `unsigned char' argument types. - (Per Bothner suggested the basic approach.) */ + (Per Bothner suggested the basic approach.) */ #undef SIGN_EXTEND_CHAR #if __STDC__ #define SIGN_EXTEND_CHAR(c) ((signed char) (c)) @@ -3807,15 +3812,15 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; /* Restore this and inner groups' (if any) registers. */ - for (r = *p; r < *p + *(p + 1); r++) - { - regstart[r] = old_regstart[r]; - - /* xx why this test? */ - if ((int) old_regend[r] >= (int) regstart[r]) - regend[r] = old_regend[r]; - } - } + for (r = *p; r < *p + *(p + 1); r++) + { + regstart[r] = old_regstart[r]; + + /* xx why this test? */ + if (old_regend[r] >= regstart[r]) + regend[r] = old_regend[r]; + } + } p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); PUSH_FAILURE_POINT (p1 + mcnt, d, -2); diff --git a/contrib/cvs/lib/system.h b/contrib/cvs/lib/system.h index 7648b76..8beedf0 100644 --- a/contrib/cvs/lib/system.h +++ b/contrib/cvs/lib/system.h @@ -453,6 +453,13 @@ extern int errno; #define CVS_STAT stat #endif +/* Open question: should CVS_STAT be lstat by default? We need + to use lstat in order to handle symbolic links correctly with + the PreservePermissions option. -twp */ +#ifndef CVS_LSTAT +#define CVS_LSTAT lstat +#endif + #ifndef CVS_UNLINK #define CVS_UNLINK unlink #endif diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog index de2f535..96e1701 100644 --- a/contrib/cvs/src/ChangeLog +++ b/contrib/cvs/src/ChangeLog @@ -1,5 +1,490 @@ +1998-03-04 Jim Kingdon <kingdon@harvey.cyclic.com> + + * entries.c, cvs.h (Entries_Open): New argument update_dir; use it + in error message. + * add.c, checkout.c, client.c, find_names.c, import.c, recurse.c, + update.c: Pass it (as NULL except in call_in_directory). + * entries.c (Subdirs_Known): Just return if there is no CVSADM + directory (as in subdir_record). + * sanity.sh (conflicts3): New tests conflicts3-20a and + conflicts3-23 test for these fixes. + + * commit.c (commit): Only set up hardlist if preserve_perms. + + * commit.c, import.c, no_diff.c, parseinfo.c, rcs.c, rcscmds.c, + update.c: Omit the preserve_perms code if + PRESERVE_PERMISSIONS_SUPPORT is not defined. Much of that code + won't even compile on non-unix systems. + + * hardlink.c, hardlink.h: Use the 'standard' copyright (as found + in server.c). + * commit.c, rcs.c: Minor whitespace changes to Tim's submission. + * commit.c (check_fileproc), update.c (get_linkinfo_proc): Remove + unused variable delta. + * hardlink.c (set_hardlink_field_proc), update.c + (get_linkinfo_proc): Return a value rather than falling off the + end of the function. + +1998-03-02 Tim Pierce <twp@skepsis.com> + + * update.c (special_file_mismatch): Compare the hard links of the + two revisions. + + * rcs.c (RCS_checkout): + + * hardlink.c, hardlink.h: New files. + (hardlink_info): New struct. + (hardlist, working_dir): New variables. + (list_files_proc, cache_hardlinks_proc, set_hardlink_field_proc, + lookup_file_by_inode, update_hardlink_info, list_files_linked_to): + New functions. + + * Makefile.in (SOURCES): Add hardlink.c. + (OBJECTS): Add hardlink.o. + (HEADERS): Add hardlink.h. + * commit.c: Include hardlink.h. + (commit): Save the working directory before recursing. Walk the + hardlink list, calling set_hardlink_field_proc on each node. + (check_fileproc): Add each file's link information to hardlist. + * rcs.c: Include hardlink.h. + (RCS_checkin): Save list of hardlinks in delta node. + (RCS_checkout): Look up the file's `hardlinks' delta field, and + see if any of the files linked to it have been checked out + already. Link to one of those files if so. + * update.c: Include hardlink.h. + (get_linkinfo_proc): New function. + (do_update): Extra recursion to collect hardlink info. + (special_file_mismatch): Reparse the RCS file if necessary. + + fsortcmp is now used by several files, so let's make it extern. + * hash.c, hash.h (fsortcmp): New function. + * find_names.c (fsortcmp): Removed. + * lock.c (fsortcmp): Removed. + +1998-03-03 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (conflicts3): New tests conflicts3-14a, + conflicts3-14b, and conflicts3-21, conflicts3-22 test that we can + skip over a working directory with a CVSADM directory missing. + +1998-02-26 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (conflicts3): Tests conflicts3-16 and conflicts3-20 + test that we include update_dir in messages. Rename test + conflicts3-14 to fix typo. + +Sun Feb 22 23:14:25 1998 Steve Cameron <steve.cameron@compaq.com> + and Ian Lance Taylor <ian@cygnus.com> + + * update.c (tag_update_dir): New static variable. + (update_dirent_proc): If no tag or date were specified when + creating a subdirectory, use the tag and/or date of the parent + directory. + (update_dirleave_proc): If we set the tag and/or date in + update_dirent_proc, reset them when we leave the directory. + * sanity.sh (branches2): New set of tests for above patch, and + related behaviour. + +Sun Feb 22 13:31:51 1998 Ian Lance Taylor <ian@cygnus.com> + + * commit.c (lock_RCS): Don't call RCS_rewrite. + + * update.c (patch_file): If the revision is dead, let + checkout_file handle it. + * sanity.sh (death2): Add test for above patch: add + death2-10a, death2-10b, death2-13a, and adjust + death2-{2,4,5,11,14,diff-11,diff-12,19}. + + * cvs.h (RCS_FLAGS_KEEPFILE): Define. + * rcs.c (RCS_checkin): If RCS_FLAGS_KEEPFILE is set in the flags + parameter, don't unlink the working file. + * checkin.c (Checkin): Don't copy the file. Instead pass + RCS_FLAGS_KEEPFILE to RCS_checkin, and only check the file out + again if it has changed. + +1998-02-21 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.c (rcs_internal_unlockfile, RCS_rewrite): Don't assume errno + means anything just because ferror is set. + +Sat Feb 21 20:02:24 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (clean): Change "/bin/rm" to "rm". + + * buffer.c (buf_append_buffer): Correct typo in comment. + * rcs.c (RCS_putadmin): Likewise. + +Fri Feb 20 17:53:06 1998 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (rcs_internal_unlockfile): Pass errno when calling error + because ferror is true. + +1998-02-20 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (abspath): Don't assume that we can't write to /; this + is the kind of thing that is sure to break sooner or later + (especially on Windows). + + * sanity.sh: Add summary of which modules tests are which (at + "modules"). Move cvsadm, abspath, and toplevel next to modules. + Add comments to clarify the structure (such as it is). + +Fri Feb 20 12:47:14 1998 Larry Jones <larry.jones@sdrc.com> + + * admin.c (admin_fileproc): Better fix for -b. + + * rcs.c (RCS_whatbranch): Back out previous change. + (RCS_getversion): Ditto. + (RCS_setbranch): Treat an empty revision string like a null pointer. + +1998-02-18 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.c (RCS_whatbranch): Fix indentation. + + * patch.c (patch_fileproc): Check for errors from fclose; check + for errors from fopen properly. + +Wed Feb 18 16:03:37 1998 Larry Jones <larry.jones@sdrc.com> + + * admin.c (admin_fileproc): Convert -b argument from symbolic name + to revision number before storing in the RCS file. + * rcs.c (RCS_whatbranch): Allow numeric as well as symbolic revision. + (RCS_getversion): Take advantage of above. + * sanity.sh (admin): Add/revise/renumber admin-10c, admin-11a, + admin-12, and admin-12a to check above. + + * commmit.c (lock_RCS): Minor clean-up. + + * sanity.sh (abspath-6a): Don't depend on the sepcific contents of + CVSROOT, it depends on which other tests have been run. + +Wed Feb 18 01:56:04 1998 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (putsymbol_proc): Use putc and fputs rather than fprintf. + (RCS_putadmin): Don't call RCS_symbols if the symbols have not yet + been converted to a list. + + * rcs.c (rcsbuf_cache, rcsbuf_cache_open, rcsbuf_cache_close): New + static functions to avoid closing and reopening the RCS file. + (cached_rcs, cached_rcsbuf): New static variables. + (RCS_parse): Call rcsbuf_cache_close. Don't call fclose. + (RCS_parsercsfile): Likewise. + (RCS_parsercsfile_i): Call rcsbuf_cache rather than + rcsbuf_close. Call fclose on error. Remove comment about + inefficiency of opening file twice. + (RCS_reparsercsfile): Call rcsbuf_cache_open rather than fopen and + rcsbuf_open. Call rcsbuf_cache rather than rcsbuf_close and + fclose. + (RCS_fully_parse, RCS_checkout, RCS_deltas): Likewise. + (RCS_rewrite): Likewise. + (RCS_checkin): Call rcsbuf_cache_close. + + * rcs.c (RCS_copydeltas): Fix code which checks for an extra + newline in buffered data. + + * rcs.c (rcsbuf_getkey): Save an indirection by using start rather + than *valp when trimming trailing whitespace from value. + + * rcs.c (rcsbuf_get_buffered): New static function. + (RCS_copydeltas): After we have done all the required special + actions, and inserted any new revision, just copy the file bytes + directly, rather than interpreting all the data. + (count_delta_actions): New static function. + * sanity.sh (rcs): Add rcs-6a and rcs-6b to commit a new branch + revision, to force CVS to interpret all the data, rather than just + copying it. Adjust rcs-5 to add a branch tag. Adjust rcs-8a and + rcs-14 for the changes created by rcs-6b. + +Tue Feb 17 18:34:01 1998 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh (cvsadm, diffmerge2): Remove directories at the end of + the test. + + * import.c (expand_at_signs): Rewrite to use memchr and fwrite + rather than putc. + + Rewrite RCS file reading routines for speed: + * rcs.c (struct rcsbuffer): Define. + (rcsbuf_open, rcsbuf_close, rcsbuf_getkey, rcsbuf_getrevnum, + rcsbuf_fill, rcsbuf_valcopy, rcsbuf_valpolish, + rcsbuf_valpolish_internal, rcsbuf_ftell): New static functions. + (getrcskey, getrcsrev, getrevnum): Remove. + (many functions): Change to use new rcsbuf functions instead of + old getrcskey/getrcsrev/getrevnum functions. + (RCS_reparsercsfile): Add rcsbufp parameter. Change all callers. + (RCS_deltas): Add rcsbuf parameter. Change all callers. + (getdelta): Change fp parameter to rcsbuf parameter. Change all + callers. + (RCS_getdeltatext): Add rcsbuf parameter. Change all callers. + (RCS_copydeltas): Add rcsbufin parameter. Change all callers. + * rcs.h (RCS_reparsercsfile): Update declaration. + * admin.c (admin_fileproc): Update calls to RCS_reparsercsfile for + new parameters. + +1998-02-17 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (toplevel): Also clean up second-dir (not a new + bug, but triggered by running tests as "toplevel abspath"). + + * create_adm.c (Create_Admin): Just print update_dir to tell the + user where we are; not the whole xgetwd. Cleaner than + Noel's change (which also had problems in errno handling). + * sanity.sh (toplevel-12): Update accordingly. + +Tue Feb 17 02:32:21 1998 Noel Cragg <noel@swish.red-bean.com> + + [These mods make "checkout" work with "-d /absolute/pathname" + once again.] + + * checkout.c (checkout_proc): the -d flag on the command line + should override the -d flag in the modules file if the latter is + an absolute path. The loop that assembles the list of directories + to build has been reorganized slightly to prepare for rewriting + with last_component rather than assuming '/' as a path separator. + Also added to that loop was some code to handle absolute + pathnames. + (build_dirs_and_chdir): add a new argument that tells this routine + whether or not to check before it creates and populates + directories or not. + + * filesubr.c (last_component): return the top-level directory when + asked about the top-level directory. + + * sanity.sh (toplevel-12): change test to reflect the new style of + this error message. + + * create_adm.c (Create_Admin): include the directory in the error + message. + +1998-02-16 Jim Kingdon <kingdon@harvey.cyclic.com> + + * diff.c (diff_fileproc), import.c (import, add_rcs_file), rcs.c + (RCS_cmp_file): Don't ignore errors from CVS_UNLINK and fclose. + + * patch.c (patch_fileproc): Check for errors from fclose; if we + get -1 from getline check for end of file vs. error. + + * rcs.c (RCS_checkout): Comment return value (0/1, not -1). + * commit.c, diff.c, mkmodules.c, patch.c, rcs.c, update.c: Update + to match this convention. Don't suppress errors based on + quiet or really_quiet variables. + + Fix a longstanding bug which also makes stamps-8kw in make + remotecheck work again (it stopped working with Ian's 8 Feb 98 + checkin): + * client.c, client.h (change_mode): If new argument respect_umask + is set, then honor the umask. + * client.c, server.c: Update callers. + + Cleanups to Tim's checkin: + * rcs.c (RCS_checkout): Use existence_error not ENOENT. + * commit.c (checkaddfile): Remove comment about whether we want to + check for errors from fclose; there is no reason not to. + * rcs.c (RCS_checkout), update.c (special_file_mismatch): sscanf + on %ld requires an unsigned long, not a dev_t. + * update.c (special_file_mismatch): Remove unused variable + check_devnums. + * mkmodules.c (config_contents): Between two settings, use a blank + line not a "#" line. + +1998-02-15 Tim Pierce <twp@skepsis.com> + + [This is the code as submitted. I'll be checking in my cleanups + shortly. This work sponsored by Abbott Labs. -kingdon] + + Support for device special files, symbolic links, user and group + ownerships, and file permissions. + + * parseinfo.c: (parse_config): Handle new config variable + `PreservePermissions'. + * mkmodules.c (config_contents): Add new PreservePermissions var. + + * rcs.c, rcs.h (preserve_perms): New variable. + (RCS_checkout, RCS_checkin): Support for newphrases `owner', + `group', `permissions', `special', `symlink'. + (RCS_checkout): If `workfile' and `sout' are symlinks, remove them + before attempting to open them for writing. + * import.c (add_rcs_file): Support for newphrases. Do not attempt + to read data from special files or symlinks. Error message + `cannot fstat' is now `cannot lstat'. + + New metrics for deciding when two files are different: + + * update.c, cvs.h (special_file_mismatch): New function. + (merge_file, join_file): Call it. + * no_diff.c (No_Difference): Call it. + + * filesubr.c (xcmp): Consider files to be different if they are of + different types; if they are symlinks which link to different + pathnames; or if they are devices with different device numbers. + Error message is now `cannot lstat'. + * rcs.c (RCS_cmp_file): Use `xcmp' to compare files, simplifying + the special handling for nonregular files. + + * rcscmds.c (diff_exec, diff_execv): If asked to obtain diffs for + special files, report no differences. + + Miscellaneous changes to make special file support possible: + + * commit.c (fix_rcs_modes): Don't attempt to `fix' permissions on + a symlink. + + * import.c (add_rcs_file): Don't try to close fpuser if it was + never opened (e.g. when operating on a symlink). + + * filesubr.c, cvs.h (isdevice, xreadlink): New functions. + * filesubr.c (copy_file): Handle special files and symlinks. + (xchmod): Do nothing if `preserve_perms' is set. + + * commit.c (checkaddfile): Replace `copy_file (DEVNULL, ...)' with + fopen/fclose calls. Copy_file no longer attempts to read data + from device files. + + * filesubr.c (islink): Use CVS_LSTAT, not lstat. + * vers_ts.c (time_stamp, time_stamp_server): Use CVS_LSTAT, not stat, + to get symlinks right. + * subr.c (get_file): Same. Don't attempt to read from special + files or symlinks. + + * classify.c (Classify_File): Doc fix. + +Fri Feb 13 17:07:32 1998 Eric Mumpower <nocturne@cygnus.com> + and Ian Lance Taylor <ian@cygnus.com> + + Fix some file system ordering problems found on Irix 6.4: + * sanity.sh (basic2): Use dotest_sort for test 56. + (importb): Use dotest_sort for tests importb-1 and importb-2. + (head): Use dotest_sort for test head-1. + +Thu Feb 12 15:15:33 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + * import.c (add_rcs_file): If add_logfp is NULL, don't call fperror. + +11 Feb 1998 Andy Piper + + * server.c (cvs_output_binary): Use OPEN_BINARY not _O_BINARY. + +Mon Feb 9 18:34:39 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + Tweaks to Ian's checkin: + * update.c (merge_file): Remove comment about sending file to + client before the message. It doesn't apply to this code any more + (it does apply to checkout_file, but I'm not sure it is important + to have such a comment anyway). + * buffer.c (buf_default_memory_error, buf_length): Reindent. + * server.h: Declare struct buffer before use. + +Mon Feb 9 21:05:28 1998 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_fully_parse): Call getrevnum rather than getrcsrev. + Don't bother with ungetc. + + * rcs.c (getrcsrev): Rewrite to simply call getrevnum. + +Sun Feb 8 15:49:39 1998 Ian Lance Taylor <ian@cygnus.com> + + Don't have the server check out a revision into a file and then + immediately read the file; just read into a buffer instead. + * update.c: Include buffer.h. + (update_fileproc): Let checkout_file call server_updated. + (checkout_file): Add merging and update_server parameters. Change + all callers. If server_active, don't mess with backup files. If + server_active, copy the revision into a buffer rather than a file + when possible. If update_server, call server_updated. Fix + handling of error status. + (checkout_to_buffer): New static function used by checkout_file. + (merge_file): Let checkout_file call server_updated. + (join_file): Likewise. + * server.c (server_updated): Change file_info parameter to mode + parameter. Add filebuf parameter. Change all callers. If + filebuf is not NULL, don't read the file. + * server.h (server_updated): Update declaration. + * buffer.c (buf_free): New function. + (buf_append_buffer): New function. + (buf_length): New function. + * buffer.h (buf_free, buf_append_buffer, buf_length): Declare. + + * buffer.c: (buf_initialize): If the memory parameter is NULL, use + buf_default_memory_error. + (buf_default_memory_error): New static function. + * buffer.h (BUFMEMERRPROC): Define typedef. + * client.c (buf_memory_error): Remove. + (start_server): Pass NULL rather than buf_memory_error as buffer + memory error function. + +Sat Feb 7 16:27:30 1998 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_parsercsfile_i): Read the expand keyword from the RCS + file. We do this because Version_TS calls RCS_getexpand in many + common cases, and we don't want to reopen the file just for that. + (RCS_reparsercsfile): Skip the expand keyword. + (RCS_getexpand): Don't call RCS_reparsercsfile. + + * rcs.c (STREQ): New macro. In all string equality tests in the + file, replace strcmp with STREQ. + +Fri Feb 6 16:14:49 1998 Ian Lance Taylor <ian@cygnus.com> + + * update.c (checkout_file): If we've already removed the backup + file once, don't try to remove it again. + + * filesubr.c (unlink_file_dir): Call stat rather than isdir, and + don't call unlink if the file does not exist. + + * myndbm.c (mydbm_load_file): Rename line_len to line_size. Call + getstr rather than getline, to avoid any confusion between \n and + \012. Use the line length returned by getstr rather than calling + strlen. Remove local variable len. + +Fri Feb 6 13:23:46 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.c (RCS_parsercsfile_i): Don't suppress errors on + really_quiet. + (RCS_parsercsfile_i, RCS_reparsercsfile, RCS_fully_parse, + RCS_deltas, getdelta, getrcskey, RCS_getdeltatext): + Check for errors. Include errno in error messages. Include + filename in error messages. Pass new argument to getrcskey. + (getrcskey): New argument NAME, so we can report errors ourself. + +Fri Feb 6 12:10:18 1998 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_reparsercsfile): Don't use ftell/fseek; just keep + track of whether we've already read a key/value pair. Use sizeof + rather than strlen for a constant string. Pass the current key + and value to getdelta, and get them back as well. + (getdelta): Add keyp and valp parameters. Don't use ftell/fseek; + just return the key/value pair to the caller. Don't allocate + vnode before we know we need it. Check one getrcskey return + value. Use sizeof rather than strlen for a constant string. + + * rcs.c (getrcskey): Correct comment describing return value. + +Thu Feb 5 22:51:13 1998 Ian Lance Taylor <ian@cygnus.com> + + * subr.c (getcaller): Cache the result, so that we don't keep + searching the password file. + +Wed Feb 4 23:31:08 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.c (max_rev): Don't prototype. Interesting that noone + complained about this until now. + +4 Feb 1998 Jim Kingdon + + * rcs.c (RCS_checkin): When adding a new file, read it + with "rb" if binary. + +Fri Jan 30 11:32:41 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh: Also test "first-dir" as the regexp in loginfo in + addition to ALL. + + * main.c (main): Update year in copyright notice to 1998. + Thu Jan 29 00:01:05 1998 Jim Kingdon <kingdon@harvey.cyclic.com> + * version.c: Change version number to 1.9.25. + * Version 1.9.24. * sanity.sh (multibranch2): File file2 and tests multibranch2-13 diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in index 296554a..61b4fe2 100644 --- a/contrib/cvs/src/Makefile.in +++ b/contrib/cvs/src/Makefile.in @@ -39,7 +39,7 @@ LIBS = @LIBS@ SOURCES = add.c admin.c buffer.c checkin.c checkout.c classify.c client.c \ commit.c create_adm.c cvsrc.c diff.c edit.c entries.c error.c expand_path.c \ -fileattr.c find_names.c hash.c history.c ignore.c import.c \ +fileattr.c find_names.c hardlink.c hash.c history.c ignore.c import.c \ lock.c log.c login.c logmsg.c main.c mkmodules.c modules.c myndbm.c no_diff.c \ parseinfo.c patch.c rcs.c rcscmds.c recurse.c release.c remove.c repos.c \ root.c rtag.c scramble.c server.c status.c subr.c filesubr.c run.c \ @@ -47,14 +47,14 @@ tag.c update.c watch.c wrapper.c vers_ts.c version.c zlib.c OBJECTS = add.o admin.o buffer.o checkin.o checkout.o classify.o client.o \ commit.o create_adm.o cvsrc.o diff.o edit.o entries.o expand_path.o \ -fileattr.o find_names.o hash.o history.o ignore.o import.o \ +fileattr.o find_names.o hardlink.o hash.o history.o ignore.o import.o \ lock.o log.o login.o logmsg.o main.o mkmodules.o modules.o myndbm.o no_diff.o \ parseinfo.o patch.o rcs.o rcscmds.o recurse.o release.o remove.o repos.o \ root.o rtag.o scramble.o server.o status.o tag.o update.o \ watch.o wrapper.o vers_ts.o \ subr.o filesubr.o run.o version.o error.o zlib.o -HEADERS = buffer.h cvs.h rcs.h hash.h myndbm.h \ +HEADERS = buffer.h cvs.h rcs.h hardlink.h hash.h myndbm.h \ update.h server.h client.h error.h fileattr.h edit.h watch.h TAGFILES = $(HEADERS) options.h.in $(SOURCES) @@ -125,7 +125,7 @@ ls: .PHONY: ls clean: - /bin/rm -f $(PROGS) *.o core check.log check.plog + rm -f $(PROGS) *.o core check.log check.plog .PHONY: clean distclean: clean diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c index ab667df..d44435a 100644 --- a/contrib/cvs/src/add.c +++ b/contrib/cvs/src/add.c @@ -264,7 +264,7 @@ add (argc, argv) /* Find the repository associated with our current dir. */ repository = Name_Repository (NULL, finfo.update_dir); - entries = Entries_Open (0); + entries = Entries_Open (0, NULL); finfo.repository = repository; finfo.entries = entries; diff --git a/contrib/cvs/src/admin.c b/contrib/cvs/src/admin.c index a78bada..3c50f4a 100644 --- a/contrib/cvs/src/admin.c +++ b/contrib/cvs/src/admin.c @@ -478,7 +478,7 @@ admin_fileproc (callerdat, finfo) rcs = vers->srcfile; if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, NULL); + RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); status = 0; @@ -490,9 +490,23 @@ admin_fileproc (callerdat, finfo) } if (admin_data->branch != NULL) - RCS_setbranch (rcs, (admin_data->branch[2] == '\0' - ? NULL - : admin_data->branch + 2)); + { + char *branch = &admin_data->branch[2]; + if (*branch != '\0' && ! isdigit (*branch)) + { + branch = RCS_whatbranch (rcs, admin_data->branch + 2); + if (branch == NULL) + { + error (0, 0, "%s: Symbolic name %s is undefined.", + rcs->path, admin_data->branch + 2); + status = 1; + } + } + if (status == 0) + RCS_setbranch (rcs, branch); + if (branch != NULL && branch != &admin_data->branch[2]) + free (branch); + } if (admin_data->comment != NULL) { if (rcs->comment != NULL) @@ -793,7 +807,7 @@ admin_fileproc (callerdat, finfo) RCS data structure. Forcing a reparse does the trick, but leaks memory and is kludgey. Should we export free_rcsnode_contents for this purpose? */ - RCS_reparsercsfile (rcs, NULL); + RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); } exitfunc: diff --git a/contrib/cvs/src/buffer.c b/contrib/cvs/src/buffer.c index 0042e4c..8f90545 100644 --- a/contrib/cvs/src/buffer.c +++ b/contrib/cvs/src/buffer.c @@ -16,6 +16,7 @@ static struct buffer_data *free_buffer_data; /* Local functions. */ +static void buf_default_memory_error PROTO ((struct buffer *)); static void allocate_buffer_datas PROTO((void)); static struct buffer_data *get_buffer_data PROTO((void)); @@ -42,11 +43,25 @@ buf_initialize (input, output, flush, block, shutdown, memory, closure) buf->flush = flush; buf->block = block; buf->shutdown = shutdown; - buf->memory_error = memory; + buf->memory_error = memory ? memory : buf_default_memory_error; buf->closure = closure; return buf; } +/* Free a buffer structure. */ + +void +buf_free (buf) + struct buffer *buf; +{ + if (buf->data != NULL) + { + buf->last->next = free_buffer_data; + free_buffer_data = buf->data; + } + free (buf); +} + /* Initialize a buffer structure which is not to be used for I/O. */ struct buffer * @@ -63,6 +78,15 @@ buf_nonio_initialize (memory) (void *) NULL)); } +/* Default memory error handler. */ + +static void +buf_default_memory_error (buf) + struct buffer *buf; +{ + error (1, 0, "out of memory"); +} + /* Allocate more buffer_data structures. */ static void @@ -470,6 +494,19 @@ buf_append_data (buf, data, last) } } +/* Append the data on one buffer to another. This removes the data + from the source buffer. */ + +void +buf_append_buffer (to, from) + struct buffer *to; + struct buffer *from; +{ + buf_append_data (to, from->data, from->last); + from->data = NULL; + from->last = NULL; +} + /* * Copy the contents of file F into buffer_data structures. We can't * copy directly into an buffer, because we want to handle failure and @@ -621,6 +658,15 @@ buf_chain_length (buf) return size; } +/* Return the number of bytes in a buffer. */ + +int +buf_length (buf) + struct buffer *buf; +{ + return buf_chain_length (buf->data); +} + /* * Read an arbitrary amount of data into an input buffer. The buffer * will be in nonblocking mode, and we just grab what we can. Return diff --git a/contrib/cvs/src/buffer.h b/contrib/cvs/src/buffer.h index c632490..0556781 100644 --- a/contrib/cvs/src/buffer.h +++ b/contrib/cvs/src/buffer.h @@ -96,6 +96,9 @@ struct buffer_data /* The size we allocate for each buffer_data structure. */ #define BUFFER_DATA_SIZE (4096) +/* The type of a function passed as a memory error handler. */ +typedef void (*BUFMEMERRPROC) PROTO ((struct buffer *)); + extern struct buffer *buf_initialize PROTO((int (*) (void *, char *, int, int, int *), int (*) (void *, const char *, @@ -105,6 +108,7 @@ extern struct buffer *buf_initialize PROTO((int (*) (void *, char *, int, int (*) (void *), void (*) (struct buffer *), void *)); +extern void buf_free PROTO((struct buffer *)); extern struct buffer *buf_nonio_initialize PROTO((void (*) (struct buffer *))); extern struct buffer *stdio_buffer_initialize PROTO((FILE *, int, void (*) (struct buffer *))); @@ -127,6 +131,7 @@ extern int buf_send_special_count PROTO((struct buffer *, int)); extern void buf_append_data PROTO((struct buffer *, struct buffer_data *, struct buffer_data *)); +extern void buf_append_buffer PROTO((struct buffer *, struct buffer *)); extern int buf_read_file PROTO((FILE *, long, struct buffer_data **, struct buffer_data **)); extern int buf_read_file_to_eof PROTO((FILE *, struct buffer_data **, @@ -137,6 +142,7 @@ extern int buf_read_data PROTO((struct buffer *, int, char **, int *)); extern void buf_copy_lines PROTO((struct buffer *, struct buffer *, int)); extern int buf_copy_counted PROTO((struct buffer *, struct buffer *, int *)); extern int buf_chain_length PROTO((struct buffer_data *)); +extern int buf_length PROTO((struct buffer *)); extern int buf_shutdown PROTO((struct buffer *)); #ifdef SERVER_FLOWCONTROL diff --git a/contrib/cvs/src/checkin.c b/contrib/cvs/src/checkin.c index 1d89ae1..70fb74c 100644 --- a/contrib/cvs/src/checkin.c +++ b/contrib/cvs/src/checkin.c @@ -29,7 +29,6 @@ Checkin (type, finfo, rcs, rev, tag, options, message) char *options; char *message; { - char *fname; Vers_TS *vers; int set_time; char *tocvsPath = NULL; @@ -42,69 +41,63 @@ Checkin (type, finfo, rcs, rev, tag, options, message) cvs_output (finfo->fullname, 0); cvs_output (";\n", 0); - fname = xmalloc (strlen (finfo->file) + 80); - (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file); - - /* - * Move the user file to a backup file, so as to preserve its - * modification times, then place a copy back in the original file name - * for the checkin and checkout. - */ - tocvsPath = wrap_tocvs_process_file (finfo->file); - if (!noexec) { if (tocvsPath) { - copy_file (tocvsPath, fname); if (unlink_file_dir (finfo->file) < 0) if (! existence_error (errno)) error (1, errno, "cannot remove %s", finfo->fullname); - copy_file (tocvsPath, finfo->file); - } - else - { - copy_file (finfo->file, fname); + rename_file (tocvsPath, finfo->file); } } if (finfo->rcs == NULL) finfo->rcs = RCS_parse (finfo->file, finfo->repository); - switch (RCS_checkin (finfo->rcs, NULL, message, rev, 0)) + switch (RCS_checkin (finfo->rcs, NULL, message, rev, RCS_FLAGS_KEEPFILE)) { case 0: /* everything normal */ - /* - * The checkin succeeded, so now check the new file back out and - * see if it matches exactly with the one we checked in. If it - * does, just move the original user file back, thus preserving - * the modes; otherwise, we have no recourse but to leave the - * newly checkout file as the user file and remove the old - * original user file. - */ + /* The checkin succeeded. If checking the file out again + would not cause any changes, we are done. Otherwise, + we need to check out the file, which will change the + modification time of the file. + + The only way checking out the file could cause any + changes is if the file contains RCS keywords. So we if + we are not expanding RCS keywords, we are done. */ if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */ options[0] = '\0'; - /* FIXME: should be checking for errors. */ - (void) RCS_checkout (finfo->rcs, finfo->file, rev, - (char *) NULL, options, RUN_TTY, - (RCSCHECKOUTPROC) NULL, (void *) NULL); - - xchmod (finfo->file, 1); - if (xcmp (finfo->file, fname) == 0) + /* FIXME: If PreservePermissions is on, RCS_cmp_file is + going to call RCS_checkout into a temporary file + anyhow. In that case, it would be more efficient to + call RCS_checkout here, compare the resulting files + using xcmp, and rename if necessary. I think this + should be fixed in RCS_cmp_file. */ + if ((! preserve_perms + && options != NULL + && (strcmp (options, "-ko") == 0 + || strcmp (options, "-kb") == 0)) + || RCS_cmp_file (finfo->rcs, rev, options, finfo->file) == 0) { - rename_file (fname, finfo->file); - /* the time was correct, so leave it alone */ + /* The existing file is correct. We don't have to do + anything. */ set_time = 0; } else { - if (unlink_file (fname) < 0) - error (0, errno, "cannot remove %s", fname); - /* sync up with the time from the RCS file */ + /* The existing file is incorrect. We need to check + out the correct file contents. */ + if (RCS_checkout (finfo->rcs, finfo->file, rev, (char *) NULL, + options, RUN_TTY, (RCSCHECKOUTPROC) NULL, + (void *) NULL) != 0) + error (1, 0, "failed when checking out new copy of %s", + finfo->fullname); + xchmod (finfo->file, 1); set_time = 1; } @@ -140,25 +133,19 @@ Checkin (type, finfo, rcs, rev, tag, options, message) if (!noexec) error (1, errno, "could not check in %s -- fork failed", finfo->fullname); - free (fname); return (1); default: /* ci failed */ - /* - * The checkin failed, for some unknown reason, so we restore the - * original user file, print an error, and return an error - */ + /* The checkin failed, for some unknown reason, so we + print an error, and return an error. We assume that + the original file has not been touched. */ if (tocvsPath) if (unlink_file_dir (tocvsPath) < 0) error (0, errno, "cannot remove %s", tocvsPath); if (!noexec) - { - rename_file (fname, finfo->file); error (0, 0, "could not check in %s", finfo->fullname); - } - free (fname); return (1); } @@ -179,7 +166,8 @@ Checkin (type, finfo, rcs, rev, tag, options, message) if (set_time) /* Need to update the checked out file on the client side. */ server_updated (finfo, vers, SERVER_UPDATED, - NULL, NULL); + (mode_t) -1, (unsigned char *) NULL, + (struct buffer *) NULL); else server_checked_in (finfo->file, finfo->update_dir, finfo->repository); } @@ -188,6 +176,5 @@ Checkin (type, finfo, rcs, rev, tag, options, message) mark_up_to_date (finfo->file); freevers_ts (&vers); - free (fname); return (0); } diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c index 3c1eef7..46151eb 100644 --- a/contrib/cvs/src/checkout.c +++ b/contrib/cvs/src/checkout.c @@ -33,6 +33,7 @@ * edited by the user, if necessary (when the repository is moved, e.g.) */ +#include <assert.h> #include "cvs.h" static char *findslash PROTO((char *start, char *p)); @@ -431,7 +432,7 @@ struct dir_to_build }; static int build_dirs_and_chdir PROTO ((struct dir_to_build *list, - int sticky)); + int sticky, int check_existing_dirs)); static void build_one_dir PROTO ((char *, char *, int)); @@ -580,7 +581,11 @@ checkout_proc (pargc, argv, where_orig, mwhere, mfile, shorten, (void) strcat (where, "/"); } - if (mwhere != NULL) + /* If the -d flag in the modules file specified an absolute + directory, let the user override it with the command-line + -d option. */ + + if ((mwhere != NULL) && (! isabsolute (mwhere))) (void) strcat (where, mwhere); else (void) strcat (where, argv[0]); @@ -723,19 +728,39 @@ internal error: %s doesn't start with %s in checkout_proc", /* Make a copy of the repository name to play with. */ reposcopy = xstrdup (repository); - /* FIXME: this should be written in terms of last_component instead - of hardcoding '/'. This presumably affects OS/2, NT, &c, if - the user specifies '\'. Likewise for the call to findslash. */ - cp = strrchr (where, '/'); - while (cp != NULL) + /* FIXME: this should be written in terms of last_component + instead of hardcoding '/'. This presumably affects OS/2, + NT, &c, if the user specifies '\'. Likewise for the call + to findslash. */ + cp = where + strlen (where); + while (1) { struct dir_to_build *new; + + cp = findslash (where, cp - 1); + if (cp == NULL) + break; /* we're done */ + new = (struct dir_to_build *) xmalloc (sizeof (struct dir_to_build)); new->dirpath = xmalloc (strlen (where)); - strncpy (new->dirpath, where, cp - where); - new->dirpath[cp - where] = '\0'; + /* If the user specified an absolute path for where, the + last path element we create should be the top-level + directory. */ + + if (cp - where) + { + strncpy (new->dirpath, where, cp - where); + new->dirpath[cp - where] = '\0'; + } + else + { + /* where should always be at least one character long. */ + assert (strlen (where)); + strcpy (new->dirpath, "/"); + } + /* Now figure out what repository directory to generate. The most complete case would be something like this: @@ -813,31 +838,41 @@ internal error: %s doesn't start with %s in checkout_proc", new->next = head; head = new; - - cp = findslash (where, cp - 1); } /* clean up */ free (reposcopy); - /* The top-level CVSADM directory should always be - CVSroot_directory. Create it. - - It may be argued that we shouldn't set any sticky bits for - the top-level repository. FIXME? */ - build_one_dir (CVSroot_directory, ".", *pargc <= 1); - - /* - * build dirs on the path if necessary and leave us in the bottom - * directory (where if where was specified) doesn't contain a CVS - * subdir yet, but all the others contain CVS and Entries.Static - * files - */ - if (build_dirs_and_chdir (head, *pargc <= 1) != 0) { - error (0, 0, "ignoring module %s", omodule); - err = 1; - goto out; + int where_is_absolute = isabsolute (where); + + /* The top-level CVSADM directory should always be + CVSroot_directory. Create it, but only if WHERE is + relative. If WHERE is absolute, our current directory + may not have a thing to do with where the sources are + being checked out. If it does, build_dirs_and_chdir + will take care of creating adm files here. */ + + if (! where_is_absolute) + { + /* It may be argued that we shouldn't set any sticky + bits for the top-level repository. FIXME? */ + build_one_dir (CVSroot_directory, ".", *pargc <= 1); + } + + + /* Build dirs on the path if necessary and leave us in the + bottom directory (where if where was specified) doesn't + contain a CVS subdir yet, but all the others contain + CVS and Entries.Static files */ + + if (build_dirs_and_chdir (head, *pargc <= 1, + where_is_absolute) != 0) + { + error (0, 0, "ignoring module %s", omodule); + err = 1; + goto out; + } } /* set up the repository (or make sure the old one matches) */ @@ -969,7 +1004,7 @@ internal error: %s doesn't start with %s in checkout_proc", List *entries; /* we are only doing files, so register them */ - entries = Entries_Open (0); + entries = Entries_Open (0, NULL); for (i = 1; i < *pargc; i++) { char *line; @@ -1066,13 +1101,22 @@ emptydir_name () return repository; } -/* Build all the dirs along the path to DIRS with CVS subdirs with appropriate - repositories. If ->repository is NULL, do not create a CVSADM directory - for that subdirectory; just CVS_CHDIR into it. */ + +/* Build all the dirs along the path to DIRS with CVS subdirs with + appropriate repositories. If ->repository is NULL, do not create a + CVSADM directory for that subdirectory; just CVS_CHDIR into it. If + check_existing_dirs is nonzero, don't create directories if they + already exist, and don't try to write adm files in directories + where we don't have write permission. We use this last option + primarily when a user has specified an absolute path for checkout + -- we will often not have permission to top-level directories, so + we shouldn't complain. */ + static int -build_dirs_and_chdir (dirs, sticky) +build_dirs_and_chdir (dirs, sticky, check_existing_dirs) struct dir_to_build *dirs; int sticky; + int check_existing_dirs; { int retval = 0; struct dir_to_build *nextdir; @@ -1080,20 +1124,31 @@ build_dirs_and_chdir (dirs, sticky) while (dirs != NULL) { char *dir = last_component (dirs->dirpath); + int dir_is_writeable; + + if ((! check_existing_dirs) || (! isdir (dir))) + mkdir_if_needed (dir); - mkdir_if_needed (dir); Subdir_Register (NULL, NULL, dir); + + /* This is an expensive call -- only make it if necessary. */ + if (check_existing_dirs) + dir_is_writeable = iswritable (dir); + if (CVS_CHDIR (dir) < 0) { error (0, errno, "cannot chdir to %s", dir); retval = 1; goto out; } - if (dirs->repository != NULL) + + if ((dirs->repository != NULL) + && ((! check_existing_dirs) || dir_is_writeable)) { build_one_dir (dirs->repository, dirs->dirpath, sticky); free (dirs->repository); } + nextdir = dirs->next; free (dirs->dirpath); free (dirs); diff --git a/contrib/cvs/src/classify.c b/contrib/cvs/src/classify.c index 57c23cd..b33c945 100644 --- a/contrib/cvs/src/classify.c +++ b/contrib/cvs/src/classify.c @@ -302,6 +302,8 @@ conflict: %s created independently by second party", * has changed. If the sticky tag has changed, we just need * to re-register the entry */ + /* TODO: decide whether we need to check file permissions + for a mismatch, and return T_CONFLICT if so. */ if (vers->entdata->options && strcmp (vers->entdata->options, vers->options) != 0) ret = T_CHECKOUT; @@ -377,7 +379,7 @@ conflict: %s created independently by second party", * The user file is still unmodified, so just get it as well */ #ifdef SERVER_SUPPORT - if (strcmp (vers->entdata->options ? + if (strcmp (vers->entdata->options ? vers->entdata->options : "", vers->options) != 0 || (vers->srcfile != NULL && (vers->srcfile->flags & INATTIC) != 0)) diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c index ca6f464..aa897d5 100644 --- a/contrib/cvs/src/client.c +++ b/contrib/cvs/src/client.c @@ -134,7 +134,6 @@ static void handle_e PROTO((char *, int)); static void handle_f PROTO((char *, int)); static void handle_notified PROTO((char *, int)); -static void buf_memory_error PROTO((struct buffer *)); static size_t try_read_from_server PROTO ((char *, size_t)); #endif /* CLIENT_SUPPORT */ @@ -182,11 +181,13 @@ mode_to_string (mode) /* * Change mode of FILENAME to MODE_STRING. * Returns 0 for success or errno code. + * If RESPECT_UMASK is set, then honor the umask. */ int -change_mode (filename, mode_string) +change_mode (filename, mode_string, respect_umask) char *filename; char *mode_string; + int respect_umask; { #ifdef CHMOD_BROKEN char *p; @@ -217,6 +218,10 @@ change_mode (filename, mode_string) ++p; } + /* xchmod honors the umask for us. In the !respect_umask case, we + don't try to cope with it (probably to handle that well, the server + needs to deal with modes in data structures, rather than via the + modes in temporary files). */ xchmod (filename, writeable); return 0; @@ -224,6 +229,7 @@ change_mode (filename, mode_string) char *p; mode_t mode = 0; + mode_t oumask; p = mode_string; while (*p != '\0') @@ -277,6 +283,13 @@ change_mode (filename, mode_string) ++p; } + if (respect_umask) + { + oumask = umask (0); + (void) umask (oumask); + mode &= ~oumask; + } + if (chmod (filename, mode) < 0) return errno; return 0; @@ -305,16 +318,6 @@ static FILE *from_server_fp; static int rsh_pid = -1; -/* This routine is called when one of the buffer routines runs out of - memory. */ - -static void -buf_memory_error (buf) - struct buffer *buf; -{ - error (1, 0, "out of memory"); -} - /* We want to be able to log data sent between us and the server. We do it using log buffers. Each log buffer has another buffer which handles the actual I/O, and a file to log information to. @@ -1138,7 +1141,7 @@ warning: server is not creating directories one at a time"); if (strcmp (command_name, "export") != 0) { - last_entries = Entries_Open (0); + last_entries = Entries_Open (0, dir_name); /* If this is a newly created directory, we will record all subdirectory information, so call Subdirs_Known in @@ -1928,8 +1931,7 @@ update_entries (data_arg, ent_list, short_pathname, filename) } { - /* FIXME: we should be respecting the umask. */ - int status = change_mode (filename, mode_string); + int status = change_mode (filename, mode_string, 1); if (status != 0) error (0, status, "cannot change mode of %s", short_pathname); } @@ -1939,7 +1941,7 @@ update_entries (data_arg, ent_list, short_pathname, filename) } if (stored_mode_valid) - change_mode (filename, stored_mode); + change_mode (filename, stored_mode, 1); stored_mode_valid = 0; if (stored_modtime_valid) @@ -4012,9 +4014,9 @@ the :server: access method is not supported by this port of CVS"); if (use_socket_style) { to_server = socket_buffer_initialize (server_sock, 0, - buf_memory_error); + (BUFMEMERRPROC) NULL); from_server = socket_buffer_initialize (server_sock, 1, - buf_memory_error); + (BUFMEMERRPROC) NULL); } else #endif /* NO_SOCKET_TO_FD */ @@ -4038,13 +4040,13 @@ the :server: access method is not supported by this port of CVS"); if (to_server_fp == NULL) error (1, errno, "cannot fdopen %d for write", tofd); to_server = stdio_buffer_initialize (to_server_fp, 0, - buf_memory_error); + (BUFMEMERRPROC) NULL); from_server_fp = fdopen (fromfd, FOPEN_BINARY_READ); if (from_server_fp == NULL) error (1, errno, "cannot fdopen %d for read", fromfd); from_server = stdio_buffer_initialize (from_server_fp, 1, - buf_memory_error); + (BUFMEMERRPROC) NULL); } /* Set up logfiles, if any. */ @@ -4071,7 +4073,7 @@ the :server: access method is not supported by this port of CVS"); error (0, errno, "opening to-server logfile %s", buf); else to_server = log_buffer_initialize (to_server, fp, 0, - buf_memory_error); + (BUFMEMERRPROC) NULL); strcpy (p, ".out"); fp = open_file (buf, "wb"); @@ -4079,7 +4081,7 @@ the :server: access method is not supported by this port of CVS"); error (0, errno, "opening from-server logfile %s", buf); else from_server = log_buffer_initialize (from_server, fp, 1, - buf_memory_error); + (BUFMEMERRPROC) NULL); free (buf); } @@ -4240,10 +4242,10 @@ the :server: access method is not supported by this port of CVS"); send_to_server ("Kerberos-encrypt\012", 0); to_server = krb_encrypt_buffer_initialize (to_server, 0, sched, kblock, - buf_memory_error); + (BUFMEMERRPROC) NULL); from_server = krb_encrypt_buffer_initialize (from_server, 1, sched, kblock, - buf_memory_error); + (BUFMEMERRPROC) NULL); } else #endif /* HAVE_KERBEROS */ @@ -4255,10 +4257,12 @@ the :server: access method is not supported by this port of CVS"); send_to_server ("Gssapi-encrypt\012", 0); to_server = cvs_gssapi_wrap_buffer_initialize (to_server, 0, gcontext, - buf_memory_error); + ((BUFMEMERRPROC) + NULL)); from_server = cvs_gssapi_wrap_buffer_initialize (from_server, 1, gcontext, - buf_memory_error); + ((BUFMEMERRPROC) + NULL)); cvs_gssapi_encrypt = 1; } else @@ -4283,10 +4287,10 @@ the :server: access method is not supported by this port of CVS"); compressed. */ to_server = compress_buffer_initialize (to_server, 0, gzip_level, - buf_memory_error); + (BUFMEMERRPROC) NULL); from_server = compress_buffer_initialize (from_server, 1, gzip_level, - buf_memory_error); + (BUFMEMERRPROC) NULL); } #ifndef NO_CLIENT_GZIP_PROCESS else if (supported_request ("gzip-file-contents")) @@ -4327,10 +4331,12 @@ the :server: access method is not supported by this port of CVS"); send_to_server ("Gssapi-authenticate\012", 0); to_server = cvs_gssapi_wrap_buffer_initialize (to_server, 0, gcontext, - buf_memory_error); + ((BUFMEMERRPROC) + NULL)); from_server = cvs_gssapi_wrap_buffer_initialize (from_server, 1, gcontext, - buf_memory_error); + ((BUFMEMERRPROC) + NULL)); } else error (1, 0, "Stream authentication is only supported when using GSSAPI"); @@ -5093,7 +5099,7 @@ send_file_names (argc, argv, flags) command line, not the case of the directory in the filesystem. This is correct behavior. */ - entries = Entries_Open (0); + entries = Entries_Open (0, NULL); node = findnode_fn (entries, p); if (node != NULL) { diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h index 119168c..996dc63 100644 --- a/contrib/cvs/src/client.h +++ b/contrib/cvs/src/client.h @@ -2,7 +2,7 @@ /* Stuff shared with the server. */ extern char *mode_to_string PROTO((mode_t)); -extern int change_mode PROTO((char *, char *)); +extern int change_mode PROTO((char *, char *, int)); extern int gzip_level; extern int file_gzip_level; diff --git a/contrib/cvs/src/create_adm.c b/contrib/cvs/src/create_adm.c index c1772b2..c51785c 100644 --- a/contrib/cvs/src/create_adm.c +++ b/contrib/cvs/src/create_adm.c @@ -59,6 +59,12 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn) if (CVS_MKDIR (tmp, 0777) < 0) { + /* We want to print out the entire update_dir, since a lot of + our code calls this function with dir == "." or dir == + NULL. I hope that gives enough information in cases like + absolute pathnames; printing out xgetwd or something would + be way too verbose in the common cases. */ + if (warn) { /* The reason that this is a warning, rather than silently @@ -66,11 +72,14 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn) CVS's behavior to vary subtly based on factors (like directory permissions) which are not made clear to the user. With the warning at least we let them know what is going on. */ - error (0, errno, "warning: cannot make directory %s", tmp); + error (0, errno, "warning: cannot make directory %s in %s", + CVSADM, update_dir); + free (tmp); return 1; } else - error (1, errno, "cannot make directory %s", tmp); + error (1, errno, "cannot make directory %s in %s", + CVSADM, update_dir); } /* record the current cvs root for later use */ diff --git a/contrib/cvs/src/entries.c b/contrib/cvs/src/entries.c index 538cd21..aeab313 100644 --- a/contrib/cvs/src/entries.c +++ b/contrib/cvs/src/entries.c @@ -450,12 +450,15 @@ fputentent(fp, p) } -/* - * Read the entries file into a list, hashing on the file name. - */ +/* Read the entries file into a list, hashing on the file name. + + UPDATE_DIR is the name of the current directory, for use in error + messages, or NULL if not known (that is, noone has gotten around + to updating the caller to pass in the information). */ List * -Entries_Open (aflag) +Entries_Open (aflag, update_dir) int aflag; + char *update_dir; { List *entries; struct stickydirtag *sdtp = NULL; @@ -492,7 +495,11 @@ Entries_Open (aflag) fpin = CVS_FOPEN (CVSADM_ENT, "r"); if (fpin == NULL) + { + if (update_dir != NULL) + error (0, 0, "in directory %s:", update_dir); error (0, errno, "cannot open %s for reading", CVSADM_ENT); + } else { while ((ent = fgetentent (fpin, (char *) NULL, &sawdir)) != NULL) @@ -797,9 +804,22 @@ Subdirs_Known (entries) if (!noexec) { /* Create Entries.Log so that Entries_Close will do something. */ - fp = open_file (CVSADM_ENTLOG, "a"); - if (fclose (fp) == EOF) - error (1, errno, "cannot close %s", CVSADM_ENTLOG); + fp = CVS_FOPEN (CVSADM_ENTLOG, "a"); + if (fp == NULL) + { + int save_errno = errno; + + /* As in subdir_record, just silently skip the whole thing + if there is no CVSADM directory. */ + if (! isdir (CVSADM)) + return; + error (1, save_errno, "cannot open %s", entfilename); + } + else + { + if (fclose (fp) == EOF) + error (1, errno, "cannot close %s", CVSADM_ENTLOG); + } } } } diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c index b5121a7..0ccc3df 100644 --- a/contrib/cvs/src/filesubr.c +++ b/contrib/cvs/src/filesubr.c @@ -43,46 +43,66 @@ copy_file (from, to) if (noexec) return; - if ((fdin = open (from, O_RDONLY)) < 0) - error (1, errno, "cannot open %s for copying", from); - if (fstat (fdin, &sb) < 0) - error (1, errno, "cannot fstat %s", from); - if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) - error (1, errno, "cannot create %s for copying", to); - if (sb.st_size > 0) + /* If the file to be copied is a link or a device, then just create + the new link or device appropriately. */ + if (islink (from)) { - char buf[BUFSIZ]; - int n; + char *source = xreadlink (from); + symlink (source, to); + free (source); + return; + } - for (;;) + if (isdevice (from)) + { + if (stat (from, &sb) < 0) + error (1, errno, "cannot stat %s", from); + mknod (to, sb.st_mode, sb.st_rdev); + } + else + { + /* Not a link or a device... probably a regular file. */ + if ((fdin = open (from, O_RDONLY)) < 0) + error (1, errno, "cannot open %s for copying", from); + if (fstat (fdin, &sb) < 0) + error (1, errno, "cannot fstat %s", from); + if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) + error (1, errno, "cannot create %s for copying", to); + if (sb.st_size > 0) { - n = read (fdin, buf, sizeof(buf)); - if (n == -1) + char buf[BUFSIZ]; + int n; + + for (;;) { + n = read (fdin, buf, sizeof(buf)); + if (n == -1) + { #ifdef EINTR - if (errno == EINTR) - continue; + if (errno == EINTR) + continue; #endif - error (1, errno, "cannot read file %s for copying", from); - } - else if (n == 0) - break; - - if (write(fdout, buf, n) != n) { - error (1, errno, "cannot write file %s for copying", to); + error (1, errno, "cannot read file %s for copying", from); + } + else if (n == 0) + break; + + if (write(fdout, buf, n) != n) { + error (1, errno, "cannot write file %s for copying", to); + } } - } #ifdef HAVE_FSYNC - if (fsync (fdout)) - error (1, errno, "cannot fsync file %s after copying", to); + if (fsync (fdout)) + error (1, errno, "cannot fsync file %s after copying", to); #endif - } + } - if (close (fdin) < 0) - error (0, errno, "cannot close %s", from); - if (close (fdout) < 0) - error (1, errno, "cannot close %s", to); + if (close (fdin) < 0) + error (0, errno, "cannot close %s", from); + if (close (fdout) < 0) + error (1, errno, "cannot close %s", to); + } /* now, set the times for the copied file to match those of the original */ memset ((char *) &t, 0, sizeof (t)); @@ -119,7 +139,7 @@ islink (file) #ifdef S_ISLNK struct stat sb; - if (lstat (file, &sb) < 0) + if (CVS_LSTAT (file, &sb) < 0) return (0); return (S_ISLNK (sb.st_mode)); #else @@ -128,6 +148,29 @@ islink (file) } /* + * Returns non-zero if the argument file is a block or + * character special device. + */ +int +isdevice (file) + const char *file; +{ + struct stat sb; + + if (CVS_LSTAT (file, &sb) < 0) + return (0); +#ifdef S_ISBLK + if (S_ISBLK (sb.st_mode)) + return 1; +#endif +#ifdef S_ISCHR + if (S_ISCHR (sb.st_mode)) + return 1; +#endif + return 0; +} + +/* * Returns non-zero if the argument file exists. */ int @@ -298,6 +341,9 @@ mkdir_if_needed (name) /* * Change the mode of a file, either adding write permissions, or removing * all write permissions. Either change honors the current umask setting. + * + * Don't do anything if PreservePermissions is set to `yes'. This may + * have unexpected consequences for some uses of xchmod. */ void xchmod (fname, writable) @@ -307,6 +353,9 @@ xchmod (fname, writable) struct stat sb; mode_t mode, oumask; + if (preserve_perms) + return; + if (stat (fname, &sb) < 0) { if (!noexec) @@ -417,6 +466,8 @@ int unlink_file_dir (f) const char *f; { + struct stat sb; + if (trace #ifdef SERVER_SUPPORT /* This is called by the server parent process in contexts where @@ -433,20 +484,23 @@ unlink_file_dir (f) /* For at least some unices, if root tries to unlink() a directory, instead of doing something rational like returning EISDIR, the system will gleefully go ahead and corrupt the filesystem. - So we first call isdir() to see if it is OK to call unlink(). This + So we first call stat() to see if it is OK to call unlink(). This doesn't quite work--if someone creates a directory between the - call to isdir() and the call to unlink(), we'll still corrupt + call to stat() and the call to unlink(), we'll still corrupt the filesystem. Where is the Unix Haters Handbook when you need it? */ - if (isdir(f)) - return deep_remove_dir(f); - else + if (stat (f, &sb) < 0) { - if (unlink (f) != 0) + if (existence_error (errno)) + { + /* The file or directory doesn't exist anyhow. */ return -1; + } } - /* We were able to remove the file from the disk */ - return 0; + else if (S_ISDIR (sb.st_mode)) + return deep_remove_dir (f); + + return unlink (f); } /* Remove a directory and everything it contains. Returns 0 for @@ -557,6 +611,8 @@ block_read (fd, buf, nchars) /* * Compare "file1" to "file2". Return non-zero if they don't compare exactly. + * If FILE1 and FILE2 are special files, compare their salient characteristics + * (i.e. major/minor device numbers, links, etc. */ int xcmp (file1, file2) @@ -568,14 +624,42 @@ xcmp (file1, file2) int fd1, fd2; int ret; + if (CVS_LSTAT (file1, &sb1) < 0) + error (1, errno, "cannot lstat %s", file1); + if (CVS_LSTAT (file2, &sb2) < 0) + error (1, errno, "cannot lstat %s", file2); + + /* If FILE1 and FILE2 are not the same file type, they are unequal. */ + if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT)) + return 1; + + /* If FILE1 and FILE2 are symlinks, they are equal if they point to + the same thing. */ + if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode)) + { + int result; + buf1 = xreadlink (file1); + buf2 = xreadlink (file2); + result = (strcmp (buf1, buf2) == 0); + free (buf1); + free (buf2); + return result; + } + + /* If FILE1 and FILE2 are devices, they are equal if their device + numbers match. */ + if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode)) + { + if (sb1.st_rdev == sb2.st_rdev) + return 0; + else + return 1; + } + if ((fd1 = open (file1, O_RDONLY)) < 0) error (1, errno, "cannot open file %s for comparing", file1); if ((fd2 = open (file2, O_RDONLY)) < 0) error (1, errno, "cannot open file %s for comparing", file2); - if (fstat (fd1, &sb1) < 0) - error (1, errno, "cannot fstat %s", file1); - if (fstat (fd2, &sb2) < 0) - error (1, errno, "cannot fstat %s", file2); /* A generic file compare routine might compare st_dev & st_ino here to see if the two files being compared are actually the same file. @@ -677,6 +761,39 @@ isabsolute (filename) return filename[0] == '/'; } +/* + * Return a string (dynamically allocated) with the name of the file to which + * LINK is symlinked. + */ +char * +xreadlink (link) + const char *link; +{ + char *file = NULL; + int buflen = BUFSIZ; + + if (!islink (link)) + return NULL; + + /* Get the name of the file to which `from' is linked. + FIXME: what portability issues arise here? Are readlink & + ENAMETOOLONG defined on all systems? -twp */ + do + { + file = xrealloc (file, buflen); + errno = 0; + readlink (link, file, buflen); + buflen *= 2; + } + while (errno == ENAMETOOLONG); + + if (errno) + error (1, errno, "cannot readlink %s", link); + + return file; +} + + /* Return a pointer into PATH's last component. */ char * @@ -684,8 +801,8 @@ last_component (path) char *path; { char *last = strrchr (path, '/'); - - if (last) + + if (last && (last != path)) return last + 1; else return path; diff --git a/contrib/cvs/src/find_names.c b/contrib/cvs/src/find_names.c index ed6c5c4..4fa795a 100644 --- a/contrib/cvs/src/find_names.c +++ b/contrib/cvs/src/find_names.c @@ -50,18 +50,6 @@ add_entries_proc (node, closure) return (0); } -/* - * compare two files list node (for sort) - */ -static int fsortcmp PROTO ((const Node *, const Node *)); -static int -fsortcmp (p, q) - const Node *p; - const Node *q; -{ - return (strcmp (p->key, q->key)); -} - List * Find_Names (repository, which, aflag, optentries) char *repository; @@ -79,7 +67,7 @@ Find_Names (repository, which, aflag, optentries) if (which & W_LOCAL) { /* parse the entries file (if it exists) */ - entries = Entries_Open (aflag); + entries = Entries_Open (aflag, NULL); if (entries != NULL) { /* walk the entries file adding elements to the files list */ @@ -182,7 +170,7 @@ Find_Directories (repository, which, entries) if (entries != NULL) tmpentries = entries; else if (isfile (CVSADM_ENT)) - tmpentries = Entries_Open (0); + tmpentries = Entries_Open (0, NULL); else tmpentries = NULL; diff --git a/contrib/cvs/src/hardlink.c b/contrib/cvs/src/hardlink.c new file mode 100644 index 0000000..51bd2a6 --- /dev/null +++ b/contrib/cvs/src/hardlink.c @@ -0,0 +1,298 @@ +/* This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. */ + +/* Collect and manage hardlink info associated with a particular file. */ + +#include "cvs.h" +#include "hardlink.h" + +/* The structure currently used to manage hardlink info is a list. + Therefore, most of the functions which manipulate hardlink data + are walklist procedures. This is not a very efficient implementation; + if someone decides to use a real hash table (for instance), then + much of this code can be rewritten to be a little less arcane. + + Each element of `hardlist' represents an inode. It is keyed on the + inode number, and points to a list of files. This is to make it + easy to find out what files are linked to a given file FOO: find + FOO's inode, look it up in hardlist, and retrieve the list of files + associated with that inode. + + Each file node, in turn, is represented by a `hardlink_info' struct, + which includes `status' and `links' fields. The `status' field should + be used by a procedure like commit_fileproc or update_fileproc to + record each file's status; that way, after all file links have been + recorded, CVS can check the linkage of files which are in doubt + (i.e. T_NEEDS_MERGE files). + + TODO: a diagram of an example hardlist would help here. */ + +/* TODO: change this to something with a marginal degree of + efficiency, like maybe a hash table. Yeah. */ + +List *hardlist; /* Record hardlink information for working files */ +char *working_dir; /* The top-level working directory, used for + constructing full pathnames. */ + +/* For check_link_proc: list all of the files named in an inode list. */ +static int +list_files_proc (node, vstrp) + Node *node; + void *vstrp; +{ + char **strp, *file; + int len; + + /* Get the file's basename. This is because -- VERY IMPORTANT -- + the `hardlinks' field is presently defined only to include links + within a directory. So the hardlinks field might be `foo' or + `mumble grump flink', but not `foo bar com/baz' or `wham ../bam + ../thank/you'. Someday it would be nice to extend this to + permit cross-directory links, but the issues involved are + hideous. */ + + file = strrchr (node->key, '/'); + if (file) + ++file; + else + file = node->key; + + /* Is it safe to cast vstrp to (char **) here, and then play with + the contents? I think so, since vstrp will have started out + a char ** to begin with, so we should not have alignment bugs. */ + strp = (char **) vstrp; + len = (*strp == NULL ? 0 : strlen (*strp)); + *strp = (char *) xrealloc (*strp, len + strlen (file) + 2); + if (*strp == NULL) + { + error (0, errno, "could not allocate memory"); + return 1; + } + if (sprintf (*strp + len, "%s ", file) < 0) + { + error (0, errno, "could not compile file list"); + return 1; + } + + return 0; +} + +/* Set the link field of each hardlink_info node to `data', which is a + list of linked files. */ +static int +set_hardlink_field_proc (node, data) + Node *node; + void *data; +{ + struct hardlink_info *hlinfo = (struct hardlink_info *) node->data; + hlinfo->links = xstrdup ((char *) data); + + return 0; +} + +/* For each file being checked in, compile a list of the files linked + to it, and cache the list in the file's hardlink_info field. */ +int +cache_hardlinks_proc (node, data) + Node *node; + void *data; +{ + List *inode_links; + char *p, *linked_files = NULL; + int err; + + inode_links = (List *) node->data; + + /* inode->data is a list of hardlink_info structures: all the + files linked to this inode. We compile a string of each file + named in this list, in alphabetical order, separated by spaces. + Then store this string in the `links' field of each + hardlink_info structure, so that RCS_checkin can easily add + it to the `hardlinks' field of a new delta node. */ + + sortlist (inode_links, fsortcmp); + err = walklist (inode_links, list_files_proc, &linked_files); + if (err) + return err; + + /* Trim trailing whitespace. */ + p = linked_files + strlen(linked_files) - 1; + while (p > linked_files && isspace (*p)) + *p-- = '\0'; + + err = walklist (inode_links, set_hardlink_field_proc, linked_files); + return err; +} + +/* Return a pointer to FILEPATH's node in the hardlist. This means + looking up its inode, retrieving the list of files linked to that + inode, and then looking up FILE in that list. If the file doesn't + seem to exist, return NULL. */ +Node * +lookup_file_by_inode (filepath) + const char *filepath; +{ + char *inodestr, *file; + struct stat sb; + Node *hp, *p; + + /* Get file's basename, so that we can stat it. */ + file = strrchr (filepath, '/'); + if (file) + ++file; + else + file = (char *) filepath; + + /* inodestr contains the hexadecimal representation of an + inode, so it requires two bytes of text to represent + each byte of the inode number. */ + inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1); + if (stat (file, &sb) < 0) + { + if (errno == ENOENT) + { + /* The file doesn't exist; we may be doing an update on a + file that's been removed. A nonexistent file has no + link information, so return without changing hardlist. */ + free (inodestr); + return NULL; + } + error (1, errno, "cannot stat %s", file); + } + + sprintf (inodestr, "%lx", (unsigned long) sb.st_ino); + + /* Find out if this inode is already in the hardlist, adding + a new entry to the list if not. */ + hp = findnode (hardlist, inodestr); + if (hp == NULL) + { + hp = getnode (); + hp->type = UNKNOWN; + hp->key = inodestr; + hp->data = (char *) getlist(); + hp->delproc = dellist; + (void) addnode (hardlist, hp); + } + else + { + free (inodestr); + } + + p = findnode ((List *) hp->data, filepath); + if (p == NULL) + { + p = getnode(); + p->type = UNKNOWN; + p->key = xstrdup (filepath); + p->data = NULL; + (void) addnode ((List *) hp->data, p); + } + + return p; +} + +/* After a file has been checked out, add a node for it to the hardlist + (if necessary) and mark it as checked out. */ +void +update_hardlink_info (file) + const char *file; +{ + char *path; + Node *n; + struct hardlink_info *hlinfo; + + if (file[0] == '/') + { + path = xstrdup (file); + } + else + { + /* file is a relative pathname; assume it's from the current + working directory. */ + char *dir = xgetwd(); + path = xmalloc (sizeof(char) * (strlen(dir) + strlen(file) + 2)); + sprintf (path, "%s/%s", dir, file); + free (dir); + } + + n = lookup_file_by_inode (path); + if (n == NULL) + { + /* Something is *really* wrong if the file doesn't exist here; + update_hardlink_info should be called only when a file has + just been checked out to a working directory. */ + error (1, 0, "lost hardlink info for %s", file); + } + + if (n->data == NULL) + n->data = (char *) xmalloc (sizeof (struct hardlink_info)); + hlinfo = (struct hardlink_info *) n->data; + hlinfo->status = T_UPTODATE; + hlinfo->checked_out = 1; + hlinfo->links = NULL; +} + +/* Return a string listing all the files known to be linked to FILE in + the working directory. Used by special_file_mismatch, to determine + whether it is safe to merge two files. */ +char * +list_files_linked_to (file) + const char *file; +{ + char *inodestr, *filelist, *path; + struct stat sb; + Node *n; + int err; + + /* If hardlist is NULL, we have not been doing an operation that + would permit us to know anything about the file's hardlinks + (cvs update, cvs commit, etc). Return an empty string. */ + if (hardlist == NULL) + return xstrdup (""); + + /* Get the full pathname of file (assuming the working directory) */ + if (file[0] == '/') + path = xstrdup (file); + else + { + char *dir = xgetwd(); + path = (char *) xmalloc (sizeof(char) * + (strlen(dir) + strlen(file) + 2)); + sprintf (path, "%s/%s", dir, file); + free (dir); + } + + /* We do an extra lookup_file here just to make sure that there + is a node for `path' in the hardlist. If that were not so, + comparing the working directory linkage against the repository + linkage for a file would always fail. */ + (void) lookup_file_by_inode (path); + + if (stat (path, &sb) < 0) + error (1, errno, "cannot stat %s", file); + /* inodestr contains the hexadecimal representation of an + inode, so it requires two bytes of text to represent + each byte of the inode number. */ + inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1); + sprintf (inodestr, "%lx", (unsigned long) sb.st_ino); + + /* Make sure the files linked to this inode are sorted. */ + n = findnode (hardlist, inodestr); + sortlist ((List *) n->data, fsortcmp); + + filelist = NULL; + err = walklist ((List *) n->data, list_files_proc, &filelist); + if (err) + error (1, 0, "cannot get list of hardlinks for %s", file); + + free (inodestr); + return filelist; +} diff --git a/contrib/cvs/src/hardlink.h b/contrib/cvs/src/hardlink.h new file mode 100644 index 0000000..cce3f33 --- /dev/null +++ b/contrib/cvs/src/hardlink.h @@ -0,0 +1,33 @@ +/* This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. */ + +/* Data type definitions and declarations for hardlink management. */ + +/* This file should be #included in CVS source files after cvs.h + since it relies on types and macros defined there. */ + +/* The `checked_out' member of a hardlink_info struct is used only + when files are being checked out or updated. It is used only when + hardlinked files are being checked out. */ + +struct hardlink_info +{ + Ctype status; /* as returned from Classify_File() */ + int checked_out; /* has this file been checked out lately? */ + char *links; /* contents of `hardlinks' RCS field */ +}; + +extern List *hardlist; +extern char *working_dir; + +int cache_hardlinks_proc PROTO ((Node *, void *)); +Node *lookup_file_by_inode PROTO ((const char *)); +void update_hardlink_info PROTO ((const char *)); +char *list_files_linked_to PROTO ((const char *)); diff --git a/contrib/cvs/src/hash.c b/contrib/cvs/src/hash.c index ff3f122..af000ac 100644 --- a/contrib/cvs/src/hash.c +++ b/contrib/cvs/src/hash.c @@ -436,6 +436,17 @@ sortlist (list, comp) free (array); } +/* + * compare two files list node (for sort) + */ +int +fsortcmp (p, q) + const Node *p; + const Node *q; +{ + return (strcmp (p->key, q->key)); +} + /* Debugging functions. Quite useful to call from within gdb. */ static char *nodetypestring PROTO ((Ntype)); diff --git a/contrib/cvs/src/hash.h b/contrib/cvs/src/hash.h index d29c757..06867a7 100644 --- a/contrib/cvs/src/hash.h +++ b/contrib/cvs/src/hash.h @@ -56,3 +56,4 @@ void dellist PROTO((List ** listp)); void delnode PROTO((Node * p)); void freenode PROTO((Node * p)); void sortlist PROTO((List * list, int (*)(const Node *, const Node *))); +int fsortcmp PROTO((const Node * p, const Node * q)); diff --git a/contrib/cvs/src/myndbm.c b/contrib/cvs/src/myndbm.c index 949ac78..6b15e77 100644 --- a/contrib/cvs/src/myndbm.c +++ b/contrib/cvs/src/myndbm.c @@ -200,27 +200,34 @@ mydbm_load_file (fp, list) List *list; { char *line = NULL; - size_t line_len; + size_t line_size; char *value; size_t value_allocated; char *cp, *vp; - int len, cont; + int cont; int line_length; value_allocated = 1; value = xmalloc (value_allocated); - for (cont = 0; (line_length = getline (&line, &line_len, fp)) >= 0;) + cont = 0; + while ((line_length = getstr (&line, &line_size, fp, '\012', 0)) >= 0) { - if ((cp = strrchr (line, '\012')) != NULL) - *cp = '\0'; /* strip the newline */ - cp = line + strlen (line); - if (cp > line && cp[-1] == '\015') + if (line_length > 0 && line[line_length - 1] == '\012') + { + /* Strip the newline. */ + --line_length; + line[line_length] = '\0'; + } + if (line_length > 0 && line[line_length - 1] == '\015') + { /* If the file (e.g. modules) was written on an NT box, it will contain CRLF at the ends of lines. Strip them (we can't do this by opening the file in text mode because we might be running on unix). */ - cp[-1] = '\0'; + --line_length; + line[line_length] = '\0'; + } /* * Add the line to the value, at the end if this is a continuation @@ -234,15 +241,15 @@ mydbm_load_file (fp, list) * See if the line we read is a continuation line, and strip the * backslash if so. */ - len = strlen (line); - if (len > 0) - cp = &line[len - 1]; + if (line_length > 0) + cp = &line[line_length - 1]; else cp = line; if (*cp == '\\') { cont = 1; *cp = '\0'; + --line_length; } else { @@ -250,7 +257,7 @@ mydbm_load_file (fp, list) } expand_string (&value, &value_allocated, - strlen (value) + strlen (line) + 5); + strlen (value) + line_length + 5); strcat (value, line); if (value[0] == '#') diff --git a/contrib/cvs/src/no_diff.c b/contrib/cvs/src/no_diff.c index 6d6a6fb..078343e 100644 --- a/contrib/cvs/src/no_diff.c +++ b/contrib/cvs/src/no_diff.c @@ -36,6 +36,13 @@ No_Difference (finfo, vers) if (!vers->srcfile || !vers->srcfile->path) return (-1); /* different since we couldn't tell */ +#ifdef PRESERVE_PERMISSIONS_SUPPORT + /* If special files are in use, then any mismatch of file metadata + information also means that the files should be considered different. */ + if (preserve_perms && special_file_mismatch (finfo, vers->vn_user, NULL)) + return 1; +#endif + if (vers->entdata && vers->entdata->options) options = xstrdup (vers->entdata->options); else diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c index c492be0..a8a1b4a 100644 --- a/contrib/cvs/src/parseinfo.c +++ b/contrib/cvs/src/parseinfo.c @@ -326,6 +326,26 @@ parse_config (cvsroot) goto error_return; } } + else if (strcmp (line, "PreservePermissions") == 0) + { + if (strcmp (p, "no") == 0) + preserve_perms = 0; + else if (strcmp (p, "yes") == 0) + { +#ifdef PRESERVE_PERMISSIONS_SUPPORT + preserve_perms = 1; +#else + error (0, 0, "\ +warning: this CVS does not support PreservePermissions"); +#endif + } + else + { + error (0, 0, "unrecognized value '%s' for PreservePermissions", + p); + goto error_return; + } + } else { /* We may be dealing with a keyword which was added in a diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c index 9d091c3..9f56b62 100644 --- a/contrib/cvs/src/patch.c +++ b/contrib/cvs/src/patch.c @@ -499,23 +499,43 @@ patch_fileproc (callerdat, finfo) ret = 0; goto out2; } + + /* Create 3 empty files. I'm not really sure there is any advantage + to doing so now rather than just waiting until later. */ tmpfile1 = cvs_temp_name (); - if ((fp1 = CVS_FOPEN (tmpfile1, "w+")) != NULL) - (void) fclose (fp1); + fp1 = CVS_FOPEN (tmpfile1, "w+"); + if (fp1 == NULL) + { + error (0, errno, "cannot create temporary file %s", tmpfile1); + ret = 1; + goto out; + } + else + if (fclose (fp1) < 0) + error (0, errno, "warning: cannot close %s", tmpfile1); tmpfile2 = cvs_temp_name (); - if ((fp2 = CVS_FOPEN (tmpfile2, "w+")) != NULL) - (void) fclose (fp2); + fp2 = CVS_FOPEN (tmpfile2, "w+"); + if (fp2 == NULL) + { + error (0, errno, "cannot create temporary file %s", tmpfile2); + ret = 1; + goto out; + } + else + if (fclose (fp2) < 0) + error (0, errno, "warning: cannot close %s", tmpfile2); tmpfile3 = cvs_temp_name (); - if ((fp3 = CVS_FOPEN (tmpfile3, "w+")) != NULL) - (void) fclose (fp3); - if (fp1 == NULL || fp2 == NULL || fp3 == NULL) + fp3 = CVS_FOPEN (tmpfile3, "w+"); + if (fp3 == NULL) { - /* FIXME: should be printing a proper error message, with errno-based - message, and the filename which we could not create. */ - error (0, 0, "cannot create temporary files"); + error (0, errno, "cannot create temporary file %s", tmpfile3); ret = 1; goto out; } + else + if (fclose (fp3) < 0) + error (0, errno, "warning: cannot close %s", tmpfile3); + if (vers_tag != NULL) { retcode = RCS_checkout (rcsfile, (char *) NULL, vers_tag, @@ -523,9 +543,8 @@ patch_fileproc (callerdat, finfo) (RCSCHECKOUTPROC) NULL, (void *) NULL); if (retcode != 0) { - if (!really_quiet) - error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0, - "co of revision %s in %s failed", vers_tag, rcs); + error (0, 0, + "cannot check out revision %s of %s", vers_tag, rcs); ret = 1; goto out; } @@ -548,9 +567,8 @@ patch_fileproc (callerdat, finfo) (RCSCHECKOUTPROC) NULL, (void *) NULL); if (retcode != 0) { - if (!really_quiet) - error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0, - "co of revision %s in %s failed", vers_head, rcs); + error (0, 0, + "cannot check out revision %s of %s", vers_head, rcs); ret = 1; goto out; } @@ -584,10 +602,16 @@ patch_fileproc (callerdat, finfo) if (getline (&line1, &line1_chars_allocated, fp) < 0 || getline (&line2, &line2_chars_allocated, fp) < 0) { - error (0, errno, "failed to read diff file header %s for %s", - tmpfile3, rcs); + if (feof (fp)) + error (0, 0, "\ +failed to read diff file header %s for %s: end of file", tmpfile3, rcs); + else + error (0, errno, + "failed to read diff file header %s for %s", + tmpfile3, rcs); ret = 1; - (void) fclose (fp); + if (fclose (fp) < 0) + error (0, errno, "error closing %s", tmpfile3); goto out; } if (!unidiff) @@ -599,7 +623,8 @@ patch_fileproc (callerdat, finfo) { error (0, 0, "invalid diff header for %s", rcs); ret = 1; - (void) fclose (fp); + if (fclose (fp) < 0) + error (0, errno, "error closing %s", tmpfile3); goto out; } } @@ -612,7 +637,8 @@ patch_fileproc (callerdat, finfo) { error (0, 0, "invalid unidiff header for %s", rcs); ret = 1; - (void) fclose (fp); + if (fclose (fp) < 0) + error (0, errno, "error closing %s", tmpfile3); goto out; } } diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh index e407cbd..1d877fe 100755 --- a/contrib/cvs/src/sanity.sh +++ b/contrib/cvs/src/sanity.sh @@ -548,20 +548,29 @@ RCSINIT=; export RCSINIT # tests. if test x"$*" = x; then + # Basic/miscellaneous functionality tests="basica basicb basicc basic1 deep basic2" - tests="${tests} rdiff death death2 branches" + # Branching, tagging, removing, adding, multiple directories + tests="${tests} rdiff death death2 branches branches2" tests="${tests} rcslib multibranch import importb join join2 join3" tests="${tests} new newb conflicts conflicts2 conflicts3" + # Checking out various places (modules, checkout -d, &c) tests="${tests} modules modules2 modules3 modules4" + tests="${tests} cvsadm abspath toplevel" + # Log messages, error messages. tests="${tests} mflag editor errmsg1 errmsg2" + # Watches, binary files, history browsing, &c. tests="${tests} devcom devcom2 devcom3 watch4" tests="${tests} ignore binfiles binfiles2 mcopy binwrap binwrap2" tests="${tests} binwrap3 mwrap info config" tests="${tests} serverpatch log log2 ann crerepos rcs big modes stamps" + # More tag and branch tests, keywords. tests="${tests} sticky keyword keywordlog" - tests="${tests} toplevel head tagdate multibranch2" + tests="${tests} head tagdate multibranch2" + # "cvs admin", reserved checkouts. tests="${tests} admin reserved" - tests="${tests} cvsadm diffmerge1 diffmerge2" + # Nuts and bolts of diffing/merging (diff library, &c) + tests="${tests} diffmerge1 diffmerge2" else tests="$*" fi @@ -1903,20 +1912,21 @@ done" # interrupt, while we've got a clean 1.1 here, let's import it # into a couple of other modules. cd export-dir - dotest 56 "${testcvs} import -m first-import second-dir first-immigration immigration1 immigration1_0" \ -"N second-dir/file14 -N second-dir/file6 -N second-dir/file7 -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1 -N second-dir/dir1/file14 -N second-dir/dir1/file6 -N second-dir/dir1/file7 -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1/dir2 + dotest_sort 56 "${testcvs} import -m first-import second-dir first-immigration immigration1 immigration1_0" \ +" + N second-dir/dir1/dir2/file14 N second-dir/dir1/dir2/file6 N second-dir/dir1/dir2/file7 - -No conflicts created by this import" +N second-dir/dir1/file14 +N second-dir/dir1/file6 +N second-dir/dir1/file7 +N second-dir/file14 +N second-dir/file6 +N second-dir/file7 +No conflicts created by this import +${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1 +${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1/dir2" cd .. if ${CVS} export -r HEAD second-dir ; then @@ -2532,11 +2542,13 @@ U first-dir/file3' cd first-dir - # Add a file on the trunk. + # Add two files on the trunk. echo "first revision" > file1 - dotest death2-2 "${testcvs} add file1" \ + echo "file4 first revision" > file4 + dotest death2-2 "${testcvs} add file1 file4" \ "${PROG}"' [a-z]*: scheduling file `file1'\'' for addition -'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' +'"${PROG}"' [a-z]*: scheduling file `file4'\'' for addition +'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently' dotest death2-3 "${testcvs} -q commit -m add" \ "RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v @@ -2544,11 +2556,21 @@ done Checking in file1; ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 initial revision: 1\.1 +done +RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +done +Checking in file4; +${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +initial revision: 1\.1 done" # Make a branch and a non-branch tag. - dotest death2-4 "${testcvs} -q tag -b branch" 'T file1' - dotest death2-5 "${testcvs} -q tag tag" 'T file1' + dotest death2-4 "${testcvs} -q tag -b branch" \ +'T file1 +T file4' + dotest death2-5 "${testcvs} -q tag tag" \ +'T file1 +T file4' # Switch over to the branch. dotest death2-6 "${testcvs} -q update -r branch" '' @@ -2659,8 +2681,20 @@ ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 done" + # Delete file4 from the branch + dotest death2-10a "${testcvs} rm -f file4" \ +"${PROG} [a-z]*: scheduling .file4. for removal +${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" + dotest death2-10b "${testcvs} -q ci -m removed" \ +"Removing file4; +${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.1\.2 +done" + # Back to the trunk. - dotest death2-11 "${testcvs} -q update -A" 'U file1' 'P file1' + dotest death2-11 "${testcvs} -q update -A" \ +"[UP] file1 +U file4" # Add another file on the trunk. echo "first revision" > file2 @@ -2675,15 +2709,22 @@ ${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 initial revision: 1\.1 done" + # Modify file4 on the trunk. + echo "new file4 revision" > file4 + dotest death2-13a "${testcvs} -q commit -m mod" \ +"Checking in file4; +${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +new revision: 1\.2; previous revision: 1\.1 +done" + # Back to the branch. # The ``no longer in the repository'' message doesn't really # look right to me, but that's what CVS currently prints for # this case. dotest death2-14 "${testcvs} -q update -r branch" \ -"U file1 -${PROG} [a-z]*: file2 is no longer in the repository" \ -"P file1 -${PROG} [a-z]*: file2 is no longer in the repository" +"[UP] file1 +${PROG} [a-z]*: file2 is no longer in the repository +${PROG} [a-z]*: warning: file4 is not (any longer) pertinent" # Add a file on the branch with the same name. echo "branch revision" > file2 @@ -2740,7 +2781,8 @@ diff -c -r1\.1 -r1\.1\.2\.2 --- 1 ---- ! second revision ${PROG} [a-z]*: tag tag is not in file file2 -${PROG} [a-z]*: tag tag is not in file file3" +${PROG} [a-z]*: tag tag is not in file file3 +${PROG} [a-z]*: file4 no longer exists, no comparison available" dotest_fail death2-diff-12 "${testcvs} -q diff -rtag -c -N ." \ "Index: file1 @@ -2775,16 +2817,24 @@ diff -N file3 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 0 \*\*\*\* --- 1 ---- -${PLUS} first revision" +${PLUS} first revision +Index: file4 +=================================================================== +RCS file: file4 +diff -N file4 +\*\*\* ${tempname}[ ][ ]*[a-zA-Z0-9: ]* +--- /dev/null[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file4 first revision +--- 0 ----" # Switch to the nonbranch tag. dotest death2-19 "${testcvs} -q update -r tag" \ -"U file1 -${PROG} [a-z]*: file2 is no longer in the repository -${PROG} [a-z]*: file3 is no longer in the repository" \ -"P file1 +"[UP] file1 ${PROG} [a-z]*: file2 is no longer in the repository -${PROG} [a-z]*: file3 is no longer in the repository" +${PROG} [a-z]*: file3 is no longer in the repository +U file4" dotest_fail death2-20 "test -f file2" @@ -3036,6 +3086,272 @@ done" rm -r first-dir ;; + branches2) + # More branch tests. + # Test that when updating a new subdirectory in a directory + # which was checked out on a branch, the new subdirectory is + # created on the appropriate branch. Test this when joining + # as well. + + mkdir ${CVSROOT_DIRNAME}/first-dir + mkdir trunk; cd trunk + + # Create a file. + dotest branches2-1 "${testcvs} -q co first-dir" + cd first-dir + echo "file1 first revision" > file1 + dotest branches2-2 "${testcvs} add file1" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + dotest branches2-3 "${testcvs} commit -m add file1" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done" + + # Tag the file. + dotest branches2-4 "${testcvs} -q tag tag1" 'T file1' + + # Make two branches. + dotest branches2-5 "${testcvs} -q rtag -b -r tag1 b1 first-dir" '' + dotest branches2-6 "${testcvs} -q rtag -b -r tag1 b2 first-dir" '' + + # Create some files and a subdirectory on branch b1. + cd ../.. + mkdir b1; cd b1 + dotest branches2-7 "${testcvs} -q co -r b1 first-dir" \ +"U first-dir/file1" + cd first-dir + echo "file2 first revision" > file2 + dotest branches2-8 "${testcvs} add file2" \ +"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition on branch `b1'\'' +'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' + mkdir dir1 + dotest branches2-9 "${testcvs} add dir1" \ +"Directory ${TESTDIR}/cvsroot/first-dir/dir1 added to the repository +--> Using per-directory sticky tag "'`'"b1'" + echo "file3 first revision" > dir1/file3 + dotest branches2-10 "${testcvs} add dir1/file3" \ +"${PROG}"' [a-z]*: scheduling file `dir1/file3'\'' for addition on branch `b1'\'' +'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' + dotest branches2-11 "${testcvs} -q ci -madd ." \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file2,v +done +Checking in file2; +${TESTDIR}/cvsroot/first-dir/Attic/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done +RCS file: ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v +done +Checking in dir1/file3; +${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done" + + # Check out the second branch, and update the working + # directory to the first branch, to make sure the right + # happens with dir1. + cd ../.. + mkdir b2; cd b2 + dotest branches2-12 "${testcvs} -q co -r b2 first-dir" \ +'U first-dir/file1' + cd first-dir + dotest branches2-13 "${testcvs} update -d -r b1 dir1" \ +"${PROG} [a-z]*: Updating dir1 +U dir1/file3" + dotest branches2-14 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Sticky Tag: b2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v + Sticky Tag: b1 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + + # FIXME: Just clobbering the directory like this is a bit + # tacky, although people generally expect it to work. Maybe + # we should release it instead. We do it a few other places + # below as well. + rm -r dir1 + dotest branches2-15 "${testcvs} update -d -j b1 dir1" \ +"${PROG} [a-z]*: Updating dir1 +U dir1/file3" + # FIXCVS: The `No revision control file' stuff seems to be + # CVS's way of telling us that we're adding the file on a + # branch, and the file is not on that branch yet. This + # should be nicer. + dotest branches2-16 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Sticky Tag: b2 (branch: 1\.1\.4) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: b2 - MISSING from RCS file! + Sticky Date: (none) + Sticky Options: (none)" + + cd ../../trunk/first-dir + dotest branches2-17 "${testcvs} update -d -P dir1" \ +"${PROG} [a-z]*: Updating dir1" + dotest_fail branches2-18 "test -d dir1" + dotest branches2-19 "${testcvs} update -d -P -r b1 dir1" \ +"${PROG} [a-z]*: Updating dir1 +U dir1/file3" + dotest branches2-20 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Up-to-date + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v + Sticky Tag: b1 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + + rm -r dir1 + dotest branches2-21 "${testcvs} update -d -P -j b1 dir1" \ +"${PROG} [a-z]*: Updating dir1 +U dir1/file3" + dotest branches2-22 "${testcvs} -q status" \ +"=================================================================== +File: file1 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file3 Status: Locally Added + + Working revision: New file! + Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + cd ../.. + rm -r b1 b2 + + # Check out branch b1 twice. Crate a new directory in one + # working directory, then do a cvs update in the other + # working directory and see if the tags are right. + mkdir b1a + mkdir b1b + cd b1b + dotest branches2-23 "${testcvs} -q co -r b1 first-dir" \ +'U first-dir/file1 +U first-dir/file2 +U first-dir/dir1/file3' + cd ../b1a + dotest branches2-24 "${testcvs} -q co -r b1 first-dir" \ +'U first-dir/file1 +U first-dir/file2 +U first-dir/dir1/file3' + cd first-dir + mkdir dir2 + dotest branches2-25 "${testcvs} add dir2" \ +"Directory ${TESTDIR}/cvsroot/first-dir/dir2 added to the repository +--> Using per-directory sticky tag "'`'"b1'" + echo "file4 first revision" > dir2/file4 + dotest branches2-26 "${testcvs} add dir2/file4" \ +"${PROG}"' [a-z]*: scheduling file `dir2/file4'\'' for addition on branch `b1'\'' +'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' + dotest branches2-27 "${testcvs} -q commit -madd" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/dir2/Attic/file4,v +done +Checking in dir2/file4; +${TESTDIR}/cvsroot/first-dir/dir2/Attic/file4,v <-- file4 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done" + + cd ../../b1b/first-dir + dotest branches2-28 "${testcvs} update -d dir2" \ +"${PROG} [a-z]*: Updating dir2 +U dir2/file4" + cd dir2 + dotest branches2-29 "${testcvs} -q status" \ +"=================================================================== +File: file4 Status: Up-to-date + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/dir2/Attic/file4,v + Sticky Tag: b1 (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + dotest branches2-30 "cat CVS/Tag" 'Tb1' + + # Test update -A on a subdirectory + cd .. + rm -r dir2 + dotest branches2-31 "${testcvs} update -A -d dir2" \ +"${PROG} [a-z]*: Updating dir2" + cd dir2 + dotest branches2-32 "${testcvs} -q status" '' + dotest_fail branches2-33 "test -f CVS/Tag" + + # Add a file on the trunk. + echo "file5 first revision" > file5 + dotest branches2-34 "${testcvs} add file5" \ +"${PROG}"' [a-z]*: scheduling file `file5'\'' for addition +'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' + dotest branches2-35 "${testcvs} -q commit -madd" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/dir2/file5,v +done +Checking in file5; +${TESTDIR}/cvsroot/first-dir/dir2/file5,v <-- file5 +initial revision: 1\.1 +done" + + cd ../../../trunk/first-dir + dotest branches2-36 "${testcvs} -q update -d dir2" 'U dir2/file5' + cd dir2 + dotest branches2-37 "${testcvs} -q status" \ +"=================================================================== +File: file5 Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/dir2/file5,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + dotest_fail branches2-38 "test -f CVS/status" + + cd ../../.. + rm -rf ${CVSROOT_DIRNAME}/first-dir + rm -r trunk b1a b1b + ;; + rcslib) # Test librarification of RCS. # First: test whether `cvs diff' handles $Name expansion @@ -3567,11 +3883,12 @@ rev 2 of file 2 cd imp-dir echo 'OpenMunger sources' >file1 echo 'OpenMunger sources' >file2 - dotest importb-1 \ + dotest_sort importb-1 \ "${testcvs} import -m add first-dir openmunger openmunger-1_0" \ -"N first-dir/file1 -N first-dir/file2 +" +N first-dir/file1 +N first-dir/file2 No conflicts created by this import" cd .. rm -r imp-dir @@ -3583,15 +3900,16 @@ No conflicts created by this import" echo 'FreeMunger sources' >file2 # Not completely sure how the conflict detection is supposed to # be working here (haven't really thought about it). - dotest importb-2 \ + dotest_sort importb-2 \ "${testcvs} import -m add -b 1.1.3 first-dir freemunger freemunger-1_0" \ -"C first-dir/file1 -C first-dir/file2 +" -2 conflicts created by this import. -Use the following command to help the merge: - ${PROG} checkout -jfreemunger:yesterday -jfreemunger first-dir" + ${PROG} checkout -jfreemunger:yesterday -jfreemunger first-dir +2 conflicts created by this import. +C first-dir/file1 +C first-dir/file2 +Use the following command to help the merge:" cd .. rm -r imp-dir @@ -4920,8 +5238,20 @@ ${PROG} [a-z]*: warning: file2 is not (any longer) pertinent" # OK, now add a directory to both working directories # and see that CVS doesn't lose its mind. mkdir sdir - dotest conficts3-14 "${testcvs} add sdir" \ + dotest conflicts3-14 "${testcvs} add sdir" \ "Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository" + touch sdir/sfile + dotest conflicts3-14a "${testcvs} add sdir/sfile" \ +"${PROG} [a-z]*: scheduling file .sdir/sfile. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + dotest conflicts3-14b "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/sfile,v +done +Checking in sdir/sfile; +${TESTDIR}/cvsroot/first-dir/sdir/sfile,v <-- sfile +initial revision: 1\.1 +done" + cd ../../2/first-dir # Create a CVS directory without the proper administrative @@ -4946,6 +5276,11 @@ ${PROG} [a-z]*: ignoring sdir (CVS/Repository missing)" dotest conflicts3-16 "${testcvs} -q update" \ "${QUESTION} sdir ${PROG} [a-z]*: ignoring sdir (CVS/Entries missing)" + cd .. + dotest conflicts3-16a "${testcvs} -q update first-dir" \ +"${QUESTION} first-dir/sdir +${PROG} [a-z]*: ignoring first-dir/sdir (CVS/Entries missing)" + cd first-dir fi rm -r sdir @@ -4960,8 +5295,40 @@ ${PROG} [a-z]*: ignoring sdir (CVS/Entries missing)" touch newdir/CVS/Repository dotest conflicts3-19 "${testcvs} -q update" \ "${PROG} [a-z]*: ignoring newdir (CVS/Entries missing)" + cd .. + dotest conflicts3-20 "${testcvs} -q update first-dir" \ +"${PROG} [a-z]*: ignoring first-dir/newdir (CVS/Entries missing)" + cd first-dir rm -r newdir + # The previous tests have left CVS/Entries in something of a mess. + # While we "should" be able to deal with that (maybe), for now + # we just start over. + cd .. + rm -r first-dir + dotest conflicts3-20a "${testcvs} -q co -l first-dir" '' + cd first-dir + + dotest conflicts3-21 "${testcvs} -q update -d sdir" "U sdir/sfile" + rm -r sdir/CVS + dotest conflicts3-22 "${testcvs} -q update" "? sdir" + if test "x$remote" = xyes; then + # It isn't particularly swift that CVS prints this + # "cannot open CVS/Entries" where it has already printed + # "? sdir". At least I don't think so. But do note: (1) + # non-fatal error, and (2) tells us which directory has + # the problem. + dotest_fail conflicts3-23 "${testcvs} -q update -PdA" \ +"${QUESTION} sdir +${PROG} update: in directory sdir: +${PROG} update: cannot open CVS/Entries for reading: No such file or directory +${PROG} update: move away sdir/sfile; it is in the way +C sdir/sfile" + else + dotest conflicts3-23 "${testcvs} -q update -PdA" \ +"${QUESTION} sdir" + fi + cd ../.. rm -r 1 2 @@ -4970,6 +5337,17 @@ ${PROG} [a-z]*: ignoring sdir (CVS/Entries missing)" modules) # Tests of various ways to define and use modules. + # Roadmap to various modules tests: + # -a: + # error on incorrect placement: modules + # error combining with other options: modules2-a* + # use to specify a file more than once: modules3 + # use with ! feature: modules4 + # regular modules: modules, modules2, cvsadm + # ampersand modules: modules2 + # -s: modules. + # -d: modules, modules3, cvsadm + # slashes in module names: modules3 ############################################################ # These tests are to make sure that administrative files get @@ -5805,6 +6183,1652 @@ add-it rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + cvsadm) + # These test check the content of CVS' administrative + # files as they are checked out in various configurations. + # (As a side note, I'm not using the "-q" flag in any of + # this code, which should provide some extra checking for + # those messages which don't seem to be checked thoroughly + # anywhere else.) To do a thorough test, we need to make + # a bunch of modules in various configurations. + # + # <1mod> is a directory at the top level of cvsroot + # ``foo bar'' + # <2mod> is a directory at the second level of cvsroot + # ``foo bar/baz'' + # <1d1mod> is a directory at the top level which is + # checked out into another directory + # ``foo -d bar baz'' + # <1d2mod> is a directory at the second level which is + # checked out into another directory + # ``foo -d bar baz/quux'' + # <2d1mod> is a directory at the top level which is + # checked out into a directory that is two deep + # ``foo -d bar/baz quux'' + # <2d2mod> is a directory at the second level which is + # checked out into a directory that is two deep + # ``foo -d bar/baz quux'' + # + # The tests do each of these types separately and in twos. + # We also repeat each test -d flag for 1-deep and 2-deep + # directories. + # + # Each test should check the output for the Repository + # file, since that is the one which varies depending on + # the directory and how it was checked out. + # + # Yes, this is verbose, but at least it's very thorough. + + # convenience variables + REP=${CVSROOT} + + # First, check out the modules file and edit it. + mkdir 1; cd 1 + dotest cvsadm-1 "${testcvs} co CVSROOT/modules" \ +"U CVSROOT/modules" + + # Try to determine whether RELATIVE_REPOS is defined + # so that we can make the following a lot less + # verbose. + + echo "${CVSROOT_DIRNAME}/." > ${TESTDIR}/dotest.abs + echo "." > ${TESTDIR}/dotest.rel + if cmp ${TESTDIR}/dotest.abs CVS/Repository >/dev/null 2>&1; then + AREP="${CVSROOT_DIRNAME}/" + elif cmp ${TESTDIR}/dotest.rel CVS/Repository >/dev/null 2>&1; then + AREP="" + else + fail "Cannot figure out if RELATIVE_REPOS is defined." + fi + + # Test CVS/Root once. Since there is only one part of + # the code which writes CVS/Root files (Create_Admin), + # there is no point in testing this every time. + dotest cvsadm-1a "cat CVS/Root" ${REP} + dotest cvsadm-1b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-1c "cat CVSROOT/CVS/Root" ${REP} + dotest cvsadm-1d "cat CVSROOT/CVS/Repository" \ +"${AREP}CVSROOT" + # All of the defined module names begin with a number. + # All of the top-level directory names begin with "dir". + # All of the subdirectory names begin with "sub". + # All of the top-level modules begin with "mod". + echo "# Module defs for cvsadm tests" > CVSROOT/modules + echo "1mod mod1" >> CVSROOT/modules + echo "1mod-2 mod1-2" >> CVSROOT/modules + echo "2mod mod2/sub2" >> CVSROOT/modules + echo "2mod-2 mod2-2/sub2-2" >> CVSROOT/modules + echo "1d1mod -d dir1d1 mod1" >> CVSROOT/modules + echo "1d1mod-2 -d dir1d1-2 mod1-2" >> CVSROOT/modules + echo "1d2mod -d dir1d2 mod2/sub2" >> CVSROOT/modules + echo "1d2mod-2 -d dir1d2-2 mod2-2/sub2-2" >> CVSROOT/modules + echo "2d1mod -d dir2d1/sub2d1 mod1" >> CVSROOT/modules + echo "2d1mod-2 -d dir2d1-2/sub2d1-2 mod1-2" >> CVSROOT/modules + echo "2d2mod -d dir2d2/sub2d2 mod2/sub2" >> CVSROOT/modules + echo "2d2mod-2 -d dir2d2-2/sub2d2-2 mod2-2/sub2-2" >> CVSROOT/modules + dotest cvsadm-1e "${testcvs} ci -m add-modules" \ +"${PROG} [a-z]*: Examining . +${PROG} [a-z]*: Examining CVSROOT +Checking in CVSROOT/modules; +${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules +new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* +done +${PROG} [a-z]*: Rebuilding administrative file database" + rm -rf CVS CVSROOT; + + # Create the various modules + mkdir ${CVSROOT_DIRNAME}/mod1 + mkdir ${CVSROOT_DIRNAME}/mod1-2 + mkdir ${CVSROOT_DIRNAME}/mod2 + mkdir ${CVSROOT_DIRNAME}/mod2/sub2 + mkdir ${CVSROOT_DIRNAME}/mod2-2 + mkdir ${CVSROOT_DIRNAME}/mod2-2/sub2-2 + dotest cvsadm-2 "${testcvs} co mod1 mod1-2 mod2 mod2-2" \ +"${PROG} [a-z]*: Updating mod1 +${PROG} [a-z]*: Updating mod1-2 +${PROG} [a-z]*: Updating mod2 +${PROG} [a-z]*: Updating mod2/sub2 +${PROG} [a-z]*: Updating mod2-2 +${PROG} [a-z]*: Updating mod2-2/sub2-2" + + # Populate the directories for the halibut + echo "file1" > mod1/file1 + echo "file1-2" > mod1-2/file1-2 + echo "file2" > mod2/sub2/file2 + echo "file2-2" > mod2-2/sub2-2/file2-2 + dotest cvsadm-2a "${testcvs} add mod1/file1 mod1-2/file1-2 mod2/sub2/file2 mod2-2/sub2-2/file2-2" \ +"${PROG} [a-z]*: scheduling file .mod1/file1. for addition +${PROG} [a-z]*: scheduling file .mod1-2/file1-2. for addition +${PROG} [a-z]*: scheduling file .mod2/sub2/file2. for addition +${PROG} [a-z]*: scheduling file .mod2-2/sub2-2/file2-2. for addition +${PROG} [a-z]*: use '${PROG} commit' to add these files permanently" + + dotest cvsadm-2b "${testcvs} ci -m yup mod1 mod1-2 mod2 mod2-2" \ +"${PROG} [a-z]*: Examining mod1 +${PROG} [a-z]*: Examining mod1-2 +${PROG} [a-z]*: Examining mod2 +${PROG} [a-z]*: Examining mod2/sub2 +${PROG} [a-z]*: Examining mod2-2 +${PROG} [a-z]*: Examining mod2-2/sub2-2 +RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v +done +Checking in mod1/file1; +${CVSROOT_DIRNAME}/mod1/file1,v <-- file1 +initial revision: 1.1 +done +RCS file: ${CVSROOT_DIRNAME}/mod1-2/file1-2,v +done +Checking in mod1-2/file1-2; +${CVSROOT_DIRNAME}/mod1-2/file1-2,v <-- file1-2 +initial revision: 1.1 +done +RCS file: ${CVSROOT_DIRNAME}/mod2/sub2/file2,v +done +Checking in mod2/sub2/file2; +${CVSROOT_DIRNAME}/mod2/sub2/file2,v <-- file2 +initial revision: 1.1 +done +RCS file: ${CVSROOT_DIRNAME}/mod2-2/sub2-2/file2-2,v +done +Checking in mod2-2/sub2-2/file2-2; +${CVSROOT_DIRNAME}/mod2-2/sub2-2/file2-2,v <-- file2-2 +initial revision: 1.1 +done" + # Finished creating the modules -- clean up. + rm -rf CVS mod1 mod1-2 mod2 mod2-2 + # Done. + + ################################################## + ## Start the dizzying array of possibilities. + ## Begin with each module type separately. + ################################################## + + # Pattern -- after each checkout, first check the top-level + # CVS directory. Then, check the directories in numerical + # order. + + dotest cvsadm-3 "${testcvs} co 1mod" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1" + dotest cvsadm-3b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-3d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS 1mod + + dotest cvsadm-4 "${testcvs} co 2mod" \ +"${PROG} [a-z]*: Updating 2mod +U 2mod/file2" + dotest cvsadm-4b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-4d "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS 2mod + + dotest cvsadm-5 "${testcvs} co 1d1mod" \ +"${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1" + dotest cvsadm-5b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-5d "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir1d1 + + dotest cvsadm-6 "${testcvs} co 1d2mod" \ +"${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2" + dotest cvsadm-6b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-6d "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir1d2 + + dotest cvsadm-7 "${testcvs} co 2d1mod" \ +"${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + dotest cvsadm-7b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-7d "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-7f "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir2d1 + + dotest cvsadm-8 "${testcvs} co 2d2mod" \ +"${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + dotest cvsadm-8b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-8d "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-8f "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir2d2 + + ################################################## + ## You are in a shell script of twisted little + ## module combination statements, all alike. + ################################################## + + ### 1mod + + dotest cvsadm-9 "${testcvs} co 1mod 1mod-2" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1 +${PROG} [a-z]*: Updating 1mod-2 +U 1mod-2/file1-2" + # the usual for the top level + dotest cvsadm-9b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-9d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1mod copy + dotest cvsadm-9f "cat 1mod-2/CVS/Repository" \ +"${AREP}mod1-2" + rm -rf CVS 1mod 1mod-2 + + # 1mod 2mod redmod bluemod + dotest cvsadm-10 "${testcvs} co 1mod 2mod" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1 +${PROG} [a-z]*: Updating 2mod +U 2mod/file2" + # the usual for the top level + dotest cvsadm-10b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-10d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2dmod + dotest cvsadm-10f "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS 1mod 2mod + + dotest cvsadm-11 "${testcvs} co 1mod 1d1mod" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1 +${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1" + # the usual for the top level + dotest cvsadm-11b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-11d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d1mod + dotest cvsadm-11f "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS 1mod dir1d1 + + dotest cvsadm-12 "${testcvs} co 1mod 1d2mod" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1 +${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2" + # the usual for the top level + dotest cvsadm-12b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-12d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d2mod + dotest cvsadm-12f "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS 1mod dir1d2 + + dotest cvsadm-13 "${testcvs} co 1mod 2d1mod" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1 +${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-13b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-13d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d1mod + dotest cvsadm-13f "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-13h "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS 1mod dir2d1 + + dotest cvsadm-14 "${testcvs} co 1mod 2d2mod" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1 +${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-14b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-14d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d2mod + dotest cvsadm-14f "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-14h "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS 1mod dir2d2 + + + ### 2mod + + dotest cvsadm-15 "${testcvs} co 2mod 2mod-2" \ +"${PROG} [a-z]*: Updating 2mod +U 2mod/file2 +${PROG} [a-z]*: Updating 2mod-2 +U 2mod-2/file2-2" + # the usual for the top level + dotest cvsadm-15b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-15d "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2mod copy + dotest cvsadm-15f "cat 2mod-2/CVS/Repository" \ +"${AREP}mod2-2/sub2-2" + rm -rf CVS 2mod 2mod-2 + + + dotest cvsadm-16 "${testcvs} co 2mod 1d1mod" \ +"${PROG} [a-z]*: Updating 2mod +U 2mod/file2 +${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1" + # the usual for the top level + dotest cvsadm-16b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-16d "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 1d1mod + dotest cvsadm-16f "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS 2mod dir1d1 + + dotest cvsadm-17 "${testcvs} co 2mod 1d2mod" \ +"${PROG} [a-z]*: Updating 2mod +U 2mod/file2 +${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2" + # the usual for the top level + dotest cvsadm-17b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-17d "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 1d2mod + dotest cvsadm-17f "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS 2mod dir1d2 + + dotest cvsadm-18 "${testcvs} co 2mod 2d1mod" \ +"${PROG} [a-z]*: Updating 2mod +U 2mod/file2 +${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-18b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-18d "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-18f "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-18h "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS 2mod dir2d1 + + dotest cvsadm-19 "${testcvs} co 2mod 2d2mod" \ +"${PROG} [a-z]*: Updating 2mod +U 2mod/file2 +${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-19b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-19d "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-19f "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-19h "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS 2mod dir2d2 + + + ### 1d1mod + + dotest cvsadm-20 "${testcvs} co 1d1mod 1d1mod-2" \ +"${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1 +${PROG} [a-z]*: Updating dir1d1-2 +U dir1d1-2/file1-2" + # the usual for the top level + dotest cvsadm-20b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-20d "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d1mod copy + dotest cvsadm-20f "cat dir1d1-2/CVS/Repository" \ +"${AREP}mod1-2" + rm -rf CVS dir1d1 dir1d1-2 + + dotest cvsadm-21 "${testcvs} co 1d1mod 1d2mod" \ +"${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1 +${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2" + # the usual for the top level + dotest cvsadm-21b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-21d "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d2mod + dotest cvsadm-21f "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir1d1 dir1d2 + + dotest cvsadm-22 "${testcvs} co 1d1mod 2d1mod" \ +"${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1 +${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-22b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-22d "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d1mod + dotest cvsadm-22f "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-22h "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir1d1 dir2d1 + + dotest cvsadm-23 "${testcvs} co 1d1mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1 +${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-23b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-23d "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d2mod + dotest cvsadm-23f "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-23h "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir1d1 dir2d2 + + + ### 1d2mod + + dotest cvsadm-24 "${testcvs} co 1d2mod 1d2mod-2" \ +"${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2 +${PROG} [a-z]*: Updating dir1d2-2 +U dir1d2-2/file2-2" + # the usual for the top level + dotest cvsadm-24b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1d2mod + dotest cvsadm-24d "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 1d2mod copy + dotest cvsadm-24f "cat dir1d2-2/CVS/Repository" \ +"${AREP}mod2-2/sub2-2" + rm -rf CVS dir1d2 dir1d2-2 + + dotest cvsadm-25 "${testcvs} co 1d2mod 2d1mod" \ +"${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2 +${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + # the usual for the top level + dotest cvsadm-25b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1d2mod + dotest cvsadm-25d "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-25f "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-25h "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir1d2 dir2d1 + + dotest cvsadm-26 "${testcvs} co 1d2mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2 +${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-26b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 1d2mod + dotest cvsadm-26d "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-26f "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-26h "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir1d2 dir2d2 + + + # 2d1mod + + dotest cvsadm-27 "${testcvs} co 2d1mod 2d1mod-2" \ +"${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1 +${PROG} [a-z]*: Updating dir2d1-2/sub2d1-2 +U dir2d1-2/sub2d1-2/file1-2" + # the usual for the top level + dotest cvsadm-27b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2d1mod + dotest cvsadm-27d "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-27f "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d1mod + dotest cvsadm-27h "cat dir2d1-2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-27j "cat dir2d1-2/sub2d1-2/CVS/Repository" \ +"${AREP}mod1-2" + rm -rf CVS dir2d1 dir2d1-2 + + dotest cvsadm-28 "${testcvs} co 2d1mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1 +${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + # the usual for the top level + dotest cvsadm-28b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2d1mod + dotest cvsadm-28d "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-28f "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d2mod + dotest cvsadm-28h "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-28j "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir2d1 dir2d2 + + + # 2d2mod + + dotest cvsadm-29 "${testcvs} co 2d2mod 2d2mod-2" \ +"${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2 +${PROG} [a-z]*: Updating dir2d2-2/sub2d2-2 +U dir2d2-2/sub2d2-2/file2-2" + # the usual for the top level + dotest cvsadm-29b "cat CVS/Repository" \ +"${AREP}\." + # the usual for 2d2mod + dotest cvsadm-29d "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-29f "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-29h "cat dir2d2-2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-29j "cat dir2d2-2/sub2d2-2/CVS/Repository" \ +"${AREP}mod2-2/sub2-2" + rm -rf CVS dir2d2 dir2d2-2 + + ################################################## + ## And now, all of that again using the "-d" flag + ## on the command line. + ################################################## + + dotest cvsadm-1d3 "${testcvs} co -d dir 1mod" \ +"${PROG} [a-z]*: Updating dir +U dir/file1" + dotest cvsadm-1d3b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-1d3d "cat dir/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d4 "${testcvs} co -d dir 2mod" \ +"${PROG} [a-z]*: Updating dir +U dir/file2" + dotest cvsadm-1d4b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-1d4d "cat dir/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d5 "${testcvs} co -d dir 1d1mod" \ +"${PROG} [a-z]*: Updating dir +U dir/file1" + dotest cvsadm-1d5b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-1d5d "cat dir/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d6 "${testcvs} co -d dir 1d2mod" \ +"${PROG} [a-z]*: Updating dir +U dir/file2" + dotest cvsadm-1d6b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-1d6d "cat dir/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d7 "${testcvs} co -d dir 2d1mod" \ +"${PROG} [a-z]*: Updating dir +U dir/file1" + dotest cvsadm-1d7b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-1d7d "cat dir/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d8 "${testcvs} co -d dir 2d2mod" \ +"${PROG} [a-z]*: Updating dir +U dir/file2" + dotest cvsadm-1d8b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-1d8d "cat dir/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + ################################################## + ## Los Combonaciones + ################################################## + + ### 1mod + + dotest cvsadm-1d9 "${testcvs} co -d dir 1mod 1mod-2" \ +"${PROG} [a-z]*: Updating dir/1mod +U dir/1mod/file1 +${PROG} [a-z]*: Updating dir/1mod-2 +U dir/1mod-2/file1-2" + # the usual for the top level + dotest cvsadm-1d9b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d9d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-1d9f "cat dir/1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1mod copy + dotest cvsadm-1d9h "cat dir/1mod-2/CVS/Repository" \ +"${AREP}mod1-2" + rm -rf CVS dir + + # 1mod 2mod redmod bluemod + dotest cvsadm-1d10 "${testcvs} co -d dir 1mod 2mod" \ +"${PROG} [a-z]*: Updating dir/1mod +U dir/1mod/file1 +${PROG} [a-z]*: Updating dir/2mod +U dir/2mod/file2" + dotest cvsadm-1d10b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d10d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-1d10f "cat dir/1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2dmod + dotest cvsadm-1d10h "cat dir/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d11 "${testcvs} co -d dir 1mod 1d1mod" \ +"${PROG} [a-z]*: Updating dir/1mod +U dir/1mod/file1 +${PROG} [a-z]*: Updating dir/dir1d1 +U dir/dir1d1/file1" + dotest cvsadm-1d11b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d11d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-1d11f "cat dir/1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d1mod + dotest cvsadm-1d11h "cat dir/dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d12 "${testcvs} co -d dir 1mod 1d2mod" \ +"${PROG} [a-z]*: Updating dir/1mod +U dir/1mod/file1 +${PROG} [a-z]*: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-1d12b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d12d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-1d12f "cat dir/1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d2mod + dotest cvsadm-1d12h "cat dir/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d13 "${testcvs} co -d dir 1mod 2d1mod" \ +"${PROG} [a-z]*: Updating dir/1mod +U dir/1mod/file1 +${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d13b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d13d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-1d13f "cat dir/1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d1mod + dotest cvsadm-1d13h "cat dir/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d13j "cat dir/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d14 "${testcvs} co -d dir 1mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir/1mod +U dir/1mod/file1 +${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d14b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d14d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1mod + dotest cvsadm-1d14f "cat dir/1mod/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d2mod + dotest cvsadm-1d14h "cat dir/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d14j "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + + ### 2mod + + dotest cvsadm-1d15 "${testcvs} co -d dir 2mod 2mod-2" \ +"${PROG} [a-z]*: Updating dir/2mod +U dir/2mod/file2 +${PROG} [a-z]*: Updating dir/2mod-2 +U dir/2mod-2/file2-2" + dotest cvsadm-1d15b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d15d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-1d15f "cat dir/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2mod copy + dotest cvsadm-1d15h "cat dir/2mod-2/CVS/Repository" \ +"${AREP}mod2-2/sub2-2" + rm -rf CVS dir + + dotest cvsadm-1d16 "${testcvs} co -d dir 2mod 1d1mod" \ +"${PROG} [a-z]*: Updating dir/2mod +U dir/2mod/file2 +${PROG} [a-z]*: Updating dir/dir1d1 +U dir/dir1d1/file1" + dotest cvsadm-1d16b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d16d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-1d16f "cat dir/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 1d1mod + dotest cvsadm-1d16h "cat dir/dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d17 "${testcvs} co -d dir 2mod 1d2mod" \ +"${PROG} [a-z]*: Updating dir/2mod +U dir/2mod/file2 +${PROG} [a-z]*: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-1d17b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d17d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-1d17f "cat dir/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 1d2mod + dotest cvsadm-1d17h "cat dir/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d18 "${testcvs} co -d dir 2mod 2d1mod" \ +"${PROG} [a-z]*: Updating dir/2mod +U dir/2mod/file2 +${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d18b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d18d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-1d18f "cat dir/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-1d18h "cat dir/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d18j "cat dir/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d19 "${testcvs} co -d dir 2mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir/2mod +U dir/2mod/file2 +${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d19b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d19d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2mod + dotest cvsadm-1d19f "cat dir/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-1d19h "cat dir/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d19j "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + + ### 1d1mod + + dotest cvsadm-1d20 "${testcvs} co -d dir 1d1mod 1d1mod-2" \ +"${PROG} [a-z]*: Updating dir/dir1d1 +U dir/dir1d1/file1 +${PROG} [a-z]*: Updating dir/dir1d1-2 +U dir/dir1d1-2/file1-2" + dotest cvsadm-1d20b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d20d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-1d20f "cat dir/dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d1mod copy + dotest cvsadm-1d20h "cat dir/dir1d1-2/CVS/Repository" \ +"${AREP}mod1-2" + rm -rf CVS dir + + dotest cvsadm-1d21 "${testcvs} co -d dir 1d1mod 1d2mod" \ +"${PROG} [a-z]*: Updating dir/dir1d1 +U dir/dir1d1/file1 +${PROG} [a-z]*: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-1d21b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d21d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-1d21f "cat dir/dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 1d2mod + dotest cvsadm-1d21h "cat dir/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-1d22 "${testcvs} co -d dir 1d1mod 2d1mod" \ +"${PROG} [a-z]*: Updating dir/dir1d1 +U dir/dir1d1/file1 +${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d22b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d22d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-1d22f "cat dir/dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d1mod + dotest cvsadm-1d22h "cat dir/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d22j "cat dir/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d23 "${testcvs} co -d dir 1d1mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir/dir1d1 +U dir/dir1d1/file1 +${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d23b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d23d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1d1mod + dotest cvsadm-1d23f "cat dir/dir1d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d2mod + dotest cvsadm-1d23h "cat dir/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d23j "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + + ### 1d2mod + + dotest cvsadm-1d24 "${testcvs} co -d dir 1d2mod 1d2mod-2" \ +"${PROG} [a-z]*: Updating dir/dir1d2 +U dir/dir1d2/file2 +${PROG} [a-z]*: Updating dir/dir1d2-2 +U dir/dir1d2-2/file2-2" + dotest cvsadm-1d24b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d24d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1d2mod + dotest cvsadm-1d24f "cat dir/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 1d2mod copy + dotest cvsadm-1d24h "cat dir/dir1d2-2/CVS/Repository" \ +"${AREP}mod2-2/sub2-2" + rm -rf CVS dir + + dotest cvsadm-1d25 "${testcvs} co -d dir 1d2mod 2d1mod" \ +"${PROG} [a-z]*: Updating dir/dir1d2 +U dir/dir1d2/file2 +${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-1d25b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d25d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1d2mod + dotest cvsadm-1d25f "cat dir/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d1mod + dotest cvsadm-1d25h "cat dir/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d25j "cat dir/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-1d26 "${testcvs} co -d dir 1d2mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir/dir1d2 +U dir/dir1d2/file2 +${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d26b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d26d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 1d2mod + dotest cvsadm-1d26f "cat dir/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-1d26h "cat dir/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d26j "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + + # 2d1mod + + dotest cvsadm-1d27 "${testcvs} co -d dir 2d1mod 2d1mod-2" \ +"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1 +${PROG} [a-z]*: Updating dir/dir2d1-2/sub2d1-2 +U dir/dir2d1-2/sub2d1-2/file1-2" + dotest cvsadm-1d27b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d27d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2d1mod + dotest cvsadm-1d27f "cat dir/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d27h "cat dir/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d1mod + dotest cvsadm-1d27j "cat dir/dir2d1-2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d27l "cat dir/dir2d1-2/sub2d1-2/CVS/Repository" \ +"${AREP}mod1-2" + rm -rf CVS dir + + dotest cvsadm-1d28 "${testcvs} co -d dir 2d1mod 2d2mod" \ +"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1 +${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-1d28b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d28d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2d1mod + dotest cvsadm-1d28f "cat dir/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d28h "cat dir/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + # the usual for 2d2mod + dotest cvsadm-1d28j "cat dir/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d28l "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + + # 2d2mod + + dotest cvsadm-1d29 "${testcvs} co -d dir 2d2mod 2d2mod-2" \ +"${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2 +${PROG} [a-z]*: Updating dir/dir2d2-2/sub2d2-2 +U dir/dir2d2-2/sub2d2-2/file2-2" + dotest cvsadm-1d29b "cat CVS/Repository" \ +"${AREP}\." + # the usual for the dir level + dotest cvsadm-1d29d "cat dir/CVS/Repository" \ +"${AREP}\." + # the usual for 2d2mod + dotest cvsadm-1d29f "cat dir/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d29h "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + # the usual for 2d2mod + dotest cvsadm-1d29j "cat dir/dir2d2-2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-1d29l "cat dir/dir2d2-2/sub2d2-2/CVS/Repository" \ +"${AREP}mod2-2/sub2-2" + rm -rf CVS dir + + ################################################## + ## And now, some of that again using the "-d" flag + ## on the command line, but use a longer path. + ################################################## + + dotest cvsadm-2d3 "${testcvs} co -d dir/dir2 1mod" \ +"${PROG} [a-z]*: Updating dir/dir2 +U dir/dir2/file1" + dotest cvsadm-2d3b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-2d3d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-2d3f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-2d4 "${testcvs} co -d dir/dir2 2mod" \ +"${PROG} [a-z]*: Updating dir/dir2 +U dir/dir2/file2" + dotest cvsadm-2d4b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-2d4d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-2d4f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-2d5 "${testcvs} co -d dir/dir2 1d1mod" \ +"${PROG} [a-z]*: Updating dir/dir2 +U dir/dir2/file1" + dotest cvsadm-2d5b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-2d5d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-2d5f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-2d6 "${testcvs} co -d dir/dir2 1d2mod" \ +"${PROG} [a-z]*: Updating dir/dir2 +U dir/dir2/file2" + dotest cvsadm-2d6b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-2d6d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-2d6f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-2d7 "${testcvs} co -d dir/dir2 2d1mod" \ +"${PROG} [a-z]*: Updating dir/dir2 +U dir/dir2/file1" + dotest cvsadm-2d7b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-2d7d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-2d7f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-2d8 "${testcvs} co -d dir/dir2 2d2mod" \ +"${PROG} [a-z]*: Updating dir/dir2 +U dir/dir2/file2" + dotest cvsadm-2d8b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-2d8d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-2d8f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + ################################################## + ## And now, a few of those tests revisited to + ## test the behavior of the -N flag. + ################################################## + + dotest cvsadm-N3 "${testcvs} co -N 1mod" \ +"${PROG} [a-z]*: Updating 1mod +U 1mod/file1" + dotest cvsadm-N3b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N3d "cat 1mod/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS 1mod + + dotest cvsadm-N4 "${testcvs} co -N 2mod" \ +"${PROG} [a-z]*: Updating 2mod +U 2mod/file2" + dotest cvsadm-N4b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N4d "cat 2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS 2mod + + dotest cvsadm-N5 "${testcvs} co -N 1d1mod" \ +"${PROG} [a-z]*: Updating dir1d1 +U dir1d1/file1" + dotest cvsadm-N5b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N5d "cat dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir1d1 + + dotest cvsadm-N6 "${testcvs} co -N 1d2mod" \ +"${PROG} [a-z]*: Updating dir1d2 +U dir1d2/file2" + dotest cvsadm-N6b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N6d "cat dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir1d2 + + dotest cvsadm-N7 "${testcvs} co -N 2d1mod" \ +"${PROG} [a-z]*: Updating dir2d1/sub2d1 +U dir2d1/sub2d1/file1" + dotest cvsadm-N7b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N7d "cat dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N7f "cat dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir2d1 + + dotest cvsadm-N8 "${testcvs} co -N 2d2mod" \ +"${PROG} [a-z]*: Updating dir2d2/sub2d2 +U dir2d2/sub2d2/file2" + dotest cvsadm-N8b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N8d "cat dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N8f "cat dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir2d2 + + ## the ones in one-deep directories + + dotest cvsadm-N1d3 "${testcvs} co -N -d dir 1mod" \ +"${PROG} [a-z]*: Updating dir/1mod +U dir/1mod/file1" + dotest cvsadm-N1d3b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d3d "cat dir/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d3f "cat dir/1mod/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-N1d4 "${testcvs} co -N -d dir 2mod" \ +"${PROG} [a-z]*: Updating dir/2mod +U dir/2mod/file2" + dotest cvsadm-N1d4b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d4d "cat dir/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d4f "cat dir/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-N1d5 "${testcvs} co -N -d dir 1d1mod" \ +"${PROG} [a-z]*: Updating dir/dir1d1 +U dir/dir1d1/file1" + dotest cvsadm-N1d5b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d5d "cat dir/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d5d "cat dir/dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-N1d6 "${testcvs} co -N -d dir 1d2mod" \ +"${PROG} [a-z]*: Updating dir/dir1d2 +U dir/dir1d2/file2" + dotest cvsadm-N1d6b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d6d "cat dir/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d6f "cat dir/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-N1d7 "${testcvs} co -N -d dir 2d1mod" \ +"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 +U dir/dir2d1/sub2d1/file1" + dotest cvsadm-N1d7b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d7d "cat dir/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d7f "cat dir/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N1d7h "cat dir/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-N1d8 "${testcvs} co -N -d dir 2d2mod" \ +"${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 +U dir/dir2d2/sub2d2/file2" + dotest cvsadm-N1d8b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d8d "cat dir/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d8d "cat dir/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N1d8d "cat dir/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + ## the ones in two-deep directories + + dotest cvsadm-N2d3 "${testcvs} co -N -d dir/dir2 1mod" \ +"${PROG} [a-z]*: Updating dir/dir2/1mod +U dir/dir2/1mod/file1" + dotest cvsadm-N2d3b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d3d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d3f "cat dir/dir2/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d3h "cat dir/dir2/1mod/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-N2d4 "${testcvs} co -N -d dir/dir2 2mod" \ +"${PROG} [a-z]*: Updating dir/dir2/2mod +U dir/dir2/2mod/file2" + dotest cvsadm-N2d4b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d4d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d4f "cat dir/dir2/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d4h "cat dir/dir2/2mod/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-N2d5 "${testcvs} co -N -d dir/dir2 1d1mod" \ +"${PROG} [a-z]*: Updating dir/dir2/dir1d1 +U dir/dir2/dir1d1/file1" + dotest cvsadm-N2d5b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d5d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d5f "cat dir/dir2/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d5h "cat dir/dir2/dir1d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-N2d6 "${testcvs} co -N -d dir/dir2 1d2mod" \ +"${PROG} [a-z]*: Updating dir/dir2/dir1d2 +U dir/dir2/dir1d2/file2" + dotest cvsadm-N2d6b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d6d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d6f "cat dir/dir2/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d6h "cat dir/dir2/dir1d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + dotest cvsadm-N2d7 "${testcvs} co -N -d dir/dir2 2d1mod" \ +"${PROG} [a-z]*: Updating dir/dir2/dir2d1/sub2d1 +U dir/dir2/dir2d1/sub2d1/file1" + dotest cvsadm-N2d7b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d7d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d7f "cat dir/dir2/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d7f "cat dir/dir2/dir2d1/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d7h "cat dir/dir2/dir2d1/sub2d1/CVS/Repository" \ +"${AREP}mod1" + rm -rf CVS dir + + dotest cvsadm-N2d8 "${testcvs} co -N -d dir/dir2 2d2mod" \ +"${PROG} [a-z]*: Updating dir/dir2/dir2d2/sub2d2 +U dir/dir2/dir2d2/sub2d2/file2" + dotest cvsadm-N2d8b "cat CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d8d "cat dir/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d8f "cat dir/dir2/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d8h "cat dir/dir2/dir2d2/CVS/Repository" \ +"${AREP}CVSROOT/Emptydir" + dotest cvsadm-N2d8j "cat dir/dir2/dir2d2/sub2d2/CVS/Repository" \ +"${AREP}mod2/sub2" + rm -rf CVS dir + + ################################################## + ## That's enough of that, thank you very much. + ################################################## + + # remove our junk + cd .. + rm -rf 1 + rm -rf ${CVSROOT_DIRNAME}/1mod + rm -rf ${CVSROOT_DIRNAME}/1mod-2 + rm -rf ${CVSROOT_DIRNAME}/2mod + rm -rf ${CVSROOT_DIRNAME}/2mod-2 + rm -rf ${CVSROOT_DIRNAME}/mod1 + rm -rf ${CVSROOT_DIRNAME}/mod1-2 + rm -rf ${CVSROOT_DIRNAME}/mod2 + rm -rf ${CVSROOT_DIRNAME}/mod2-2 + ;; + + abspath) + + # These tests test the thituations thin thwitch thoo theck + # things thout twith thabsolute thaths. Threally. + + # + # CHECKOUTS + # + + # Create a few modules to use + mkdir ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/mod2 + dotest abspath-1a "${testcvs} co mod1 mod2" \ +"${PROG} [a-z]*: Updating mod1 +${PROG} [a-z]*: Updating mod2" + + # Populate the module + echo "file1" > mod1/file1 + echo "file2" > mod2/file2 + dotest abspath-1b "${testcvs} add mod1/file1 mod2/file2" \ +"${PROG} [a-z]*: scheduling file .mod1/file1. for addition +${PROG} [a-z]*: scheduling file .mod2/file2. for addition +${PROG} [a-z]*: use '${PROG} commit' to add these files permanently" + + dotest abspath-1c "${testcvs} ci -m yup mod1 mod2" \ +"${PROG} [a-z]*: Examining mod1 +${PROG} [a-z]*: Examining mod2 +RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v +done +Checking in mod1/file1; +${CVSROOT_DIRNAME}/mod1/file1,v <-- file1 +initial revision: 1.1 +done +RCS file: ${CVSROOT_DIRNAME}/mod2/file2,v +done +Checking in mod2/file2; +${CVSROOT_DIRNAME}/mod2/file2,v <-- file2 +initial revision: 1.1 +done" + # Finished creating the module -- clean up. + rm -rf CVS mod1 mod2 + # Done. + + # Try checking out the module in a local directory + dotest abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ +"${PROG} [a-z]*: Updating ${TESTDIR}/1 +U ${TESTDIR}/1/file1" + + # Are we relative or absolute in our Repository file? + echo "${CVSROOT_DIRNAME}/mod1" > ${TESTDIR}/dotest.abs + echo "mod1" > ${TESTDIR}/dotest.rel + if cmp ${TESTDIR}/dotest.abs ${TESTDIR}/1/CVS/Repository >/dev/null 2>&1; then + AREP="${CVSROOT_DIRNAME}/" + elif cmp ${TESTDIR}/dotest.rel ${TESTDIR}/1/CVS/Repository >/dev/null 2>&1; then + AREP="" + else + fail "Cannot figure out if RELATIVE_REPOS is defined." + fi + rm -f ${TESTDIR}/dotest.rel ${TESTDIR}/dotest.abs + + dotest abspath-2b "cat ${TESTDIR}/1/CVS/Repository" \ +"${AREP}mod1" + + # Done. Clean up. + rm -rf ${TESTDIR}/1 + + + # Now try in a subdirectory. We're not covering any more + # code here, but we might catch a future error if someone + # changes the checkout code. + dotest abspath-3a "${testcvs} co -d ${TESTDIR}/1/2 mod1" \ +"${PROG} [a-z]*: Updating ${TESTDIR}/1/2 +U ${TESTDIR}/1/2/file1" + dotest abspath-3b "cat ${TESTDIR}/1/2/CVS/Repository" \ +"${AREP}mod1" + # Done. Clean up. + rm -rf ${TESTDIR}/1 + + + # Now try someplace where we don't have permission. + mkdir ${TESTDIR}/barf + chmod -w ${TESTDIR}/barf + dotest_fail abspath-4 "${testcvs} co -d ${TESTDIR}/barf/sub mod1" \ +"${PROG} \[[a-z]* aborted\]: cannot make directory sub: No such file or directory" + chmod +w ${TESTDIR}/barf + rmdir ${TESTDIR}/barf + # Done. Nothing to clean up. + + + # Try checking out two modules into the same directory. + dotest abspath-5a "${testcvs} co -d ${TESTDIR}/1 mod1 mod2" \ +"${PROG} [a-z]*: Updating ${TESTDIR}/1/mod1 +U ${TESTDIR}/1/mod1/file1 +${PROG} [a-z]*: Updating ${TESTDIR}/1/mod2 +U ${TESTDIR}/1/mod2/file2" + dotest abspath-5b "cat ${TESTDIR}/1/CVS/Repository" \ +"${AREP}." + dotest abspath-5c "cat ${TESTDIR}/1/mod1/CVS/Repository" \ +"${AREP}mod1" + dotest abspath-5d "cat ${TESTDIR}/1/mod2/CVS/Repository" \ +"${AREP}mod2" + # Done. Clean up. + rm -rf ${TESTDIR}/1 + + + # Try checking out the top-level module. + dotest abspath-6a "${testcvs} co -d ${TESTDIR}/1 ." \ +"${PROG} [a-z]*: Updating ${TESTDIR}/1 +${PROG} [a-z]*: Updating ${TESTDIR}/1/CVSROOT +${DOTSTAR} +${PROG} [a-z]*: Updating ${TESTDIR}/1/mod1 +U ${TESTDIR}/1/mod1/file1 +${PROG} [a-z]*: Updating ${TESTDIR}/1/mod2 +U ${TESTDIR}/1/mod2/file2" + dotest abspath-6b "cat ${TESTDIR}/1/CVS/Repository" \ +"${AREP}." + dotest abspath-6c "cat ${TESTDIR}/1/CVSROOT/CVS/Repository" \ +"${AREP}CVSROOT" + dotest abspath-6c "cat ${TESTDIR}/1/mod1/CVS/Repository" \ +"${AREP}mod1" + dotest abspath-6d "cat ${TESTDIR}/1/mod2/CVS/Repository" \ +"${AREP}mod2" + # Done. Clean up. + rm -rf ${TESTDIR}/1 + + # + # FIXME: do other functions here (e.g. update /tmp/foo) + # + + # Finished with all tests. Remove the module. + rm -rf ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/mod1 + + # FIXME: the absolute pathname fixes create CVS directories + # wherever they can. That means for the standard TESTDIR, a + # /tmp/CVS directory will be created as well. It's not safe + # to remove it, however. + + ;; + + toplevel) + # test the feature that cvs creates a CVS subdir also for + # the toplevel directory + + # Some test, somewhere, is creating Emptydir. That test + # should, perhaps, clean up for itself, but I don't know which + # one it is. + rm -rf ${CVSROOT_DIRNAME}/CVSROOT/Emptydir + + mkdir 1; cd 1 + dotest toplevel-1 "${testcvs} -q co -l ." '' + mkdir top-dir second-dir + dotest toplevel-2 "${testcvs} add top-dir second-dir" \ +"Directory ${TESTDIR}/cvsroot/top-dir added to the repository +Directory ${TESTDIR}/cvsroot/second-dir added to the repository" + cd top-dir + + touch file1 + dotest toplevel-3 "${testcvs} add file1" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + dotest toplevel-4 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/top-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/top-dir/file1,v <-- file1 +initial revision: 1\.1 +done" + cd .. + + cd second-dir + touch file2 + dotest toplevel-3s "${testcvs} add file2" \ +"${PROG} [a-z]*: scheduling file .file2. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + dotest toplevel-4s "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/second-dir/file2,v +done +Checking in file2; +${TESTDIR}/cvsroot/second-dir/file2,v <-- file2 +initial revision: 1\.1 +done" + + cd ../.. + rm -r 1; mkdir 1; cd 1 + dotest toplevel-5 "${testcvs} co top-dir" \ +"${PROG} [a-z]*: Updating top-dir +U top-dir/file1" + + dotest toplevel-6 "${testcvs} update top-dir" \ +"${PROG} [a-z]*: Updating top-dir" + dotest toplevel-7 "${testcvs} update" \ +"${PROG} [a-z]*: Updating \. +${PROG} [a-z]*: Updating top-dir" + + dotest toplevel-8 "${testcvs} update -d top-dir" \ +"${PROG} [a-z]*: Updating top-dir" + # There is some sentiment that + # "${PROG} [a-z]*: Updating \. + # ${PROG} [a-z]*: Updating top-dir" + # is correct but it isn't clear why that would be correct instead + # of the remote CVS behavior (which also updates CVSROOT). + # + # The DOTSTAR matches of a bunch of lines like + # "U CVSROOT/checkoutlist". Trying to match them more precisely + # seemed to cause trouble. For example CVSROOT/cvsignore will + # be present or absent depending on whether we ran the "ignore" + # test or not. + dotest toplevel-9 "${testcvs} update -d" \ +"${PROG} [a-z]*: Updating \. +${PROG} [a-z]*: Updating CVSROOT +${DOTSTAR} +${PROG} [a-z]*: Updating top-dir" + + cd .. + rm -r 1; mkdir 1; cd 1 + dotest toplevel-10 "${testcvs} co top-dir" \ +"${PROG} [a-z]*: Updating top-dir +U top-dir/file1" + # This tests more or less the same thing, in a particularly + # "real life" example. + dotest toplevel-11 "${testcvs} -q update -d second-dir" \ +"U second-dir/file2" + + # Now remove the CVS directory (people may do this manually, + # especially if they formed their habits with CVS + # 1.9 and older, which didn't create it. Or perhaps the working + # directory itself was created with 1.9 or older). + rm -r CVS + # Now set the permissions so we can't recreate it. + chmod -w ../1 + # Now see whether CVS has trouble because it can't create CVS. + dotest toplevel-12 "${testcvs} co top-dir" \ +"${PROG} [a-z]*: warning: cannot make directory CVS in \.: Permission denied +${PROG} [a-z]*: Updating top-dir" + chmod +w ../1 + + cd .. + rm -r 1 + rm -rf ${CVSROOT_DIRNAME}/top-dir ${CVSROOT_DIRNAME}/second-dir + ;; + mflag) for message in '' ' ' ' ' ' test' ; do @@ -7867,7 +9891,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database" echo "ALL echo %{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo echo "ALL echo %s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo echo "ALL echo %{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo - echo "ALL echo %sux >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo + echo "first-dir echo %sux >>$TESTDIR/testlog2; cat >/dev/null" \ + >> loginfo # Might be nice to move this to crerepos tests; it should # work to create a loginfo file if you didn't create one @@ -8965,7 +10990,7 @@ add file1 head 1.5 ; branch 1.2.6; access ; -symbols; +symbols branch:1.2.6; locks; testofanewphrase @without newphrase we'd have trouble extending @@ all@ ; 1.5 date 71.01.01.01.00.00; author joe; state bogus; branches; next 1.4; @@ -8997,6 +11022,16 @@ EOF dotest rcs-5 "${testcvs} -q update file2" "U file2" dotest rcs-6 "cat file2" "branch revision" + # Check in a revision on the branch to force CVS to + # interpret every revision in the file. + dotest rcs-6a "${testcvs} -q update -r branch file2" "" + echo "next branch revision" > file2 + dotest rcs-6b "${testcvs} -q ci -m mod file2" \ +"Checking in file2; +${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +new revision: 1\.2\.6\.2; previous revision: 1\.2\.6\.1 +done" + # Now get rid of the default branch, it will get in the way. dotest rcs-7 "${testcvs} admin -b file2" \ "RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v @@ -9013,7 +11048,8 @@ done" dotest rcs-8a "cat ${CVSROOT_DIRNAME}/first-dir/file2,v" \ "head 1\.5; access; -symbols; +symbols + branch:1.2.6; locks; testofanewphrase @without newphrase we'd have trouble extending @@ all@; @@ -9048,6 +11084,11 @@ newph ; 1\.2\.6\.1 date 71\.01\.01\.08\.00\.05; author joe; state Exp; branches; +next 1\.2\.6\.2; + +1\.2\.6\.2 +date [0-9.]*; author ${username}; state Exp; +branches; next ; @@ -9106,7 +11147,18 @@ log text @d1 1 a1 1 -branch revision@" +branch revision@ + + +1\.2\.6\.2 +log +@mod +@ +text +@d1 1 +a1 1 +next branch revision +@" # For remote, the "update -p -D" usage seems not to work. # I'm not sure what is going on. @@ -9166,8 +11218,9 @@ branch: locks: access list: symbolic names: + branch: 1\.2\.6 keyword substitution: kv -total revisions: 6; selected revisions: 6 +total revisions: 7; selected revisions: 7 description: ---------------------------- revision 1\.5 @@ -9191,6 +11244,10 @@ revision 1\.1 date: 1970/12/31 11:00:05; author: joe; state: bogus; \*\*\* empty log message \*\*\* ---------------------------- +revision 1\.2\.6\.2 +date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 +mod +---------------------------- revision 1\.2\.6\.1 date: 1971/01/01 08:00:05; author: joe; state: Exp; lines: ${PLUS}1 -1 \*\*\* empty log message \*\*\* @@ -9972,108 +12029,6 @@ xx" rm -rf ${CVSROOT_DIRNAME}/first-dir ;; - toplevel) - # test the feature that cvs creates a CVS subdir also for - # the toplevel directory - - # Some test, somewhere, is creating Emptydir. That test - # should, perhaps, clean up for itself, but I don't know which - # one it is. - rm -rf ${CVSROOT_DIRNAME}/CVSROOT/Emptydir - - mkdir 1; cd 1 - dotest toplevel-1 "${testcvs} -q co -l ." '' - mkdir top-dir second-dir - dotest toplevel-2 "${testcvs} add top-dir second-dir" \ -"Directory ${TESTDIR}/cvsroot/top-dir added to the repository -Directory ${TESTDIR}/cvsroot/second-dir added to the repository" - cd top-dir - - touch file1 - dotest toplevel-3 "${testcvs} add file1" \ -"${PROG} [a-z]*: scheduling file .file1. for addition -${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" - dotest toplevel-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/top-dir/file1,v -done -Checking in file1; -${TESTDIR}/cvsroot/top-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd .. - - cd second-dir - touch file2 - dotest toplevel-3s "${testcvs} add file2" \ -"${PROG} [a-z]*: scheduling file .file2. for addition -${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" - dotest toplevel-4s "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/second-dir/file2,v -done -Checking in file2; -${TESTDIR}/cvsroot/second-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - - cd ../.. - rm -r 1; mkdir 1; cd 1 - dotest toplevel-5 "${testcvs} co top-dir" \ -"${PROG} [a-z]*: Updating top-dir -U top-dir/file1" - - dotest toplevel-6 "${testcvs} update top-dir" \ -"${PROG} [a-z]*: Updating top-dir" - dotest toplevel-7 "${testcvs} update" \ -"${PROG} [a-z]*: Updating \. -${PROG} [a-z]*: Updating top-dir" - - dotest toplevel-8 "${testcvs} update -d top-dir" \ -"${PROG} [a-z]*: Updating top-dir" - # There is some sentiment that - # "${PROG} [a-z]*: Updating \. - # ${PROG} [a-z]*: Updating top-dir" - # is correct but it isn't clear why that would be correct instead - # of the remote CVS behavior (which also updates CVSROOT). - # - # The DOTSTAR matches of a bunch of lines like - # "U CVSROOT/checkoutlist". Trying to match them more precisely - # seemed to cause trouble. For example CVSROOT/cvsignore will - # be present or absent depending on whether we ran the "ignore" - # test or not. - dotest toplevel-9 "${testcvs} update -d" \ -"${PROG} [a-z]*: Updating \. -${PROG} [a-z]*: Updating CVSROOT -${DOTSTAR} -${PROG} [a-z]*: Updating top-dir" - - cd .. - rm -r 1; mkdir 1; cd 1 - dotest toplevel-10 "${testcvs} co top-dir" \ -"${PROG} [a-z]*: Updating top-dir -U top-dir/file1" - # This tests more or less the same thing, in a particularly - # "real life" example. - dotest toplevel-11 "${testcvs} -q update -d second-dir" \ -"U second-dir/file2" - - # Now remove the CVS directory (people may do this manually, - # especially if they formed their habits with CVS - # 1.9 and older, which didn't create it. Or perhaps the working - # directory itself was created with 1.9 or older). - rm -r CVS - # Now set the permissions so we can't recreate it. - chmod -w ../1 - # Now see whether CVS has trouble because it can't create CVS. - dotest toplevel-12 "${testcvs} co top-dir" \ -"${PROG} [a-z]*: warning: cannot make directory ./CVS: Permission denied -${PROG} [a-z]*: Updating top-dir" - chmod +w ../1 - - cd .. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/top-dir - ;; - head) # Testing handling of the HEAD special tag. # There are many cases involving added and removed files @@ -10088,10 +12043,11 @@ ${PROG} [a-z]*: Updating top-dir" # It may seem like we don't do much with file2, but do note that # the "cvs diff" invocations do also diff file2 (and come up empty). echo 'imported contents' >file2 - dotest head-1 "${testcvs} import -m add first-dir tag1 tag2" \ -"N first-dir/file1 -N first-dir/file2 + dotest_sort head-1 "${testcvs} import -m add first-dir tag1 tag2" \ +" +N first-dir/file1 +N first-dir/file2 No conflicts created by this import" cd .. rm -r imp-dir @@ -10511,6 +12467,15 @@ ${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision" "${PROG} [a-z]*: while processing more than one file: ${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision" + # try a bad symbolic revision + dotest_fail admin-10c "${testcvs} -q admin -bBOGUS" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file1,v: Symbolic name BOGUS is undefined. +${PROG} [a-z]*: cannot modify RCS file for .file1. +RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file2,v: Symbolic name BOGUS is undefined. +${PROG} [a-z]*: cannot modify RCS file for .file2." + # Note that -s option applies to the new default branch, not # the old one. # Also note that the implementation of -a via "rcs" requires @@ -10520,8 +12485,33 @@ ${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision" -b1.1.2 -cxx -U -sfoo file1" \ "RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v done" - - dotest admin-12 "${testcvs} log -N file1" " + dotest admin-11a "${testcvs} log -N file1" " +RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: 1\.1\.2 +locks: +access list: + foo + bar + baz +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1\.1 +date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; +branches: 1\.1\.2; +add +---------------------------- +revision 1\.1\.2\.1 +date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0 +modify-on-branch +=============================================================================" + dotest admin-12 "${testcvs} -q admin -bbr file1" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done" + dotest admin-12a "${testcvs} log -N file1" " RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v Working file: file1 head: 1\.1 @@ -11179,1408 +13169,6 @@ ${PROG} [a-z]*: Rebuilding administrative file database" rm -rf ${CVSROOT_DIRNAME}/first-dir ;; - cvsadm) - # These test check the content of CVS' administrative - # files as they are checked out in various configurations. - # (As a side note, I'm not using the "-q" flag in any of - # this code, which should provide some extra checking for - # those messages which don't seem to be checked thoroughly - # anywhere else.) To do a thorough test, we need to make - # a bunch of modules in various configurations. - # - # <1mod> is a directory at the top level of cvsroot - # ``foo bar'' - # <2mod> is a directory at the second level of cvsroot - # ``foo bar/baz'' - # <1d1mod> is a directory at the top level which is - # checked out into another directory - # ``foo -d bar baz'' - # <1d2mod> is a directory at the second level which is - # checked out into another directory - # ``foo -d bar baz/quux'' - # <2d1mod> is a directory at the top level which is - # checked out into a directory that is two deep - # ``foo -d bar/baz quux'' - # <2d2mod> is a directory at the second level which is - # checked out into a directory that is two deep - # ``foo -d bar/baz quux'' - # - # The tests do each of these types separately and in twos. - # We also repeat each test -d flag for 1-deep and 2-deep - # directories. - # - # Each test should check the output for the Repository - # file, since that is the one which varies depending on - # the directory and how it was checked out. - # - # Yes, this is verbose, but at least it's very thorough. - - # convenience variables - REP=${CVSROOT} - - # First, check out the modules file and edit it. - mkdir 1; cd 1 - dotest cvsadm-1 "${testcvs} co CVSROOT/modules" \ -"U CVSROOT/modules" - - # Try to determine whether RELATIVE_REPOS is defined - # so that we can make the following a lot less - # verbose. - - echo "${CVSROOT_DIRNAME}/." > ${TESTDIR}/dotest.abs - echo "." > ${TESTDIR}/dotest.rel - if cmp ${TESTDIR}/dotest.abs CVS/Repository >/dev/null 2>&1; then - AREP="${CVSROOT_DIRNAME}/" - elif cmp ${TESTDIR}/dotest.rel CVS/Repository >/dev/null 2>&1; then - AREP="" - else - fail "Cannot figure out if RELATIVE_REPOS is defined." - fi - - # Test CVS/Root once. Since there is only one part of - # the code which writes CVS/Root files (Create_Admin), - # there is no point in testing this every time. - dotest cvsadm-1a "cat CVS/Root" ${REP} - dotest cvsadm-1b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-1c "cat CVSROOT/CVS/Root" ${REP} - dotest cvsadm-1d "cat CVSROOT/CVS/Repository" \ -"${AREP}CVSROOT" - # All of the defined module names begin with a number. - # All of the top-level directory names begin with "dir". - # All of the subdirectory names begin with "sub". - # All of the top-level modules begin with "mod". - echo "# Module defs for cvsadm tests" > CVSROOT/modules - echo "1mod mod1" >> CVSROOT/modules - echo "1mod-2 mod1-2" >> CVSROOT/modules - echo "2mod mod2/sub2" >> CVSROOT/modules - echo "2mod-2 mod2-2/sub2-2" >> CVSROOT/modules - echo "1d1mod -d dir1d1 mod1" >> CVSROOT/modules - echo "1d1mod-2 -d dir1d1-2 mod1-2" >> CVSROOT/modules - echo "1d2mod -d dir1d2 mod2/sub2" >> CVSROOT/modules - echo "1d2mod-2 -d dir1d2-2 mod2-2/sub2-2" >> CVSROOT/modules - echo "2d1mod -d dir2d1/sub2d1 mod1" >> CVSROOT/modules - echo "2d1mod-2 -d dir2d1-2/sub2d1-2 mod1-2" >> CVSROOT/modules - echo "2d2mod -d dir2d2/sub2d2 mod2/sub2" >> CVSROOT/modules - echo "2d2mod-2 -d dir2d2-2/sub2d2-2 mod2-2/sub2-2" >> CVSROOT/modules - dotest cvsadm-1e "${testcvs} ci -m add-modules" \ -"${PROG} [a-z]*: Examining . -${PROG} [a-z]*: Examining CVSROOT -Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} [a-z]*: Rebuilding administrative file database" - rm -rf CVS CVSROOT; - - # Create the various modules - mkdir ${CVSROOT_DIRNAME}/mod1 - mkdir ${CVSROOT_DIRNAME}/mod1-2 - mkdir ${CVSROOT_DIRNAME}/mod2 - mkdir ${CVSROOT_DIRNAME}/mod2/sub2 - mkdir ${CVSROOT_DIRNAME}/mod2-2 - mkdir ${CVSROOT_DIRNAME}/mod2-2/sub2-2 - dotest cvsadm-2 "${testcvs} co mod1 mod1-2 mod2 mod2-2" \ -"${PROG} [a-z]*: Updating mod1 -${PROG} [a-z]*: Updating mod1-2 -${PROG} [a-z]*: Updating mod2 -${PROG} [a-z]*: Updating mod2/sub2 -${PROG} [a-z]*: Updating mod2-2 -${PROG} [a-z]*: Updating mod2-2/sub2-2" - - # Populate the directories for the halibut - echo "file1" > mod1/file1 - echo "file1-2" > mod1-2/file1-2 - echo "file2" > mod2/sub2/file2 - echo "file2-2" > mod2-2/sub2-2/file2-2 - dotest cvsadm-2a "${testcvs} add mod1/file1 mod1-2/file1-2 mod2/sub2/file2 mod2-2/sub2-2/file2-2" \ -"${PROG} [a-z]*: scheduling file .mod1/file1. for addition -${PROG} [a-z]*: scheduling file .mod1-2/file1-2. for addition -${PROG} [a-z]*: scheduling file .mod2/sub2/file2. for addition -${PROG} [a-z]*: scheduling file .mod2-2/sub2-2/file2-2. for addition -${PROG} [a-z]*: use '${PROG} commit' to add these files permanently" - - dotest cvsadm-2b "${testcvs} ci -m yup mod1 mod1-2 mod2 mod2-2" \ -"${PROG} [a-z]*: Examining mod1 -${PROG} [a-z]*: Examining mod1-2 -${PROG} [a-z]*: Examining mod2 -${PROG} [a-z]*: Examining mod2/sub2 -${PROG} [a-z]*: Examining mod2-2 -${PROG} [a-z]*: Examining mod2-2/sub2-2 -RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v -done -Checking in mod1/file1; -${CVSROOT_DIRNAME}/mod1/file1,v <-- file1 -initial revision: 1.1 -done -RCS file: ${CVSROOT_DIRNAME}/mod1-2/file1-2,v -done -Checking in mod1-2/file1-2; -${CVSROOT_DIRNAME}/mod1-2/file1-2,v <-- file1-2 -initial revision: 1.1 -done -RCS file: ${CVSROOT_DIRNAME}/mod2/sub2/file2,v -done -Checking in mod2/sub2/file2; -${CVSROOT_DIRNAME}/mod2/sub2/file2,v <-- file2 -initial revision: 1.1 -done -RCS file: ${CVSROOT_DIRNAME}/mod2-2/sub2-2/file2-2,v -done -Checking in mod2-2/sub2-2/file2-2; -${CVSROOT_DIRNAME}/mod2-2/sub2-2/file2-2,v <-- file2-2 -initial revision: 1.1 -done" - # Finished creating the modules -- clean up. - rm -rf CVS mod1 mod1-2 mod2 mod2-2 - # Done. - - ################################################## - ## Start the dizzying array of possibilities. - ## Begin with each module type separately. - ################################################## - - # Pattern -- after each checkout, first check the top-level - # CVS directory. Then, check the directories in numerical - # order. - - dotest cvsadm-3 "${testcvs} co 1mod" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1" - dotest cvsadm-3b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-3d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS 1mod - - dotest cvsadm-4 "${testcvs} co 2mod" \ -"${PROG} [a-z]*: Updating 2mod -U 2mod/file2" - dotest cvsadm-4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-4d "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS 2mod - - dotest cvsadm-5 "${testcvs} co 1d1mod" \ -"${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1" - dotest cvsadm-5b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-5d "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir1d1 - - dotest cvsadm-6 "${testcvs} co 1d2mod" \ -"${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2" - dotest cvsadm-6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-6d "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir1d2 - - dotest cvsadm-7 "${testcvs} co 2d1mod" \ -"${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - dotest cvsadm-7b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-7d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-7f "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir2d1 - - dotest cvsadm-8 "${testcvs} co 2d2mod" \ -"${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - dotest cvsadm-8b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-8d "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-8f "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir2d2 - - ################################################## - ## You are in a shell script of twisted little - ## module combination statements, all alike. - ################################################## - - ### 1mod - - dotest cvsadm-9 "${testcvs} co 1mod 1mod-2" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1 -${PROG} [a-z]*: Updating 1mod-2 -U 1mod-2/file1-2" - # the usual for the top level - dotest cvsadm-9b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-9d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1mod copy - dotest cvsadm-9f "cat 1mod-2/CVS/Repository" \ -"${AREP}mod1-2" - rm -rf CVS 1mod 1mod-2 - - # 1mod 2mod redmod bluemod - dotest cvsadm-10 "${testcvs} co 1mod 2mod" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1 -${PROG} [a-z]*: Updating 2mod -U 2mod/file2" - # the usual for the top level - dotest cvsadm-10b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-10d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2dmod - dotest cvsadm-10f "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS 1mod 2mod - - dotest cvsadm-11 "${testcvs} co 1mod 1d1mod" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1 -${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1" - # the usual for the top level - dotest cvsadm-11b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-11d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d1mod - dotest cvsadm-11f "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS 1mod dir1d1 - - dotest cvsadm-12 "${testcvs} co 1mod 1d2mod" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1 -${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2" - # the usual for the top level - dotest cvsadm-12b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-12d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d2mod - dotest cvsadm-12f "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS 1mod dir1d2 - - dotest cvsadm-13 "${testcvs} co 1mod 2d1mod" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1 -${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-13b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-13d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d1mod - dotest cvsadm-13f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-13h "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS 1mod dir2d1 - - dotest cvsadm-14 "${testcvs} co 1mod 2d2mod" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1 -${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-14b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-14d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d2mod - dotest cvsadm-14f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-14h "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS 1mod dir2d2 - - - ### 2mod - - dotest cvsadm-15 "${testcvs} co 2mod 2mod-2" \ -"${PROG} [a-z]*: Updating 2mod -U 2mod/file2 -${PROG} [a-z]*: Updating 2mod-2 -U 2mod-2/file2-2" - # the usual for the top level - dotest cvsadm-15b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-15d "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2mod copy - dotest cvsadm-15f "cat 2mod-2/CVS/Repository" \ -"${AREP}mod2-2/sub2-2" - rm -rf CVS 2mod 2mod-2 - - - dotest cvsadm-16 "${testcvs} co 2mod 1d1mod" \ -"${PROG} [a-z]*: Updating 2mod -U 2mod/file2 -${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1" - # the usual for the top level - dotest cvsadm-16b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-16d "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 1d1mod - dotest cvsadm-16f "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS 2mod dir1d1 - - dotest cvsadm-17 "${testcvs} co 2mod 1d2mod" \ -"${PROG} [a-z]*: Updating 2mod -U 2mod/file2 -${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2" - # the usual for the top level - dotest cvsadm-17b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-17d "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 1d2mod - dotest cvsadm-17f "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS 2mod dir1d2 - - dotest cvsadm-18 "${testcvs} co 2mod 2d1mod" \ -"${PROG} [a-z]*: Updating 2mod -U 2mod/file2 -${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-18b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-18d "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-18f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-18h "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS 2mod dir2d1 - - dotest cvsadm-19 "${testcvs} co 2mod 2d2mod" \ -"${PROG} [a-z]*: Updating 2mod -U 2mod/file2 -${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-19b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-19d "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-19f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-19h "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS 2mod dir2d2 - - - ### 1d1mod - - dotest cvsadm-20 "${testcvs} co 1d1mod 1d1mod-2" \ -"${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1 -${PROG} [a-z]*: Updating dir1d1-2 -U dir1d1-2/file1-2" - # the usual for the top level - dotest cvsadm-20b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-20d "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d1mod copy - dotest cvsadm-20f "cat dir1d1-2/CVS/Repository" \ -"${AREP}mod1-2" - rm -rf CVS dir1d1 dir1d1-2 - - dotest cvsadm-21 "${testcvs} co 1d1mod 1d2mod" \ -"${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1 -${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2" - # the usual for the top level - dotest cvsadm-21b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-21d "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d2mod - dotest cvsadm-21f "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir1d1 dir1d2 - - dotest cvsadm-22 "${testcvs} co 1d1mod 2d1mod" \ -"${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1 -${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-22b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-22d "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d1mod - dotest cvsadm-22f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-22h "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir1d1 dir2d1 - - dotest cvsadm-23 "${testcvs} co 1d1mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1 -${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-23b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-23d "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d2mod - dotest cvsadm-23f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-23h "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir1d1 dir2d2 - - - ### 1d2mod - - dotest cvsadm-24 "${testcvs} co 1d2mod 1d2mod-2" \ -"${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2 -${PROG} [a-z]*: Updating dir1d2-2 -U dir1d2-2/file2-2" - # the usual for the top level - dotest cvsadm-24b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1d2mod - dotest cvsadm-24d "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 1d2mod copy - dotest cvsadm-24f "cat dir1d2-2/CVS/Repository" \ -"${AREP}mod2-2/sub2-2" - rm -rf CVS dir1d2 dir1d2-2 - - dotest cvsadm-25 "${testcvs} co 1d2mod 2d1mod" \ -"${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2 -${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-25b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1d2mod - dotest cvsadm-25d "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-25f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-25h "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir1d2 dir2d1 - - dotest cvsadm-26 "${testcvs} co 1d2mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2 -${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-26b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 1d2mod - dotest cvsadm-26d "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-26f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-26h "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir1d2 dir2d2 - - - # 2d1mod - - dotest cvsadm-27 "${testcvs} co 2d1mod 2d1mod-2" \ -"${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1 -${PROG} [a-z]*: Updating dir2d1-2/sub2d1-2 -U dir2d1-2/sub2d1-2/file1-2" - # the usual for the top level - dotest cvsadm-27b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2d1mod - dotest cvsadm-27d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-27f "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d1mod - dotest cvsadm-27h "cat dir2d1-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-27j "cat dir2d1-2/sub2d1-2/CVS/Repository" \ -"${AREP}mod1-2" - rm -rf CVS dir2d1 dir2d1-2 - - dotest cvsadm-28 "${testcvs} co 2d1mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1 -${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-28b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2d1mod - dotest cvsadm-28d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-28f "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d2mod - dotest cvsadm-28h "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-28j "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir2d1 dir2d2 - - - # 2d2mod - - dotest cvsadm-29 "${testcvs} co 2d2mod 2d2mod-2" \ -"${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2 -${PROG} [a-z]*: Updating dir2d2-2/sub2d2-2 -U dir2d2-2/sub2d2-2/file2-2" - # the usual for the top level - dotest cvsadm-29b "cat CVS/Repository" \ -"${AREP}\." - # the usual for 2d2mod - dotest cvsadm-29d "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-29f "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-29h "cat dir2d2-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-29j "cat dir2d2-2/sub2d2-2/CVS/Repository" \ -"${AREP}mod2-2/sub2-2" - rm -rf CVS dir2d2 dir2d2-2 - - ################################################## - ## And now, all of that again using the "-d" flag - ## on the command line. - ################################################## - - dotest cvsadm-1d3 "${testcvs} co -d dir 1mod" \ -"${PROG} [a-z]*: Updating dir -U dir/file1" - dotest cvsadm-1d3b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-1d3d "cat dir/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d4 "${testcvs} co -d dir 2mod" \ -"${PROG} [a-z]*: Updating dir -U dir/file2" - dotest cvsadm-1d4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-1d4d "cat dir/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d5 "${testcvs} co -d dir 1d1mod" \ -"${PROG} [a-z]*: Updating dir -U dir/file1" - dotest cvsadm-1d5b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-1d5d "cat dir/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d6 "${testcvs} co -d dir 1d2mod" \ -"${PROG} [a-z]*: Updating dir -U dir/file2" - dotest cvsadm-1d6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-1d6d "cat dir/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d7 "${testcvs} co -d dir 2d1mod" \ -"${PROG} [a-z]*: Updating dir -U dir/file1" - dotest cvsadm-1d7b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-1d7d "cat dir/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d8 "${testcvs} co -d dir 2d2mod" \ -"${PROG} [a-z]*: Updating dir -U dir/file2" - dotest cvsadm-1d8b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-1d8d "cat dir/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - ################################################## - ## Los Combonaciones - ################################################## - - ### 1mod - - dotest cvsadm-1d9 "${testcvs} co -d dir 1mod 1mod-2" \ -"${PROG} [a-z]*: Updating dir/1mod -U dir/1mod/file1 -${PROG} [a-z]*: Updating dir/1mod-2 -U dir/1mod-2/file1-2" - # the usual for the top level - dotest cvsadm-1d9b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d9d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-1d9f "cat dir/1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1mod copy - dotest cvsadm-1d9h "cat dir/1mod-2/CVS/Repository" \ -"${AREP}mod1-2" - rm -rf CVS dir - - # 1mod 2mod redmod bluemod - dotest cvsadm-1d10 "${testcvs} co -d dir 1mod 2mod" \ -"${PROG} [a-z]*: Updating dir/1mod -U dir/1mod/file1 -${PROG} [a-z]*: Updating dir/2mod -U dir/2mod/file2" - dotest cvsadm-1d10b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d10d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-1d10f "cat dir/1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2dmod - dotest cvsadm-1d10h "cat dir/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d11 "${testcvs} co -d dir 1mod 1d1mod" \ -"${PROG} [a-z]*: Updating dir/1mod -U dir/1mod/file1 -${PROG} [a-z]*: Updating dir/dir1d1 -U dir/dir1d1/file1" - dotest cvsadm-1d11b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d11d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-1d11f "cat dir/1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d1mod - dotest cvsadm-1d11h "cat dir/dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d12 "${testcvs} co -d dir 1mod 1d2mod" \ -"${PROG} [a-z]*: Updating dir/1mod -U dir/1mod/file1 -${PROG} [a-z]*: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-1d12b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d12d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-1d12f "cat dir/1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d2mod - dotest cvsadm-1d12h "cat dir/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d13 "${testcvs} co -d dir 1mod 2d1mod" \ -"${PROG} [a-z]*: Updating dir/1mod -U dir/1mod/file1 -${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d13b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d13d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-1d13f "cat dir/1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d1mod - dotest cvsadm-1d13h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d13j "cat dir/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d14 "${testcvs} co -d dir 1mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir/1mod -U dir/1mod/file1 -${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d14b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d14d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1mod - dotest cvsadm-1d14f "cat dir/1mod/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d2mod - dotest cvsadm-1d14h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d14j "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - - ### 2mod - - dotest cvsadm-1d15 "${testcvs} co -d dir 2mod 2mod-2" \ -"${PROG} [a-z]*: Updating dir/2mod -U dir/2mod/file2 -${PROG} [a-z]*: Updating dir/2mod-2 -U dir/2mod-2/file2-2" - dotest cvsadm-1d15b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d15d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-1d15f "cat dir/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2mod copy - dotest cvsadm-1d15h "cat dir/2mod-2/CVS/Repository" \ -"${AREP}mod2-2/sub2-2" - rm -rf CVS dir - - dotest cvsadm-1d16 "${testcvs} co -d dir 2mod 1d1mod" \ -"${PROG} [a-z]*: Updating dir/2mod -U dir/2mod/file2 -${PROG} [a-z]*: Updating dir/dir1d1 -U dir/dir1d1/file1" - dotest cvsadm-1d16b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d16d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-1d16f "cat dir/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 1d1mod - dotest cvsadm-1d16h "cat dir/dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d17 "${testcvs} co -d dir 2mod 1d2mod" \ -"${PROG} [a-z]*: Updating dir/2mod -U dir/2mod/file2 -${PROG} [a-z]*: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-1d17b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d17d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-1d17f "cat dir/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 1d2mod - dotest cvsadm-1d17h "cat dir/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d18 "${testcvs} co -d dir 2mod 2d1mod" \ -"${PROG} [a-z]*: Updating dir/2mod -U dir/2mod/file2 -${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d18b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d18d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-1d18f "cat dir/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-1d18h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d18j "cat dir/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d19 "${testcvs} co -d dir 2mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir/2mod -U dir/2mod/file2 -${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d19b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d19d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2mod - dotest cvsadm-1d19f "cat dir/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-1d19h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d19j "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - - ### 1d1mod - - dotest cvsadm-1d20 "${testcvs} co -d dir 1d1mod 1d1mod-2" \ -"${PROG} [a-z]*: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} [a-z]*: Updating dir/dir1d1-2 -U dir/dir1d1-2/file1-2" - dotest cvsadm-1d20b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d20d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-1d20f "cat dir/dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d1mod copy - dotest cvsadm-1d20h "cat dir/dir1d1-2/CVS/Repository" \ -"${AREP}mod1-2" - rm -rf CVS dir - - dotest cvsadm-1d21 "${testcvs} co -d dir 1d1mod 1d2mod" \ -"${PROG} [a-z]*: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} [a-z]*: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-1d21b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d21d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-1d21f "cat dir/dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 1d2mod - dotest cvsadm-1d21h "cat dir/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d22 "${testcvs} co -d dir 1d1mod 2d1mod" \ -"${PROG} [a-z]*: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d22b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d22d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-1d22f "cat dir/dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d1mod - dotest cvsadm-1d22h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d22j "cat dir/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d23 "${testcvs} co -d dir 1d1mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d23b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d23d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1d1mod - dotest cvsadm-1d23f "cat dir/dir1d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d2mod - dotest cvsadm-1d23h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d23j "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - - ### 1d2mod - - dotest cvsadm-1d24 "${testcvs} co -d dir 1d2mod 1d2mod-2" \ -"${PROG} [a-z]*: Updating dir/dir1d2 -U dir/dir1d2/file2 -${PROG} [a-z]*: Updating dir/dir1d2-2 -U dir/dir1d2-2/file2-2" - dotest cvsadm-1d24b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d24d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1d2mod - dotest cvsadm-1d24f "cat dir/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 1d2mod copy - dotest cvsadm-1d24h "cat dir/dir1d2-2/CVS/Repository" \ -"${AREP}mod2-2/sub2-2" - rm -rf CVS dir - - dotest cvsadm-1d25 "${testcvs} co -d dir 1d2mod 2d1mod" \ -"${PROG} [a-z]*: Updating dir/dir1d2 -U dir/dir1d2/file2 -${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d25b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d25d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1d2mod - dotest cvsadm-1d25f "cat dir/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-1d25h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d25j "cat dir/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-1d26 "${testcvs} co -d dir 1d2mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir/dir1d2 -U dir/dir1d2/file2 -${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d26b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d26d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 1d2mod - dotest cvsadm-1d26f "cat dir/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-1d26h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d26j "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - - # 2d1mod - - dotest cvsadm-1d27 "${testcvs} co -d dir 2d1mod 2d1mod-2" \ -"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1 -${PROG} [a-z]*: Updating dir/dir2d1-2/sub2d1-2 -U dir/dir2d1-2/sub2d1-2/file1-2" - dotest cvsadm-1d27b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d27d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2d1mod - dotest cvsadm-1d27f "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d27h "cat dir/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d1mod - dotest cvsadm-1d27j "cat dir/dir2d1-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d27l "cat dir/dir2d1-2/sub2d1-2/CVS/Repository" \ -"${AREP}mod1-2" - rm -rf CVS dir - - dotest cvsadm-1d28 "${testcvs} co -d dir 2d1mod 2d2mod" \ -"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1 -${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d28b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d28d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2d1mod - dotest cvsadm-1d28f "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d28h "cat dir/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - # the usual for 2d2mod - dotest cvsadm-1d28j "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d28l "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - - # 2d2mod - - dotest cvsadm-1d29 "${testcvs} co -d dir 2d2mod 2d2mod-2" \ -"${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2 -${PROG} [a-z]*: Updating dir/dir2d2-2/sub2d2-2 -U dir/dir2d2-2/sub2d2-2/file2-2" - dotest cvsadm-1d29b "cat CVS/Repository" \ -"${AREP}\." - # the usual for the dir level - dotest cvsadm-1d29d "cat dir/CVS/Repository" \ -"${AREP}\." - # the usual for 2d2mod - dotest cvsadm-1d29f "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d29h "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-1d29j "cat dir/dir2d2-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-1d29l "cat dir/dir2d2-2/sub2d2-2/CVS/Repository" \ -"${AREP}mod2-2/sub2-2" - rm -rf CVS dir - - ################################################## - ## And now, some of that again using the "-d" flag - ## on the command line, but use a longer path. - ################################################## - - dotest cvsadm-2d3 "${testcvs} co -d dir/dir2 1mod" \ -"${PROG} [a-z]*: Updating dir/dir2 -U dir/dir2/file1" - dotest cvsadm-2d3b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-2d3d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-2d3f "cat dir/dir2/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-2d4 "${testcvs} co -d dir/dir2 2mod" \ -"${PROG} [a-z]*: Updating dir/dir2 -U dir/dir2/file2" - dotest cvsadm-2d4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-2d4d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-2d4f "cat dir/dir2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-2d5 "${testcvs} co -d dir/dir2 1d1mod" \ -"${PROG} [a-z]*: Updating dir/dir2 -U dir/dir2/file1" - dotest cvsadm-2d5b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-2d5d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-2d5f "cat dir/dir2/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-2d6 "${testcvs} co -d dir/dir2 1d2mod" \ -"${PROG} [a-z]*: Updating dir/dir2 -U dir/dir2/file2" - dotest cvsadm-2d6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-2d6d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-2d6f "cat dir/dir2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-2d7 "${testcvs} co -d dir/dir2 2d1mod" \ -"${PROG} [a-z]*: Updating dir/dir2 -U dir/dir2/file1" - dotest cvsadm-2d7b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-2d7d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-2d7f "cat dir/dir2/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-2d8 "${testcvs} co -d dir/dir2 2d2mod" \ -"${PROG} [a-z]*: Updating dir/dir2 -U dir/dir2/file2" - dotest cvsadm-2d8b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-2d8d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-2d8f "cat dir/dir2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - ################################################## - ## And now, a few of those tests revisited to - ## test the behavior of the -N flag. - ################################################## - - dotest cvsadm-N3 "${testcvs} co -N 1mod" \ -"${PROG} [a-z]*: Updating 1mod -U 1mod/file1" - dotest cvsadm-N3b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N3d "cat 1mod/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS 1mod - - dotest cvsadm-N4 "${testcvs} co -N 2mod" \ -"${PROG} [a-z]*: Updating 2mod -U 2mod/file2" - dotest cvsadm-N4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N4d "cat 2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS 2mod - - dotest cvsadm-N5 "${testcvs} co -N 1d1mod" \ -"${PROG} [a-z]*: Updating dir1d1 -U dir1d1/file1" - dotest cvsadm-N5b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N5d "cat dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir1d1 - - dotest cvsadm-N6 "${testcvs} co -N 1d2mod" \ -"${PROG} [a-z]*: Updating dir1d2 -U dir1d2/file2" - dotest cvsadm-N6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N6d "cat dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir1d2 - - dotest cvsadm-N7 "${testcvs} co -N 2d1mod" \ -"${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - dotest cvsadm-N7b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N7d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N7f "cat dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir2d1 - - dotest cvsadm-N8 "${testcvs} co -N 2d2mod" \ -"${PROG} [a-z]*: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - dotest cvsadm-N8b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N8d "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N8f "cat dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir2d2 - - ## the ones in one-deep directories - - dotest cvsadm-N1d3 "${testcvs} co -N -d dir 1mod" \ -"${PROG} [a-z]*: Updating dir/1mod -U dir/1mod/file1" - dotest cvsadm-N1d3b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d3d "cat dir/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d3f "cat dir/1mod/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-N1d4 "${testcvs} co -N -d dir 2mod" \ -"${PROG} [a-z]*: Updating dir/2mod -U dir/2mod/file2" - dotest cvsadm-N1d4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d4d "cat dir/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d4f "cat dir/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-N1d5 "${testcvs} co -N -d dir 1d1mod" \ -"${PROG} [a-z]*: Updating dir/dir1d1 -U dir/dir1d1/file1" - dotest cvsadm-N1d5b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d5d "cat dir/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d5d "cat dir/dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-N1d6 "${testcvs} co -N -d dir 1d2mod" \ -"${PROG} [a-z]*: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-N1d6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d6d "cat dir/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d6f "cat dir/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-N1d7 "${testcvs} co -N -d dir 2d1mod" \ -"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-N1d7b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d7d "cat dir/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d7f "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N1d7h "cat dir/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-N1d8 "${testcvs} co -N -d dir 2d2mod" \ -"${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-N1d8b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d8d "cat dir/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d8d "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N1d8d "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - ## the ones in two-deep directories - - dotest cvsadm-N2d3 "${testcvs} co -N -d dir/dir2 1mod" \ -"${PROG} [a-z]*: Updating dir/dir2/1mod -U dir/dir2/1mod/file1" - dotest cvsadm-N2d3b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d3d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d3f "cat dir/dir2/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d3h "cat dir/dir2/1mod/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-N2d4 "${testcvs} co -N -d dir/dir2 2mod" \ -"${PROG} [a-z]*: Updating dir/dir2/2mod -U dir/dir2/2mod/file2" - dotest cvsadm-N2d4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d4d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d4f "cat dir/dir2/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d4h "cat dir/dir2/2mod/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-N2d5 "${testcvs} co -N -d dir/dir2 1d1mod" \ -"${PROG} [a-z]*: Updating dir/dir2/dir1d1 -U dir/dir2/dir1d1/file1" - dotest cvsadm-N2d5b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d5d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d5f "cat dir/dir2/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d5h "cat dir/dir2/dir1d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-N2d6 "${testcvs} co -N -d dir/dir2 1d2mod" \ -"${PROG} [a-z]*: Updating dir/dir2/dir1d2 -U dir/dir2/dir1d2/file2" - dotest cvsadm-N2d6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d6d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d6f "cat dir/dir2/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d6h "cat dir/dir2/dir1d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-N2d7 "${testcvs} co -N -d dir/dir2 2d1mod" \ -"${PROG} [a-z]*: Updating dir/dir2/dir2d1/sub2d1 -U dir/dir2/dir2d1/sub2d1/file1" - dotest cvsadm-N2d7b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d7d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d7f "cat dir/dir2/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d7f "cat dir/dir2/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d7h "cat dir/dir2/dir2d1/sub2d1/CVS/Repository" \ -"${AREP}mod1" - rm -rf CVS dir - - dotest cvsadm-N2d8 "${testcvs} co -N -d dir/dir2 2d2mod" \ -"${PROG} [a-z]*: Updating dir/dir2/dir2d2/sub2d2 -U dir/dir2/dir2d2/sub2d2/file2" - dotest cvsadm-N2d8b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d8d "cat dir/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d8f "cat dir/dir2/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d8h "cat dir/dir2/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d8j "cat dir/dir2/dir2d2/sub2d2/CVS/Repository" \ -"${AREP}mod2/sub2" - rm -rf CVS dir - - ################################################## - ## That's enough of that, thank you very much. - ################################################## - - # remove our junk - cd .. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/1mod - rm -rf ${CVSROOT_DIRNAME}/1mod-2 - rm -rf ${CVSROOT_DIRNAME}/2mod - rm -rf ${CVSROOT_DIRNAME}/2mod-2 - ;; - diffmerge1) # Make sure CVS can merge correctly in circumstances where it # used to mess up (due to a bug which existed in diffutils 2.7 @@ -13439,6 +14027,9 @@ d472 12 dotest diffmerge2_diff \ "${testcvs} diff -r Review_V1p3 sgrid.h" '' + cd .. + rm -rf diffmerge2 + rm -rf ${CVSROOT_DIRNAME}/diffmerge2 ;; *) diff --git a/contrib/cvs/src/server.h b/contrib/cvs/src/server.h index e5a3c3f..f94b7aa 100644 --- a/contrib/cvs/src/server.h +++ b/contrib/cvs/src/server.h @@ -57,16 +57,19 @@ extern void server_checked_in extern void server_copy_file PROTO((char *file, char *update_dir, char *repository, char *newfile)); -/* Send the appropriate responses for a file described by FILE, - UPDATE_DIR, REPOSITORY, and VERS. FILE_INFO is the result of - statting the file, or NULL if it hasn't been statted yet. This is - called after server_register or server_scratch. In the latter case - the file is to be removed (and vers can be NULL). In the former - case, vers must be non-NULL, and UPDATED indicates whether the file - is now up to date (SERVER_UPDATED, yes, SERVER_MERGED, no, - SERVER_PATCHED, yes, but file is a diff from user version to - repository version, SERVER_RCS_DIFF, yes, like SERVER_PATCHED but - with an RCS style diff). */ +/* Send the appropriate responses for a file described by FINFO and + VERS. This is called after server_register or server_scratch. In + the latter case the file is to be removed (and VERS can be NULL). + In the former case, VERS must be non-NULL, and UPDATED indicates + whether the file is now up to date (SERVER_UPDATED, yes, + SERVER_MERGED, no, SERVER_PATCHED, yes, but file is a diff from + user version to repository version, SERVER_RCS_DIFF, yes, like + SERVER_PATCHED but with an RCS style diff). MODE is the mode the + file should get, or (mode_t) -1 if this should be obtained from the + file itself. CHECKSUM is the MD5 checksum of the file, or NULL if + this need not be sent. If FILEBUF is not NULL, it holds the + contents of the file, in which case the file itself may not exist. + If FILEBUF is not NULL, server_updated will free it. */ enum server_updated_arg4 { SERVER_UPDATED, @@ -74,10 +77,14 @@ enum server_updated_arg4 SERVER_PATCHED, SERVER_RCS_DIFF }; +#ifdef __STDC__ +struct buffer; +#endif + extern void server_updated PROTO((struct file_info *finfo, Vers_TS *vers, - enum server_updated_arg4 updated, struct stat *, - unsigned char *checksum)); + enum server_updated_arg4 updated, mode_t mode, + unsigned char *checksum, struct buffer *filebuf)); /* Whether we should send RCS format patches. */ extern int server_use_rcs_diff PROTO((void)); diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c index 61b3103..07d516f 100644 --- a/contrib/cvs/src/subr.c +++ b/contrib/cvs/src/subr.c @@ -288,18 +288,13 @@ increment_revnum (rev) /* Return the username by which the caller should be identified in CVS, in contexts such as the author field of RCS files, various - logs, etc. - - Returns a pointer to storage that we manage; it is good until the - next call to getcaller () (provided that the caller doesn't call - getlogin () or some such themself). */ + logs, etc. */ char * getcaller () { #ifndef SYSTEM_GETCALLER - static char uidname[20]; + static char *cache; struct passwd *pw; - char *name; uid_t uid; #endif @@ -316,20 +311,32 @@ getcaller () try LOGNAME USER or getlogin(). If getlogin() and getpwuid() both fail, return the uid as a string. */ + if (cache != NULL) + return cache; + uid = getuid (); if (uid == (uid_t) 0) { + char *name; + /* super-user; try getlogin() to distinguish */ if (((name = getlogin ()) || (name = getenv("LOGNAME")) || (name = getenv("USER"))) && *name) - return (name); + { + cache = xstrdup (name); + return cache; + } } if ((pw = (struct passwd *) getpwuid (uid)) == NULL) { + char uidname[20]; + (void) sprintf (uidname, "uid%lu", (unsigned long) uid); - return (uidname); + cache = xstrdup (uidname); + return cache; } - return (pw->pw_name); + cache = xstrdup (pw->pw_name); + return cache; #endif } @@ -608,8 +615,16 @@ get_file (name, fullname, mode, buf, bufsize, len) } else { - if (CVS_STAT (name, &s) < 0) + if (CVS_LSTAT (name, &s) < 0) error (1, errno, "can't stat %s", fullname); + + /* Don't attempt to read special files or symlinks. */ + if (!S_ISREG (s.st_mode)) + { + *len = 0; + return; + } + /* Convert from signed to unsigned. */ filesize = s.st_size; diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c index bae3a43..be0f588 100644 --- a/contrib/cvs/src/vers_ts.c +++ b/contrib/cvs/src/vers_ts.c @@ -251,7 +251,7 @@ time_stamp_server (file, vers_ts, entdata) struct stat sb; char *cp; - if ( CVS_STAT (file, &sb) < 0) + if (CVS_LSTAT (file, &sb) < 0) { if (! existence_error (errno)) error (1, errno, "cannot stat temp file"); @@ -322,7 +322,7 @@ time_stamp (file) char *cp; char *ts; - if ( CVS_STAT (file, &sb) < 0) + if (CVS_LSTAT (file, &sb) < 0) { ts = NULL; } diff --git a/contrib/cvs/src/version.c b/contrib/cvs/src/version.c index 1f77f58..f386895 100644 --- a/contrib/cvs/src/version.c +++ b/contrib/cvs/src/version.c @@ -12,7 +12,7 @@ #include "cvs.h" -char *version_string = "\nConcurrent Versions System (CVS) 1.9.24"; +char *version_string = "\nConcurrent Versions System (CVS) 1.9.26"; #ifdef CLIENT_SUPPORT #ifdef SERVER_SUPPORT diff --git a/contrib/cvs/tools/ChangeLog b/contrib/cvs/tools/ChangeLog index 407c053..8cd177e 100644 --- a/contrib/cvs/tools/ChangeLog +++ b/contrib/cvs/tools/ChangeLog @@ -1,3 +1,7 @@ +Sat Feb 21 22:02:12 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (clean): Change "/bin/rm" to "rm". + Wed Jan 8 14:50:47 1997 Jim Kingdon <kingdon@harvey.cyclic.com> * Makefile.in: Remove CVSid; we decided to get rid diff --git a/contrib/cvs/tools/Makefile.in b/contrib/cvs/tools/Makefile.in index 3a39bc3..578b210 100644 --- a/contrib/cvs/tools/Makefile.in +++ b/contrib/cvs/tools/Makefile.in @@ -50,7 +50,7 @@ ls: .PHONY: ls clean: - /bin/rm -f *.o core + rm -f *.o core .PHONY: clean distclean: clean |