summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/cvs/COPYING6
-rw-r--r--gnu/usr.bin/cvs/COPYING.LIB7
-rw-r--r--gnu/usr.bin/cvs/ChangeLog116
-rw-r--r--gnu/usr.bin/cvs/FAQ243
-rw-r--r--gnu/usr.bin/cvs/HACKING2
-rw-r--r--gnu/usr.bin/cvs/INSTALL18
-rw-r--r--gnu/usr.bin/cvs/NEWS25
-rw-r--r--gnu/usr.bin/cvs/TESTS12
-rw-r--r--gnu/usr.bin/cvs/TODO23
-rw-r--r--gnu/usr.bin/cvs/contrib/.cvsignore3
-rw-r--r--gnu/usr.bin/cvs/contrib/ChangeLog44
-rw-r--r--gnu/usr.bin/cvs/contrib/README11
-rw-r--r--gnu/usr.bin/cvs/contrib/log.pl5
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs2log.sh326
-rw-r--r--gnu/usr.bin/cvs/diff/ChangeLog32
-rw-r--r--gnu/usr.bin/cvs/diff/analyze.c4
-rw-r--r--gnu/usr.bin/cvs/diff/cmpbuf.c4
-rw-r--r--gnu/usr.bin/cvs/diff/cmpbuf.h4
-rw-r--r--gnu/usr.bin/cvs/diff/context.c4
-rw-r--r--gnu/usr.bin/cvs/diff/diagmeet.note71
-rw-r--r--gnu/usr.bin/cvs/diff/diff.c4
-rw-r--r--gnu/usr.bin/cvs/diff/diff.h4
-rw-r--r--gnu/usr.bin/cvs/diff/diff3.c4
-rw-r--r--gnu/usr.bin/cvs/diff/diffrun.h10
-rw-r--r--gnu/usr.bin/cvs/diff/dir.c4
-rw-r--r--gnu/usr.bin/cvs/diff/ed.c4
-rw-r--r--gnu/usr.bin/cvs/diff/io.c4
-rw-r--r--gnu/usr.bin/cvs/diff/normal.c4
-rw-r--r--gnu/usr.bin/cvs/diff/system.h7
-rw-r--r--gnu/usr.bin/cvs/diff/util.c56
-rw-r--r--gnu/usr.bin/cvs/doc/ChangeLog254
-rw-r--r--gnu/usr.bin/cvs/doc/RCSFILES30
-rw-r--r--gnu/usr.bin/cvs/doc/cvs-paper.ms4
-rw-r--r--gnu/usr.bin/cvs/doc/cvs.texinfo922
-rw-r--r--gnu/usr.bin/cvs/doc/cvsclient.texi169
-rw-r--r--gnu/usr.bin/cvs/emx/ChangeLog5
-rw-r--r--gnu/usr.bin/cvs/emx/Makefile.in3
-rw-r--r--gnu/usr.bin/cvs/lib/ChangeLog38
-rw-r--r--gnu/usr.bin/cvs/lib/build_lib.com3
-rw-r--r--gnu/usr.bin/cvs/lib/fnmatch.c13
-rw-r--r--gnu/usr.bin/cvs/lib/md5.c55
-rw-r--r--gnu/usr.bin/cvs/lib/md5.h23
-rw-r--r--gnu/usr.bin/cvs/man/ChangeLog4
-rw-r--r--gnu/usr.bin/cvs/man/Makefile.in2
-rw-r--r--gnu/usr.bin/cvs/os2/ChangeLog9
-rw-r--r--gnu/usr.bin/cvs/os2/Makefile.in4
-rw-r--r--gnu/usr.bin/cvs/src/ChangeLog1069
-rw-r--r--gnu/usr.bin/cvs/src/add.c4
-rw-r--r--gnu/usr.bin/cvs/src/admin.c17
-rw-r--r--gnu/usr.bin/cvs/src/client.c544
-rw-r--r--gnu/usr.bin/cvs/src/client.h5
-rw-r--r--gnu/usr.bin/cvs/src/create_adm.c6
-rw-r--r--gnu/usr.bin/cvs/src/cvsrc.c7
-rw-r--r--gnu/usr.bin/cvs/src/diff.c28
-rw-r--r--gnu/usr.bin/cvs/src/edit.c25
-rw-r--r--gnu/usr.bin/cvs/src/entries.c41
-rw-r--r--gnu/usr.bin/cvs/src/error.c165
-rw-r--r--gnu/usr.bin/cvs/src/expand_path.c9
-rw-r--r--gnu/usr.bin/cvs/src/filesubr.c43
-rw-r--r--gnu/usr.bin/cvs/src/find_names.c63
-rw-r--r--gnu/usr.bin/cvs/src/hardlink.c2
-rw-r--r--gnu/usr.bin/cvs/src/history.c14
-rw-r--r--gnu/usr.bin/cvs/src/import.c113
-rw-r--r--gnu/usr.bin/cvs/src/log.c16
-rw-r--r--gnu/usr.bin/cvs/src/login.c20
-rw-r--r--gnu/usr.bin/cvs/src/logmsg.c6
-rw-r--r--gnu/usr.bin/cvs/src/modules.c22
-rw-r--r--gnu/usr.bin/cvs/src/myndbm.c6
-rw-r--r--gnu/usr.bin/cvs/src/no_diff.c9
-rw-r--r--gnu/usr.bin/cvs/src/options.h.in11
-rw-r--r--gnu/usr.bin/cvs/src/rcs.h2
-rw-r--r--gnu/usr.bin/cvs/src/recurse.c343
-rw-r--r--gnu/usr.bin/cvs/src/release.c73
-rw-r--r--gnu/usr.bin/cvs/src/remove.c8
-rw-r--r--gnu/usr.bin/cvs/src/root.c95
-rw-r--r--gnu/usr.bin/cvs/src/rtag.c15
-rw-r--r--gnu/usr.bin/cvs/src/run.c91
-rw-r--r--gnu/usr.bin/cvs/src/sanity.sh3985
-rw-r--r--gnu/usr.bin/cvs/src/server.h60
-rw-r--r--gnu/usr.bin/cvs/src/status.c6
-rw-r--r--gnu/usr.bin/cvs/src/subr.c64
-rw-r--r--gnu/usr.bin/cvs/src/tag.c31
-rw-r--r--gnu/usr.bin/cvs/src/vers_ts.c20
-rw-r--r--gnu/usr.bin/cvs/src/version.c3
-rw-r--r--gnu/usr.bin/cvs/src/watch.c22
-rw-r--r--gnu/usr.bin/cvs/src/wrapper.c13
-rw-r--r--gnu/usr.bin/cvs/src/zlib.c84
-rw-r--r--gnu/usr.bin/cvs/tools/ChangeLog6
-rw-r--r--gnu/usr.bin/cvs/tools/Makefile.in3
-rw-r--r--gnu/usr.bin/cvs/tools/README14
-rw-r--r--gnu/usr.bin/cvs/windows-NT/ChangeLog28
-rw-r--r--gnu/usr.bin/cvs/windows-NT/README67
-rw-r--r--gnu/usr.bin/cvs/windows-NT/SCC/ChangeLog4
-rw-r--r--gnu/usr.bin/cvs/windows-NT/SCC/README.txt1
-rw-r--r--gnu/usr.bin/cvs/windows-NT/config.h5
-rw-r--r--gnu/usr.bin/cvs/windows-NT/filesubr.c37
-rw-r--r--gnu/usr.bin/cvs/windows-NT/win32.c31
97 files changed, 8079 insertions, 1876 deletions
diff --git a/gnu/usr.bin/cvs/COPYING b/gnu/usr.bin/cvs/COPYING
index 9a170375811..57da8a45c33 100644
--- a/gnu/usr.bin/cvs/COPYING
+++ b/gnu/usr.bin/cvs/COPYING
@@ -1,9 +1,11 @@
+[I have snipped the snail mail address of the FSF because it has
+changed in the past and is likely to change again. The current
+address should be at http://www.gnu.org/]
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Copyright (C) 1989 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -217,7 +219,7 @@ the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ Foundation, Inc.
Also add information on how to contact you by electronic and paper mail.
diff --git a/gnu/usr.bin/cvs/COPYING.LIB b/gnu/usr.bin/cvs/COPYING.LIB
index eb685a5ec98..5e5cda218c8 100644
--- a/gnu/usr.bin/cvs/COPYING.LIB
+++ b/gnu/usr.bin/cvs/COPYING.LIB
@@ -1,8 +1,11 @@
+[I have snipped the snail mail address of the FSF because it has
+changed in the past and is likely to change again. The current
+address should be at http://www.gnu.org/]
+
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -464,7 +467,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ Software Foundation, Inc.
Also add information on how to contact you by electronic and paper mail.
diff --git a/gnu/usr.bin/cvs/ChangeLog b/gnu/usr.bin/cvs/ChangeLog
index cb4801be423..cc0da9ea698 100644
--- a/gnu/usr.bin/cvs/ChangeLog
+++ b/gnu/usr.bin/cvs/ChangeLog
@@ -1,3 +1,119 @@
+1999-02-09 Jim Kingdon <http://www.cyclic.com>
+
+ * configure.in (AC_REPLACE_FUNCS): Remove vasprintf; see
+ lib/ChangeLog for rationale.
+ * configure: Regenerated.
+
+1999-01-31 Assar Westerlund of sics.se
+ and Jim Kingdon
+
+ * configure.in: The GSSAPI code in CVS requires krb5.h which
+ Solaris 2.7 doesn't have. Check for it.
+ * configure: Regenerated.
+
+1999-01-12 Jim Kingdon <http://www.cyclic.com>
+
+ * COPYING, COPYING.LIB: Remove obsolete snail address of the Free
+ Software Foundation.
+
+1998-12-01 Jim Kingdon
+
+ * TODO (195): Check in a few clarifications from Andrew Tridgell,
+ the rsync author.
+
+1998-11-11 Jim Kingdon
+
+ * HACKING: Change prep.ai.mit.edu to gnu.org.
+
+1998-10-26 Jim Kingdon
+
+ * INSTALL: Add information for Sequent DYNIX/ptx4.0, from a report
+ by Marco Franzen.
+
+1998-10-14 Jim Kingdon
+
+ * configure.in (AC_OUTPUT): Remove contrib/elib/Makefile.
+ * configure: Regenerated using autoconf 2.10.
+
+1998-10-13 Jim Kingdon
+
+ * TODO (149): Update since -d doesn't rewrite CVS/Root any more.
+
+1998-10-03 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * TODO (31): Mention the ,foo.c, and SIGINT issue.
+
+1998-09-25 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * FAQ: Update from FAQ-O-Matic. This features fewer blank lines
+ and a few more minor formatting changes (not sure whether the
+ FAQ-O-Matic changed or whether this is because I upgraded Lynx).
+ I read through the diffs, and the real changes are: (A) In
+ /Advanced_Topics_/Setting_up_and_Manag/, #1, describe "cvs init",
+ don't describe committing modules file twice
+ (no longer needed now that mkmodules is not a separate program),
+ don't mention "cvs import" here. (B)
+ /Advanced_Topics_/Setting_up_and_Manag/, #5, describe special
+ issues with pserver and repository permissions,
+ (C), /Advanced_Topics_/Tricks_of_the_Trade/, renumber the question
+ "Why do timestamps sometimes get set to the date of the revision"
+ from #17 to #9. Renumber the questions between #9 and #17
+ accordingly, (D) /User_Tasks_/Less_Common_User_Tas/, "8. How do I
+ split a file into pieces, retaining revision histories?", include
+ a script which may help with this, (E)
+ /What_is_CVS_/How_does_CVS_differ_/, correct the name of SABLIME,
+ (F) /What_is_CVS_/Where_do_I_find_CVS_/, "2. Is there an archive
+ of CVS material?", note that http://www.delos.com/cvs doesn't
+ exist any more.
+
+ * NEWS: Mention :fork:.
+
+1998-09-24 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * INSTALL (Tested platforms): Update SCO OpenServer information,
+ from a report by Robert Lipe@DIGI.
+
+1998-09-22 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * NEWS: Add items about multiple roots and -d not updating
+ CVS/Root.
+
+1998-09-09 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * configure.in (AC_OUTPUT): Remove tools/pcl-cvs/Makefile.
+ * configure: Regenerated using autoconf 2.10.
+
+1998-09-07 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * NEWS: Add item about LockDir.
+
+1998-08-31 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * INSTALL (Tested platforms): Add Solaris x86 (reported by Jeremy of
+ exit109.com) and Irix 6.4 (reported by Russ Allbery).
+
+ * INSTALL (Tested platforms): Add Solaris 2.6 (reported by Russ
+ Allbery).
+
+1998-08-28 Noel Cragg <noel@swish.red-bean.com>
+
+ * TODO (196): new item.
+
+1998-08-26 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * TESTS: Update comments concerning Solaris sort and LC_COLLATE.
+
+1998-08-17 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * INSTALL: Update Irix, Ultrix, and NetBSD/Alpha with test results
+ from Noel.
+
+1998-08-14 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * INSTALL: Add NetBSD/mac68k (reported by Hauke Fath of melog.de).
+ Add alpha-dec-osf4.0 and update SunOS and linux entries (reported
+ by Jim Kingdon and Noel Cragg).
+
1998-08-06 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL: Update for SCO OpenServer 5 (reported by Jeffery
diff --git a/gnu/usr.bin/cvs/FAQ b/gnu/usr.bin/cvs/FAQ
index 20912ddb40e..06fe8180da6 100644
--- a/gnu/usr.bin/cvs/FAQ
+++ b/gnu/usr.bin/cvs/FAQ
@@ -126,12 +126,10 @@ molli@loria.fr
CVS uses the word "branch" in a number of ways. The two most
important are:
-
- The vendor branch holds releases from (normally) an outside
software vendor. It is implemented using a specific RCS branch
(i.e. 1.1.1).
-
- The "Main Branch", which normally holds your "Main Line
Development", but is defined as the collection of revisions you
get when you "checkout" something fresh, or when you use the
@@ -142,7 +140,6 @@ molli@loria.fr
Branches, files you have never changed are on three branches at
the same time:
-
- The RCS 1.1.1 branch.
- The CVS Vendor branch.
- The CVS "Main Branch".
@@ -151,13 +148,11 @@ molli@loria.fr
In referring to CVS, "branch" can be used in four other ways:
-
- A CVS working directory satisfies the definition of "branch"
for a single developer -- you are on a private "virtual branch"
that does not appear in any of the RCS files or the CVS control
files.
-
- The CVS "default branch" is the Repository source for the
collection of files in your working directory. It is *not* the
same as the RCS "default branch". Normally the CVS default
@@ -166,26 +161,22 @@ molli@loria.fr
a "sticky" tag that changes your default branch to the one you
checked out.
-
- A "magic" branch can be a branch that hasn't happened yet. It
is implemented by a special tag you can check out that is not
attached to a real RCS branch. When you commit a file to a
magic branch, the branch becomes real (i.e. a physical RCS
branch).
-
- And, of course, CVS uses "branch" to indicate a
human-oriented "branch in development".
How RCS uses the word "branch":
-
- The RCS "Main Branch" (Synonym: "The Trunk") contains a
series of two-part revision numbers separated by a single '.'
(e.g. 1.2). It is treated specially and is the initial default
branch. (The default default?)
-
- The RCS "Default" branch starts out attached to the RCS "Main
Branch". For RCS purposes, it can be changed to point to any
branch. Within CVS, you *must*not* alter the RCS default
@@ -358,11 +349,9 @@ molli@loria.fr
directory (in ./CVS/Tag) and the checked-out files (on each line of
./CVS/Entries).
-
- A "sticky" <tag> (including a <branch_tag>) causes most CVS commands
to act as if "-r <tag>" were on the command line.
-
- A "sticky" <branch_tag> indicates that the working directory (and
working files) are "on the branch".
@@ -377,17 +366,13 @@ molli@loria.fr
Specifically, you must:
-
- Remember that the branch exists. (This is non-trivial if you create
a lot of them.)
-
- Plan when to merge it back into the main line of development.
-
- Schedule the order that multiple branch merges are to be done.
-
- If you ever intend to merge branches into each other, instead of
limiting merges of branch work back into the "main line", you must
keep careful track of which parts of which branches have merged into
@@ -1445,13 +1430,11 @@ You can branch a branch.
So, here's an un-reviewed suggestion originally from Graydon Dodson
<grdodson@lexmark.com>, which I've altered and edited heavily.
-
- Keep a directory where the whole tree is checked out. (It might be
built and tested once in a while to make sure it is worth linking to,
but that doesn't affect the source control aspect of this procedure).
Let's call it /master/build.
-
- Write a tool that creates a tree of directories (like the X11
"lndir" command) filled with links to the checked out files in the
/master/build tree.
@@ -1459,14 +1442,12 @@ You can branch a branch.
This tool should also provide real copies of, not symlinks to, all the
files within the CVS administrative directories.
-
- You could also provide a way for the tool to take a list of whole
directories that you will never change, for which it would create a
single symlink to the directory and not a subtree of symlinks to
files. Or you could rm -r pieces of the resulting working directory
yourself and replace it with links.
-
- If you want to edit a file, you have to grab a real copy and keep it
until your revision shows up in the /master/build tree. I'd create a
script to do this: cvsgrab <file>
@@ -1487,12 +1468,10 @@ You can branch a branch.
You'll have to run "update" before "commit" anyway if there are newer
revisions.
-
- Presumably there would also be a tool to traverse the link tree and
revert it to links if there are no modified files and/or if all the
real files match the revision of the /master/build tree.
-
- To avoid confusing CVS when the /master/build revisions are updated
but your CVS/Entries files is not, CVS would have to change to handle
symlinks. It currently causes problems with this scenario:
@@ -1627,7 +1606,6 @@ You can branch a branch.
RCS versions earlier than 5.5 print the above error when a file does
not end in a newline character. It can be caused by:
-
- Editing with Emacs and not using "require-final-newline".
- Committing a binary file.
- Filesystem failures (NFS!) that put nulls in your file.
@@ -1738,11 +1716,9 @@ You can branch a branch.
Recovery:
- If only the ,<file>, exists, rename it to <file>,v.
-
- If both ,<file>, and <file>,v exist and are linked, remove the
,<file>, file.
-
- If both ,<file>, and <file>,v exist and are separate files, look at
the dates, "diff" them and make your best guess. This sounds like the
remnants of two separate events.
@@ -1952,7 +1928,6 @@ You can branch a branch.
CAVEMAN is a front end to CVS written in PERL providing a collection
of features desired by the site where it was developed.
-
- The ability to spread a "project" over multiple Repositories.
- Optional automatic tagging after each commit.
- Additional locking of files.
@@ -1980,21 +1955,13 @@ You can branch a branch.
First, install all the programs. (See Section 4A.)
- Then create a Repository by executing "cvsinit", which works only from
- within the head of the CVS source directory. (It needs files from the
- distribution to work.)
-
- If you want a very primitive Repository and don't want to save a
- history log, refer to modules, or use any of the "info" files for
- logging, pre-commit checks, or editing templates, you can dispense
- with "cvsinit" entirely. I would advise executing it.
+ Then create a Repository by executing "cvs -d init". (This works with
+ CVS 1.9.)
- The cvsinit program will create a short modules file containing the
- module named "CVSROOT". Change to your work directory and type:
-
- cvs checkout CVSROOT
-
- Then read the files that are checked out.
+ Now you can configure your repository by checking out CVSROOT: "cvs -d
+ checkout CVSROOT". Change into the created directory CVSROOT. Edit the
+ files you want to edit, and afterwards, commit the changes by typing
+ "cvs commit".
You will certainly want to add modules of your own. Edit the "modules"
file and add lines to describe the items you want to "checkout" by
@@ -2014,15 +1981,9 @@ You can branch a branch.
test test
junk test/junk
- When you are done editing, "commit" the modules file. If you
- configured CVS to use "dbm", you might have to edit and commit the
- modules file twice to change the pathname of the mkmodules program in
- the modules file.
-
- Try using the "import" command to insert the "junk" module and play
- around until you are comfortable.
+ Andreas Kostyrka
- Last modified: _11/7/1997_
+ Last modified: _4/21/1998_
2. What are those files in $CVSROOT/CVSROOT?
@@ -2115,20 +2076,19 @@ You can branch a branch.
5. What file permissions should I use on (and in) the Repository?
+ If you are using pserver (password-authenticated access), see below.
+
If you run a completely open environment (which usually means that you
don't have, or don't want to waste, the time to deal with it):
-
- Set all directory permissions to 777.
-
- Have everyone set their umasks to 0.
(BTW, I don't suggest this. I am merely reporting it.)
If you are a normal Unix shop and want to use groups effectively:
-
- Set all the directory permissions in the Repository to 775.
If you are using a system that handles both System V and BSD
@@ -2136,25 +2096,20 @@ You can branch a branch.
If you are using one of the many recent versions of Unix that don't
allow you to use the full octal mode, then you'll have to type: chmod
- u=rwx,g=rwx,o=rx,g+s <dir>
-
+ u=rwx,g=rwx,o=rx,g+s dir&gt;
- Change all the groups on the directories to match the groups you
want to write to various directories.
-
- Make sure every user is in the appropriate groups.
-
- Have everyone set their umask to 002, including root.
If you don't want non-group members to even read the files, do the
above, but change:
-
- Repository directory permissions to 770. (or 2770)
-
- umasks to 007.
If you work in an environment where people can't be trusted to set
@@ -2168,7 +2123,21 @@ You can branch a branch.
exec /usr/local/bin/cvs.real ${1+"$@"}
^D
- Last modified: _6/13/1997_
+ Pserver (Password-Authenticated Access) &lt;blome@de.ibm.com&gt;
+
+ The above suggestions are not valid when you use the pserver facility.
+ Be sure to read and understand the manual section about this (should
+ be 4.6.something). Above all: do /not/ make the repository and CVSROOT
+ group writeable. In CVSROOT, make `history´ group or world writeable
+ instead.
+
+ I suggest creating one unix group per project group. In the
+ repository, you would then create one directory for each group, group
+ writeable. New projects must then be created in these group
+ directories. If you don't want to say &lt;group&gt;/&lt;project&gt; on
+ checkout, create a &lt;project&gt; module and point it there.
+
+ Last modified: _9/24/1998_
6. How do I structure my Repository?
@@ -2189,7 +2158,6 @@ You can branch a branch.
needs, usually tied in with the other tools you use to build, install
and distribute your work. Common needs include the ability to:
-
- mount (or automount) directories from many places in your
organization.
- check out just what you need and no more.
@@ -2242,20 +2210,16 @@ You can branch a branch.
- "update -r <tag>" produces the correct files.
-
- The duplicated revision history can be slightly misleading.
-
- A plain (i.e. without the "-r <tag>") "checkout" or "update -d" will
create directories "renamed" this way, but you can delete it and a
plain "update" won't bring it back.
Move the files and directories in the Repository to the new names.
-
- You save the revision history under a different file name.
-
- You save a little space.
- "update -r <tag>" produces the wrong files or directories.
@@ -2270,7 +2234,6 @@ You can branch a branch.
sophisticated, revision of the Makefile. (Yes, this changes the
"released" file if <tag> indicates a release. But it is an option.)
-
- Important Note: If you rename a directory, you must rename the
corresponding directory in every checked-out working directory. At the
same time, you must edit the pathname stored in the ./CVS/Repository
@@ -2280,7 +2243,6 @@ You can branch a branch.
everyone to remove their working directories and check them out again
from scratch.
-
- The file exists in the working directory and in the ./CVS/Entries
file, but not in the Repository. For the old file, "update" prints:
@@ -2302,11 +2264,9 @@ You can branch a branch.
"cvs add" to add the new one. Since there is no way for CVS to remove
a directory, this only works for files.
-
- This is what most people think of first. Without a "rename" command,
the remove/add technique seems obvious.
-
- You lose the connection of your new working file to its past
revision history.
@@ -2446,7 +2406,6 @@ You can branch a branch.
The best form of Repository control is a combination of:
-
- A reliable backup scheme (verify it!)
- Enough training to ensure your developers are competent and
knowledgeable about all areas of your sources.
@@ -2659,7 +2618,6 @@ kingdon@cyclic.com
people have succumbed to the urge to do so when pressed for time. The
reasons given, usually with evident contrition, include:
-
- Editing mistakes in, or adding text to, log entries. (If you have
RCS 5.6 or later, you should use `cvs admin -m'.)
- Renaming or moving symbolic names. (You should `cvs admin -N'
@@ -2940,7 +2898,36 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 9. While in the middle of a large "commit", how do I run other commands,
+ 9. Why do timestamps sometimes get set to the date of the revision,
+ sometimes not? The inconsistency causes unnecessary recompiles.
+
+ The "checkout" command normally sets the timestamp of a working file
+ to match the timestamp stored on the revision in the Repository's RCS
+ file.
+
+ The "commit" command retains the timestamp of the file, if the act of
+ checking it in didn't change it (by expanding keywords).
+
+ The "update" command sets the time to the revision time the first time
+ it sees the file. After that, it sets the time of the file to the
+ current time. See 4D.8 for a reason why.
+
+ Here's a two-line PERL program to set timestamps on files based on
+ other timestamps. I've found this program useful. When you are certain
+ you don't want a source file to be recompiled, you can set its
+ timestamp to the stamp on the object file.
+
+ #!/usr/local/bin/perl
+ #
+ # Set timestamp of args 2nd-Last to that of the first arg.
+ #
+ ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime)
+ = stat(shift);
+ utime($atime,$mtime,@ARGV);
+
+ Last modified: _6/13/1997_
+
+ 10. While in the middle of a large "commit", how do I run other commands,
like "diff" or "stat" without seeing lock errors?
Type:
@@ -2977,7 +2964,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 10. Where did the ./CVS/Entries.Static file come from? What is it for?
+ 11. Where did the ./CVS/Entries.Static file come from? What is it for?
Each CVS working directory contains a ./CVS/Entries file listing the
files managed by CVS in that working directory. Normally, if the
@@ -3014,7 +3001,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 11. Why did I get the wrong Repository in the loginfo message?
+ 12. Why did I get the wrong Repository in the loginfo message?
You probably:
@@ -3038,7 +3025,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 12. How do I run CVS setuid so I can only allow access through the CVS
+ 13. How do I run CVS setuid so I can only allow access through the CVS
program itself?
Setuid to root is not a great idea. Any program that modifies files
@@ -3067,7 +3054,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 13. How about using groups and setgid() then?
+ 14. How about using groups and setgid() then?
Here is a way to run CVS setgid in some environments:
@@ -3122,7 +3109,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 14. How do I use the "commitinfo" file?
+ 15. How do I use the "commitinfo" file?
Go read 4B.2 first.
@@ -3133,7 +3120,6 @@ kingdon@cyclic.com
To fill out a "commitinfo" file, ask yourself (and those sharing your
Repository) these questions:
-
- Is there anything you want to check or change before someone is
allowed to commit a file? If not, forget commitinfo.
@@ -3141,7 +3127,6 @@ kingdon@cyclic.com
like the rcslock.pl program in the contrib directory of the CVS
sources.
-
- Do you want to execute the same exact thing before committing to
every file in the Repository? (This is useful if you want to program
the restrictions yourself.) If so, set up a single line in the
@@ -3156,7 +3141,6 @@ kingdon@cyclic.com
Write your program accordingly. Some examples exist in the contrib
directory.
-
- Do you want a different kind of sanity check performed for different
directories? If so, you'll have to decide what to do for all
directories and enter lines like this:
@@ -3165,7 +3149,6 @@ kingdon@cyclic.com
regexp2 /absolute/path/to/program-for-regexp2
DEFAULT /absolute/path/to/program-for-all-else
-
- Is there anything you want to happen before *all* commits, in
addition to other pattern matches? If so, include a line like this:
@@ -3176,7 +3159,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 15. How do I use the "loginfo" files?
+ 16. How do I use the "loginfo" files?
See 4B.2 and the "commitinfo" question above.
@@ -3196,7 +3179,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 16. How can I keep people with restrictive umask values from blocking
+ 17. How can I keep people with restrictive umask values from blocking
access to the Repository?
If a user creates a new file with restricted permissions (e.g. 0600),
@@ -3221,35 +3204,6 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 17. Why do timestamps sometimes get set to the date of the revision,
- sometimes not? The inconsistency causes unnecessary recompiles.
-
- The "checkout" command normally sets the timestamp of a working file
- to match the timestamp stored on the revision in the Repository's RCS
- file.
-
- The "commit" command retains the timestamp of the file, if the act of
- checking it in didn't change it (by expanding keywords).
-
- The "update" command sets the time to the revision time the first time
- it sees the file. After that, it sets the time of the file to the
- current time. See 4D.8 for a reason why.
-
- Here's a two-line PERL program to set timestamps on files based on
- other timestamps. I've found this program useful. When you are certain
- you don't want a source file to be recompiled, you can set its
- timestamp to the stamp on the object file.
-
- #!/usr/local/bin/perl
- #
- # Set timestamp of args 2nd-Last to that of the first arg.
- #
- ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime)
- = stat(shift);
- utime($atime,$mtime,@ARGV);
-
- Last modified: _6/13/1997_
-
Category: /Commands_/
" Commands "
@@ -4245,14 +4199,12 @@ kingdon@cyclic.com
Providing a list of files changed since
-
- A tagged release.
- Yesterday, last Thursday, or a specific date.
- Someone changed a specific file.
Providing a list of special events:
-
- Files added or removed since one of the above events.
- Merge failures since one of the above events. (Where did the
conflicts occur?)
@@ -4376,7 +4328,6 @@ kingdon@cyclic.com
To list (for the selected users): Type "cvs history" and:
-
* Checked out modules: -o (the default)
* Files added since creation: -x A
* Modified files since creation: -c
@@ -5939,15 +5890,12 @@ kingdon@cyclic.com
working file to contain conflict markers surrounding the overlapping
code segments. For example, say that
-
- Two developers acquire revision 1.2 of <file> via "checkout" or
"update".
-
- Developer A changes line 1 from "9999" to "5555", then commits the
file, creating revision 1.3.
-
- Developer B changes line 1 from "9999" to "7777", then tries to
commit the file, but is blocked because the file is not up to date.
Developer B then runs "update" and sees the conflict marker 'C'. The
@@ -7464,24 +7412,45 @@ kingdon@cyclic.com
If you decide to split the file, here's a suggestion. In many ways, it
is similar to multiple "renamings" as described in 2C.4 above.
- Say you want to split <fileA>, which already in the Repository, into
- three pieces, <fileA>, <fileB> and <fileC>.
+ Say you want to split , which already in the Repository, into three
+ pieces, , and .
Copy the RCS (",v") files directly in the Repository, creating the
new files, then bring readable copies of the new files into the
working directory via "update".
- cp $CVSROOT/<path>/<fileA>,v $CVSROOT/<path>/<fileB>,v cp
- $CVSROOT/<path>/<fileA>,v $CVSROOT/<path>/<fileC>,v
- cvs update <fileB> <fileC>
+ cp $CVSROOT//,v $CVSROOT//,v cp $CVSROOT//,v $CVSROOT//,v
+ cvs update
- Then remove all the <tags> from the new files by using:
+ Then remove all the from the new files, either using:
- cvs log <fileB> <fileC> # Save the list of <tag?>
- cvs tag -d <tag1> <fileB> <fileC>
- cvs tag -d <tag2> <fileB> <fileC>
+ cvs log # Save the list of
+ cvs tag -d
+ cvs tag -d
. . .
+ (eivind@freebsd.org) or using the following little script to
+ autmatically remove the tags directly from the repository files:
+
+#!/bin/sh
+for file in $*
+do
+ TAGS=`rlog $file | awk '/^symbolic names:/,/^keyword subst/' | awk 'BEG
+IN {FS=":"} /^\t/ {print $1}'`
+ echo The tags in $file are
+ echo $TAGS
+ echo Is it OK to remove these?
+ read confirm
+ if [ "$confirm" = "y" -o "$confirm" = "yes" ]
+ then
+ for tag in $TAGS
+ do
+ echo Removing $file:$tag
+ rcs -n$tag $file
+ done
+ fi
+done
+
Edit each file until it has the data you want in it. This is a
hand-editing job, not something CVS can handle. Then commit all the
files.
@@ -7491,8 +7460,8 @@ kingdon@cyclic.com
statements, which must be duplicated. And make sure the code
compiles.]
- emacs <fileA> <fileB> <fileC>
- cvs commit <fileA> <fileB> <fileC>
+ emacs
+ cvs commit
As in the "rename" case, by duplicating the files, you'll preserve the
change history and the ability to retrieve earlier revisions.
@@ -7500,7 +7469,7 @@ kingdon@cyclic.com
Of course, you have to alter your build system (e.g. Makefiles) to
take the new names and the change in contents into account.
- Last modified: _6/13/1997_
+ Last modified: _3/11/1998_
Category: /What_is_CVS_/
@@ -7772,7 +7741,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
- 10. How does CVS differ from Sublime?
+ 10. How does CVS differ from SABLIME?
Produced by AT&T. Sablime uses SCCS as the underlying source code
control system. It uses some other control system (called sbcs I
@@ -7790,7 +7759,7 @@ kingdon@cyclic.com
weight though, and the interface is not too polished and does not work
on windows (though that may have changed). rama@savera.com
- Last modified: _12/12/1997_
+ Last modified: _7/30/1998_
11. How does CVS differ from PVCS?
@@ -8457,7 +8426,7 @@ kingdon@cyclic.com
ftp ftp.delos.com
>>> User: anonymous
- >>> Passwd: <Your Internet address>
+ >>> Passwd:
cd /pub/cvs
get README
get Index
@@ -8467,7 +8436,9 @@ kingdon@cyclic.com
A WWW home page is also available at http://www.delos.com/cvs.
- Last modified: _6/13/1997_
+ This Didn't Exist 6/23/1998
+
+ Last modified: _6/24/1998_
3. How do I get files out of the archive if I don't have FTP?
@@ -8569,17 +8540,17 @@ kingdon@cyclic.com
Last modified: _9/6/1997_
_________________________________________________________________
-
+
[Add an answer to this category]
[Category /]
_________________________________________________________________
-
- _Search the FAQ-O-Matic:_ ____________________ ______
+
+ _Search the FAQ-O-Matic:_ ____________________ Search
[matching all words]
- Or look for questions modified in the last: [7.] ____
+ Or look for questions modified in the last: [7.] Days
_________________________________________________________________
-
+
The FAQ-O-Matic lives at http://gille.loria.fr:7000/cgi-bin/faqomatic.
The code was written by Jon Howell, and the content by folks from all
over the web.
diff --git a/gnu/usr.bin/cvs/HACKING b/gnu/usr.bin/cvs/HACKING
index a1b3d37dd30..4c49228b4f5 100644
--- a/gnu/usr.bin/cvs/HACKING
+++ b/gnu/usr.bin/cvs/HACKING
@@ -195,5 +195,5 @@ list which users are requested to send bug reports to. Anyone can
subscribe; to do so send mail to bug-cvs-request@gnu.org.
Other CVS discussions take place on the info-cvs mailing list
-(send mail to info-cvs-request@prep.ai.mit.edu to subscribe) or on
+(send mail to info-cvs-request@gnu.org to subscribe) or on
the newsgroup comp.software.config-mgmt.
diff --git a/gnu/usr.bin/cvs/INSTALL b/gnu/usr.bin/cvs/INSTALL
index 252849077f9..27acf8203be 100644
--- a/gnu/usr.bin/cvs/INSTALL
+++ b/gnu/usr.bin/cvs/INSTALL
@@ -108,8 +108,10 @@ Alpha:
DEC Alpha running OSF/1 version 2.1 (about 1.4A2)
DEC Alpha running OSF/1 version 3.0 (1.5.95) (footnote 7)
DEC Alpha running OSF/1 version 3.2 (1.9)
+ Alpha running alpha-dec-osf4.0 (1.10)
DEC Alpha running Digital UNIX v4.0C using gcc 2.7.2.2 (1.9.14)
DEC Alpha running VMS 6.2 (1.8.85 client-only)
+ Alpha running NetBSD 1.2E (1.10)
Cray:
J90 (CVS 970215 snapshot)
T3E (CVS 970215 snapshot)
@@ -124,17 +126,20 @@ HPPA:
NextSTEP 3.3 (1.7)
i386 family:
Solaris 2.4 using gcc (about 1.4A2)
+ Solaris 2.6 (1.9)
UnixWare v1.1.1 using gcc (about 1.4A2)
Unixware 2.1 (1.8.86)
Unixware 7 (1.9.29)
ISC 4.0.1 (1.8.87)
Linux (kernel 1.2.x) (1.8.86)
- Linux (kernel 2.0.x, RedHat 4.2) (1.9)
+ Linux (kernel 2.0.x, RedHat 4.2) (1.10)
+ Linux (kernel 2.0.x, RedHat 5.x) (1.10)
BSDI 2.0 (1.4.93) (footnote 5)
FreeBSD 2.1.5-stable (1.8.87)
NextSTEP 3.3 (1.7)
SCO Unix 3.2.4.2, gcc 2.7.2 (1.8.87) (footnote 4)
- SCO OpenServer 5 (1.9.29)
+ SCO OpenServer 5.0.5 (1.10.2)
+ Sequent DYNIX/ptx4.0 (1.10 or so) (remove -linet)
Sequent Dynix/PTX 4.1.4 (1.9.20 or so + patches)
Lynx 2.3.0 080695 (1.6.86) (footnote 9)
Windows NT 3.51 (1.8.86 client; 1.8.3 local)
@@ -150,17 +155,19 @@ m68k:
Sun 3 running SunOS 4.1.1_U1 w/ bundled K&R /usr/5bin/cc (1.8.86+)
NextSTEP 3.3p1 (1.8.87)
Lynx 2.3.0 062695 (1.6.86) (footnote 9)
+ NetBSD/mac68k (1.9.28)
m88k:
Data General AViiON running dgux 5.4R2.10 (1.5)
Data General AViiON running dgux 5.4R3.10 (1.7.1)
Harris Nighthawk 5800 running CX/UX 7.1 (1.5) (footnote 6)
MIPS:
DECstation running Ultrix 4.2a (1.4.90)
- DECstation running Ultrix 4.3 (1.8.85)
+ DECstation running Ultrix 4.3 (1.10)
SGI running Irix 4.0.5H using gcc and cc (about 1.4A2) (footnote 2)
- SGI running Irix 5.3 using gcc 2.7.2 (1.8.87)
+ SGI running Irix 5.3 (1.10)
SGI running Irix 6.2 using SGI MIPSpro 6.2 and beta 7.2 compilers (1.9)
SGI running Irix-6.2 (1.9.8)
+ SGI running IRIX 6.4 (1.10)
Siemens-Nixdorf RM600 running SINIX-Y (1.6)
PowerPC or RS/6000:
IBM RS/6000 running AIX 3.1 using gcc and cc (1.6.86)
@@ -169,11 +176,12 @@ PowerPC or RS/6000:
Lynx 2.3.1 120495 (1.6.86) (footnote 9)
Lynx 2.5 (1.9) (footnote 10)
SPARC:
- Sun SPARC running SunOS 4.1.x using gcc 2.7.2.1 (1.9.14)
+ Sun SPARC running SunOS 4.1.x (1.10)
Sun SPARCstation 10 running Solaris 2.3 using gcc and cc (about 1.4A2)
Sun SPARCstation running Solaris 2.4 using gcc and cc (about 1.5.91)
Sun SPARC running Solaris 2.5 (1.8.87)
Sun SPARC running Solaris 2.5.1 using gcc 2.7.2.2 (1.9.14)
+ Sun UltraSPARC running Solaris 2.6 using gcc 2.8.1 (1.10)
NextSTEP 3.3 (1.7)
Sun SPARC running Linux 2.0.17, gcc 2.7.2 (1.8.87)
VAX:
diff --git a/gnu/usr.bin/cvs/NEWS b/gnu/usr.bin/cvs/NEWS
index 309c5105a61..05506ef7843 100644
--- a/gnu/usr.bin/cvs/NEWS
+++ b/gnu/usr.bin/cvs/NEWS
@@ -1,4 +1,27 @@
-Changes since 1.9:
+Changes since 1.10:
+
+* There is a new access method :fork: which is similar to :local:
+except that it is implemented via the CVS remote protocol, and thus
+has a somewhat different set of quirks and bugs.
+
+* The -d command line option no longer updates the CVS/Root file. For
+one thing, the CVS 1.9/1.10 behavior never had updated CVS/Root in
+subdirectories, and for another, it didn't seem that popular in
+general. So this change restores the CVS 1.8 behavior (which is also
+the CVS 1.9/1.10 behavior if the environment variable
+CVS_IGNORE_REMOTE_ROOT is set; with this change,
+CVS_IGNORE_REMOTE_ROOT no longer has any effect).
+
+* It is now possible for a single CVS command to recurse into several
+CVS roots. This includes roots which are located on several servers,
+or which are both remote and local. CVS will make connections to as
+many servers as necessary.
+
+* It is now possible to put the CVS lock files in a directory
+set by the new LockDir option in CVSROOT/config. The default
+continues to be to put the lock files in the repository itself.
+
+Changes from 1.9 to 1.10:
* There is a new feature, enabled by TopLevelAdmin in CVSROOT/config,
which tells CVS to modify the behavior of the "checkout" command. The
diff --git a/gnu/usr.bin/cvs/TESTS b/gnu/usr.bin/cvs/TESTS
index 7281ac1a928..b3fe5c288c9 100644
--- a/gnu/usr.bin/cvs/TESTS
+++ b/gnu/usr.bin/cvs/TESTS
@@ -17,11 +17,13 @@ can set the TESTDIR environment variable to the desired location
before running them.
You will probably need GNU expr, which is part of the GNU sh-utils
-package. You may also need sort from the GNU textutils; Solaris
-in particular has been reported to have a sort program which does not
-behave the way that the testsuite expects (with Solaris, lines
-starting with tabs sort before blank lines). These programs are just
-for running the tests; CVS itself doesn't require expr or sort.
+package. This is just for running the tests; CVS itself doesn't
+require expr.
+
+With CVS 1.10 people also had trouble with the Solaris sort program
+not behaving the way that the testsuite expects (with Solaris, lines
+starting with tabs sort before blank lines). I suspect this is fixed
+now that the testsuite sets LC_COLLATE.
If there is some unexpected output, that is a failure which can be
somewhat hard to track down. Finding out which test is producing the
diff --git a/gnu/usr.bin/cvs/TODO b/gnu/usr.bin/cvs/TODO
index cc40ab2a68b..91313a309c0 100644
--- a/gnu/usr.bin/cvs/TODO
+++ b/gnu/usr.bin/cvs/TODO
@@ -11,6 +11,8 @@ too?). (perhaps should think a little harder about what this is
trying to accomplish and what the best way is -kingdon, Jul 1997).
31. Think hard about ^C recovery.
+ One particular issue: RCS removes the ,foo.c, file on ^C and CVS
+ doesn't.
38. Think hard about using RCS state information to allow one to checkin
a new vendor release without having it be accessed until it has been
@@ -254,10 +256,10 @@ trying to accomplish and what the best way is -kingdon, Jul 1997).
probably want to give an error if it disagreed with CVS/Root, as
CVS 1.8 and earlier did). The other is the "reposmv"
functionality above (in which the two repositories really are the
- same, and we want to update the CVS/Root files). A related issue
- is that the fact that CVS only sets and looks at the CVS/Root
- file in the directory where CVS is run; it doesn't do anything
- about CVS/Root files in subdirectories.
+ same, and we want to update the CVS/Root files). In CVS 1.9 and
+ 1.10, -d rewrites the CVS/Root file (but not in subdirectories).
+ This behavior was not particularly popular and has been since
+ reverted.
Note also RELATIVE_REPOS in options.h; it needs to be set for
changing CVS/Root (not CVS/Repository) to be sufficient in the
@@ -767,7 +769,8 @@ or vice versa.
a. Cases in which the status quo already sends a diff. For most text
files, this is probably already close to optimal. For binary files,
-and anomalous text files, it might be worth looking into other
+and anomalous (?) text files (e.g. those in which it would help to do
+moves, as well as adds and deletes), it might be worth looking into other
difference algorithms (see item #191).
b. Cases in which the status quo does not send a diff (e.g. "cvs
@@ -777,9 +780,9 @@ b1. With some frequency, people suggest rsync or a similar algorithm
(see ftp://samba.anu.edu.au/pub/rsync/). This could speed things up,
and in some ways involves the most minimal changes to the default CVS
paradigm. There are some downsides though: (1) there is an extra
-network turnaround, (2) the algorithm is not as efficient with network
-bandwidth as difference type programs (it transmits a fair bit of data
-to discover what a difference program discovers locally).
+network turnaround, (2) the algorithm needs to transmit some data to
+discover what difference type programs can discover locally (although
+this is only about 1% of the size of the files).
b2. If one is willing to require that users use "cvs edit" before
editing a file on the client side (in some cases, a development
@@ -788,3 +791,7 @@ request in the protocol could be extended to allow the client to just
send differences instead of entire files. In the degenerate case
(e.g. "cvs diff" without arguments) the required network traffic is
reduced to zero, and the client need not even contact the server.
+
+196. Using a CVSROOT with a trailing slash will confuse CVS. I think
+we need to add a call to strip_trailing_slashes in root.c
+(parse_cvsroot), but I haven't considered all of the ramifications.
diff --git a/gnu/usr.bin/cvs/contrib/.cvsignore b/gnu/usr.bin/cvs/contrib/.cvsignore
index 0cc730565ea..deb5efc5de7 100644
--- a/gnu/usr.bin/cvs/contrib/.cvsignore
+++ b/gnu/usr.bin/cvs/contrib/.cvsignore
@@ -5,9 +5,6 @@ commit_prep
cvs2vendor
cvs_acls
cvscheck
-Debug
-listen2.mdp
-listen2.ncb
log
log_accum
mfpipe
diff --git a/gnu/usr.bin/cvs/contrib/ChangeLog b/gnu/usr.bin/cvs/contrib/ChangeLog
index 8bf96a16b54..46cf007051b 100644
--- a/gnu/usr.bin/cvs/contrib/ChangeLog
+++ b/gnu/usr.bin/cvs/contrib/ChangeLog
@@ -1,3 +1,47 @@
+1999-01-19 Graham Stoney <greyham@research.canon.com.au>
+
+ * log.pl: The author commited the canonical perl "localtime" Y2K
+ offence, of printing "19$year" instead of (1900 + $year). Of
+ course, the result is non-compliance in year 2000. Fix it.
+
+1998-10-14 Jim Kingdon
+
+ * ccvs-rsh.pl: Removed; it was not in DISTFILES so it didn't
+ actually get distributed. I'm going to move it to the web on the
+ theory that the web is a better place for such things.
+ * README: Don't mention it.
+
+ * Makefile.in (dist-dir, distclean): Remove references to elib.
+ * elib: Remove this subdirectory and all its contents. It went
+ with pcl-cvs, which is no longer distributed with CVS.
+
+1998-09-22 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * pvcs_to_rcs: Removed; it was not in DISTFILES so it didn't
+ actually get distributed. I'm going to move it to the web on the
+ theory that the web is a better place for such things.
+ * README: Don't mention it.
+
+1998-09-10 Jim Kingdon
+
+ Check in Paul Eggert <eggert@twinsun.com>'s submission of
+ 1998-08-15. I also ran "cvs admin -ko" on this file so that his
+ version number would be intact (not an ideal solution, because
+ people will import it into other repositories, but I don't feel
+ like hacking the master version).
+ * rcs2log.sh: Sync with master version at gnu.org.
+
+1998-08-15 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * README: Don't mention listener, since it was removed a while
+ ago.
+ * listen2.c, listen2.mak: Removed; because there is no easy way to
+ pass a socket (as opposed to file descriptor) from one process to
+ another on Windows, this isn't a promising approach (at least not
+ in this form).
+ * Makefile.in (DISTFILES): Remove them.
+ * .cvsignore: Remove listen2.ncb listen2.mdp Debug.
+
1998-05-11 W. Bradley Rubenstein
* log.pl: Check for errors from open and exec.
diff --git a/gnu/usr.bin/cvs/contrib/README b/gnu/usr.bin/cvs/contrib/README
index 223b759b0c7..8a93f8f689b 100644
--- a/gnu/usr.bin/cvs/contrib/README
+++ b/gnu/usr.bin/cvs/contrib/README
@@ -64,9 +64,6 @@ An attempt at a table of Contents for this directory:
currently locked by someone else, as might be the
case for a binary file.
Contributed by John Rouillard <rouilj@cs.umb.edu>.
- ccvs-rsh A Perl script which allows "rsh pipelines" to
- be built in order to use Cyclic CVS from
- behind some varieties of firewall.
cvs_acls A perl script that implements Access Control Lists
by using the "commitinfo" hook provided with the
"cvs commit" command.
@@ -86,10 +83,6 @@ An attempt at a table of Contents for this directory:
into RCS files, retaining the info contained in the
SCCS file (like dates, author, and log message).
Contributed by Ken Cox <kenstir@viewlogic.com>.
- pvcs_to_rcs A perl script that can convert (some) PVCS histories
- into RCS files, retaining the info contained in the
- PVCS history. See the comments at the start of the
- file for more details.
intro.doc A user's view of what you need to know to get
started with CVS.
Contributed by <Steven.Pemberton@cwi.nl>.
@@ -105,10 +98,6 @@ An attempt at a table of Contents for this directory:
clmerge A perl script to handle merge conflicts in GNU
style ChangeLog files .
Contributed by Tom Tromey <tromey@busco.lanl.gov>.
- listener A program which listens to a TCP port, authenticates
- by hostname, then runs a subprocess whose input/output
- is redirected through the port.
- Contributed by Benjamin J. Lee <benjamin@cyclic.com>
cvs2vendor A shell script to move changes from a repository
that was started without a vendor branch to one
that has a vendor branch.
diff --git a/gnu/usr.bin/cvs/contrib/log.pl b/gnu/usr.bin/cvs/contrib/log.pl
index f1d66e3db02..3a8ad992b60 100644
--- a/gnu/usr.bin/cvs/contrib/log.pl
+++ b/gnu/usr.bin/cvs/contrib/log.pl
@@ -91,6 +91,7 @@ $mailcmd = "| Mail -s 'CVS update: $modulepath'";
@days = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
+$year += 1900;
# get a login name for the guy doing the commit....
#
@@ -111,12 +112,12 @@ if ($users) {
#
print OUT "\n";
print OUT "****************************************\n";
-print OUT "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
+print OUT "Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n";
print OUT "Author:\t$login\n\n";
if (MAIL) {
print MAIL "\n";
- print MAIL "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
+ print MAIL "Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n";
print MAIL "Author:\t$login\n\n";
}
diff --git a/gnu/usr.bin/cvs/contrib/rcs2log.sh b/gnu/usr.bin/cvs/contrib/rcs2log.sh
index 55485669566..a8a92c188b0 100644
--- a/gnu/usr.bin/cvs/contrib/rcs2log.sh
+++ b/gnu/usr.bin/cvs/contrib/rcs2log.sh
@@ -2,7 +2,8 @@
# RCS to ChangeLog generator
-# Generate a change log prefix from RCS files and the ChangeLog (if any).
+# Generate a change log prefix from RCS files (perhaps in the CVS repository)
+# and the ChangeLog (if any).
# Output the new prefix to standard output.
# You can edit this prefix by hand, and then prepend it to ChangeLog.
@@ -10,25 +11,49 @@
# Clump together log entries that start with `{topic} ',
# where `topic' contains neither white space nor `}'.
-# Author: Paul Eggert <eggert@twinsun.com>
+Help='The default FILEs are the files registered under the working directory.
+Options:
+
+ -c CHANGELOG Output a change log prefix to CHANGELOG (default ChangeLog).
+ -h HOSTNAME Use HOSTNAME in change log entries (default current host).
+ -i INDENT Indent change log lines by INDENT spaces (default 8).
+ -l LENGTH Try to limit log lines to LENGTH characters (default 79).
+ -R If no FILEs are given and RCS is used, recurse through working directory.
+ -r OPTION Pass OPTION to subsidiary log command.
+ -t TABWIDTH Tab stops are every TABWIDTH characters (default 8).
+ -u "LOGIN<tab>FULLNAME<tab>MAILADDR" Assume LOGIN has FULLNAME and MAILADDR.
+ -v Append RCS revision to file names in log lines.
+ --help Output help.
+ --version Output version number.
+
+Report bugs to <bug-gnu-emacs@gnu.org>.'
-# Copyright 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+Id='$Id: rcs2log.sh,v 1.1.1.5 1999/02/28 21:34:25 tholo Exp $'
+
+# Copyright 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
# 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.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
+Copyright='Copyright 1998 Free Software Foundation, Inc.
+This program comes with NO WARRANTY, to the extent permitted by law.
+You may redistribute copies of this program
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING.
+Author: Paul Eggert <eggert@twinsun.com>'
+
tab=' '
nl='
'
@@ -38,18 +63,23 @@ nl='
# defaults
: ${AWK=awk}
: ${TMPDIR=/tmp}
+changelog=ChangeLog # change log file name
+datearg= # rlog date option
hostname= # name of local host (if empty, will deduce it later)
indent=8 # indent of log line
length=79 # suggested max width of log line
logins= # login names for people we know fullnames and mailaddrs of
loginFullnameMailaddrs= # login<tab>fullname<tab>mailaddr triplets
+logTZ= # time zone for log dates (if empty, use local time)
recursive= # t if we want recursive rlog
+revision= # t if we want revision numbers
rlog_options= # options to pass to rlog
tabwidth=8 # width of horizontal tab
while :
do
case $1 in
+ -c) changelog=${2?}; shift;;
-i) indent=${2?}; shift;;
-h) hostname=${2?}; shift;;
-l) length=${2?}; shift;;
@@ -60,7 +90,10 @@ do
echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed"
exit 1
esac
- loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
+ case $loginFullnameMailaddrs in
+ '') loginFullnameMailaddrs=$2$tab$3$tab$4;;
+ ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
+ esac
shift; shift; shift;;
-u)
# If $2 is not tab-separated, use colon for separator.
@@ -83,19 +116,36 @@ do
echo >&2 "$0: -u '$2': not enough fields"
exit 1
esac
- loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
+ case $loginFullnameMailaddrs in
+ '') loginFullnameMailaddrs=$2;;
+ ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
+ esac
shift
esac
- logins=$logins$nl$login
+ case $logins in
+ '') logins=$login;;
+ ?*) logins=$logins$nl$login
+ esac
;;
- -r) rlog_options=$rlog_options$nl${2?}; shift;;
+ -r)
+ case $rlog_options in
+ '') rlog_options=${2?};;
+ ?*) rlog_options=$rlog_options$nl${2?}
+ esac
+ shift;;
-R) recursive=t;;
-t) tabwidth=${2?}; shift;;
- -*) echo >&2 "$0: usage: $0 [options] [file ...]
-Options:
- [-h hostname] [-i indent] [-l length] [-R] [-r rlog_option]
- [-t tabwidth] [-u 'login<TAB>fullname<TAB>mailaddr']..."
- exit 1;;
+ -v) revision=t;;
+ --version)
+ set $Id
+ rcs2logVersion=$3
+ echo >&2 "rcs2log (GNU Emacs) $rcs2logVersion$nl$Copyright"
+ exit 0;;
+ -*) echo >&2 "Usage: $0 [OPTION]... [FILE ...]$nl$Help"
+ case $1 in
+ --help) exit 0;;
+ *) exit 1
+ esac;;
*) break
esac
shift
@@ -106,12 +156,6 @@ month_data='
m[3]="Apr"; m[4]="May"; m[5]="Jun"
m[6]="Jul"; m[7]="Aug"; m[8]="Sep"
m[9]="Oct"; m[10]="Nov"; m[11]="Dec"
-
- # days in non-leap year thus far, indexed by month (0-12)
- mo[0]=0; mo[1]=31; mo[2]=59; mo[3]=90
- mo[4]=120; mo[5]=151; mo[6]=181; mo[7]=212
- mo[8]=243; mo[9]=273; mo[10]=304; mo[11]=334
- mo[12]=365
'
@@ -119,63 +163,59 @@ month_data='
# If no rlog options are given,
# log the revisions checked in since the first ChangeLog entry.
+# Since ChangeLog is only by date, some of these revisions may be duplicates of
+# what's already in ChangeLog; it's the user's responsibility to remove them.
case $rlog_options in
'')
- date=1970-01-01
- if test -s ChangeLog
+ if test -s "$changelog"
then
- # Add 1 to seconds to avoid duplicating most recent log.
e='
+ /^[0-9]+-[0-9][0-9]-[0-9][0-9]/{
+ # ISO 8601 date
+ print $1
+ exit
+ }
/^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{
+ # old-fashioned date and time (Emacs 19.31 and earlier)
'"$month_data"'
year = $5
for (i=0; i<=11; i++) if (m[i] == $2) break
dd = $3
- hh = substr($0,12,2)
- mm = substr($0,15,2)
- ss = substr($0,18,2)
- ss++
- if (ss == 60) {
- ss = 0
- mm++
- if (mm == 60) {
- mm = 0
- hh++
- if (hh == 24) {
- hh = 0
- dd++
- monthdays = mo[i+1] - mo[i]
- if (i == 1 && year%4 == 0 && (year%100 != 0 || year%400 == 0)) monthdays++
- if (dd == monthdays + 1) {
- dd = 1
- i++
- if (i == 12) {
- i = 0
- year++
- }
- }
- }
- }
- }
- printf "%02d/%02d/%d %02d:%02d:%02d\n", i+1,dd,year,hh,mm,ss
+ printf "%d-%02d-%02d\n", year, i+1, dd
exit
}
'
- d=`$AWK "$e" <ChangeLog` || exit
+ d=`$AWK "$e" <"$changelog"` || exit
case $d in
- ?*) date=$d
+ ?*) datearg="-d>$d"
esac
fi
- datearg="-d>$date"
esac
+# Use TZ specified by ChangeLog local variable, if any.
+if test -s "$changelog"
+then
+ extractTZ='
+ /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*"\([^"]*\)".*/{
+ s//\1/; p; q
+ }
+ /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*t.*/{
+ s//UTC0/; p; q
+ }
+ '
+ logTZ=`tail "$changelog" | sed -n "$extractTZ"`
+ case $logTZ in
+ ?*) TZ=$logTZ; export TZ
+ esac
+fi
+
# If CVS is in use, examine its repository, not the normal RCS files.
if test ! -f CVS/Repository
then
rlog=rlog
repository=
else
- rlog='cvs log'
+ rlog='cvs -q log'
repository=`sed 1q <CVS/Repository` || exit
test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit
case $CVSROOT in
@@ -196,6 +236,16 @@ else
esac
fi
+# Use $rlog's -zLT option, if $rlog supports it.
+case `$rlog -zLT 2>&1` in
+*' option'*) ;;
+*)
+ case $rlog_options in
+ '') rlog_options=-zLT;;
+ ?*) rlog_options=-zLT$nl$rlog_options
+ esac
+esac
+
# With no arguments, examine all files under the RCS directory.
case $# in
0)
@@ -210,7 +260,14 @@ case $# in
files=`
{
case $RCSdirs in
- ?*) find $RCSdirs -type f -print
+ ?*) find $RCSdirs \
+ -type f \
+ ! -name '*_' \
+ ! -name ',*,' \
+ ! -name '.*_' \
+ ! -name .rcsfreeze.log \
+ ! -name .rcsfreeze.ver \
+ -print
esac
find . -name '*,v' -print
} |
@@ -222,10 +279,16 @@ case $# in
for file in RCS/.* RCS/* .*,v *,v
do
case $file in
- RCS/. | RCS/..) continue;;
- RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue
+ RCS/. | RCS/.. | RCS/,*, | RCS/*_) continue;;
+ RCS/.rcsfreeze.log | RCS/.rcsfreeze.ver) continue;;
+ RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue;;
+ RCS/*,v | RCS/.*,v) ;;
+ RCS/* | RCS/.*) test -f "$file" || continue
+ esac
+ case $files in
+ '') files=$file;;
+ ?*) files=$files$nl$file
esac
- files=$files$nl$file
done
case $files in
'') exit 0
@@ -242,9 +305,9 @@ rlogout=$TMPDIR/rcs2log$$r
trap exit 1 2 13 15
trap "rm -f $llogout $rlogout; exit 1" 0
-case $rlog_options in
-?*) $rlog $rlog_options ${1+"$@"} >$rlogout;;
-'') $rlog "$datearg" ${1+"$@"} >$rlogout
+case $datearg in
+?*) $rlog $rlog_options "$datearg" ${1+"$@"} >$rlogout;;
+'') $rlog $rlog_options ${1+"$@"} >$rlogout
esac || exit
@@ -362,13 +425,16 @@ EOF
'
initialize_fullname=`
- (
- cat /etc/passwd
- for author in $authors
- do nismatch $author passwd.org_dir
- done
- ypmatch $authors passwd
- ) 2>/dev/null |
+ {
+ (getent passwd $authors) ||
+ (
+ cat /etc/passwd
+ for author in $authors
+ do NIS_PATH= nismatch $author passwd.org_dir
+ done
+ ypmatch $authors passwd
+ )
+ } 2>/dev/null |
$AWK -F: "$awkscript"
`$initialize_fullname
esac
@@ -376,7 +442,7 @@ esac
# Function to print a single log line.
# We don't use awk functions, to stay compatible with old awk versions.
-# `Log' is the log message (with \n replaced by \r).
+# `Log' is the log message (with \n replaced by \001).
# `files' contains the affected files.
printlogline='{
@@ -392,13 +458,13 @@ printlogline='{
# If "label: comment" is too long, break the line after the ":".
sep = " "
- if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, CR)) sep = "\n" indent_string
+ if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, SOH)) sep = "\n" indent_string
# Print the label.
printf "%s*%s:", indent_string, files
- # Print each line of the log, transliterating \r to \n.
- while ((i = index(Log, CR)) != 0) {
+ # Print each line of the log, transliterating \001 to \n.
+ while ((i = index(Log, SOH)) != 0) {
logline = substr(Log, 1, i-1)
if (logline ~ /[^'"$tab"' ]/) {
printf "%s%s\n", sep, logline
@@ -410,6 +476,9 @@ printlogline='{
}
}'
+# Pattern to match the `revision' line of rlog output.
+rlog_revision_pattern='^revision [0-9]+\.[0-9]+(\.[0-9]+\.[0-9]+)*(['"$tab"' ]+locked by: [^'"$tab"' $,.0-9:;@]*[^'"$tab"' $,:;@][^'"$tab"' $,.0-9:;@]*;)?['"$tab"' ]*$'
+
case $hostname in
'')
hostname=`(
@@ -433,7 +502,7 @@ esac
# Process the rlog output, generating ChangeLog style entries.
# First, reformat the rlog output so that each line contains one log entry.
-# Transliterate \n to \r so that multiline entries fit on a single line.
+# Transliterate \n to \001 so that multiline entries fit on a single line.
# Discard irrelevant rlog output.
$AWK <$rlogout '
BEGIN { repository = "'"$repository"'" }
@@ -446,47 +515,66 @@ $AWK <$rlogout '
if (filename ~ /,v$/) {
filename = substr(filename, 1, length(filename) - 2)
}
+ if (filename ~ /(^|\/)Attic\/[^\/]*$/) {
+ i = length(filename)
+ while (substr(filename, i, 1) != "/") i--
+ filename = substr(filename, 1, i - 6) substr(filename, i + 1)
+ }
}
+ rev = "?"
}
/^Working file:/ { if (repository == "") filename = $3 }
- /^date: /, /^(-----------*|===========*)$/ {
- if ($0 ~ /^branches: /) { next }
- if ($0 ~ /^date: [0-9][- +\/0-9:]*;/) {
+ /'"$rlog_revision_pattern"'/, /^(-----------*|===========*)$/ {
+ line = $0
+ if (line ~ /'"$rlog_revision_pattern"'/) {
+ rev = $2
+ next
+ }
+ if (line ~ /^date: [0-9][- +\/0-9:]*;/) {
date = $2
- if (date ~ /-/) {
- # An ISO format date. Replace all "-"s with "/"s.
+ if (date ~ /\//) {
+ # This is a traditional RCS format date YYYY/MM/DD.
+ # Replace "/"s with "-"s to get ISO format.
newdate = ""
- while ((i = index(date, "-")) != 0) {
- newdate = newdate substr(date, 1, i-1) "/"
+ while ((i = index(date, "/")) != 0) {
+ newdate = newdate substr(date, 1, i-1) "-"
date = substr(date, i+1)
}
date = newdate date
}
- # Ignore any time zone; ChangeLog has no room for it.
- time = substr($3, 1, 8)
+ time = substr($3, 1, length($3) - 1)
author = substr($5, 1, length($5)-1)
- printf "%s %s %s %s %c", filename, date, time, author, 13
+ printf "%s %s %s %s %s %c", filename, rev, date, time, author, 1
+ rev = "?"
next
}
- if ($0 ~ /^(-----------*|===========*)$/) { print ""; next }
- printf "%s%c", $0, 13
+ if (line ~ /^branches: /) { next }
+ if (line ~ /^(-----------*|===========*)$/) { print ""; next }
+ if (line == "Initial revision" || line ~ /^file .+ was initially added on branch .+\.$/) {
+ line = "New file."
+ }
+ printf "%s%c", line, 1
}
' |
# Now each line is of the form
-# FILENAME YYYY/MM/DD HH:MM:SS AUTHOR \rLOG
-# where \r stands for a carriage return,
-# and each line of the log is terminated by \r instead of \n.
+# FILENAME REVISION YYYY-MM-DD HH:MM:SS[+-TIMEZONE] AUTHOR \001LOG
+# where \001 stands for a carriage return,
+# and each line of the log is terminated by \001 instead of \n.
# Sort the log entries, first by date+time (in reverse order),
-# then by author, then by log entry, and finally by file name (just in case).
-sort +1 -3r +3 +0 |
+# then by author, then by log entry, and finally by file name and revision
+# (just in case).
+sort +2 -4r +4 +0 |
# Finally, reformat the sorted log entries.
$AWK '
BEGIN {
- # Some awk variants do not understand "\r" or "\013", so we have to
- # put a carriage return directly in the file.
- CR=" " # <-- There is a single CR between the " chars here.
+ logTZ = "'"$logTZ"'"
+ revision = "'"$revision"'"
+
+ # Some awk variants do not understand "\001", so we have to
+ # put the char directly in the file.
+ SOH="" # <-- There is a single SOH (octal code 001) here.
# Initialize the fullname and mailaddr associative arrays.
'"$initialize_fullname"'
@@ -500,28 +588,15 @@ $AWK '
indent_string = indent_string "\t"
while (1 <= i--)
indent_string = indent_string " "
-
- # Set up date conversion tables.
- # RCS uses a nice, clean, sortable format,
- # but ChangeLog wants the traditional, ugly ctime format.
-
- # January 1, 0 AD (Gregorian) was Saturday = 6
- EPOCH_WEEKDAY = 6
- # Of course, there was no 0 AD, but the algorithm works anyway.
-
- w[0]="Sun"; w[1]="Mon"; w[2]="Tue"; w[3]="Wed"
- w[4]="Thu"; w[5]="Fri"; w[6]="Sat"
-
- '"$month_data"'
}
{
- newlog = substr($0, 1 + index($0, CR))
+ newlog = substr($0, 1 + index($0, SOH))
# Ignore log entries prefixed by "#".
if (newlog ~ /^#/) { next }
- if (Log != newlog || date != $2 || author != $4) {
+ if (Log != newlog || date != $3 || author != $5) {
# The previous log and this log differ.
@@ -552,33 +627,25 @@ $AWK '
filesknown[i] = 0
files = ""
}
- if (date != $2 || author != $4) {
+ if (date != $3 || author != $5) {
# The previous date+author and this date+author differ.
# Print the new one.
- date = $2
- author = $4
-
- # Convert nice RCS date like "1992/01/03 00:03:44"
- # into ugly ctime date like "Fri Jan 3 00:03:44 1992".
- # Calculate day of week from Gregorian calendar.
- i = index($2, "/")
- year = substr($2, 1, i-1) + 0
- monthday = substr($2, i+1)
- i = index(monthday, "/")
- month = substr(monthday, 1, i-1) + 0
- day = substr(monthday, i+1) + 0
- leap = 0
- if (2 < month && year%4 == 0 && (year%100 != 0 || year%400 == 0)) leap = 1
- days_since_Sunday_before_epoch = EPOCH_WEEKDAY + year * 365 + int((year + 3) / 4) - int((year + 99) / 100) + int((year + 399) / 400) + mo[month-1] + leap + day - 1
-
- # Print "date fullname (email address)".
+ date = $3
+ time = $4
+ author = $5
+
+ zone = ""
+ if (logTZ && ((i = index(time, "-")) || (i = index(time, "+"))))
+ zone = " " substr(time, i)
+
+ # Print "date[ timezone] fullname <email address>".
# Get fullname and email address from associative arrays;
# default to author and author@hostname if not in arrays.
if (fullname[author])
auth = fullname[author]
else
auth = author
- printf "%s %s %2d %s %d %s ", w[days_since_Sunday_before_epoch%7], m[month-1], day, $3, year, auth
+ printf "%s%s %s ", date, zone, auth
if (mailaddr[author])
printf "<%s>\n\n", mailaddr[author]
else
@@ -588,6 +655,7 @@ $AWK '
filesknown[$1] = 1
if (files == "") files = " " $1
else files = files ", " $1
+ if (revision && $2 != "?") files = files " " $2
}
}
END {
@@ -603,3 +671,7 @@ $AWK '
# Exit successfully.
exec rm -f $llogout $rlogout
+
+# Local Variables:
+# tab-width:4
+# End:
diff --git a/gnu/usr.bin/cvs/diff/ChangeLog b/gnu/usr.bin/cvs/diff/ChangeLog
index 3ebde5df9d0..90ba69b11b9 100644
--- a/gnu/usr.bin/cvs/diff/ChangeLog
+++ b/gnu/usr.bin/cvs/diff/ChangeLog
@@ -1,3 +1,35 @@
+1999-02-17 Jim Kingdon <http://www.cyclic.com>
+ and Hallvard B Furuseth.
+
+ * util.c: Use __STDC__ consistently with ./system.h.
+ * system.h: Add comment about PARAMS.
+
+1999-01-12 Jim Kingdon <http://www.cyclic.com>
+
+ * Makefile.in, analyze.c, cmpbuf.c, cmpbuf.h, context.c, diff.c,
+ diff.h, diff3.c, diffrun.h, dir.c, ed.c, io.c, normal.c, system.h,
+ util.c: Remove paragraph containing the old snail mail address of
+ the Free Software Foundation.
+
+1998-09-21 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * util.c (printf_output): Make msg static; avoids auto
+ initializer, which is not portable to SunOS4 /bin/cc.
+ Reported by Mike Sutton@SAIC.
+
+1998-09-14 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * Makefile.in (DISTFILES): Add diagmeet.note.
+
+1998-08-15 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * diffrun.h (struct diff_callbacks): Change calling convention of
+ write_output so that a zero length means to output zero bytes.
+ The cvs_output convention is just too ugly/error-prone.
+ * util.c (printf_output): Rewrite to parse format string
+ overselves rather than calling vasprintf, which cannot be
+ implemented in portable C.
+
1998-08-06 David Masterson of kla-tencor.com
* util.c (flush_output): Don't prototype.
diff --git a/gnu/usr.bin/cvs/diff/analyze.c b/gnu/usr.bin/cvs/diff/analyze.c
index 0bda3cf7723..f2925946e38 100644
--- a/gnu/usr.bin/cvs/diff/analyze.c
+++ b/gnu/usr.bin/cvs/diff/analyze.c
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
/* The basic algorithm is described in:
"An O(ND) Difference Algorithm and its Variations", Eugene Myers,
diff --git a/gnu/usr.bin/cvs/diff/cmpbuf.c b/gnu/usr.bin/cvs/diff/cmpbuf.c
index e95a8f98ed9..2820dfa5a28 100644
--- a/gnu/usr.bin/cvs/diff/cmpbuf.c
+++ b/gnu/usr.bin/cvs/diff/cmpbuf.c
@@ -11,9 +11,7 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ */
#include "system.h"
#include "cmpbuf.h"
diff --git a/gnu/usr.bin/cvs/diff/cmpbuf.h b/gnu/usr.bin/cvs/diff/cmpbuf.h
index e3852b7bd4f..b7b965d8575 100644
--- a/gnu/usr.bin/cvs/diff/cmpbuf.h
+++ b/gnu/usr.bin/cvs/diff/cmpbuf.h
@@ -13,8 +13,6 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
size_t buffer_lcm PARAMS((size_t, size_t));
diff --git a/gnu/usr.bin/cvs/diff/context.c b/gnu/usr.bin/cvs/diff/context.c
index e843734f45c..c4562c94b13 100644
--- a/gnu/usr.bin/cvs/diff/context.c
+++ b/gnu/usr.bin/cvs/diff/context.c
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#include "diff.h"
diff --git a/gnu/usr.bin/cvs/diff/diagmeet.note b/gnu/usr.bin/cvs/diff/diagmeet.note
new file mode 100644
index 00000000000..8f7242c7356
--- /dev/null
+++ b/gnu/usr.bin/cvs/diff/diagmeet.note
@@ -0,0 +1,71 @@
+Here is a comparison matrix which shows a case in which
+it is possible for the forward and backward scan in `diag'
+to meet along a nonzero length of diagonal simultaneous
+(so that bdiag[d] and fdiag[d] are not equal)
+even though there is no snake on that diagonal at the meeting point.
+
+
+ 85 1 1 1 159 1 1 17
+ 1 2 3 4
+60
+ 1 2
+1
+ 2 2 3 4
+71
+ 3 3 4 5
+85
+ 4 3 4 5
+17
+ 5 4 5
+1
+ 6 4 5 6
+183
+ 7 5 6 7
+10
+ 8 6 7
+1
+ 9 6 7 8
+12
+ 7 8 9 10
+13
+ 10 8 9 10
+14
+ 10 9 10
+17
+ 10 10
+1
+ 10 9 10
+1
+ 8 10 10 10
+183
+ 8 7 9 9 9
+10
+ 7 6 8 9 8 8
+1
+ 6 5 7 7
+1
+ 5 6 6
+1
+ 5 5 5
+50
+ 5 4 4 4
+1
+ 4 3 3
+85
+ 5 4 3 2 2
+1
+ 2 1
+17
+ 5 4 3 2 1 1
+1
+ 1 0
+ 85 1 1 1 159 1 1 17
+
+
+
+
+
+
+
+
+
diff --git a/gnu/usr.bin/cvs/diff/diff.c b/gnu/usr.bin/cvs/diff/diff.c
index 3467b537aec..bc951c4105f 100644
--- a/gnu/usr.bin/cvs/diff/diff.c
+++ b/gnu/usr.bin/cvs/diff/diff.c
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
/* GNU DIFF was written by Mike Haertel, David Hayes,
Richard Stallman, Len Tower, and Paul Eggert. */
diff --git a/gnu/usr.bin/cvs/diff/diff.h b/gnu/usr.bin/cvs/diff/diff.h
index 6107e6221fb..642138d6ef0 100644
--- a/gnu/usr.bin/cvs/diff/diff.h
+++ b/gnu/usr.bin/cvs/diff/diff.h
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#include "system.h"
#include <stdio.h>
diff --git a/gnu/usr.bin/cvs/diff/diff3.c b/gnu/usr.bin/cvs/diff/diff3.c
index 64867f48f23..65b783b3e67 100644
--- a/gnu/usr.bin/cvs/diff/diff3.c
+++ b/gnu/usr.bin/cvs/diff/diff3.c
@@ -11,9 +11,7 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ */
/* Written by Randy Smith */
/* Librarification by Tim Pierce */
diff --git a/gnu/usr.bin/cvs/diff/diffrun.h b/gnu/usr.bin/cvs/diff/diffrun.h
index 28c1f45e5fd..08fbd0db70a 100644
--- a/gnu/usr.bin/cvs/diff/diffrun.h
+++ b/gnu/usr.bin/cvs/diff/diffrun.h
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#ifndef DIFFRUN_H
#define DIFFRUN_H
@@ -41,12 +39,14 @@ struct diff_callbacks
{
/* Write output. This function just writes a string of a given
length to the output file. The default is to fwrite to OUTFILE.
- If this callback is defined, flush_output must also be defined. */
+ If this callback is defined, flush_output must also be defined.
+ If the length is zero, output zero bytes. */
void (*write_output) DIFFPARAMS((char const *, size_t));
/* Flush output. The default is to fflush OUTFILE. If this
callback is defined, write_output must also be defined. */
void (*flush_output) DIFFPARAMS((void));
- /* Write to stdout. This is called for version and help messages. */
+ /* Write a '\0'-terminated string to stdout.
+ This is called for version and help messages. */
void (*write_stdout) DIFFPARAMS((char const *));
/* Print an error message. The first argument is a printf format,
and the next two are parameters. The default is to print a
diff --git a/gnu/usr.bin/cvs/diff/dir.c b/gnu/usr.bin/cvs/diff/dir.c
index 6eef9a63244..fae74e82c65 100644
--- a/gnu/usr.bin/cvs/diff/dir.c
+++ b/gnu/usr.bin/cvs/diff/dir.c
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#include "diff.h"
diff --git a/gnu/usr.bin/cvs/diff/ed.c b/gnu/usr.bin/cvs/diff/ed.c
index 6b00d133e4d..74fc2a4f1fe 100644
--- a/gnu/usr.bin/cvs/diff/ed.c
+++ b/gnu/usr.bin/cvs/diff/ed.c
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#include "diff.h"
diff --git a/gnu/usr.bin/cvs/diff/io.c b/gnu/usr.bin/cvs/diff/io.c
index 66059155109..730c09acd54 100644
--- a/gnu/usr.bin/cvs/diff/io.c
+++ b/gnu/usr.bin/cvs/diff/io.c
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#include "diff.h"
diff --git a/gnu/usr.bin/cvs/diff/normal.c b/gnu/usr.bin/cvs/diff/normal.c
index 75dae889930..b1f495522e0 100644
--- a/gnu/usr.bin/cvs/diff/normal.c
+++ b/gnu/usr.bin/cvs/diff/normal.c
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#include "diff.h"
diff --git a/gnu/usr.bin/cvs/diff/system.h b/gnu/usr.bin/cvs/diff/system.h
index 7812b767592..76bc1631fee 100644
--- a/gnu/usr.bin/cvs/diff/system.h
+++ b/gnu/usr.bin/cvs/diff/system.h
@@ -13,9 +13,7 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
/* We must define `volatile' and `const' first (the latter inside config.h),
so that they're used consistently in all system includes. */
@@ -29,6 +27,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/types.h>
#include <sys/stat.h>
+/* Note that PARAMS is just internal to the diff library; diffrun.h
+ has its own mechanism, which will hopefully be less likely to
+ conflict with the library's caller's namespace. */
#if __STDC__
#define PARAMS(args) args
#define VOID void
diff --git a/gnu/usr.bin/cvs/diff/util.c b/gnu/usr.bin/cvs/diff/util.c
index 1b281700a5d..c4d2d7169a1 100644
--- a/gnu/usr.bin/cvs/diff/util.c
+++ b/gnu/usr.bin/cvs/diff/util.c
@@ -13,13 +13,11 @@ 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.
-You should have received a copy of the GNU General Public License
-along with GNU DIFF; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+*/
#include "diff.h"
-#ifdef __STDC__
+#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
@@ -340,14 +338,14 @@ write_output (text, len)
/* Printf something to the output file. */
-#ifdef __STDC__
+#if __STDC__
#define VA_START(args, lastarg) va_start(args, lastarg)
#else /* ! __STDC__ */
#define VA_START(args, lastarg) va_start(args)
#endif /* __STDC__ */
void
-#if defined (__STDC__)
+#if __STDC__
printf_output (const char *format, ...)
#else
printf_output (format, va_alist)
@@ -360,17 +358,51 @@ printf_output (format, va_alist)
VA_START (args, format);
if (callbacks && callbacks->write_output)
{
- char *p;
+ /* We implement our own limited printf-like functionality (%s, %d,
+ and %c only). Callers who want something fancier can use
+ sprintf. */
+ const char *p = format;
+ char *q;
+ char *str;
+ int num;
+ int ch;
+ unsigned char buf[100];
+
+ while ((q = strchr (p, '%')) != NULL)
+ {
+ static const char msg[] =
+ "\ninternal error: bad % in printf_output\n";
+ (*callbacks->write_output) (p, q - p);
- p = NULL;
- vasprintf (&p, format, args);
- if (p == NULL)
- fatal ("out of memory");
+ switch (q[1])
+ {
+ case 's':
+ str = va_arg (args, char *);
+ (*callbacks->write_output) (str, strlen (str));
+ break;
+ case 'd':
+ num = va_arg (args, int);
+ sprintf (buf, "%d", num);
+ (*callbacks->write_output) (buf, strlen (buf));
+ break;
+ case 'c':
+ ch = va_arg (args, int);
+ buf[0] = ch;
+ (*callbacks->write_output) (buf, 1);
+ break;
+ default:
+ (*callbacks->write_output) (msg, sizeof (msg) - 1);
+ /* Don't just keep going, because q + 1 might point to the
+ terminating '\0'. */
+ goto out;
+ }
+ p = q + 2;
+ }
(*callbacks->write_output) (p, strlen (p));
- free (p);
}
else
vfprintf (outfile, format, args);
+ out:
va_end (args);
}
diff --git a/gnu/usr.bin/cvs/doc/ChangeLog b/gnu/usr.bin/cvs/doc/ChangeLog
index e9e4925939e..15547b5fec9 100644
--- a/gnu/usr.bin/cvs/doc/ChangeLog
+++ b/gnu/usr.bin/cvs/doc/ChangeLog
@@ -1,3 +1,257 @@
+1999-01-29 Jim Kingdon <http://www.cyclic.com>
+
+ * cvs.texinfo: Use EXAMPLE.COM EXAMPLE.ORG and EXAMPLE.NET instead
+ of domains which might conflict with actual (current or future)
+ domains. The EXAMPLE domains are registered for this purpose.
+
+1999-01-22 Jim Kingdon <http://www.cyclic.com>
+
+ * cvs.texinfo (Sticky tags): Refer to -j as the better way to undo
+ a change.
+ (Merging two revisions): Also talk about undoing removals and
+ adds. Move the index entries to here.
+
+1999-01-21 Jim Kingdon <http://www.cyclic.com>
+
+ * cvs.texinfo (Error messages): Add "waiting for USER's lock".
+
+1999-01-16 Jim Kingdon <http://www.cyclic.com>
+
+ * cvs.texinfo (Wrappers): Comment out all the -t/-f documentation,
+ since that feature is currently disabled.
+
+1999-01-14 Jim Kingdon <http://www.cyclic.com>
+
+ * cvs.texinfo (Connecting via rsh): Add some more index entries so
+ that people who want to use SSH and such are slightly less lost.
+
+1999-01-12 Jim Kingdon <http://www.cyclic.com>
+
+ * cvs-paper.ms: Remove comments which contained the FSF's old
+ address; it has changed.
+
+1998-12-29 Jim Kingdon <http://www.cyclic.com>
+
+ * cvsclient.texi (Dates): Numeric timezones are preferred.
+ Also mention the Checkin-time request.
+
+1998-12-23 Jim Kingdon <http://www.cyclic.com>
+
+ * RCSFILES: Add clarification about certain character set issues
+ from Paul Eggert, the RCS maintainer. The last paragraph and the
+ change from Shift-JIS to JIS as an example of a character set
+ which contains 0x40 bytes which are not '@' characters are mine;
+ the rest is directly from Paul Eggert.
+
+1998-12-22 Martin Buchholz <martin@xemacs.org>
+
+ * cvs.texinfo: Fixed various trivial typos.
+
+1998-12-17 Jim Kingdon
+
+ * cvsclient.texi (Responses): Explicitly say that Mod-time need
+ not be sent for all files.
+
+1998-12-16 Jim Kingdon
+
+ Thanks to Ram Rajadhyaksha of the MacCVS Pro team for raising the
+ following issues.
+ * cvs.texinfo (Working directory storage): The deal about storing
+ files as text files applies to all the CVS/* files, not just
+ CVS/Entries. State the rationale too.
+ Document CVSROOT/Emptydir in CVS/Repository.
+ There is no set order in CVS/Entries.
+ Explicitly say that writing Entries.Log is optional.
+
+1998-12-03 Jim Kingdon
+
+ * cvs.texinfo (Error messages): Add "unrecognized auth response".
+ (Password authentication server): Remove comment about
+ "unrecognized auth response" and link to the troubleshooting
+ section.
+
+1998-12-02 Jim Kingdon
+
+ * cvs.texinfo (Multiple repositories): Add an example.
+
+1998-11-18 Jim Kingdon
+
+ * cvs.texinfo (Invoking CVS): Change "-r tag" to "-r rev". We
+ already use "tag" as the name of the tag we are adding.
+
+1998-11-13 Jim Kingdon
+
+ * cvs.texinfo (CVS commands): Add comment about whether part of
+ the manual should be organized by command.
+
+1998-11-06 Jim Kingdon
+
+ Clean up various confusions between modules and directories:
+ * cvs.texinfo: In "are you sure you want to release" message,
+ change module to directory. CVS was changed some time ago.
+ (Tags): "working copy of the module" -> "working directory".
+ (Merging two revisions): Remove unnecessary text "that make up a
+ module".
+ (Recursive behavior): Change "module" to "directory".
+ (Removing files): Likewise.
+ (Tracking sources): Remove "a module" from titles.
+ (Moving directories): Change "module" to "parent-dir".
+ (Inside): Remove "of the module".
+ (Inside): Change "module" to "dir".
+ (Rename by copying): Change "module" to "dir".
+ (Rename by copying): Remove "of the module".
+ (Moving directories): "copy of the module" -> "checked out copy of
+ the directory"; remove second "of the module". Change "check out
+ the module" to " check out again".
+ (Moving directories): Remove "of the module".
+ (Keyword substitution): "your working copy of a module" -> "a
+ working directory".
+ (CVS commands): Change "module" to "directory".
+ (release examples): "module" -> "tc directory".
+ (commitinfo): "relative path to the module" -> "directory in the
+ repository".
+ (verifymsg): Change "module" to "directory".
+ (Updating a file): "working copy of a module" -> "working directory".
+
+1998-10-25 Jim Kingdon
+
+ * cvs.texinfo (Branches and revisions): Fix error in branch
+ numbering which was introduced with change of 4 May 1997.
+
+1998-10-20 Jim Kingdon
+
+ * cvs.texinfo (Tags): Point to Invoking CVS node so people aren't
+ left wondering what the syntax is. When introducing -r option,
+ warn people about sticky tags right off.
+ (Tagging the working directory, Tagging by date/tag, Modifying
+ tags, Tagging add/remove): New sections.
+ (Invoking CVS): Adjust tag and rtag to point to the new sections,
+ and to add tag -c which had been omitted. Delete tag -n; there is
+ no such option.
+ (rtag, tag): Removed; no longer needed.
+ (commit examples): Update xref.
+
+1998-10-15 Jim Kingdon
+
+ * cvsclient.texi (Requests): It is OK to send Set before Root.
+
+1998-10-13 Jim Kingdon
+
+ * cvsclient.texi (Protocol Notes): Remove item about "cvs update"
+ sending modified files to the server; there are some better ideas
+ at http://www.cyclic.com/cvs/dev-update.txt
+ Add mention of www.cyclic.com.
+
+1998-09-30 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Committing your changes, Environment variables):
+ Document VISUAL.
+
+1998-09-27 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Password authentication server): Say explicitly
+ that you edit passwd directly, many users get confused by this.
+
+1998-09-24 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Connecting via fork): :fork: may be of interest to
+ users, for example those who prefer CVS to prompt for one log
+ message per checkin, rather than one per directory.
+ (Connecting via fork): Document CVS_SERVER.
+
+1998-09-24 Noel Cragg <noel@swish.red-bean.com>
+
+ * cvs.texinfo (Connecting via fork): new node about the fork
+ access method.
+
+1998-09-22 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Environment variables): Document
+ CVS_IGNORE_REMOTE_ROOT in the CVS 1.10 context.
+ (Moving a repository): Update comments concerning surgery on
+ CVS/Root and CVS/Repository files.
+
+1998-09-21 Noel Cragg <noel@swish.red-bean.com>
+
+ * cvs.texinfo (Environment variables): remove information about
+ CVS_IGNORE_REMOTE_ROOT, since it's no longer used.
+
+1998-09-21 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (config): Mention that CVS 1.10 doesn't have
+ LockDir.
+
+1998-09-18 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Keyword list): Describe $Name and checking out with
+ a revision.
+
+1998-09-16 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo: RFC2346 is out; update comment.
+
+1998-09-13 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Keyword list, Substitution modes): In describing
+ $Locker and -kkvl, refer to cvs admin -l.
+
+ * cvsclient.texi (Requests): Re-word description of Sticky to
+ allow room for "Ntagname" (or other, future, values).
+
+ * cvs.texinfo (tag): Remove confusing wording about supplying
+ revision numbers "implicitly".
+
+1998-09-10 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (rdiff options): Thanks to the diff library, -u is
+ supported regardless of your diff program.
+
+1998-09-07 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (config): Add LockDir.
+
+1998-09-01 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvsclient.texi (Requests): "Directory" and "Argument" are
+ requests, not commands. Likewise for "other-request". A command,
+ roughly, is a request that uses "Argument"s, but we might want to
+ phase out the use of that term more so than codify it, I'm not sure.
+
+1998-09-01 Noel Cragg <noel@swish.red-bean.com>
+
+ * cvsclient.texi (Requests): added a detailed explanation of the
+ Directory request and how it is handled, both for pre-1.10 and
+ post-1.10 servers.
+
+1998-09-01 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Multiple repositories): Also describe the CVS 1.10
+ behavior. Looking at a mismatched version of the manual seems to
+ be a reasonably common occurrence.
+
+ * cvs.texinfo (Environment variables): Revert change regarding
+ CVS_SERVER_SLEEP*; having that kind of debugging code in the main
+ CVS is getting out of hand.
+
+1998-09-01 Noel Cragg <noel@swish.red-bean.com>
+
+ * cvs.texinfo (Multiple repositories): brief mention that cvs now
+ handles a working directory composed of multiple repositories.
+ (Environment variables): add note about CVS_SERVER_SLEEP2.
+
+1998-08-21 Ian Lance Taylor <ian@cygnus.com>
+
+ * cvsclient.texi (Text tags): Document importmergecmd tag.
+
+1998-08-20 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.texinfo (Common options): Replace out of date URL concerning
+ ISO8601 dates with a more general statement and a few comments.
+
+1998-08-18 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvsclient.texi (Requests): Add "Checkin-time" request.
+
Sun Jul 26 02:42:20 1998 Noel Cragg <noel@swish.red-bean.com>
* cvs.texinfo (config): TopLevelAdmin variable.
diff --git a/gnu/usr.bin/cvs/doc/RCSFILES b/gnu/usr.bin/cvs/doc/RCSFILES
index 13c4f93c796..46503377901 100644
--- a/gnu/usr.bin/cvs/doc/RCSFILES
+++ b/gnu/usr.bin/cvs/doc/RCSFILES
@@ -136,6 +136,36 @@ Both RCS 5.7 and current versions of CVS handle the $Log keyword in a
different way if the log message starts with "checked in with -k by ".
I don't think this behavior is documented anywhere.
+Here is a clarification regarding characters versus bytes in certain
+character sets like JIS and Big5:
+
+ The RCS file format, as described in the rcsfile(5) man page, is
+ actually byte-oriented, not character-oriented, despite hints to
+ the contrary in the man page. This distinction is important for
+ multibyte characters. For example, if a multibyte character
+ contains a `@' byte, the `@' must be doubled within strings in RCS
+ files, since RCS uses `@' bytes as escapes.
+
+ This point is not an issue for encodings like ISO 8859, which do
+ not have multibyte characters. Nor is it an issue for encodings
+ like UTF-8 and EUC-JIS, which never uses ASCII bytes within a
+ multibyte character. It is an issue only for multibyte encodings
+ like JIS and BIG5, which _do_ usurp ASCII bytes.
+
+ If `@' doubling occurs within a multibyte char, the resulting RCS
+ file is not a properly encoded text file. Instead, it is a byte
+ stream that does not use a consistent character encoding that can
+ be understood by the usual text tools, since doubling `@' messes
+ up the encoding. This point affects only programs that examine
+ the RCS files -- it doesn't affect the external RCS interface, as
+ the RCS commands always give you the properly encoded text files
+ and logs (assuming that you always check in properly encoded
+ text).
+
+ CVS 1.10 (and earlier) probably has some bugs in this area on
+ systems where a C "char" is signed and where the data contains
+ bytes with the eighth bit set.
+
One common concern about the RCS file format is the fact that to get
the head of a branch, one must apply deltas from the head of the trunk
to the branchpoint, and then from the branchpoint to the head of the
diff --git a/gnu/usr.bin/cvs/doc/cvs-paper.ms b/gnu/usr.bin/cvs/doc/cvs-paper.ms
index 567179b393f..ea9445ad168 100644
--- a/gnu/usr.bin/cvs/doc/cvs-paper.ms
+++ b/gnu/usr.bin/cvs/doc/cvs-paper.ms
@@ -14,10 +14,6 @@
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" GNU General Public License for more details.
.\"
-.\" You should have received a copy of the GNU General Public License
-.\" along with this program; if not, write to the Free Software
-.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
.\" The author can be reached at: berliner@prisma.com
.\"
.de SP
diff --git a/gnu/usr.bin/cvs/doc/cvs.texinfo b/gnu/usr.bin/cvs/doc/cvs.texinfo
index 5dd2f77b327..385fa0f984e 100644
--- a/gnu/usr.bin/cvs/doc/cvs.texinfo
+++ b/gnu/usr.bin/cvs/doc/cvs.texinfo
@@ -27,8 +27,7 @@
@c http://www.ft.uni-erlangen.de/~mskuhn/iso-paper.html
@c for more on paper sizes. Insuring that margins are
@c big enough to print on either A4 or US letter does
-@c indeed seem to be the usual approach (according to
-@c an internet draft by Jacob Palme).
+@c indeed seem to be the usual approach (RFC2346).
@c This document seems to get overfull hboxes with some
@c frequency (probably because the tendency is to
@@ -556,6 +555,14 @@ which will vary with your operating system, for example
@code{vi} for unix or @code{notepad} for Windows
NT/95.
+@cindex VISUAL, environment variable
+In addition, @sc{cvs} checks the @code{$VISUAL} environment
+variable. Opinions vary on whether this behavior is desirable and
+whether future releases of @sc{cvs} should check @code{$VISUAL} or
+ignore it. You will be OK either way if you make sure that
+@code{$VISUAL} is either unset or set to the same thing as
+@code{$EDITOR}.
+
@c This probably should go into some new node
@c containing detailed info on the editor, rather than
@c the intro. In fact, perhaps some of the stuff with
@@ -624,7 +631,7 @@ $ cvs release -d tc
M driver.c
? tc
You have [1] altered files in this repository.
-Are you sure you want to release (and delete) module `tc': n
+Are you sure you want to release (and delete) directory `tc': n
** `release' aborted by user choice.
@end example
@@ -686,7 +693,7 @@ $ cd ..
$ cvs release -d tc
? tc
You have [0] altered files in this repository.
-Are you sure you want to release (and delete) module `tc': y
+Are you sure you want to release (and delete) directory `tc': y
@end example
@c ---------------------------------------------------------------------
@@ -818,10 +825,8 @@ repository, it will remember where its repository is
The @code{-d} option and the @file{CVS/Root} file both
override the @code{$CVSROOT} environment variable. If
@code{-d} option differs from @file{CVS/Root}, the
-former is used (and specifying @code{-d} will cause
-@file{CVS/Root} to be updated). Of course, for proper
-operation they should be two ways of referring to the
-same repository.
+former is used. Of course, for proper operation they
+should be two ways of referring to the same repository.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Repository storage
@@ -1349,6 +1354,14 @@ silently ignore files which are in the directory but
which are not documented here, to allow for future
expansion.
+The files are stored according to the text file
+convention for the system in question. This means that
+working directories are not portable between systems
+with differing conventions for storing text files.
+This is intentional, on the theory that the files being
+managed by CVS probably will not be portable between
+such systems either.
+
@table @file
@item Root
This file contains the current @sc{cvs} root, as
@@ -1390,19 +1403,15 @@ or
yoyodyne/tc
@end example
+If the particular working directory does not correspond
+to a directory in the repository, then @file{Repository}
+should contain @file{CVSROOT/Emptydir}.
+
@cindex Entries file, in CVS directory
@cindex CVS/Entries file
@item Entries
This file lists the files and directories in the
-working directory. It is a text file according to the
-conventions appropriate for the operating system in
-question.
-@c Using OS text file conventions makes it impossible (it
-@c would seem) to share a working directory via a
-@c networked file system between systems with diverse
-@c text file conventions. But that might be correct,
-@c because the text files under CVS control are subject
-@c to the same problem. It is also the status quo.
+working directory.
The first character of each line indicates what sort of
line it is. If the character is unrecognized, programs
reading the file should silently skip that line, to
@@ -1464,6 +1473,8 @@ all the @var{filler} fields should be silently ignored,
for future expansion. Programs which modify
@code{Entries} files should preserve these fields.
+The lines in the @file{Entries} file can be in any order.
+
@cindex Entries.Log file, in CVS directory
@cindex CVS/Entries.Log file
@item Entries.Log
@@ -1492,6 +1503,9 @@ in @file{Entries.Log} is not a space, then it was
written by an older version of @sc{cvs} (not documented
here).
+Programs which are writing rather than reading can
+safely ignore @file{Entries.Log} if they so choose.
+
@cindex Entries.Backup file, in CVS directory
@cindex CVS/Entries.Backup file
@item Entries.Backup
@@ -1706,23 +1720,31 @@ to check out the working directory
(@pxref{Specifying a repository}).
The big advantage of having multiple repositories is
-that they can reside on different servers. The big
-disadvantage is that you cannot have a single @sc{cvs}
-command recurse into directories which comes from
-different repositories. Generally speaking, if you are
-thinking of setting up several repositories on the same
-machine, you might want to consider using several
-directories within the same repository.
-@c FIXCVS: the thing about recursing into diverse roots
-@c would be nice to fix. But it gets hairy if they are
-@c on diverse servers--it isn't clear this is really
-@c all that useful.
+that they can reside on different servers. With @sc{cvs}
+version 1.10, a single command cannot recurse into
+directories from different repositories. With development
+versions of @sc{cvs}, you can check out code from multiple
+servers into your working directory. @sc{cvs} will
+recurse and handle all the details of making
+connections to as many server machines as necessary to
+perform the requested command. Here is an example of
+how to set up a working directory:
+
+@example
+cvs -d server1:/cvs co dir1
+cd dir1
+cvs -d server2:/root co sdir
+cvs update
+@end example
+
+The @code{cvs co} commands set up the working
+directory, and then the @code{cvs update} command will
+contact server2, to update the dir1/sdir subdirectory,
+and server1, to update everything else.
+
@c FIXME: Does the FAQ have more about this? I have a
@c dim recollection, but I'm too lazy to check right now.
-None of the examples in this manual show multiple
-repositories.
-
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Creating a repository
@section Creating a repository
@@ -1755,7 +1777,7 @@ approximately one working directory for each developer
(either the entire tree or a portion of it, depending
on what each developer uses).
-The repository should be accessable
+The repository should be accessible
(directly or via a networked file system) from all
machines which want to use @sc{cvs} in server or local
mode; the client machines need not have any access to
@@ -1863,14 +1885,12 @@ see @ref{Working directory storage}, for information on
the @file{CVS/Repository} and @file{CVS/Root} files, but
unless you are sure you want to bother, it probably
isn't worth it.
-@c FIXME: This should be made unnecessary by:
-@c 1) a new -d should affect CVS/Root files throughout
-@c the tree, not just at the top level.
-@c 2) the RELATIVE_REPOS code should be fixed and made the
-@c default. I think that CVS already reads
-@c CVS/Repository files which are absolute or
-@c relative. FIXME: needs more investigation and
-@c documentation in "Working directory storage".
+@c FIXME: Surgery on CVS/Repository should be avoided
+@c by making RELATIVE_REPOS the default.
+@c FIXME-maybe: might want some documented way to
+@c change the CVS/Root files in some particular tree.
+@c But then again, I don't know, maybe just having
+@c people do this in perl/shell/&c isn't so bad...
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Remote repositories
@@ -1926,6 +1946,7 @@ described in @ref{Connecting via rsh}.
* Password authenticated:: Direct connections using passwords
* GSSAPI authenticated:: Direct connections using GSSAPI
* Kerberos authenticated:: Direct connections with kerberos
+* Connecting via fork:: Using a forked @code{cvs server} to connect
@end menu
@node Server requirements
@@ -2027,19 +2048,19 @@ operations, so the remote user host needs to have a
user.
For example, suppose you are the user @file{mozart} on
-the local machine @file{toe.grunge.com}, and the
-server machine is @file{chainsaw.yard.com}. On
-chainsaw, put the following line into the file
+the local machine @file{toe.example.com}, and the
+server machine is @file{faun.example.org}. On
+faun, put the following line into the file
@file{.rhosts} in @file{bach}'s home directory:
@example
-toe.grunge.com mozart
+toe.example.com mozart
@end example
Then test that @code{rsh} is working with
@example
-rsh -l bach chainsaw.yard.com 'echo $PATH'
+rsh -l bach faun.example.org 'echo $PATH'
@end example
@cindex CVS_SERVER, environment variable
@@ -2063,6 +2084,9 @@ There is no need to edit @code{inetd.conf} or start a
@cindex :server:, setting up
@cindex :ext:, setting up
+@cindex Kerberos, using kerberized rsh
+@cindex SSH (rsh replacement)
+@cindex rsh replacements (Kerberized, SSH, &c)
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.
@@ -2095,10 +2119,10 @@ replacement.
Continuing our example, supposing you want to access
the module @file{foo} in the repository
@file{/usr/local/cvsroot/}, on machine
-@file{chainsaw.yard.com}, you are ready to go:
+@file{faun.example.org}, you are ready to go:
@example
-cvs -d :ext:bach@@chainsaw.yard.com:/usr/local/cvsroot checkout foo
+cvs -d :ext:bach@@faun.example.org:/usr/local/cvsroot checkout foo
@end example
(The @file{bach@@} can be omitted if the username is
@@ -2183,14 +2207,8 @@ cvspserver 2401/tcp
@code{inetd}, or do whatever is necessary to force it
to reread its initialization files.
-@c FIXME: should be documenting how to troubleshoot
-@c this. One strange situation I ran into recently
-@c was that if inetd.conf specifies a non-existent
-@c cvs (e.g. /usr/local/bin/cvs doesn't exist in
-@c the above example), the client says
-@c cvs-1.8 [login aborted]: unrecognized auth response from harvey:
-@c which is a very unhelpful response (can it be
-@c improved? does inetd log somewhere?)
+If you are having trouble setting this up, see
+@ref{Connection}.
@cindex CVS passwd file
@cindex passwd (admin file)
@@ -2247,11 +2265,11 @@ anyone:1sOp854gDF3DY:spwang
@end example
Thus, someone remotely accessing the repository
-on @file{chainsaw.yard.com} with the following
+on @file{faun.example.org} with the following
command:
@example
-cvs -d :pserver:cvs@@chainsaw.yard.com:/usr/local/cvsroot checkout foo
+cvs -d :pserver:cvs@@faun.example.org:/usr/local/cvsroot checkout foo
@end example
would end up running the server under the
@@ -2274,6 +2292,9 @@ Right now, the only way to put a password in the
@sc{cvs} @file{passwd} file is to paste it there from
somewhere else. Someday, there may be a @code{cvs
passwd} command.
+Unlike many of the files in @file{$CVSROOT/CVSROOT},
+you edit the @file{passwd} file directly, rather than
+via @sc{cvs}.
@c We might also suggest using the @code{htpasswd} command
@c from freely available web servers as well, but that
@c would open up a can of worms in that the users next
@@ -2301,7 +2322,7 @@ argument or the @code{CVSROOT} environment variable.
password:
@example
-cvs -d :pserver:bach@@chainsaw.yard.com:/usr/local/cvsroot login
+cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot login
CVS password:
@end example
@@ -2314,7 +2335,7 @@ connect directly to the server and authenticate with
the stored password:
@example
-cvs -d :pserver:bach@@chainsaw.yard.com:/usr/local/cvsroot checkout foo
+cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot checkout foo
@end example
The @samp{:pserver:} is necessary because without it,
@@ -2338,7 +2359,7 @@ administrator who happens to look at that file).
@c FIXME: seems to me this needs somewhat more
@c explanation.
@cindex Logout (subcommand)
-The password for the currently choosen remote repository
+The password for the currently chosen remote repository
can be removed from the CVS_PASSFILE by using the
@code{cvs logout} command.
@@ -2421,6 +2442,7 @@ security, get Kerberos.
@cindex GSSAPI
@cindex security, GSSAPI
@cindex :gserver:, setting up
+@cindex Kerberos, using :gserver:
GSSAPI is a generic interface to network security
systems such as Kerberos 5.
If you have a working GSSAPI library, you can have
@@ -2465,13 +2487,13 @@ To connect using GSSAPI, use @samp{:gserver:}. For
example,
@example
-cvs -d :gserver:chainsaw.yard.com:/usr/local/cvsroot checkout foo
+cvs -d :gserver:faun.example.org:/usr/local/cvsroot checkout foo
@end example
@node Kerberos authenticated
@subsection Direct connection with kerberos
-@cindex kerberos
+@cindex Kerberos, using :kserver:
@cindex security, kerberos
@cindex :kserver:, setting up
The easiest way to use kerberos is to use the kerberos
@@ -2513,12 +2535,47 @@ which allows you to log into the server machine. Then
you are ready to go:
@example
-cvs -d :kserver:chainsaw.yard.com:/usr/local/cvsroot checkout foo
+cvs -d :kserver:faun.example.org:/usr/local/cvsroot checkout foo
@end example
Previous versions of @sc{cvs} would fall back to a
connection via rsh; this version will not do so.
+@node Connecting via fork
+@subsection Connecting with fork
+
+@cindex fork, access method
+@cindex :fork:, setting up
+This access method allows you to connect to a
+repository on your local disk via the remote protocol.
+In other words it does pretty much the same thing as
+@code{:local:}, but various quirks, bugs and the like are
+those of the remote @sc{cvs} rather than the local
+@sc{cvs}.
+
+For day-to-day operations you might prefer either
+@code{:local:} or @code{:fork:}, depending on your
+preferences. Of course @code{:fork:} comes in
+particularly handy in testing or
+debugging @code{cvs} and the remote protocol.
+Specifically, we avoid all of the network-related
+setup/configuration, timeouts, and authentication
+inherent in the other remote access methods but still
+create a connection which uses the remote protocol.
+
+To connect using the @code{fork} method, use
+@samp{:fork:} and the pathname to your local
+repository. For example:
+
+@example
+cvs -d :fork:/usr/local/cvsroot checkout foo
+@end example
+
+@cindex CVS_SERVER, and :fork:
+As with @code{:ext:}, the server is called @samp{cvs}
+by default, or the value of the @code{CVS_SERVER}
+environment variable.
+
@c ---------------------------------------------------------------------
@node Read-only access
@section Read-only repository access
@@ -2778,7 +2835,7 @@ details). Then create the appropriate directories in
files into the appropriate directories in the @sc{cvs}
repository (the name in the repository must be the name
of the source file with @samp{,v} added; the files go
-directly in the appopriate directory of the repository,
+directly in the appropriate directory of the repository,
not in an @file{RCS} subdirectory). This is one of the
few times when it is a good idea to access the @sc{cvs}
repository directly, rather than using @sc{cvs}
@@ -2956,6 +3013,10 @@ numeric revision in each file.
* Versions revisions releases:: Terminology used in this manual
* Assigning revisions:: Assigning revisions
* Tags:: Tags--Symbolic revisions
+* Tagging the working directory:: The cvs tag command
+* Tagging by date/tag:: The cvs rtag command
+* Modifying tags:: Adding, renaming, and deleting tags
+* Tagging add/remove:: Tags with adding and removing files
* Sticky tags:: Certain tags are persistent
@end menu
@@ -3144,7 +3205,7 @@ taginfo file (@pxref{user-defined logging}).
@cindex tag, example
The following example shows how you can add a tag to a
file. The commands must be issued inside your working
-copy of the module. That is, you should issue the
+directory. That is, you should issue the
command in the directory where @file{backend.c}
resides.
@@ -3166,6 +3227,9 @@ File: backend.c Status: Up-to-date
@end example
+For a complete summary of the syntax of @code{cvs tag},
+including the various options, see @ref{Invoking CVS}.
+
There is seldom reason to tag a file in isolation. A more common use is
to tag all the files that constitute a module with the same tag at
strategic points in the development life-cycle, such as when a release
@@ -3201,7 +3265,9 @@ This is useful, for instance, if someone claims that there is a bug in
that release, but you cannot find the bug in the current working copy.
You can also check out a module as it was at any given date.
-@xref{checkout options}.
+@xref{checkout options}. When specifying @samp{-r} to
+any of these commands, you will need beware of sticky
+tags; see @ref{Sticky tags}.
When you tag more than one file with the same tag you
can think about the tag as "a curve drawn through a
@@ -3244,6 +3310,182 @@ like this:
@end group
@end example
+@node Tagging the working directory
+@section Specifying what to tag from the working directory
+
+@cindex Tag (subcommand)
+The example in the previous section demonstrates one of
+the most common ways to choose which revisions to tag.
+Namely, running the @code{cvs tag} command without
+arguments causes @sc{cvs} to select the revisions which
+are checked out in the current working directory. For
+example, if the copy of @file{backend.c} in working
+directory was checked out from revision 1.4, then
+@sc{cvs} will tag revision 1.4. Note that the tag is
+applied immediately to revision 1.4 in the repository;
+tagging is not like modifying a file, or other
+operations in which one first modifies the working
+directory and then runs @code{cvs commit} to transfer
+that modification to the repository.
+
+One potentially surprising aspect of the fact that
+@code{cvs tag} operates on the repository is that you
+are tagging the checked-in revisions, which may differ
+from locally modified files in your working directory.
+If you want to avoid doing this by mistake, specify the
+@samp{-c} option to @code{cvs tag}. If there are any
+locally modified files, @sc{cvs} will abort with an
+error before it tags any files:
+
+@example
+$ cvs tag -c rel-0-4
+cvs tag: backend.c is locally modified
+cvs [tag aborted]: correct the above errors first!
+@end example
+
+@node Tagging by date/tag
+@section Specifying what to tag by date or revision
+@cindex Rtag (subcommand)
+
+The @code{cvs rtag} command tags the repository as of a
+certain date or time (or can be used to tag the latest
+revision). @code{rtag} works directly on the
+repository contents (it requires no prior checkout and
+does not look for a working directory).
+
+The following options specify which date or revision to
+tag. See @ref{Common options}, for a complete
+description of them.
+
+@table @code
+@item -D @var{date}
+Tag the most recent revision no later than @var{date}.
+
+@item -f
+Only useful with the @samp{-D @var{date}} or @samp{-r @var{tag}}
+flags. If no matching revision is found, use the most
+recent revision (instead of ignoring the file).
+
+@item -r @var{tag}
+Only tag those files that contain existing tag @var{tag}.
+@end table
+
+The @code{cvs tag} command also allows one to specify
+files by revision or date, using the same @samp{-r},
+@samp{-D}, and @samp{-f} options. However, this
+feature is probably not what you want. The reason is
+that @code{cvs tag} chooses which files to tag based on
+the files that exist in the working directory, rather
+than the files which existed as of the given tag/date.
+Therefore, you are generally better off using @code{cvs
+rtag}. The exceptions might be cases like:
+
+@example
+cvs tag -r 1.4 backend.c
+@end example
+
+@node Modifying tags
+@section Deleting, moving, and renaming tags
+
+@c Also see:
+@c "How do I move or rename a magic branch tag?"
+@c in the FAQ (I think the issues it talks about still
+@c apply, but this could use some sanity.sh work).
+
+Normally one does not modify tags. They exist in order
+to record the history of the repository and so deleting
+them or changing their meaning would, generally, not be
+what you want.
+
+However, there might be cases in which one uses a tag
+temporarily or accidentally puts one in the wrong
+place. Therefore, one might delete, move, or rename a
+tag. Warning: the commands in this section are
+dangerous; they permanently discard historical
+information and it can difficult or impossible to
+recover from errors. If you are a @sc{cvs}
+administrator, you may consider restricting these
+commands with taginfo (@pxref{user-defined logging}).
+
+@cindex deleting tags
+@cindex removing tags
+@cindex tags, deleting
+To delete a tag, specify the @samp{-d} option to either
+@code{cvs tag} or @code{cvs rtag}. For example:
+
+@example
+cvs rtag -d rel-0-4 tc
+@end example
+
+deletes the tag @code{rel-0-4} from the module @code{tc}.
+
+@cindex moving tags
+@cindex tags, moving
+When we say @dfn{move} a tag, we mean to make the same
+name point to different revisions. For example, the
+@code{stable} tag may currently point to revision 1.4
+of @file{backend.c} and perhaps we want to make it
+point to revision 1.6. To move a tag, specify the
+@samp{-F} option to either @code{cvs tag} or @code{cvs
+rtag}. For example, the task just mentioned might be
+accomplished as:
+
+@example
+cvs tag -r 1.6 -F stable backend.c
+@end example
+
+@cindex renaming tags
+@cindex tags, renaming
+When we say @dfn{rename} a tag, we mean to make a
+different name point to the same revisions as the old
+tag. For example, one may have misspelled the tag name
+and want to correct it (hopefully before others are
+relying on the old spelling). To rename a tag, first
+create a new tag using the @samp{-r} option to
+@code{cvs rtag}, and then delete the old name. This
+leaves the new tag on exactly the same files as the old
+tag. For example:
+
+@example
+cvs rtag -r old-name-0-4 rel-0-4 tc
+cvs rtag -d old-name-0-4 tc
+@end example
+
+@node Tagging add/remove
+@section Tagging and adding and removing files
+
+The subject of exactly how tagging interacts with
+adding and removing files is somewhat obscure; for the
+most part @sc{cvs} will keep track of whether files
+exist or not without too much fussing. By default,
+tags are applied to only files which have a revision
+corresponding to what is being tagged. Files which did
+not exist yet, or which were already removed, simply
+omit the tag, and @sc{cvs} knows to treat the absence
+of a tag as meaning that the file didn't exist as of
+that tag.
+
+However, this can lose a small amount of information.
+For example, suppose a file was added and then removed.
+Then, if the tag is missing for that file, there is no
+way to know whether the tag refers to the time before
+the file was added, or the time after it was removed.
+If you specify the @samp{-r} option to @code{cvs rtag},
+then @sc{cvs} tags the files which have been removed,
+and thereby avoids this problem. For example, one
+might specify @code{-r HEAD} to tag the head.
+
+On the subject of adding and removing files, the
+@code{cvs rtag} command has a @samp{-a} option which
+means to clear the tag from removed files that would
+not otherwise be tagged. For example, one might
+specify this option in conjunction with @samp{-F} when
+moving a tag. If one moved a tag without @samp{-a},
+then the tag in the removed files might still refer to
+the old revision, rather than reflecting the fact that
+the file had been removed. I don't think this is
+necessary if @samp{-r} is specified, as noted above.
+
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Sticky tags
@section Sticky tags
@@ -3315,18 +3557,11 @@ tag with @code{cvs update -A}. Likewise, use of the
sets a @dfn{sticky date}, which, similarly, causes that
date to be used for future retrievals.
-@cindex Restoring old version of removed file
-@cindex Resurrecting old version of dead file
-Many times you will want to retrieve an old version of
-a file without setting a sticky tag. The way to do
-that is with the @samp{-p} option to @code{checkout} or
+People often want to retrieve an old version of
+a file without setting a sticky tag. This can
+be done with the @samp{-p} option to @code{checkout} or
@code{update}, which sends the contents of the file to
-standard output. For example, suppose you have a file
-named @file{file1} which existed as revision 1.1, and
-you then removed it (thus adding a dead revision 1.2).
-Now suppose you want to add it again, with the same
-contents it had previously. Here is how to do it:
-
+standard output. For example:
@example
$ cvs update -p -r 1.1 file1 >file1
===================================================================
@@ -3334,17 +3569,16 @@ Checking out file1
RCS: /tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v
VERS: 1.1
***************
-$ cvs add file1
-cvs add: re-adding file file1 (in place of dead revision 1.2)
-cvs add: use 'cvs commit' to add this file permanently
-$ cvs commit -m test
-Checking in file1;
-/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1
-new revision: 1.3; previous revision: 1.2
-done
$
@end example
+However, this isn't the easiest way, if you are asking
+how to undo a previous checkin (in this example, put
+@file{file1} back to the way it was as of revision
+1.1). In that case you are better off using the
+@samp{-j} option to @code{update}; for further
+discussion see @ref{Merging two revisions}.
+
@c ---------------------------------------------------------------------
@node Branching and merging
@chapter Branching and merging
@@ -3610,12 +3844,16 @@ The following figure illustrates branching with an
example.
@example
+@c This example used to have a 1.2.2.4 revision, which
+@c might help clarify that development can continue on
+@c 1.2.2. Might be worth reinstating if it can be done
+@c without overfull hboxes.
@group
- +-------------+
- Branch 1.2.2.3.2 -> ! 1.2.2.3.2.1 !
- / +-------------+
- /
- /
+ +-------------+
+ Branch 1.2.2.3.2 -> ! 1.2.2.3.2.1 !
+ / +-------------+
+ /
+ /
+---------+ +---------+ +---------+
Branch 1.2.2 -> _! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
/ +---------+ +---------+ +---------+
@@ -3866,16 +4104,37 @@ $ cvs update -j 1.5 -j 1.3 backend.c
@end example
@noindent
-will @emph{remove} all changes made between revision
+will undo all changes made between revision
1.3 and 1.5. Note the order of the revisions!
If you try to use this option when operating on
multiple files, remember that the numeric revisions will
-probably be very different between the various files
-that make up a module. You almost always use symbolic
+probably be very different between the various files.
+You almost always use symbolic
tags rather than revision numbers when operating on
multiple files.
+@cindex Restoring old version of removed file
+@cindex Resurrecting old version of dead file
+Specifying two @samp{-j} options can also undo file
+removals or additions. For example, suppose you have
+a file
+named @file{file1} which existed as revision 1.1, and
+you then removed it (thus adding a dead revision 1.2).
+Now suppose you want to add it again, with the same
+contents it had previously. Here is how to do it:
+
+@example
+$ cvs update -j 1.2 -j 1.1 file1
+U file1
+$ cvs commit -m test
+Checking in file1;
+/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1
+new revision: 1.3; previous revision: 1.2
+done
+$
+@end example
+
@node Merging adds and removals
@section Merging can add or remove files
@@ -3962,7 +4221,7 @@ subdirectories
@item
@samp{cvs update .} or just @samp{cvs update} updates
-all files in the @code{tc} module
+all files in the @code{tc} directory
@end itemize
If no arguments are given to @code{update} it will
@@ -4124,7 +4383,7 @@ later merge the additions to another branch if you want
@c be its own section, for example, as could the
@c various bits about undoing mistakes in adding and
@c removing).
-Modules change. New files are added, and old files
+Directories change. New files are added, and old files
disappear. Still, you want to be able to retrieve an
exact copy of old releases.
@@ -4375,7 +4634,7 @@ files inside the repository. Read this entire section
before trying it out!
@example
-$ cd $CVSROOT/@var{module}
+$ cd $CVSROOT/@var{dir}
$ mv @var{old},v @var{new},v
@end example
@@ -4395,7 +4654,7 @@ Disadvantages:
@itemize @bullet
@item
-Old releases of the module cannot easily be fetched from the
+Old releases cannot easily be fetched from the
repository. (The file will show up as @var{new} even
in revisions from the time before it was renamed).
@@ -4417,10 +4676,10 @@ repository. It is safe, but not without drawbacks.
@example
# @r{Copy the @sc{rcs} file inside the repository}
-$ cd $CVSROOT/@var{module}
+$ cd $CVSROOT/@var{dir}
$ cp @var{old},v @var{new},v
# @r{Remove the old file}
-$ cd ~/@var{module}
+$ cd ~/@var{dir}
$ rm @var{old}
$ cvs remove @var{old}
$ cvs commit @var{old}
@@ -4433,7 +4692,7 @@ $ cvs tag -d @var{tag2} @var{new}
@end example
By removing the tags you will be able to check out old
-revisions of the module.
+revisions.
@noindent
Advantages:
@@ -4492,16 +4751,16 @@ like this:
@enumerate
@item
-Inform everyone who has a copy of the module that the
+Inform everyone who has a checked out copy of the directory that the
directory will be renamed. They should commit all
-their changes, and remove their working copies of the
-module, before you take the steps below.
+their changes, and remove their working copies,
+before you take the steps below.
@item
Rename the directory inside the repository.
@example
-$ cd $CVSROOT/@var{module}
+$ cd $CVSROOT/@var{parent-dir}
$ mv @var{old-dir} @var{new-dir}
@end example
@@ -4510,12 +4769,12 @@ Fix the @sc{cvs} administrative files, if necessary (for
instance if you renamed an entire module).
@item
-Tell everyone that they can check out the module and continue
+Tell everyone that they can check out again and continue
working.
@end enumerate
-If someone had a working copy of the module the @sc{cvs} commands will
+If someone had a working copy the @sc{cvs} commands will
cease to work for him, until he removes the directory
that disappeared inside the repository.
@@ -5032,7 +5291,7 @@ is almost automatic.
@c FIXME? should probably use the word "watch" here, to
@c tie this into the text below and above.
@sc{Cvs} also supports mechanisms which facilitate
-various kinds of communcation, without actually
+various kinds of communication, without actually
enforcing rules like reserved checkouts do.
The rest of this chapter describes how these various
@@ -5293,8 +5552,7 @@ these options, see @ref{Invoking CVS}.
When you want to update or merge a file, use the @code{update}
command. For files that are not up to date this is roughly equivalent
to a @code{checkout} command: the newest revision of the file is
-extracted from the repository and put in your working copy of the
-module.
+extracted from the repository and put in your working directory.
Your modifications to a file are never lost when you
use @code{update}. If no newer revision exists,
@@ -5770,7 +6028,7 @@ files (@pxref{Intro administrative files}). This
file follows the usual conventions for administrative
files (@pxref{syntax}), where each line is a regular
expression followed by a command to execute. The
-command should contain a single ocurrence of @samp{%s}
+command should contain a single occurrence of @samp{%s}
which will be replaced by the user to notify; the rest
of the information regarding the notification will be
supplied to the command on standard input. The
@@ -5906,7 +6164,7 @@ repository since the last time you updated.
When using client/server @sc{cvs}, you can use the
@code{cvs edit} and @code{cvs unedit} commands even if
-@sc{cvs} is unable to succesfully communicate with the
+@sc{cvs} is unable to successfully communicate with the
server; the notifications will be sent upon the next
successful @sc{cvs} command.
@@ -6086,8 +6344,8 @@ goal, which is to get software written.
@comment version control, so we must not accidentally
@comment include a valid keyword in the running text.
-As long as you edit source files inside your working
-copy of a module you can always find out the state of
+As long as you edit source files inside a working
+directory you can always find out the state of
your files via @samp{cvs status} and @samp{cvs log}.
But as soon as you export the files from your
development environment it becomes harder to identify
@@ -6146,17 +6404,16 @@ filename is without a path.
@cindex Name keyword
@item $@asis{Name}$
-Tag name used to check out this file.
-@c FIXME: should supply an example (e.g. "if you use
-@c "cvs update -r foo" then Name expands to "foo"). Also
-@c should add Name to testsuite (best way to ensure
-@c that the example is correct!)
+Tag name used to check out this file. The keyword is
+expanded only if one checks out with an explicit tag
+name. For example, when running the command @code{cvs
+co -r first}, the keyword expands to @samp{Name: first}.
@cindex Locker keyword
@item $@asis{Locker}$
The login name of the user who locked the revision
-(empty if not locked, and thus almost always useless
-when you are using @sc{cvs}).
+(empty if not locked, which is the normal case unless
+@code{cvs admin -l} is in use).
@cindex Log keyword
@item $@asis{Log}$
@@ -6328,7 +6585,8 @@ keyword.
@item -kkvl
Like @samp{-kkv}, except that a locker's name is always
inserted if the given revision is currently locked.
-This option is normally not useful when @sc{cvs} is used.
+The locker's name is only relevant if @code{cvs admin
+-l} is in use.
@item -kk
Generate only keyword names in keyword strings; omit
@@ -6451,9 +6709,9 @@ placed on the main trunk, and made the `head'
revision.
@menu
-* First import:: Importing a module for the first time
-* Update imports:: Updating a module with the import command
-* Reverting local changes:: Reverting a module to the latest vendor release
+* First import:: Importing for the first time
+* Update imports:: Updating with the import command
+* Reverting local changes:: Reverting to the latest vendor release
* Binary files in imports:: Binary files require special handling
* Keywords in imports:: Keyword substitution might be undesirable
* Multiple vendor branches:: What if you get sources from several places?
@@ -6461,7 +6719,7 @@ revision.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node First import
-@section Importing a module for the first time
+@section Importing for the first time
@cindex Importing modules
@c Should mention naming conventions for vendor tags,
@@ -6506,7 +6764,7 @@ example, and the only release tag assigned is
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Update imports
-@section Updating a module with the import command
+@section Updating with the import command
When a new release of the source arrives, you import it into the
repository with the same @code{import} command that you used to set up
@@ -6867,6 +7125,15 @@ reference to @sc{cvs} commands, @pxref{Invoking CVS}).
@c in the process reorganizing the manual to be
@c organized around what the user wants to do, not
@c organized around CVS commands.
+@c
+@c Note that many users do expect a manual which is
+@c organized by command. At least some users do.
+@c One good addition to the "organized by command"
+@c section (if any) would be "see also" links.
+@c The awk manual might be a good example; it has a
+@c reference manual which is more verbose than Invoking
+@c CVS but probably somewhat less verbose than CVS
+@c Commands.
@menu
* Structure:: Overall structure of CVS commands
@@ -6883,9 +7150,7 @@ reference to @sc{cvs} commands, @pxref{Invoking CVS}).
* import:: Import sources into CVS, using vendor branches
* log:: Show log messages for files
* rdiff:: 'patch' format diffs between releases
-* release:: Indicate that a Module is no longer in use
-* rtag:: Add a tag to a module
-* tag:: Add a tag to checked out version
+* release:: Indicate that a directory is no longer in use
* update:: Bring work tree in sync with repository
@end menu
@@ -7329,14 +7594,18 @@ are:
@c bizarre and it has lots of gratuitous multiple ways
@c to specify the same thing.
-For more details about ISO8601 dates, see:
+There are a lot more ISO8601 date formats, and CVS
+accepts many of them, but you probably don't want to
+hear the @emph{whole} long story :-).
-@example
-http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html
-@end example
-@c Perhaps we want to also cite other sources in
-@c case that page goes away. For example:
+@c Citing a URL here is kind of problematic given how
+@c much they change and people who have old versions of
+@c this manual, but in case we want to reinstate an
+@c ISO8601 URL, a few are:
@c http://www.saqqara.demon.co.uk/datefmt.htm
+@c http://www.cl.cam.ac.uk/~mgk25/iso-time.html
+@c Citing some other ISO8601 source is probably even
+@c worse :-).
In addition to the dates allowed in Internet e-mail
itself, @sc{cvs} also allows some of the fields to be
@@ -7499,7 +7768,7 @@ revision you last checked out into the current working directory.
@c special tags, ".thead" for the head of the trunk,
@c and ".bhead" for the head of the current branch.
@c Then deprecate HEAD. This has the advantage of
-@c not suprising people with a change to HEAD, and a
+@c not surprising people with a change to HEAD, and a
@c side benefit of also phasing out the poorly-named
@c HEAD (see discussion of reserved tag names in node
@c "Tags"). Of course, .thead and .bhead should be
@@ -8260,13 +8529,16 @@ invoking an editor.
@node commit examples
@appendixsubsec commit examples
+@c FIXME: this material wants to be somewhere
+@c in "Branching and merging".
+
@appendixsubsubsec Committing to a branch
You can commit to a branch revision (one that has an
even number of dots) with the @samp{-r} option. To
create a branch revision, use the @samp{-b} option
-of the @code{rtag} or @code{tag} commands (@pxref{tag}
-or @pxref{rtag}). Then, either @code{checkout} or
+of the @code{rtag} or @code{tag} commands
+(@pxref{Branching and merging}). Then, either @code{checkout} or
@code{update} can be used to base your sources on the
newly created branch. From that point on, all
@code{commit} changes made within these working sources
@@ -9239,8 +9511,7 @@ last change to a file was.
@item -u
Use the unidiff format for the context diffs.
-This option is not available if your @code{diff} does not
-support the unidiff format. Remember that old versions
+Remember that old versions
of the @code{patch} program can't handle the unidiff
format, so if you plan to post this patch to the net
you should probably not use @samp{-u}.
@@ -9257,14 +9528,14 @@ way that @sc{rcs} version 5 does.
@node rdiff examples
@appendixsubsec rdiff examples
-Suppose you receive mail from @t{foo@@bar.com} asking for an
+Suppose you receive mail from @t{foo@@example.net} asking for an
update from release 1.2 to 1.4 of the tc compiler. You
have no such patches on hand, but with @sc{cvs} that can
easily be fixed with a command such as this:
@example
$ cvs rdiff -c -r FOO1_2 -r FOO1_4 tc | \
-$$ Mail -s 'The patches you asked for' foo@@bar.com
+$$ Mail -s 'The patches you asked for' foo@@example.net
@end example
Suppose you have made release 1.3, and forked a branch
@@ -9395,7 +9666,7 @@ sources, this file will be lost.
@node release examples
@appendixsubsec release examples
-Release the module, and delete your local working copy
+Release the @file{tc} directory, and delete your local working copy
of the files.
@example
@@ -9403,244 +9674,10 @@ $ cd .. # @r{You must stand immediately above the}
# @r{sources when you issue @samp{cvs release}.}
$ cvs release -d tc
You have [0] altered files in this repository.
-Are you sure you want to release (and delete) module `tc': y
+Are you sure you want to release (and delete) directory `tc': y
$
@end example
-@node rtag
-@appendixsec rtag---Add a symbolic tag to a module
-@cindex Rtag (subcommand)
-
-@itemize @bullet
-@item
-rtag [-falnR] [-b] [-d] [-r tag | -Ddate] symbolic_tag modules@dots{}
-@item
-Requires: repository.
-@item
-Changes: repository.
-@item
-Synonym: rfreeze
-@end itemize
-
-You can use this command to assign symbolic tags to
-particular, explicitly specified source revisions in
-the repository. @code{rtag} works directly on the
-repository contents (and requires no prior checkout).
-Use @code{tag} instead (@pxref{tag}), to base the
-selection of revisions on the contents of your
-working directory.
-
-If you attempt to use a tag name that already exists,
-@sc{cvs} will complain and not overwrite that tag. Use
-the @samp{-F} option to force the new tag value.
-
-@menu
-* rtag options:: rtag options
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node rtag options
-@appendixsubsec rtag options
-
-These standard options are supported by @code{rtag}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -D @var{date}
-Tag the most recent revision no later than @var{date}.
-
-@item -f
-Only useful with the @samp{-D @var{date}} or @samp{-r @var{tag}}
-flags. If no matching revision is found, use the most
-recent revision (instead of ignoring the file).
-
-@item -F
-Overwrite an existing tag of the same name on a
-different revision.
-@c FIXME: Needs an example, and/or more explanation.
-@c Also needs to contrast this with the behavior if -F
-@c is not specified, and the description needs to be
-@c moved somewhere where it is shared between "tag" and
-@c "rtag" (probably some sub-node of Revisions and
-@c branches). Also should be clear about whether this
-@c applies to branch tags, non-branch tags, or both.
-@c Also this is *not* a common option.
-
-@item -l
-Local; run only in current working directory.
-
-@item -n
-Do not run any tag program that was specified with the
-@samp{-t} flag inside the @file{modules} file.
-(@pxref{modules}).
-
-@item -R
-Tag directories recursively. This is on by default.
-
-@c FIXME: this discussion is confusing. What part of
-@c the rename operation being discussed relates to
-@c "rtag -r" (that whole discussion needs an example,
-@c and probably to be moved somewhere else)?
-@item -r @var{tag}
-Only tag those files that contain @var{tag}. This can
-be used to rename a tag: tag only the files identified
-by the old tag, then delete the old tag, leaving the
-new tag on exactly the same files as the old tag.
-@end table
-
-In addition to the above common options, these options
-are available:
-
-@table @code
-@item -a
-@c FIXME: What does this option mean in terms of user
-@c concepts, not CVS internals?
-Use the @samp{-a} option to have @code{rtag} look in the
-@file{Attic} (@pxref{Attic}) for removed files
-that contain the specified tag. The tag is removed from
-these files, which makes it convenient to re-use a
-symbolic tag as development continues (and files get
-removed from the up-coming distribution).
-
-@item -b
-Make the tag a branch tag. @xref{Branching and merging}.
-
-@item -d
-Delete the tag instead of creating it.
-
-In general, tags (often the symbolic names of software
-distributions) should not be removed, but the @samp{-d}
-option is available as a means to remove completely
-obsolete symbolic names if necessary (as might be the
-case for an Alpha release, or if you mistagged a
-module).
-@end table
-
-@ignore
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@c @node rtag examples
-@appendixsubsec rtag examples
-
-@c -- Examples here!
-@end ignore
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node tag
-@appendixsec tag---Add a symbolic tag to checked out versions of files
-@c -- //////// - unnecessary. Also
-@c -- in a lot of other
-@c -- places.
-@cindex Tag (subcommand)
-
-@itemize @bullet
-@item
-tag [-lR] [-b] [-c] [-d] symbolic_tag [files@dots{}]
-@item
-Requires: working directory, repository.
-@item
-Changes: repository.
-@item
-Synonym: freeze
-@end itemize
-
-Use this command to assign symbolic tags to the nearest
-repository versions to your working sources. The tags
-are applied immediately to the repository, as with
-@code{rtag}, but the versions are supplied implicitly by the
-@sc{cvs} records of your working files' history rather than
-applied explicitly.
-
-One use for tags is to record a snapshot of the
-current sources when the software freeze date of a
-project arrives. As bugs are fixed after the freeze
-date, only those changed sources that are to be part of
-the release need be re-tagged.
-
-The symbolic tags are meant to permanently record which
-revisions of which files were used in creating a
-software distribution. The @code{checkout} and
-@code{update} commands allow you to extract an exact
-copy of a tagged release at any time in the future,
-regardless of whether files have been changed, added,
-or removed since the release was tagged.
-
-This command can also be used to delete a symbolic tag,
-or to create a branch. See the options section below.
-
-If you attempt to use a tag name that already exists,
-@sc{cvs} will complain and not overwrite that tag. Use
-the @samp{-F} option to force the new tag value.
-
-
-@menu
-* tag options:: tag options
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node tag options
-@appendixsubsec tag options
-
-These standard options are supported by @code{tag}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@cindex renaming tags
-@cindex tags, renaming
-@cindex moving tags
-@c FIXME: Where does this talk about renaming tags?
-@c And what about rtag? This needs to be moved to
-@c the body of the manual.
-@c Also see:
-@c "How do I move or rename a magic branch tag?"
-@c in the FAQ (I think the issues it talks about still
-@c apply, but this could use some sanity.sh work).
-@item -F
-Overwrite an existing tag of the same name on a
-different revision.
-@c FIXME: See "rtag -F" for comments on this.
-
-@item -l
-Local; run only in current working directory.
-
-@item -R
-Tag directories recursively. This is on by default.
-@end table
-
-Two special options are available:
-
-@table @code
-@item -b
-Make the tag a branch tag
-(@pxref{Branching and merging}), allowing concurrent, isolated
-development. This is most useful for creating a patch
-to a previously released software distribution.
-
-@item -c
-Check that all files which are to be tagged are
-unmodified. This can be used to make sure that you can reconstruct the
-current file contents.
-
-@item -d
-Delete a tag.
-
-If you use @samp{cvs tag -d symbolic_tag}, the symbolic
-tag you specify is deleted instead of being added.
-Warning: Be very certain of your ground before you
-delete a tag; doing this permanently discards some
-historical information, which may later turn out to
-be valuable.
-@end table
-
-@ignore
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@c @node tag examples
-@appendixsubsec tag examples
-
-@c -- FIXME
-@end ignore
-
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node update
@appendixsec update---Bring work tree in sync with repository
@@ -10483,43 +10520,42 @@ behavior}.
@end table
@item rtag [@var{options}] @var{tag} @var{modules}@dots{}
-Add a symbolic tag to a module. See @ref{rtag}.
+Add a symbolic tag to a module.
+See @ref{Revisions} and @ref{Branching and merging}.
@table @code
-@c Is this one of those dumb options which used to
-@c work around the lack of death support?
@item -a
Clear tag from removed files that would not otherwise
-be tagged. See @ref{rtag options}.
+be tagged. See @ref{Tagging add/remove}.
@item -b
-Create a branch named @var{tag}. See @ref{rtag options}.
+Create a branch named @var{tag}. See @ref{Branching and merging}.
@item -D @var{date}
-Tag revisions as of @var{date}. See @ref{rtag options}.
+Tag revisions as of @var{date}. See @ref{Tagging by date/tag}.
@item -d
-Delete the given tag. See @ref{rtag options}.
+Delete @var{tag}. See @ref{Modifying tags}.
@item -F
-Move tag if it already exists. See @ref{rtag options}.
+Move @var{tag} if it already exists. See @ref{Modifying tags}.
@item -f
Force a head revision match if tag/date not found.
-See @ref{rtag options}.
+See @ref{Tagging by date/tag}.
@item -l
Local; run only in current working directory. See @ref{Recursive behavior}.
@item -n
-No execution of tag program. See @ref{rtag options}.
+No execution of tag program. See @ref{Common options}.
@item -R
Operate recursively (default). @xref{Recursive
behavior}.
-@item -r @var{tag}
-Tag existing tag @var{tag}. See @ref{rtag options}.
+@item -r @var{rev}
+Tag existing tag @var{rev}. See @ref{Tagging by date/tag}.
@end table
@item status [@var{options}] @var{files}@dots{}
@@ -10540,37 +10576,38 @@ Include tag information for file. See @ref{Tags}.
@item tag [@var{options}] @var{tag} [@var{files}@dots{}]
Add a symbolic tag to checked out version of files.
-See @ref{tag}.
+See @ref{Revisions} and @ref{Branching and merging}.
@table @code
@item -b
-Create a branch named @var{tag}. See @ref{tag options}.
+Create a branch named @var{tag}. See @ref{Branching and merging}.
+
+@item -c
+Check that working files are unmodified. See
+@ref{Tagging the working directory}.
@item -D @var{date}
-Tag revisions as of @var{date}. See @ref{tag options}.
+Tag revisions as of @var{date}. See @ref{Tagging by date/tag}.
@item -d
-Delete the given tag. See @ref{tag options}.
+Delete @var{tag}. See @ref{Modifying tags}.
@item -F
-Move tag if it already exists. See @ref{tag options}.
+Move @var{tag} if it already exists. See @ref{Modifying tags}.
@item -f
Force a head revision match if tag/date not found.
-See @ref{tag options}.
+See @ref{Tagging by date/tag}.
@item -l
Local; run only in current working directory. See @ref{Recursive behavior}.
-@item -n
-No execution of tag program. See @ref{tag options}.
-
@item -R
Operate recursively (default). @xref{Recursive
behavior}.
-@item -r @var{tag}
-Tag existing tag @var{tag}. See @ref{tag options}.
+@item -r @var{rev}
+Tag existing tag @var{rev}. See @ref{Tagging by date/tag}.
@end table
@item unedit [@var{options}] [@var{files}@dots{}]
@@ -11055,12 +11092,19 @@ this module.
@c should be better motivated (e.g. start with the
@c problems, then explain how the feature solves it).
+Wrappers refers to a @sc{cvs} feature which lets you
+control certain settings based on the name of the file
+which is being operated on. The settings are @samp{-k}
+for binary files, and @samp{-m} for nonmergeable text
+files.
+
+@ignore
Wrappers allow you to set a hook which transforms files on
their way in and out of @sc{cvs}.
The file @file{cvswrappers} defines the script that will be
run on a file when its name matches a regular
-expresion. There are two scripts that can be run on a
+expression. There are two scripts that can be run on a
file or directory. One script is executed on the file/directory
before being checked into the repository (this is denoted
with the @code{-t} flag) and the other when the file is
@@ -11071,9 +11115,10 @@ not work with client/server @sc{cvs}.
@c file converts to/from a single file, as opposed to
@c the file<->directory case. Could use more
@c investigation...
+@end ignore
-The @file{cvswrappers} also has a @samp{-m} option to
-specify the merge methodology that should be used when
+The @samp{-m} option
+specifies the merge methodology that should be used when
a non-binary file is updated. @code{MERGE} means the usual
@sc{cvs} behavior: try to merge the files. @code{COPY}
means that @code{cvs update} will refuse to merge
@@ -11104,14 +11149,17 @@ The basic format of the file @file{cvswrappers} is:
wildcard [option value][option value]...
where option is one of
+@ignore
-f from cvs filter value: path to filter
-t to cvs filter value: path to filter
+@end ignore
-m update methodology value: MERGE or COPY
-k keyword expansion value: expansion mode
and value is a single-quote delimited value.
@end example
+@ignore
@example
*.nib -f 'unwrap %s' -t 'wrap %s %s' -m 'COPY'
*.c -t 'indent %s %s'
@@ -11171,8 +11219,11 @@ options}).
@c This is, of course, a serious design flaw in -t/-f.
@c Probably the whole functionality needs to be
@c redesigned (starting from requirements) to fix this.
+@end ignore
-For another example, the following command imports a
+@c FIXME: We don't document -W or point to where it is
+@c documented. Or .cvswrappers.
+For example, the following command imports a
directory, treating files whose name ends in
@samp{.exe} as binary:
@@ -11346,9 +11397,11 @@ removed, and modified files).
@cindex exit status, of commitinfo
The first line with a regular expression matching the
-relative path to the module will be used. If the
+directory within the repository will be used. If the
command returns a non-zero exit status the commit will
be aborted.
+@c FIXME: need example(s) of what "directory within the
+@c repository" means.
@cindex DEFAULT in commitinfo
If the repository name does not match any of the
@@ -11356,7 +11409,7 @@ regular expressions in this file, the @samp{DEFAULT}
line is used, if it is specified.
@cindex ALL in commitinfo
-All occurances of the name @samp{ALL} appearing as a
+All occurrences of the name @samp{ALL} appearing as a
regular expression are used in addition to the first
matching regular expression or the name @samp{DEFAULT}.
@@ -11408,7 +11461,7 @@ One thing that should be noted is that the @samp{ALL}
keyword is not supported. If more than one matching
line is found, the first one is used. This can be
useful for specifying a default verification script in a
-module, and then overriding it in a subdirectory.
+directory, and then overriding it in a subdirectory.
@cindex DEFAULT in verifymsg
If the repository name does not match any of the
@@ -11615,7 +11668,7 @@ If the repository name does not match any of the
regular expressions in this file, the @samp{DEFAULT}
line is used, if it is specified.
-All occurances of the name @samp{ALL} appearing as a
+All occurrences of the name @samp{ALL} appearing as a
regular expression are used in addition to the first
matching regular expression or @samp{DEFAULT}.
@@ -11780,7 +11833,7 @@ If the repository name does not match any of the
regular expressions in this file, the @samp{DEFAULT}
line is used, if it is specified.
-All occurances of the name @samp{ALL} appearing as a
+All occurrences of the name @samp{ALL} appearing as a
regular expression are used in addition to the first
matching regular expression or @samp{DEFAULT}.
@@ -11791,7 +11844,7 @@ matching regular expression or @samp{DEFAULT}.
@c whether it is hardwired into CVS or who creates
@c it or anything. In particular we should say
@c how to version control the template file. A
-@c probably better answer than the /usr/cvsssupport
+@c probably better answer than the /usr/cvssupport
@c stuff is to use checkoutlist (with xref to the
@c checkoutlist doc).
@c Also I am starting to see a connection between
@@ -11964,7 +12017,7 @@ One may want to know about various pieces of
information internal to @sc{cvs}. A @sc{cvs} internal
variable has the syntax @code{$@{@var{variable}@}},
where @var{variable} starts with a letter and consists
-of alphanumberic characters and @samp{_}. If the
+of alphanumeric characters and @samp{_}. If the
character following @var{variable} is a
non-alphanumeric character other than @samp{_}, the
@samp{@{} and @samp{@}} can be omitted. The @sc{cvs}
@@ -12089,6 +12142,28 @@ each command. It also provides a place for the
@samp{CVS/Template} file (@pxref{Working directory
storage}).
+@cindex LockDir, in CVSROOT/config
+@item LockDir=@var{directory}
+Put CVS lock files in @var{directory} rather than
+directly in the repository. This is useful if you want
+to let users read from the repository while giving them
+write access only to @var{directory}, not to the
+repository. You need to create @var{directory}, but
+CVS will create subdirectories of @var{directory} as it
+needs them. For information on CVS locks, see
+@ref{Concurrency}.
+
+@c Mention this in Compatibility section?
+Before enabling the LockDir option, make sure that you
+have tracked down and removed any copies of CVS 1.9 or
+older. Such versions neither support LockDir, nor will
+give an error indicating that they don't support it.
+The result, if this is allowed to happen, is that some
+CVS users will put the locks one place, and others will
+put them another place, and therefore the repository
+could become corrupted. CVS 1.10 does not support
+LockDir but it will print a warning if run on a
+repository with LockDir enabled.
@end table
@c ---------------------------------------------------------------------
@@ -12138,6 +12213,7 @@ directory.
@item $EDITOR
@itemx $CVSEDITOR
+@itemx $VISUAL
Specifies the program to use for recording log messages
during commit. @code{$CVSEDITOR} overrides
@code{$EDITOR}. See @ref{Committing your changes}.
@@ -12209,7 +12285,12 @@ seconds so that you can attach to it with a debugger.
@cindex CVS_IGNORE_REMOTE_ROOT, environment variable
@item $CVS_IGNORE_REMOTE_ROOT
-(What is the purpose of this variable?)
+For @sc{cvs} 1.10 and older, setting this variable
+prevents @sc{cvs} from overwriting the @file{CVS/Root}
+file when the @samp{-d} global option is specified.
+Later versions of @sc{cvs} do not rewrite
+@file{CVS/Root}, so CVS_IGNORE_REMOTE_ROOT has no
+effect.
@cindex COMSPEC, environment variable
@item $COMSPEC
@@ -12557,7 +12638,7 @@ every place it appears in your @code{modules}
file. For more information on the @code{modules} file,
see @ref{modules}.
-@c This messsage comes from "co", and I believe is
+@c This message comes from "co", and I believe is
@c possible only with older versions of CVS which call
@c co. The problem with being able to create the bogus
@c RCS file still exists, though (and I think maybe
@@ -12621,6 +12702,15 @@ logfile to be specified with a @samp{-f} option. Of
course, if you don't need @file{log.pl} you can just
comment it out of @file{loginfo}.
+@item cvs [login aborted]: unrecognized auth response from @var{server}
+This message typically means that the server is not set
+up properly. For example, if @file{inetd.conf} points
+to a nonexistent cvs executable. To debug it further,
+find the log file which inetd writes
+(@file{/var/log/messages} or whatever inetd uses on
+your system). For details, see @ref{Connection}, and
+@ref{Password authentication server}.
+
@item cvs commit: Up-to-date check failed for `@var{file}'
This means that someone else has committed a change to
that file since the last time that you did a @code{cvs
@@ -12665,6 +12755,10 @@ for setting up the CVS server.
@c FIXCVS: should be printing CR as \r or \015 or some
@c such, probably.
+@item cvs commit: [@var{time}] waiting for @var{user}'s lock in @var{directory}
+This is a normal message, not an error. See
+@ref{Concurrency}, for more details.
+
@item cvs commit: warning: editor session failed
@cindex exit status, of editor
This means that the editor which @sc{cvs} is using exits with a nonzero
diff --git a/gnu/usr.bin/cvs/doc/cvsclient.texi b/gnu/usr.bin/cvs/doc/cvsclient.texi
index 6f0139976b7..c9224e3d720 100644
--- a/gnu/usr.bin/cvs/doc/cvsclient.texi
+++ b/gnu/usr.bin/cvs/doc/cvsclient.texi
@@ -479,7 +479,7 @@ For the @samp{-D} option to the @code{annotate}, @code{co}, @code{diff},
and @code{update} requests, the server should support two formats:
@example
-26 May 1997 13:01:40 GMT ; @r{RFC 822 as modified by RFC 1123}
+26 May 1997 13:01:40 -0000 ; @r{RFC 822 as modified by RFC 1123}
5/26/1997 13:01:40 GMT ; @r{traditional}
@end example
@@ -491,7 +491,9 @@ least support RFC 822/1123 format. Clients are encouraged to use this
format too (traditionally the command line CVS client has just passed
along the date format specified by the user, however).
-For @code{Mod-time}, see the description of that response.
+The @code{Mod-time} response and @code{Checkin-time} request use RFC
+822/1123 format (see the descriptions of that response and request for
+details).
For @code{Notify}, see the description of that request.
@@ -521,7 +523,7 @@ in use, connection, authentication, etc., are already taken care of.
The @code{Root} request must be sent only once, and it must be sent
before any requests other than @code{Valid-responses},
-@code{valid-requests}, @code{UseUnchanged}, or @code{init}.
+@code{valid-requests}, @code{UseUnchanged}, @code{Set} or @code{init}.
@item Valid-responses @var{request-list} \n
Response expected: no.
@@ -606,6 +608,99 @@ Each @code{Directory} request specifies a brand-new
@var{local-directory} and @var{repository} are never relative to paths
specified in any previous @code{Directory} request.
+Here's a more complex example, in which we request an update of a
+working directory which has been checked out from multiple places in the
+repository.
+
+@example
+C: Argument dir1
+C: Directory dir1
+C: /home/foo/repos/mod1
+. . .
+C: Argument dir2
+C: Directory dir2
+C: /home/foo/repos/mod2
+. . .
+C: Argument dir3
+C: Directory dir3/subdir3
+C: /home/foo/repos/mod3
+. . .
+C: update
+@end example
+
+While directories @code{dir1} and @code{dir2} will be handled in similar
+fashion to the other examples given above, @code{dir3} is slightly
+different from the server's standpoint. Notice that module @code{mod3}
+is actually checked out into @code{dir3/subdir3}, meaning that directory
+@code{dir3} is either empty or does not contain data checked out from
+this repository.
+
+The above example will work correctly in @sc{cvs} 1.10.1 and later. The
+server will descend the tree starting from all directories mentioned in
+@code{Argument} requests and update those directories specifically
+mentioned in @code{Directory} requests.
+
+Previous versions of @sc{cvs} (1.10 and earlier) do not behave the same
+way. While the descent of the tree begins at all directories mentioned
+in @code{Argument} requests, descent into subdirectories only occurs if
+a directory has been mentioned in a @code{Directory} request.
+Therefore, the above example would succeed in updating @code{dir1} and
+@code{dir2}, but would skip @code{dir3} because that directory was not
+specifically mentioned in a @code{Directory} request. A functional
+version of the above that would run on a 1.10 or earlier server is as
+follows:
+
+@example
+C: Argument dir1
+C: Directory dir1
+C: /home/foo/repos/mod1
+. . .
+C: Argument dir2
+C: Directory dir2
+C: /home/foo/repos/mod2
+. . .
+C: Argument dir3
+C: Directory dir3
+C: /home/foo/repos/.
+. . .
+C: Directory dir3/subdir3
+C: /home/foo/repos/mod3
+. . .
+C: update
+@end example
+
+Note the extra @code{Directory dir3} request. It might be better to use
+@code{Emptydir} as the repository for the @code{dir3} directory, but the
+above will certainly work.
+
+One more peculiarity of the 1.10 and earlier protocol is the ordering of
+@code{Directory} arguments. In order for a subdirectory to be
+registered correctly for descent by the recursion processor, its parent
+must be sent first. For example, the following would not work to update
+@code{dir3/subdir3}:
+
+@example
+. . .
+C: Argument dir3
+C: Directory dir3/subdir3
+C: /home/foo/repos/mod3
+. . .
+C: Directory dir3
+C: /home/foo/repos/.
+. . .
+C: update
+@end example
+
+The implementation of the server in 1.10 and earlier writes the
+administration files for a given directory at the time of the
+@code{Directory} request. It also tries to register the directory with
+its parent to mark it for recursion. In the above example, at the time
+@code{dir3/subdir3} is created, the physical directory for @code{dir3}
+will be created on disk, but the administration files will not have been
+created. Therefore, when the server tries to register
+@code{dir3/subdir3} for recursion, the operation will silently fail
+because the administration files do not yet exist for @code{dir3}.
+
@item Max-dotdot @var{level} \n
Response expected: no.
Tell the server that @var{level} levels of directories above the
@@ -627,9 +722,10 @@ responses.
@item Sticky @var{tagspec} \n
Response expected: no. Tell the server that the directory most recently
specified with @code{Directory} has a sticky tag or date @var{tagspec}.
-The first character of @var{tagspec} is @samp{T} for a tag, or @samp{D}
-for a date. The remainder of @var{tagspec} contains the actual tag or
-date.
+The first character of @var{tagspec} is @samp{T} for a tag, @samp{D}
+for a date, or some other character supplied by a Set-sticky response
+from a previous request to the server. The remainder of @var{tagspec}
+contains the actual tag or date, again as supplied by Set-sticky.
The server should remember @code{Static-directory} and @code{Sticky}
requests for a particular directory; the client need not resend them
@@ -672,6 +768,29 @@ Typically this will be a file being added via an @code{add} or
@code{import} request. The client may not send both @code{Kopt} and
@code{Entry} for the same file.
+@item Checkin-time @var{time} \n
+For the file specified by the next @code{Modified} request, use
+@var{time} as the time of the checkin. The @var{time} is in the format
+specified by RFC822 as modified by RFC1123. The client may specify any
+timezone it chooses; servers will want to convert that to their own
+timezone as appropriate. An example of this format is:
+
+@example
+26 May 1997 13:01:40 -0400
+@end example
+
+There is no requirement that the client and server clocks be
+synchronized. The client just sends its recommendation for a timestamp
+(based on file timestamps or whatever), and the server should just believe
+it (this means that the time might be in the future, for example).
+
+Note that this is not a general-purpose way to tell the server about the
+timestamp of a file; that would be a separate request (if there are
+servers which can maintain timestamp and time of checkin separately).
+
+This request should affect the @code{import} request, and may optionally
+affect the @code{ci} request or other relevant requests if any.
+
@item Modified @var{filename} \n
Response expected: no. Additional data: mode, \n, file transmission.
Send the server a copy of one locally modified file. @var{filename} is
@@ -1134,7 +1253,7 @@ Response expected: yes.
Any unrecognized request expects a response, and does not
contain any additional data. The response will normally be something like
@samp{error unrecognized request}, but it could be a different error if
-a previous command which doesn't expect a response produced an error.
+a previous request which doesn't expect a response produced an error.
@end table
When the client is done, it drops the connection.
@@ -1330,6 +1449,11 @@ synchronized. The server just sends its recommendation for a timestamp
(based on its own clock, presumably), and the client should just believe
it (this means that the time might be in the future, for example).
+If the server does not send @code{Mod-time} for a given file, the client
+should pick a modification time in the usual way (usually, just let the
+operating system set the modification time to the time that the CVS
+command is running).
+
@item Checksum @var{checksum}\n
The @var{checksum} applies to the next file sent (that is,
@code{Checksum} is a file update modifying response
@@ -1564,6 +1688,23 @@ MT fname @var{name}
MT -updated
@end example
+The @code{importmergecmd} tag is used when doing an import which has
+conflicts. The client can use it to report how to merge in the newly
+imported changes. The @var{count} is the number of conflicts. The
+newly imported changes can be merged by running the following command:
+@smallexample
+cvs checkout -j @var{tag1} -j @var{tag2} @var{repository}
+@end smallexample
+
+@example
+MT +importmergecmd
+MT conflicts @var{count}
+MT mergetag1 @var{tag1}
+MT mergetag2 @var{tag2}
+MT repository @var{repository}
+MT -importmergecmd
+@end example
+
@node Example
@section Example
@@ -1751,6 +1892,8 @@ working directory, and the meaning of sending @code{Entries} without
A number of enhancements are possible. Also see the file @sc{todo} in
the @sc{cvs} source distribution, which has further ideas concerning
various aspects of @sc{cvs}, some of which impact the protocol.
+Similarly, the @code{http://www.cyclic.com} site, in particular the
+@cite{Development of CVS} page.
@itemize @bullet
@item
@@ -1762,18 +1905,6 @@ could be handled by a package like VC for emacs). This would also allow
local operation of @code{cvs diff} without arguments.
@item
-The current procedure for @code{cvs update} is highly sub-optimal if
-there are many modified files. One possible alternative would be to
-have the client send a first request without the contents of every
-modified file, then have the server tell it what files it needs. Note
-the server needs to do the what-needs-to-be-updated check twice (or
-more, if changes in the repository mean it has to ask the client for
-more files), because it can't keep locks open while waiting for the
-network. Perhaps this whole thing is irrelevant if there is a multisite
-capability (as noted in @sc{todo}), and therefore the rcsmerge can be
-done with a repository which is connected via a fast connection.
-
-@item
The fact that @code{pserver} requires an extra network turnaround in
order to perform authentication would be nice to avoid. This relates to
the issue of reporting errors; probably the clean solution is to defer
diff --git a/gnu/usr.bin/cvs/emx/ChangeLog b/gnu/usr.bin/cvs/emx/ChangeLog
index b120ea8dc41..6a5f0184e30 100644
--- a/gnu/usr.bin/cvs/emx/ChangeLog
+++ b/gnu/usr.bin/cvs/emx/ChangeLog
@@ -1,3 +1,8 @@
+1998-08-24 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * Makefile.in (rcscmds.o): New rule, so we can supply -I for
+ diffrun.h.
+
1998-04-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* filesubr.c (link_file): Remove; no longer used.
diff --git a/gnu/usr.bin/cvs/emx/Makefile.in b/gnu/usr.bin/cvs/emx/Makefile.in
index eff256490f5..f76368d1d5d 100644
--- a/gnu/usr.bin/cvs/emx/Makefile.in
+++ b/gnu/usr.bin/cvs/emx/Makefile.in
@@ -331,6 +331,9 @@ install-cvs: cvs.exe
%.o: %.c
gcc ${OBJ_CFLAGS} ${CFLAGS} -o $@ -c $*.c
+${cvs_srcdir}/rcscmds.o: ${cvs_srcdir}/rcscmds.c ${top_srcdir}/diff/diffrun.h
+ gcc ${OBJ_CFLAGS} ${CFLAGS} -I${top_srcdir}/diff -o $@ -c $*.c
+
${lib_dir}/libcvs.a: $(LIB_OBJECTS)
$(AR) cr $@ $(LIB_OBJECTS)
diff --git a/gnu/usr.bin/cvs/lib/ChangeLog b/gnu/usr.bin/cvs/lib/ChangeLog
index 264b7ac52f3..6338f847ab6 100644
--- a/gnu/usr.bin/cvs/lib/ChangeLog
+++ b/gnu/usr.bin/cvs/lib/ChangeLog
@@ -1,3 +1,41 @@
+1999-02-09 Jim Kingdon <http://www.cyclic.com>
+
+ * vasprintf.c: Removed; there is apparently no clean, portable
+ solution to the VA_LIST_IS_ARRAY problem (C9X drafts have va_copy,
+ but we aren't even assuming C90 yet!).
+ * Makefile.in (SOURCES): Remove vasprintf.c.
+ * build_lib.com: Remove vasprintf.c and vasprintf.obj.
+
+1999-01-26 Jim Kingdon <http://www.cyclic.com>
+ and Joerg Bullmann <http://www.glink.net.hk/~jb/MacCVSClient/>
+
+ * fnmatch.c: Use FOLD_FN_CHAR in two cases where it had been
+ omitted.
+
+1999-01-22 Jim Kingdon <http://www.cyclic.com>
+
+ * fnmatch.c: Include system.h; FOLD_FN_CHAR has moved there from
+ config.h (from Alexey Milov). Don't define our own FOLD_FN_CHAR;
+ that just masks cases in which we got the includes tangled up.
+
+1999-01-12 Jim Kingdon <http://www.cyclic.com>
+
+ * memmove.c: Remove paragraph which contained the FSF's old
+ snail mail address; it has changed.
+
+1999-01-05 Jim Kingdon <http://www.cyclic.com>
+
+ * md5.c, md5.h: Rename all the external interfaces to start with
+ cvs_* to avoid namespace pollution problems. Include string.h
+ unconditionally, to avoid gcc -Wall warnings on memset.
+
+1998-12-29 Jim Kingdon <http://www.cyclic.com>
+
+ * getdate.y (RelativeMonth): Add 1900 to tm_year, so that in 2000,
+ we pass 2000, not 100, to Convert.
+ (Convert): Add comment about Year argument.
+ * getdate.c: Regenerated using byacc.
+
Tue Mar 24 16:08:00 1998 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (CFLAGS): Set to @CFLAGS@, not -g.
diff --git a/gnu/usr.bin/cvs/lib/build_lib.com b/gnu/usr.bin/cvs/lib/build_lib.com
index 258038f495b..b183d60b903 100644
--- a/gnu/usr.bin/cvs/lib/build_lib.com
+++ b/gnu/usr.bin/cvs/lib/build_lib.com
@@ -11,9 +11,8 @@ $ CC savecwd.c
$ CC sighandle.c
$ CC stripslash.c
$ CC valloc.c
-$ CC vasprintf.c
$ CC xgetwd.c
$ CC yesno.c
$ library/create gnulib.olb fnmatch.obj,getdate.obj,getline.obj,-
getopt.obj,getopt1.obj,md5.obj,regex.obj,savecwd.obj,sighandle.obj,-
-stripslash.obj,valloc.obj,vasprintf.obj,xgetwd.obj,yesno.obj
+stripslash.obj,valloc.obj,xgetwd.obj,yesno.obj
diff --git a/gnu/usr.bin/cvs/lib/fnmatch.c b/gnu/usr.bin/cvs/lib/fnmatch.c
index cf0f1242916..a41c0dc8a20 100644
--- a/gnu/usr.bin/cvs/lib/fnmatch.c
+++ b/gnu/usr.bin/cvs/lib/fnmatch.c
@@ -18,14 +18,7 @@ Library General Public License for more details. */
#include "config.h"
#endif
-/* Some file systems are case-insensitive. If FOLD_FN_CHAR is
- #defined, it maps the character C onto its "canonical" form. In a
- case-insensitive system, it would map all alphanumeric characters
- to lower case. Under Windows NT, / and \ are both path component
- separators, so FOLD_FN_CHAR would map them both to /. */
-#ifndef FOLD_FN_CHAR
-#define FOLD_FN_CHAR(c) (c)
-#endif
+#include "system.h"
/* IGNORE(@ */
/* #include <ansidecl.h> */
@@ -75,7 +68,7 @@ fnmatch (pattern, string, flags)
case '\\':
if (!(flags & FNM_NOESCAPE))
c = *p++;
- if (*n != c)
+ if (FOLD_FN_CHAR (*n) != FOLD_FN_CHAR (c))
return FNM_NOMATCH;
break;
@@ -95,7 +88,7 @@ fnmatch (pattern, string, flags)
{
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
for (--p; *n != '\0'; ++n)
- if ((c == '[' || *n == c1) &&
+ if ((c == '[' || FOLD_FN_CHAR (*n) == FOLD_FN_CHAR (c1)) &&
fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
return 0;
return FNM_NOMATCH;
diff --git a/gnu/usr.bin/cvs/lib/md5.c b/gnu/usr.bin/cvs/lib/md5.c
index 1003a403cb1..f9a3cad465c 100644
--- a/gnu/usr.bin/cvs/lib/md5.c
+++ b/gnu/usr.bin/cvs/lib/md5.c
@@ -23,13 +23,16 @@
copyright in any changes I have made; this code remains in the
public domain. */
+/* Note regarding cvs_* namespace: this avoids potential conflicts
+ with libraries such as some versions of Kerberos. No particular
+ need to worry about whether the system supplies an MD5 library, as
+ this file is only about 3k of object code. */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#if HAVE_STRING_H || STDC_HEADERS
-#include <string.h> /* for memcpy() */
-#endif
+#include <string.h> /* for memcpy() and memset() */
/* Add prototype support. */
#ifndef PROTO
@@ -43,12 +46,12 @@
#include "md5.h"
/* Little-endian byte-swapping routines. Note that these do not
- depend on the size of datatypes such as uint32, nor do they require
+ depend on the size of datatypes such as cvs_uint32, nor do they require
us to detect the endianness of the machine we are running on. It
is possible they should be macros for speed, but I would be
surprised if they were a performance bottleneck for MD5. */
-static uint32
+static cvs_uint32
getu32 (addr)
const unsigned char *addr;
{
@@ -58,7 +61,7 @@ getu32 (addr)
static void
putu32 (data, addr)
- uint32 data;
+ cvs_uint32 data;
unsigned char *addr;
{
addr[0] = (unsigned char)data;
@@ -72,8 +75,8 @@ putu32 (data, addr)
* initialization constants.
*/
void
-MD5Init(ctx)
- struct MD5Context *ctx;
+cvs_MD5Init (ctx)
+ struct cvs_MD5Context *ctx;
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
@@ -89,17 +92,17 @@ MD5Init(ctx)
* of bytes.
*/
void
-MD5Update(ctx, buf, len)
- struct MD5Context *ctx;
+cvs_MD5Update (ctx, buf, len)
+ struct cvs_MD5Context *ctx;
unsigned char const *buf;
unsigned len;
{
- uint32 t;
+ cvs_uint32 t;
/* Update bitcount */
t = ctx->bits[0];
- if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
+ if ((ctx->bits[0] = (t + ((cvs_uint32)len << 3)) & 0xffffffff) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
@@ -116,7 +119,7 @@ MD5Update(ctx, buf, len)
return;
}
memcpy(p, buf, t);
- MD5Transform(ctx->buf, ctx->in);
+ cvs_MD5Transform (ctx->buf, ctx->in);
buf += t;
len -= t;
}
@@ -125,7 +128,7 @@ MD5Update(ctx, buf, len)
while (len >= 64) {
memcpy(ctx->in, buf, 64);
- MD5Transform(ctx->buf, ctx->in);
+ cvs_MD5Transform (ctx->buf, ctx->in);
buf += 64;
len -= 64;
}
@@ -140,9 +143,9 @@ MD5Update(ctx, buf, len)
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
-MD5Final(digest, ctx)
+cvs_MD5Final (digest, ctx)
unsigned char digest[16];
- struct MD5Context *ctx;
+ struct cvs_MD5Context *ctx;
{
unsigned count;
unsigned char *p;
@@ -162,7 +165,7 @@ MD5Final(digest, ctx)
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
- MD5Transform(ctx->buf, ctx->in);
+ cvs_MD5Transform (ctx->buf, ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
@@ -175,7 +178,7 @@ MD5Final(digest, ctx)
putu32(ctx->bits[0], ctx->in + 56);
putu32(ctx->bits[1], ctx->in + 60);
- MD5Transform(ctx->buf, ctx->in);
+ cvs_MD5Transform (ctx->buf, ctx->in);
putu32(ctx->buf[0], digest);
putu32(ctx->buf[1], digest + 4);
putu32(ctx->buf[2], digest + 8);
@@ -203,12 +206,12 @@ MD5Final(digest, ctx)
* the data and converts bytes into longwords for this routine.
*/
void
-MD5Transform(buf, inraw)
- uint32 buf[4];
+cvs_MD5Transform (buf, inraw)
+ cvs_uint32 buf[4];
const unsigned char inraw[64];
{
- register uint32 a, b, c, d;
- uint32 in[16];
+ register cvs_uint32 a, b, c, d;
+ cvs_uint32 in[16];
int i;
for (i = 0; i < 16; ++i)
@@ -302,7 +305,7 @@ MD5Transform(buf, inraw)
int
main (int argc, char **argv)
{
- struct MD5Context context;
+ struct cvs_MD5Context context;
unsigned char checksum[16];
int i;
int j;
@@ -315,9 +318,9 @@ main (int argc, char **argv)
for (j = 1; j < argc; ++j)
{
printf ("MD5 (\"%s\") = ", argv[j]);
- MD5Init (&context);
- MD5Update (&context, argv[j], strlen (argv[j]));
- MD5Final (checksum, &context);
+ cvs_MD5Init (&context);
+ cvs_MD5Update (&context, argv[j], strlen (argv[j]));
+ cvs_MD5Final (checksum, &context);
for (i = 0; i < 16; i++)
{
printf ("%02x", (unsigned int) checksum[i]);
diff --git a/gnu/usr.bin/cvs/lib/md5.h b/gnu/usr.bin/cvs/lib/md5.h
index 65bac1fad3f..876b6327276 100644
--- a/gnu/usr.bin/cvs/lib/md5.h
+++ b/gnu/usr.bin/cvs/lib/md5.h
@@ -8,22 +8,19 @@
bits instead of 64 is not important; speed is considerably more
important. ANSI guarantees that "unsigned long" will be big enough,
and always using it seems to have few disadvantages. */
-typedef unsigned long uint32;
+typedef unsigned long cvs_uint32;
-struct MD5Context {
- uint32 buf[4];
- uint32 bits[2];
+struct cvs_MD5Context {
+ cvs_uint32 buf[4];
+ cvs_uint32 bits[2];
unsigned char in[64];
};
-void MD5Init PROTO((struct MD5Context *context));
-void MD5Update PROTO((struct MD5Context *context, unsigned char const *buf, unsigned len));
-void MD5Final PROTO((unsigned char digest[16], struct MD5Context *context));
-void MD5Transform PROTO((uint32 buf[4], const unsigned char in[64]));
-
-/*
- * This is needed to make RSAREF happy on some MS-DOS compilers.
- */
-typedef struct MD5Context MD5_CTX;
+void cvs_MD5Init PROTO ((struct cvs_MD5Context *context));
+void cvs_MD5Update PROTO ((struct cvs_MD5Context *context,
+ unsigned char const *buf, unsigned len));
+void cvs_MD5Final PROTO ((unsigned char digest[16],
+ struct cvs_MD5Context *context));
+void cvs_MD5Transform PROTO ((cvs_uint32 buf[4], const unsigned char in[64]));
#endif /* !MD5_H */
diff --git a/gnu/usr.bin/cvs/man/ChangeLog b/gnu/usr.bin/cvs/man/ChangeLog
index f131d3e855b..38cc91b0bf5 100644
--- a/gnu/usr.bin/cvs/man/ChangeLog
+++ b/gnu/usr.bin/cvs/man/ChangeLog
@@ -1,3 +1,7 @@
+1999-01-19 Vitaly V Fedrushkov <willy@snowyowl.csu.ac.ru>
+
+ * Makefile.in (INSTALL_DATA): Wrong manpage permissions fixed.
+
1998-06-28 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.1: Update various items which were out of date. Mostly
diff --git a/gnu/usr.bin/cvs/man/Makefile.in b/gnu/usr.bin/cvs/man/Makefile.in
index ffc36139e0b..d92d494e77e 100644
--- a/gnu/usr.bin/cvs/man/Makefile.in
+++ b/gnu/usr.bin/cvs/man/Makefile.in
@@ -25,7 +25,7 @@ MANFILES = $(MAN1FILES) $(MAN5FILES) $(MAN8FILES)
DISTFILES = .cvsignore ChangeLog Makefile.in $(MANFILES)
INSTALL = @INSTALL@
-INSTALL_DATA = $(INSTALL)
+INSTALL_DATA = @INSTALL_DATA@
prefix = @prefix@
mandir = $(prefix)/man
man1dir = $(mandir)/man1
diff --git a/gnu/usr.bin/cvs/os2/ChangeLog b/gnu/usr.bin/cvs/os2/ChangeLog
index 4744ad40987..e4371461129 100644
--- a/gnu/usr.bin/cvs/os2/ChangeLog
+++ b/gnu/usr.bin/cvs/os2/ChangeLog
@@ -1,3 +1,12 @@
+1998-12-29 Jim Kingdon <http://www.cyclic.com>
+
+ * Makefile.in: Use the getdate.c in ../lib rather than the one
+ here. I don't know whether it compiles with Watcom and/or IBM's
+ compiler, but having a copy of getdate.c in this directory has
+ proven to be unworkable (the version I am removing still had Y2K
+ bugs which were fixed in lib/getdate.c, for example).
+ * getdate.c: Removed.
+
1998-04-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* filesubr.c (link_file): Remove; no longer used.
diff --git a/gnu/usr.bin/cvs/os2/Makefile.in b/gnu/usr.bin/cvs/os2/Makefile.in
index 715959eaa7d..5febf7eb335 100644
--- a/gnu/usr.bin/cvs/os2/Makefile.in
+++ b/gnu/usr.bin/cvs/os2/Makefile.in
@@ -84,7 +84,6 @@ OS2_SOURCES = \
${srcdir}${SL}waitpid.c \
${srcdir}${SL}popen.c \
${srcdir}${SL}porttcp.c \
- ${srcdir}${SL}getdate.c \
${srcdir}${SL}getpass.c
# sources we use from the common src dir, ..${SL}src
@@ -145,6 +144,7 @@ COMMON_SOURCES = \
# sources from ..${SL}lib
# FIXME: Is this used anywhere? I don't think it is.
LIB_SOURCES = \
+ ${lib_dir}${SL}getdate.c \
${lib_dir}${SL}getopt.c \
${lib_dir}${SL}getopt1.c \
${lib_dir}${SL}getline.c \
@@ -170,7 +170,6 @@ OS2_OBJECTS = \
${srcdir}${SL}waitpid.obj \
${srcdir}${SL}popen.obj \
${srcdir}${SL}porttcp.obj \
- ${srcdir}${SL}getdate.obj \
${srcdir}${SL}getpass.obj
# object files from ..${SL}src
@@ -230,6 +229,7 @@ COMMON_OBJECTS = \
# objects from ..${SL}lib
LIB_OBJECTS = \
+ ${lib_dir}${SL}getdate.obj \
${lib_dir}${SL}getopt.obj \
${lib_dir}${SL}getopt1.obj \
${lib_dir}${SL}getline.obj \
diff --git a/gnu/usr.bin/cvs/src/ChangeLog b/gnu/usr.bin/cvs/src/ChangeLog
index 8077ce8c027..7acccf5cbfe 100644
--- a/gnu/usr.bin/cvs/src/ChangeLog
+++ b/gnu/usr.bin/cvs/src/ChangeLog
@@ -1,3 +1,1068 @@
+1999-02-18 Jim Kingdon <http://www.cyclic.com>
+
+ * sanity.sh (files): New test, for a relatively obscure spurious
+ "Up-to-date check failed" in client/server.
+
+ * main.c (lookup_command_attribute): Don't check for "history"
+ twice.
+
+1999-02-17 Jim Kingdon <http://www.cyclic.com>
+ and Hallvard B Furuseth
+
+ * root.c (parse_cvsroot): Rearrange ifdefs to squelch possible
+ warnings about statement not reached.
+
+1999-02-16 Jim Kingdon <http://www.cyclic.com>
+
+ * recurse.c (start_recursion): If we are skipping the current
+ directory (due to it being from the wrong repository), also adjust
+ the arguments we send to the server accordingly (like we already
+ do for the case in which there is no CVS directory).
+ * sanity.sh (multiroot4): New test, for this. All these tests had
+ passed locally, but remote multiroot4-12 tests for this fix.
+ (multiroot): Adjust multiroot-diff-1, multiroot-update-2,
+ multiroot-tag-1, multiroot-status-1, multiroot-update-3, and
+ multiroot-log-1 to reflect the cosmetic change this produces (one
+ less "Diffing ." message).
+ (multiroot2): multiroot2-8 likewise.
+
+1999-02-10 Jim Kingdon <http://www.cyclic.com>
+
+ * tag.c (cvstag): Don't pass SEND_NO_CONTENTS if -c specified.
+ * sanity.sh (tagc): New test, for various tag -c behaviors.
+ Test tagc-6 tests for this fix.
+
+1999-02-09 Jim Kingdon <http://www.cyclic.com>
+
+ * error.c (error): Rewrite to no longer use vasprintf (see
+ ../lib/ChangeLog for rationale). Note the slight change in
+ interface - callers which want %8.8s or similar formats need to
+ call sprintf.
+ * lock.c (lock_wait, lock_obtained): Use sprintf.
+
+1999-02-08 Jim Kingdon <http://www.cyclic.com>
+
+ * rcs.c (RCS_delete_revs): Pass -a to diff_exec.
+ * sanity.sh (binfiles3): New tests binfiles3-9 through
+ binfiles3-13 test for this fix.
+ * sanity.sh (binfiles): New tests binfiles-o4 and binfiles-o5
+ (which don't test this bug, just on general principles).
+
+1999-02-04 Jim Kingdon <http://www.cyclic.com>
+
+ * lock.c (lock_name): Permissions of directories in LockDir
+ shouldn't depend on the umask.
+ * sanity.sh (lockfiles): Set umask and CVSUMASK, to test for this.
+
+1999-02-01 Jim Kingdon <http://www.cyclic.com>
+
+ * sanity.sh (keywordlog): New tests keywordlog-22 and
+ keywordlog-23 test keyword expansion and $Log. Adjust other tests
+ so that revisions differ more from each other, so this is a
+ better test.
+
+1999-01-29 Jim Kingdon <http://www.cyclic.com>
+
+ * commit.c (checkaddfile): If options is "", treat it the same as
+ NULL. Centralize this check, and the one for it starting with
+ "-k", at the start of the function.
+
+ * rcs.c, rcs.h (RCS_setexpand): New function.
+ * admin.c (admin_fileproc): Access keyword expansion field via
+ RCS_getexpand and RCS_setexpand, rather than directly.
+ * commit.c (checkaddfile): When resurrecting, set the keyword
+ expansion mode.
+ * sanity.sh (binfiles3): Adjust tests binfiles3-7 and binfiles3-8
+ for the new behavior.
+
+1999-01-27 Jim Kingdon <http://www.cyclic.com>
+
+ * sanity.sh (multiroot3): Add new variant of multiroot3-10 test
+ for RELATIVE_REPOS. Move multiroot3-11 test out of the
+ conditionals; it works the same for remote or local,
+ RELATIVE_REPOS or no.
+
+ * options.h.in: Make RELATIVE_REPOS the default, as has been
+ announced as a future direction since 1997-10-11.
+ * sanity.sh (multiroot): Tweak multiroot-update-1a and
+ multiroot-update-1b tests to work with either RELATIVE_REPOS or
+ non-RELATIVE_REPOS.
+
+ * sanity.sh (client-9): Don't assume the time zone.
+
+1999-01-26 Jim Kingdon <http://www.cyclic.com>
+
+ Fix one facet of the "cvs add -kb" re-adding problem (the other
+ known facet is tested for by binfiles3-8).
+ * add.c (add): When re-adding a file, set the keyword expansion
+ as we normally would.
+ * sanity.sh (binfiles3): New test binfiles3-6a tests for this.
+
+1999-01-22 Jim Kingdon <http://www.cyclic.com>
+
+ * sanity.sh (rmadd2): New tests, for undoing a commit.
+
+1999-01-21 Eric Mumpower <nocturne@cygnus.com>
+
+ * sanity.sh (reposmv): Actually modify CVSROOT in current
+ environment when calling functions, rather than trying to achieve
+ the same effect with "CVSROOT=foo functionname". (Many common
+ bourne shells, including those in SunOS and Solaris 2.4-2.7,
+ do not properly handle "ENVVAR=foo command" when "command" is
+ a user-defined shell function rather than an actual executable.)
+
+1999-01-15 Jim Kingdon <http://www.cyclic.com>
+
+ * sanity.sh (rcs3): Redirect awk's stdin to /dev/null like all the
+ other awk invocations. GNU awk seems not to read stdin in this
+ case, but that behavior is hard to reconcile with the Single Unix
+ Spec and some awks don't do it.
+
+ * sanity.sh (binfiles, binfiles2, binfiles3, server): Use the same
+ tr trick as in rcs3. People don't seem to have been complaining,
+ and this should fix server-4 for HPUX.
+
+1999-01-14 Jim Kingdon <http://www.cyclic.com>
+
+ * client.c (recv_line): If the line we are reading contains a
+ character which would sign-extend to EOF, don't treat it as end of
+ file. recv() doesn't report end of file this way and this might
+ fix bugs with 0xff characters.
+
+1999-01-14 Larry Jones <larry.jones@sdrc.com>
+
+ * client.c (recv_line): Handle EOF from server.
+
+ * sanity.sh (importc-8, importc-9): Accept anything in the seconds
+ fields of the timestamps since touch doesn't set it reliably.
+ (This isn't great, but it's better than nothing.)
+
+1999-01-14 Jim Kingdon <http://www.cyclic.com>
+
+ * run.c (run_exec): Adjust comment about vfork; this isn't the place
+ to get into a treatise about fork performance vs. vfork
+ performance but it isn't quite as simple as whether one has
+ copy-on-write.
+
+1999-01-13 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (dotest_fail): Handle spurrious output from assert better.
+
+ * sanity.sh (rcs3-4, rcs3-5a): Handle even more variants of the
+ assertion failure message.
+
+1999-01-12 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (mtfr-3): ls behavior varies wildly on nonexistant files,
+ just use echo instead.
+
+1999-01-11 Jim Meyering <meyering@ascend.com>
+
+ * sanity.sh (mkmodules-temp-file-removal): New test, for this.
+ * mkmodules.c (mkmodules): Remove each `CVSROOT/.#[0-9]*' temporary
+ file that's used to check out files listed in CVSROOT/checkoutlist.
+ Remove extra semicolon at end of line.
+
+1999-01-11 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (rcs3-5a): Allow for multiple lines of output before the
+ assertion failure message.
+
+ * sanity.sh (lockfiles-6, client-8): Work around bug in HP-UX chmod
+ (doesn't allow anything to follow omitted permissions).
+
+1999-01-09 Jim Kingdon <http://www.cyclic.com>
+
+ * client.c (set_sticky): Nonfatal error if we can't write it.
+ * sanity.sh (dirs2-8 through dirs2-14): New tests, for this.
+
+ * sanity.sh (rcs3): Write NUL character with tr not awk, in
+ accordance with Single Unix Specification. Hopefully will fix
+ rcs3-7 for HPUX. Will not work on SunOS4, but then again neither
+ did the old syntax.
+
+1999-01-05 Jim Kingdon <http://www.cyclic.com>
+
+ * client.c, update.c: Rename MD5* functions to cvs_MD5* per
+ corresponding change to ../lib/md5.h.
+
+1999-01-03 Jim Kingdon <http://www.cyclic.com>
+
+ * sanity.sh (client): Give file1 a predictable mode so that the
+ output in client-9 will not depend on the umask of the user
+ running the tests.
+
+1998-12-29 Jim Kingdon <http://www.cyclic.com>
+
+ * client.c (client_senddate): Use date_to_internet rather than
+ using our own "5/26/1997 13:01:40 GMT" date format.
+ * main.c (date_to_internet): Check for errors from sscanf. Always
+ send a four digit year. Send hours, minutes, and seconds as two
+ digits per RFC822.
+ * sanity.sh (client): New tests client-8 and client-9 test for this.
+
+ * sanity.sh (rcs2): New tests rcs2-6 through rcs2-8 test for fix
+ to lib/getdate.y (before the fix, "100 months" or "8 years" would
+ tend to mean the year 1969, thus the tests would give "cvs update:
+ file1 is no longer in the repository").
+
+1998-12-28 Larry Jones <larry.jones@sdrc.com>
+
+ * entries.c (Register): Return if unable to open log file to avoid
+ referencing the invalid file pointer.
+ * sanity.sh (dirs2-7): With above change, no longer fails.
+ * sanity.sh (rcs3-5a): Another assertion failure message.
+ * sanity.sh (pserver-4, pserver-5): Some 4.4BSD derived systems spit
+ out bogus error messages when initgroups is called as non-root.
+
+1998-12-23 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (rcs3, dotest_fail): The assertion failure message varies
+ wildly between different systems and the resulting abort call can
+ even result in spurrious output. Fix the regexp to accept nearly
+ anything containing some kind of assertion failure and ensure that
+ any spurrious output ends up in the output file instead of on the
+ terminal.
+
+1998-12-23 Jim Kingdon <http://www.cyclic.com>
+
+ * admin.c, checkout.c, commit.c, cvsrc.c, expand_path.c,
+ history.c, ignore.c, import.c, log.c, mkmodules.c, modules.c,
+ myndbm.c, parseinfo.c, rcs.c, remove.c, rtag.c, status.c, subr.c,
+ tag.c, wrapper.c: Cast all char's to unsigned char before passing
+ them to ctype.h functions (isalpha, isgraph, isalnum, isspace,
+ isdigit, isprint, isupper). Whether using ctype.h is the right
+ thing at all is unclear to me (having the server depend on locale
+ seems wrong, as we don't necessarily have any good way to set the
+ right locale, if there even is such a concept as 'right' locale in
+ this context), but as long as we use ctype.h we might as use it
+ according to the standards (this affects systems where plain char
+ is signed but users supply characters with the 8th bit set).
+ Thanks to Paul Eggert for suggesting this.
+
+1998-12-22 Jim Kingdon <http://www.cyclic.com>
+
+ * sanity.sh (rcs3): Oops, the earlier fix for srcdir only fixed
+ the non-remote case, not the remote case. Fix the other occurrence.
+
+1998-12-22 Jim Kingdon
+
+ * sanity.sh (rcs3): The assertion failure message varies slightly
+ depending on whether CVS was built with srcdir != ".". Fix regexp.
+
+1998-12-21 Jim Kingdon
+
+ * rcs.c (RCS_getdate): Reindent Jim Meyering's change; remove
+ unused variable x_vers.
+
+ * rcs.c: When printing an unexpected character we found in the RCS
+ file, print it in hex rather than as a character (see comment for
+ rationale).
+ * sanity.sh (rcs3): Adjust rcs3-2 and rcs3-7 tests accordingly.
+
+ * sanity.sh (rcs3): New test, for some error handling cases
+ involving parsing RCS files.
+
+1998-12-16 Jim Meyering <meyering@ascend.com>
+
+ * rcs.c (RCS_getdate): Handle the case in which a file is first
+ imported after its initial version has been created.
+ * sanity.sh (import-after-initial): New test for that.
+
+1998-12-17 Jim Kingdon
+
+ * server.c (serve_root): Pserver_Repos only exists if
+ AUTH_SERVER_SUPPORT is defined.
+
+1998-12-12 Jim Kingdon, and Derek R. Price of Stortek.
+
+ * sanity.sh (multiroot): Change + to ${PLUS}.
+
+1998-12-12 Jim Kingdon, and Gary Young of Motorola
+
+ * sanity.sh (admin): In tests admin-13, admin-25, and admin-29,
+ allow 4 digit year in addition to 2 digit year.
+
+1998-12-12 Jim Kingdon
+
+ * sanity.sh (log): New tests log-14a and log-14b test for -rHEAD
+ and for HEAD as (nonexistent) file name.
+
+1998-12-02 Jim Kingdon
+
+ * version.c: Squish version number to 1.10.4.1.
+
+ * version.c: Version 1.10.4.
+
+1998-11-24 Jim Kingdon
+
+ * recurse.c (do_file_proc): Check for errors from RCS_parse.
+ * sanity.sh (rcslib-symlink-7 through rcslib-symlink-10): New
+ tests, test for this.
+
+ * sanity.sh (reposmv-2): Adjust for 22-Nov change to Find_Names.
+
+ * entries.c (Register): If we can't write Entries.Log, make it a
+ nonfatal error.
+ * sanity.sh (dirs2): Test for this fix.
+
+ * sanity.sh (dirs2): Clean up working directory at end of test.
+
+1998-11-23 Jim Kingdon
+
+ * sanity.sh (dirs2): New test, for some more cases involving
+ deleting directories and such.
+
+ * sanity.sh (dirs): Update for yesterday's change in Find_Names
+ error handling. The error in dirs-4 is fairly different now; in
+ dirs-3 and dirs-3a it is the obvious change.
+
+1998-11-22 Jim Kingdon
+
+ * sanity.sh (release): Move the commments listing "cvs release"
+ tests from modules2-6 to here.
+ * release.c (release): Update comment to reflect "? foo" case.
+
+ * find_names.c (Find_Names): If we can't read the repository, make
+ it a nonfatal error. Tell the caller whether this happened.
+ (find_rcs): Add comment regarding this behavior.
+ * recurse.c (do_recursion): If Find_Names gives an error, skip
+ the directory and print a message saying so.
+ * sanity.sh (modes3): New test, for this.
+
+1998-11-18 Jim Kingdon
+
+ * rtag.c (rtag_usage), tag.c (tag_usage): Use "-r rev"
+ consistently.
+
+ * sanity.sh (conflicts3): Tests conflicts3-24 through
+ conflicts3-28 test for another case similar to conflicts3-22.
+
+1998-11-14 Jim Kingdon
+
+ * sanity.sh (diff): New test, for now just tests for the "I know
+ nothing" message.
+
+ * sanity.sh (conflicts2-142b7 through conflicts2-142b11): New
+ tests; resurrecting doesn't work from one level up.
+
+ * sanity.sh (mwrap-7): Remote prints the messages in a different
+ order.
+
+1998-11-13 Jim Kingdon
+
+ * tag.c (check_fileproc): Log tag deletions.
+ * rtag.c (check_fileproc): Likewise.
+ * sanity.sh (taginfo-14 through taginfo-18): New tests, for
+ these behaviors.
+
+1998-11-12 Jim Kingdon
+
+ * sanity.sh (mwrap-7): Update for the noexec fix.
+
+ * server.c (server_copy_file): Add comment about noexec.
+
+ * update.c (checkout_file): Handle noexec case involving revbuf
+ and modes.
+ (update_fileproc): In case T_NEEDS_MERGE, let merge_file take care
+ of noexec, so it can tell the user if there would be conflicts.
+ (merge_file): Print "conflicts found in FILE" message
+ regardless of noexec. Add comment about checking for whether the
+ file already contained the changes, and noexec.
+ * sanity.sh (conflicts-192a): New test, for this.
+
+1998-10-20 Jim Kingdon
+
+ Use the gzip library on the server. Probably doesn't speed things
+ up as currently implemented, but does avoid hassles in terms of
+ finding an external gzip program.
+ * zlib.c, server.h (gunzip_and_write, read_and_gzip): Now returns
+ whether a fatal error occurred, rather than expecting error (1,
+ ...) to work.
+ * client.c (update_entries, send_modified): Change callers.
+ * server.c (receive_file): Rewrite gzip code to use
+ gunzip_and_write rather than filter_through_gunzip.
+ (server_updated): Likewise, use read_and_gzip rather than
+ filter_through_gzip.
+ * client.c, client.h (filter_through_gzip, filter_through_gunzip),
+ run.c, cvs.h (filter_stream_through_program): Removed; no longer used.
+ * sanity.sh (server): New tests server-4 and server-5 test
+ this feature (note that CVS 1.10 also passes these tests; the
+ behavior is supposed to be unchanged).
+
+1998-10-19 Jim Kingdon
+
+ * sanity.sh (multiroot3): New test, tests for a few more
+ multiroot cases.
+
+ * lock.c (lock_name): Set the permissions on each directory we
+ create to that of the parent directory.
+ * sanity.sh (lockfiles): New chmod and tests lockfiles-7a and
+ lockfiles-7b test for this. Adjust lockfiles-5 for new text of
+ error message.
+
+1998-10-15 Jim Kingdon
+
+ * server.c (requests): Set RQ_ROOTLESS for "Set".
+ * sanity.sh (info): Also clean up $HOME/.cvsrc.
+ (server): Test that we can send Set before Root (had been tested
+ by crerepos-6b, but only if you ran the info test first). Tests
+ for this fix.
+
+1998-10-14 Jim Kingdon
+
+ * subr.c (expand_string): Tweak the algorithm so that the size
+ that it allocates is generally a power of two.
+
+1998-10-14 Eivind Eklund and Jim Kingdon
+
+ * commit.c (commit): For the client, don't worry about whether we
+ are root.
+
+1998-10-13 Jim Kingdon
+
+ * server.h (struct request): Change status field to flags and add
+ RQ_ROOTLESS.
+ * client.c (handle_valid_requests, supported_request): Change
+ status to flags.
+ * server.c (requests): Change status to flags. Add RQ_ROOTLESS.
+ * server.c (server): If not RQ_ROOTLESS, and we haven't gotten a
+ Root request, give an error.
+
+1998-10-12 Jim Kingdon
+
+ * version.c: Slide version number to 1.10.3.1.
+
+ * Version 1.10.3.
+
+ * sanity.sh (modules2-17): Update for 9 Oct 1998 change to
+ update_dirent_proc.
+
+1998-10-11 Jim Kingdon
+
+ * commit.c (checkaddfile, commit_fileproc): A numeric value for
+ 'tag' does not mean that we are adding on a branch.
+ * sanity.sh (keywordlog): Adjust this test, to test for this
+ (replaces comment saying we should be doing it).
+ (rmadd): Likewise.
+
+ * sanity.sh (rmadd): New test, tests for various existing
+ behaviors with "cvs ci -r".
+
+1998-10-09 Jim Kingdon
+
+ * update.c (update_dirent_proc): For local CVS, if the directory
+ does not exist in the working directory nor in the repository,
+ just skip it.
+ * sanity.sh (dirs): New tests dirs-3a, dirs-7 and dirs-8 test for
+ this and related behaviors. Note that the new behavior was also
+ the previous behavior for remote; we are only changing it for local.
+
+ * wrapper.c, cvsrc.c, ignore.c: Add comments about ignoring .cvsrc
+ and friends if we can't find a home directory.
+ * expand_path.c (expand_path): If we can't find the home
+ directory, give an error rather than a coredump (or worse).
+ * login.c (construct_cvspass_filename): Don't use errno in error
+ message; get_homedir doesn't set it. Add comment about this
+ message.
+
+1998-10-07 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * diff.c (diff): Set variables to NULL at the start, and free
+ memory at the end.
+ * sanity.sh (multiroot2): Add tests for this (before the fix,
+ multiroot2-12 would abort with "no more than two revisions/dates
+ can be specified").
+
+1998-10-06 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * Makefile.in (installcheck check): Remove references to RCSBIN;
+ they don't do anything now that RCSBIN is ignored.
+
+ * client.c: Clean up horrible confusion about whether stored_mode
+ or stored_mode_valid (or nothing :-)) indicates whether
+ stored_mode is allocated. Should fix crashes (for example, on NT
+ when the server has renamed multiple files from uppercase to
+ lowercase).
+
+ * sanity.sh (dirs): New tests, tests for some cases involving
+ admins who do surgery on the repository.
+
+1998-10-03 Johannes Stezenbach <johannes.stezenbach@propack-data.de>
+
+ * vers_ts.c (Version_TS): If UTIME_EXPECTS_WRITABLE, if
+ necessary change the file to be writable temporarily to set its
+ modification time.
+
+1998-10-03 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * client.c (handle_error): Add comment about indicating which
+ errors are from the server.
+
+1998-10-01 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (devcom-180): Allow one digit day.
+
+1998-09-30 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * main.c (main): Don't call Name_Root if -d specified.
+ * recurse.c (do_recursion, do_dir_proc): Don't check CVS/Root
+ if -d was specified.
+ * import.c (import): Indentation fix.
+ * sanity.sh (multiroot): Update for this change.
+ (reposmv): New test, tests for this.
+
+1998-09-28 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (multiroot2): New test, tests some nested directory
+ cases.
+
+1998-09-25 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (multiroot): Change a few comments which said modules
+ when they meant directories.
+
+1998-09-25 Jim Meyering <meyering@ascend.com>
+
+ * sanity.sh (devcom-180): Add 0-9 to the range of characters allowed
+ in hostname regexp.
+
+1998-09-25 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (log2): New test log2-7a tests for one error handling
+ case. Add a comment about another.
+
+1998-09-24 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh: Change crerepos test back to :ext: (for several
+ reasons; see comments).
+
+1998-09-24 Noel Cragg <noel@swish.red-bean.com>
+
+ * sanity.sh (rcslib-symlink-5, rcslib-symlink-6): new tests to
+ check the operation of "tag" when there are symlinks in the
+ repository.
+
+ * rcs.c (RCS_checkin): remove old code that resolved the symlink
+ and call resolve_symlink instead.
+ (RCS_rewrite): call resolve_symlink before doing anything else to
+ make sure we're operating on the file and not the symlink.
+
+ * subr.c (resolve_symlink): new routine -- resolves a symbolic
+ link chain to its destination.
+ * cvs.h: add prototype.
+
+ * sanity.sh (basica-6.2, basica-6.3): changed match expressions to
+ reflect new diff output.
+
+ * rcs.c (make_file_label): generate labels for files that include
+ the pathname so that output from "cvs diff" is useable by patch.
+ Looks like I came up with the mods as Andy Piper
+ <andyp@parallax.co.uk>; his patch was on the Cyclic unofficial
+ patches page.
+
+ * sanity.sh: change remote access method from ext to fork. This
+ results in a significant speed improvement when running the
+ testsuite. The ext method on my machine (i586 120MHz Linux 2.0.35
+ with TCP wrappers installed) runs in 450% of the time of the local
+ method while the fork method runs in only 150% of the time of the
+ local method! Yow! Am I SWAPPING yet?!
+ (crerepos-6a, crerepos-6b): change to reflect different error
+ messages for fork method.
+ (modes-15): same.
+
+ * client.c (connect_to_forked_server): new routine.
+ (start_server): call the above when method is fork_method.
+
+ * root.c: add a new method named "fork". This method uses the
+ remote protocol, but does so by forking a "cvs server" process
+ directly rather than doing "rsh host cvs server" (for example).
+ This new method has few advantages for day-to-day use, but has
+ three important benefits for debugging:
+
+ 1) Most secure installations these days don't allow rsh access.
+ With this new method, we can still test the remote protocol on
+ these machines because we don't need to be able to make a local
+ TCP connection.
+
+ 2) Even if installations allow rsh access, they almost always
+ have TCP wrappers to check permissions by IP/hostname. This
+ causes a short delay for every connection. For invocations from
+ the command line, this doesn't matter much, but it adds up to a
+ significant amount of time when running the testsuite.
+
+ 3) On machines that can't (or do not usually) provide rshd
+ access (I'm thinking of WNT/W95 in particular), we can now run
+ tests of the remote protocol using this method. Indeed, we can
+ run remote protocol tests on any machine that has an
+ implementation of piped_child().
+
+ (parse_cvsroot): handle new method.
+ (error_exit, xstrdup, isabsolute): new stub functions to use when
+ compiling root.c with the DEBUG option.
+ (main): fix a few typos.
+ * cvs.h (CVSmethod): add fork_method.
+
+ * server.c (create_adm_p): use Emptydir as the placeholder
+ directory instead of "." to avoid problems with "cvs update -d" et
+ al.
+
+1998-09-22 Noel Cragg <noel@swish.red-bean.com>
+
+ * sanity.sh (devcom-180): fixed typo in regexp.
+
+ * main.c (main): remove need_to_create_root and related code
+ (including CVS_IGNORE_REMOTE_ROOT environment variable). The
+ current implementation (just removed) of rewriting the contents of
+ the CVS/Root file isn't desirable for a number of reasons:
+
+ 1) Only the top-level CVS/Root directory is updated. If we're
+ really interested in pointing our WD at another CVSROOT, we
+ should have a separate command.
+
+ 2) With the new multiroot mods, we don't ever want to rewrite
+ CVS/Root files in the way the removed code did. Consider:
+
+ cvs -d repository1 co a
+ cd a
+ cvs -d repository2 co b
+ cvs -d repository2 update b
+
+ The update command would rewrite the contents of a/CVS/Root to
+ the incorrect value. Bad. We then wouldn't be talking to the
+ correct repository for files in a.
+
+ 3) The removed code seems to be a quick hack to support working
+ directories checked out from multiple repositories. With the
+ CVS_IGNORE_REMOTE_ROOT variable set, one could perform commands
+ as in example 2, above, without worring about updating CVS/Root
+ files. While in pre-1.10.1 recursive commands wouldn't handle
+ that working directory hierarchy, one could use commands like
+ "cvs foo -l" instead. While not great, this allows you (with a
+ lot of manual interaction) to have a multiroot WD. Since we now
+ have multiroot mods checked in, we don't need this code.
+
+ (lookup_command_attribute): while we don't need the
+ CVS_CMD_USES_WORK_DIR flag anymore (since it only was supporting
+ the need_to_create_root code), I'm leaving it in. It may come in
+ handy at some later date.
+
+1998-09-18 Jim Kingdon <kingdon@pennington.cyclic.com>
+
+ * version.c: Advance version number to 1.10.2.1.
+
+ * Version 1.10.2.
+
+1998-09-13 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * client.c: Refuse to Copy-file to another directory
+ * sanity.sh (client): New test, tests for this.
+
+ * edit.c (editors_fileproc), watch.c (watchers_fileproc): Use
+ cvs_output rather than writing to stdout.
+ * sanity.sh (devcom): Use dotest for tests 178, 180, and 183
+ (tests that we preserve existing behavior on "cvs editors").
+
+ * commit.c (check_fileproc): Don't allow commits in Emptydir.
+ * sanity.sh (emptydir-8): Test for this change in behavior.
+
+ * sanity.sh: Add some compatibility tests to TODO comments at end.
+
+1998-09-10 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * wrapper.c (wrap_add): Remove obsolete comment about -m.
+
+ * server.c (server_updated): Check for error from CVS_UNLINK.
+
+1998-09-09 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * server.c (serve_root): Allocate with malloc, not xmalloc.
+
+ * root.c (set_local_cvsroot): Move memory allocation from here...
+ * server.c (serve_root): ...to here. Fixes error handling.
+
+ * root.c (parse_cvsroot): Don't call check_root_consistent;
+ parse_cvsroot is only used for local and client.
+ * root.c (set_local_cvsroot): Move check_root_consistent
+ functionality from here...
+ * server.c (serve_root): ...to here. Fixes error handling. Also
+ made the error more explicit, while I am at it.
+ * server.c (Pserver_Repos): Now static.
+ * cvs.h: Don't declare it.
+ * root.c (check_root_consistent): Removed; no longer needed.
+ * sanity.sh (pserver): New test, tests for this behavior and some
+ other basic pserver stuff.
+
+ * update.c (merge_file): Use cvs_output for "already contains the
+ differences" message. Found this one when I actually observed the
+ out-of-order bug in Real Life(TM).
+
+1998-09-09 Jim Kingdon
+
+ * find_names.c (find_dirs): Make sure to zero errno before
+ going around the loop again.
+ * find_names.c (find_rcs): Make sure to set save_errno.
+ (thanks to Alexandre Parenteau for reporting both problems).
+
+1998-09-09 Jim Kingdon <kingdon@harvey.cyclic.com> and Michael Pakovic
+
+ * edit.c (notify_do): Only free line if it is not NULL.
+
+1998-09-07 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * cvs.h: dirs_sent_to_server should not be inside
+ AUTH_SERVER_SUPPORT (reported by both Richard Levitte and Murray
+ Bishop, thanks).
+
+ * lock.c, cvs.h: New variable lock_dir.
+ * parseinfo.c (parse_config): New option LockDir.
+ * lock.c (lock_name): New function, abstracts out lock file naming
+ and also supports LockDir.
+ * lock.c (lock_simple_remove, Reader_Lock, write_lock, set_lock):
+ Call it (6 places, to create/remove read/write/master locks).
+ (Lock_Cleanup): Refuse to reenter this function.
+ * sanity.sh (lockfiles): New test, tests for this feature.
+
+1998-09-03 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (multiroot): Expect ${TESTDIR} in output instead of
+ assuming it is /tmp/cvs-sanity (thanks to Mark D. Baushke of Cisco).
+ Clean up working directory when done (fixes apparent thinko).
+
+ * server.c (create_adm_p): Fix one "return" which didn't return a
+ value.
+ (dirswitch): Check for errors from create_adm_p.
+
+ * sanity.sh: Set LC_ALL rather than just LC_COLLATE.
+
+Wed Sep 2 02:30:22 1998 Jim Kingdon <kingdon@pennington.cyclic.com>
+
+ * version.c: Bump version number to 1.10.1.1.
+
+ * Version 1.10.1.
+
+1998-09-01 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ Administrative note regarding Noel's changes to allow one to
+ switch from one CVS root to another in a single command: The
+ ChangeLog entries for the changes which Noel just checked in
+ appear for 1998-09-01, 1998-08-28, 1998-08-25, 1998-08-19, and
+ 1998-08-18, rather than being all together.
+
+ * main.c (set_root_directory): Fix whitespace.
+ (main): Nuke new -m option and just have that message controlled
+ by -t.
+ * server.c (server): Revert the CVS_SERVER_SLEEP code back the way
+ it was in CVS 1.10. Attaching to the parent process is relatively
+ boring (you can just run "cvs server" under a debugger instead),
+ but connecting to the child process is what the old code was for.
+ * recurse.c, server.c: Remove DEBUG_NJC code.
+
+1998-09-01 Noel Cragg <noel@swish.red-bean.com>
+
+ * server.c (do_cvs_command): add another environment variable,
+ CVS_SERVER_SLEEP2, after forking to pause the program so one can
+ attach a debugger.
+
+ * sanity.sh (crerepos): clean up crerepos-18 now that multiroot
+ works in this case.
+ (multiroot): finalize tests for local vs. remote operation.
+
+ * recurse.c (start_recursion): near the beginning, save the list
+ of directories to spoof as command-line arguments, if necessary.
+ Use that list near the end and call send_file_names to send those
+ arguments to the server.
+ (do_argument_proc): removed, since we call send_file_names now.
+
+ * main.c (main): re-initialize dirs_sent_to_server on each pass
+ through the loop for each CVSROOT.
+
+ * cvs.h: add proto for global variable which keeps track of which
+ directories have been sent to the server when in client mode.
+
+ * client.c (is_arg_a_parent_or_listed_dir): new function.
+ (arg_should_not_be_sent_to_server): new function. Tries to decide
+ whether the given argument should be sent to the server, based on
+ the current CVSROOT and the list of directories sent to the
+ server.
+ (send_repository): add the directory name to the list of
+ directories sent to the server.
+ (send_file_names): call arg_should_not_be_sent_to_server.
+
+ * add.c (add): switch the order of send_files and send_file_names
+ to make multiple repository support possible. send_files needs to
+ create a list of directories being requested so that
+ send_file_names can decide which command-line arguments to send to
+ the server for the given current CVSROOT.
+ * admin.c (admin): same.
+ * commit.c (commit): same.
+ * diff.c (diff): same.
+ * edit.c (editors): same.
+ * log.c (cvslog): same.
+ * rcs.c (annotate): same.
+ * remove.c (cvsremove): same.
+ * status.c (cvsstatus): same.
+ * tag.c (cvstag): same.
+ * update.c (update): same.
+ * watch.c (watch_addremove): same.
+ (watchers): same.
+
+1998-08-31 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh: Remove "debug" function; it was apparently checked
+ in accidentally by Norbert Kiesel's change.
+
+1998-08-31 Norbert Kiesel <nk@iname.com>
+
+ * release.c (release): modify last patch to release so that
+ save_cwd is called only once and restore_cwd is always called when
+ neccessary. Also fixed a tiny memory leak.
+
+ * sanity.sh (release): added some more tests for "cvs release"
+ including a test with two dirs and a "no" for the first one (which
+ fails without the above patch).
+
+1998-08-28 Noel Cragg <noel@swish.red-bean.com>
+
+ * sanity.sh (crerepos-18): add new comment and change test
+ slightly to support multiroot.
+ (multiroot): add more tests.
+
+ * server.c (create_adm_p): new function.
+ (dirswitch): call create_adm_p. Modify the code to always write a
+ new CVSADM_REP file, since create_adm_p might have put a
+ placeholder there and our value is guaranteed to be correct.
+ (server): move the CVS_SERVER_SLEEP check here so we can debug
+ things at an earlier stage.
+
+ * recurse.c (start_recursion): add large comment about the ideal
+ solution to the "Argument xxx" problem.
+
+ * main.c (main): move position of debugging comment for -m flag.
+
+ * diff.c (diff): clear a static variable.
+
+ * client.c (send_file_names): check to see if we should send this
+ argument to the server based on the contents of the appropriate
+ CVSADM directory. This avoids "nothing known about foo" messages
+ and problems with duplicate modules names in multiple
+ repositories.
+ (send_a_repository): change method of calculating toplevel_repos
+ to support multiple CVSROOTs.
+ (start_server): clear some static variables.
+
+1998-08-28 Jim Meyering <meyering@ascend.com>
+
+ * sanity.sh (basicc-8, basicc-11): Use `.*' instead of explicit
+ `Operation not permitted'. Solaris2.5.1 gets a different error:
+ `Invalid argument'.
+
+1998-08-26 Eric M. Hopper
+
+ * sanity.sh: Set LC_COLLATE to "C".
+
+1998-08-25 Noel Cragg <noel@swish.red-bean.com>
+
+ * sanity.sh (multiroot): new set of tests to check the behavior of
+ multiroot.
+
+ * diff.c (diff): set options value to NULL after freeing to reset
+ the state for the next time around.
+
+1998-08-25 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ Fix problems with trying to rename an open file:
+ * rcs.c, rcs.h (RCS_setattic): New function.
+ * commit.c (remove_file, checkaddfile): Call it.
+
+1998-08-24 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * release.c (release): Use save_cwd and restore_cwd to get back to
+ where we started, rather than hoping that CVS_CHDIR ("..") will do
+ something useful. This removes the need for most of
+ release_delete, so remove that function and inline what is left.
+ * sanity.sh (basicc): Adjust tests for this fix, also some tests
+ with multiple arguments to "cvs release" (in the non-"-d"-case, it
+ would seem like the old code would CVS_CHDIR into directories and not
+ CVS_CHDIR back, but I'm not going to investigate this and it
+ should be a moot point with this fix.).
+
+ * sanity.sh (basicc): Add tests for a serious bug in "cvs release
+ -d .".
+
+ More error handling fixes:
+ * ignore.c (ignore_files): Check for errors from opendir and
+ readdir.
+ * find_names.c (Find_Names): Check for errors from find_rcs.
+ (find_rcs, find_dirs): Comment error handling better; also return
+ an error if we got one from readdir.
+ * filesubr.c (deep_remove_dir): Also check for errors from readdir.
+ * import.c (import_descend): Print message on error from opendir
+ or readdir.
+ * commit.c (remove_file): Check for errors from CVS_MKDIR and
+ CVS_RENAME.
+ (remove_file): No need to remove the file in the temporary
+ directory; server.c now informs time_stamp_server of what is going
+ on via CVS/Entries rather than a file with a kludged up timestamp.
+ * client.c, entries.c, login.c, logmsg.c, mkmodules.c, patch.c,
+ remove.c, update.c: Check for errors from unlink_file.
+ * mkmodules.c (write_dbmfile, rename_dbfile, rename_rcsfile):
+ Check for errors from fclose, CVS_RENAME, and CVS_STAT.
+ * mkmodules.c (checkout_file): Clarify error handling convention.
+ * mkmodules.c (mkmodules): Call checkout_file accordingly.
+ * entries.c (Entries_Open): Check for errors from fclose.
+
+1998-08-21 Ian Lance Taylor <ian@cygnus.com>
+
+ * import.c (import): Output suggested merge command using
+ cvs_output_tagged rather than just cvs_output. Don't put
+ CVSroot_cmdline in the log file.
+ * client.c (importmergecmd): New static struct.
+ (handle_mt): Handle +importmergecmd tag.
+ * sanity.sh (import): Use an explicit -d in importb-2, to test
+ whether it is reported in the suggested merge command.
+
+1998-08-20 Ian Lance Taylor <ian@cygnus.com>
+
+ * sanity.sh (import): Rewrite tests to use dotest.
+
+1998-08-20 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh: Add comments about binary files and cvs import.
+
+1998-08-19 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (importc): Use ${username} in one place where I had
+ missed it.
+
+ Make import -d work client/server:
+ * client.c, client.h (client_process_import_file): Take new
+ argument, for whether -d is specified, and send Checkin-time
+ request if it is set.
+ * import.c (import_descend): Pass it.
+ * main.c, cvs.h (date_to_internet): New function.
+ * server.c (server_modtime): Call date_to_internet.
+ * server.c (serve_checkin_time): New function.
+ (requests): Add "Checkin-time" request.
+ (serve_modified): If it was sent, set the timestamp in the
+ temporary directory.
+ * import.c (import): If the client sends a -d option, complain.
+ (import): For the server, always use the timestamps from the temp
+ directory.
+ (import): Don't send a -d option to the server.
+ * sanity.sh (importc): Add tests for import -d.
+
+Wed Aug 19 15:19:13 1998 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (unedit-without-baserev-5): use ${DOTSTAR} instead
+ of .* since we expect to match multiple lines.
+
+1998-08-19 Ian Lance Taylor <ian@cygnus.com>
+
+ * cvs.h (CVSroot_cmdline): Declare.
+ * root.c (CVSroot_cmdline): Define.
+ * main.c (main): Set CVSroot_cmdline if the -d option is used.
+ * import.c (import): If CVSroot_cmdline is not NULL, then mention
+ an explicit -d option in the suggested merge command line.
+
+Wed Aug 19 00:28:50 1998 Noel Cragg <noel@swish.red-bean.com>
+
+ * recurse.c (do_dir_proc): don't muck with CVS/Root directories
+ when running in server mode.
+ (do_recursion): same.
+
+ * main.c (main): add the command-line option `m' to help debug the
+ multiroot environment; it prints out the value of CVSROOT for each
+ iteration through the main loop. Also, changed the main loop so
+ that it gets executed only once when running in server mode (the
+ server will only deal with a single CVSROOT).
+
+ * recurse.c (do_recursion): change default for
+ PROCESS_THIS_DIRECTORY to true; we should always process a
+ directory's contents unless there's an existing CVS/Root file with
+ a different root than the current root to tell us otherwise.
+ (do_dir_proc): same.
+
+Tue Aug 18 14:30:59 1998 Noel Cragg <noel@swish.red-bean.com>
+
+ * recurse.c (do_recursion): check the current value of CVS/Root
+ and add it to our list of CVSROOTs if it doesn't exist. Decide
+ whether or not to process files in this directory based based on
+ the value of CURRENT_ROOT.
+ (do_dir_proc): same.
+
+ * main.c: add two new globals -- root_directories and current_root
+ -- which keep track of the values of CVSROOT we've seen and which
+ value of CVSROOT we're currently processing.
+ (main): put the main loop for stepping through cvsroot values
+ here, since we might need to send command-specific arguments for
+ every unique non-local cvsroot. Moved blocks of code around so
+ that one-time initializations happen first (outside the loop) and
+ the other stuff happens inside the loop.
+ (set_root_directory): helper function.
+
+ * cvs.h: add prototypes for root_directories and current_root, two
+ new globals for keeping track of multiple CVSROOT information.
+
+1998-08-18 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh: Don't assume that the shell leaves $^ unexpanded in
+ an unquoted here-document (suggested by Bart Schaefer to help when
+ zsh is the shell).
+
+1998-08-17 Ian Lance Taylor <ian@cygnus.com>
+
+ * commit.c (checkaddfile): Don't call fix_rcs_modes.
+ (fix_rcs_modes): Remove.
+
+1998-08-16 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * create_adm.c (Create_Admin): Don't condition traces on
+ SERVER_SUPPORT; SERVER_SUPPORT shouldn't do (much of) anything
+ independent of server_active.
+
+ * sanity.sh (binfiles3): New test, for yet another binary file
+ bug (sigh). Thanks to Jason Aten for reporting this one.
+
+1998-08-15 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * rcscmds.c (call_diff_write_output): Update to reflect new
+ calling convention for the write_output callback.
+
+1998-08-15 Jim Meyering <meyering@ascend.com>
+
+ * update.c (merge_file): Warn about failed unlink when not due
+ to ENOENT.
+
+ * server.h (CLIENT_SERVER_STR): New macro
+ * create_adm.c (Create_Admin): Use it.
+ * entries.c (Scratch_Entry, Register): Use it.
+ * filesubr.c (copy_file, xchmod, rename_file, unlink_file): Use it.
+ * history.c (history_write): Use it.
+ * modules.c (do_module): Use it.
+ * no_diff.c (No_Difference): Use it.
+ * run.c (run_popen): Use it.
+ * server.c (server_register): Use it.
+
+1998-08-14 Jim Meyering <meyering@ascend.com>
+
+ * hardlink.c (lookup_file_by_inode): Use existence_error rather than
+ comparing errno to ENOENT directly.
+
+ * client.c (copy_a_file): Unlink destination before doing copy.
+ * sanity.sh (join-readonly-conflict): New test for this -- it would
+ fail only in client/server mode.
+
+ * sanity.sh (rcsmerge-symlink-4): Don't use `test -L', it's not
+ portable. Instead, match against the output of `ls -l'.
+ (dotest tag8k-16): Simplify tag-construction code and at the same
+ time, avoid using expr's `length' and `substr' operators. Not
+ all versions of expr support those.
+
+1998-08-14 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * version.c: Bump version number to 1.10.0.1.
+
Thu Aug 13 11:15:24 1998 Noel Cragg <noel@swish.red-bean.com>
* version.c: Change version number to 1.10 and name to `Halibut'.
@@ -67,14 +1132,14 @@ Sun Jul 26 05:14:41 1998 Noel Cragg <noel@swish.red-bean.com>
does not create CVS directories at top-level (except for the
obvious "cvs co ."). Added a new configuration option to switch
between 1.9 and 1.9.2 behavior.
-
+
* recurse.c (do_argument_proc): new function.
(start_recursion): in the case that we've done a command from
top-level but have no CVS directory there, the behavior should be
the same as "cvs <cmd> dir1 dir2 dir3...". Make sure that the
appropriate "Argument" commands are sent to the server by calling
walklist with do_argument_proc.
-
+
* client.c (call_in_directory): only create the top-level CVS
directory when we're checking out "." explicitly. The server will
force creation of this directory in all other cases.
diff --git a/gnu/usr.bin/cvs/src/add.c b/gnu/usr.bin/cvs/src/add.c
index a4eed40d90c..fa569507ab6 100644
--- a/gnu/usr.bin/cvs/src/add.c
+++ b/gnu/usr.bin/cvs/src/add.c
@@ -240,8 +240,8 @@ add (argc, argv)
free (repository);
free (filedir);
}
- send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, 0, 0, SEND_BUILD_DIRS | SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("add\012", 0);
if (message)
free (message);
@@ -420,7 +420,7 @@ file `%s' will be added on branch `%s' from version %s",
re-adding file %s (in place of dead revision %s)",
finfo.fullname, vers->vn_rcs);
Register (entries, finfo.file, "0", vers->ts_user,
- NULL,
+ vers->options,
vers->tag, NULL, NULL);
++added_files;
}
diff --git a/gnu/usr.bin/cvs/src/admin.c b/gnu/usr.bin/cvs/src/admin.c
index 72cddac616f..3e5f61d1146 100644
--- a/gnu/usr.bin/cvs/src/admin.c
+++ b/gnu/usr.bin/cvs/src/admin.c
@@ -375,9 +375,9 @@ admin (argc, argv)
check_numeric (admin_data.delete_revs + 2, argc, argv);
p = strchr (admin_data.delete_revs + 2, ':');
- if (p != NULL && isdigit (p[1]))
+ if (p != NULL && isdigit ((unsigned char) p[1]))
check_numeric (p + 1, argc, argv);
- else if (p != NULL && p[1] == ':' && isdigit(p[2]))
+ else if (p != NULL && p[1] == ':' && isdigit ((unsigned char) p[2]))
check_numeric (p + 2, argc, argv);
}
@@ -414,8 +414,8 @@ admin (argc, argv)
for (i = 0; i < admin_data.ac; ++i)
send_arg (admin_data.av[i]);
- send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, 0, 0, SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("admin\012", 0);
err = get_responses_and_close ();
goto return_it;
@@ -492,7 +492,7 @@ admin_fileproc (callerdat, finfo)
if (admin_data->branch != NULL)
{
char *branch = &admin_data->branch[2];
- if (*branch != '\0' && ! isdigit (*branch))
+ if (*branch != '\0' && ! isdigit ((unsigned char) *branch))
{
branch = RCS_whatbranch (rcs, admin_data->branch + 2);
if (branch == NULL)
@@ -604,12 +604,9 @@ admin_fileproc (callerdat, finfo)
if (admin_data->kflag != NULL)
{
char *kflag = admin_data->kflag + 2;
- if (!rcs->expand || strcmp (rcs->expand, kflag) != 0)
- {
- if (rcs->expand)
- free (rcs->expand);
- rcs->expand = xstrdup (kflag);
- }
+ char *oldexpand = RCS_getexpand (rcs);
+ if (oldexpand == NULL || strcmp (oldexpand, kflag) != 0)
+ RCS_setexpand (rcs, kflag);
}
/* Handle miscellaneous options. TODO: decide whether any or all
diff --git a/gnu/usr.bin/cvs/src/client.c b/gnu/usr.bin/cvs/src/client.c
index 222e7f26534..02c31e223ae 100644
--- a/gnu/usr.bin/cvs/src/client.c
+++ b/gnu/usr.bin/cvs/src/client.c
@@ -148,6 +148,139 @@ static void handle_notified PROTO((char *, int));
static size_t try_read_from_server PROTO ((char *, size_t));
#endif /* CLIENT_SUPPORT */
+#ifdef CLIENT_SUPPORT
+
+/* We need to keep track of the list of directories we've sent to the
+ server. This list, along with the current CVSROOT, will help us
+ decide which command-line arguments to send. */
+List *dirs_sent_to_server = NULL;
+
+static int is_arg_a_parent_or_listed_dir PROTO((Node *, void *));
+
+static int
+is_arg_a_parent_or_listed_dir (n, d)
+ Node *n;
+ void *d;
+{
+ char *directory = n->key; /* name of the dir sent to server */
+ char *this_argv_elem = (char *) d; /* this argv element */
+
+ /* Say we should send this argument if the argument matches the
+ beginning of a directory name sent to the server. This way,
+ the server will know to start at the top of that directory
+ hierarchy and descend. */
+
+ if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0)
+ return 1;
+
+ return 0;
+}
+
+static int arg_should_not_be_sent_to_server PROTO((char *));
+
+/* Return nonzero if this argument should not be sent to the
+ server. */
+
+static int
+arg_should_not_be_sent_to_server (arg)
+ char *arg;
+{
+ /* Decide if we should send this directory name to the server. We
+ should always send argv[i] if:
+
+ 1) the list of directories sent to the server is empty (as it
+ will be for checkout, etc.).
+
+ 2) the argument is "."
+
+ 3) the argument is a file in the cwd and the cwd is checked out
+ from the current root
+
+ 4) the argument lies within one of the paths in
+ dirs_sent_to_server.
+
+ 4) */
+
+ if (list_isempty (dirs_sent_to_server))
+ return 0; /* always send it */
+
+ if (strcmp (arg, ".") == 0)
+ return 0; /* always send it */
+
+ /* We should send arg if it is one of the directories sent to the
+ server or the parent of one; this tells the server to descend
+ the hierarchy starting at this level. */
+ if (isdir (arg))
+ {
+ if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg))
+ return 0;
+
+ /* If arg wasn't a parent, we don't know anything about it (we
+ would have seen something related to it during the
+ send_files phase). Don't send it. */
+ return 1;
+ }
+
+ /* Try to decide whether we should send arg to the server by
+ checking the contents of the corresponding CVSADM directory. */
+ {
+ char *t, *this_root;
+
+ /* Calculate "dirname arg" */
+ for (t = arg + strlen (arg) - 1; t >= arg; t--)
+ {
+ if (ISDIRSEP(*t))
+ break;
+ }
+
+ /* Now we're either poiting to the beginning of the
+ string, or we found a path separator. */
+ if (t >= arg)
+ {
+ /* Found a path separator. */
+ char c = *t;
+ *t = '\0';
+
+ /* First, check to see if we sent this directory to the
+ server, because it takes less time than actually
+ opening the stuff in the CVSADM directory. */
+ if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir,
+ arg))
+ {
+ *t = c; /* make sure to un-truncate the arg */
+ return 0;
+ }
+
+ /* Since we didn't find it in the list, check the CVSADM
+ files on disk. */
+ this_root = Name_Root (arg, (char *) NULL);
+ *t = c;
+ }
+ else
+ {
+ /* We're at the beginning of the string. Look at the
+ CVSADM files in cwd. */
+ this_root = Name_Root ((char *) NULL, (char *) NULL);
+ }
+
+ /* Now check the value for root. */
+ if (this_root && current_root
+ && (strcmp (this_root, current_root) != 0))
+ {
+ /* Don't send this, since the CVSROOTs don't match. */
+ free (this_root);
+ return 1;
+ }
+ free (this_root);
+ }
+
+ /* OK, let's send it. */
+ return 0;
+}
+
+
+#endif /* CLIENT_SUPPORT */
+
#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
/* Shared with server. */
@@ -710,25 +843,6 @@ int gzip_level;
*/
int file_gzip_level;
-int filter_through_gzip (fd, dir, level, pidp)
- int fd, dir, level;
- pid_t *pidp;
-{
- static char buf[5] = "-";
- static char *gzip_argv[3] = { "gzip", buf };
-
- sprintf (buf+1, "%d", level);
- return filter_stream_through_program (fd, dir, &gzip_argv[0], pidp);
-}
-
-int filter_through_gunzip (fd, dir, pidp)
- int fd, dir;
- pid_t *pidp;
-{
- static char *gunzip_argv[3] = { "gzip", "-d" };
- return filter_stream_through_program (fd, dir, &gunzip_argv[0], pidp);
-}
-
#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
#ifdef CLIENT_SUPPORT
@@ -737,7 +851,7 @@ int filter_through_gunzip (fd, dir, pidp)
* The Repository for the top level of this command (not necessarily
* the CVSROOT, just the current directory at the time we do it).
*/
-static char *toplevel_repos;
+static char *toplevel_repos = NULL;
/* Working directory when we first started. Note: we could speed things
up on some systems by using savecwd.h here instead of just always
@@ -770,6 +884,13 @@ handle_error (args, len)
return;
}
++p;
+
+ /* Next we print the text of the message from the server. We
+ probably should be prefixing it with "server error" or some
+ such, because if it is something like "Out of memory", the
+ current behavior doesn't say which machine is out of
+ memory. */
+
len -= p - args;
something_printed = 0;
for (; len > 0; --len)
@@ -807,7 +928,7 @@ handle_valid_requests (args, len)
;
else
{
- if (rq->status == rq_enableme)
+ if (rq->flags & RQ_ENABLEME)
{
/*
* Server wants to know if we have this, to enable the
@@ -817,16 +938,17 @@ handle_valid_requests (args, len)
send_to_server ("\012", 0);
}
else
- rq->status = rq_supported;
+ rq->flags |= RQ_SUPPORTED;
}
p = q;
} while (q != NULL);
for (rq = requests; rq->name != NULL; ++rq)
{
- if (rq->status == rq_essential)
+ if ((rq->flags & RQ_SUPPORTED)
+ || (rq->flags & RQ_ENABLEME))
+ continue;
+ if (rq->flags & RQ_ESSENTIAL)
error (1, 0, "request `%s' not supported by server", rq->name);
- else if (rq->status == rq_optional)
- rq->status = rq_not_supported;
}
}
@@ -1210,7 +1332,14 @@ copy_a_file (data, ent_list, short_pathname, filename)
for(p = newname; *p; p++)
if(*p == '.' || *p == '#') *p = '_';
#endif
-
+ /* cvsclient.texi has said for a long time that newname must be in the
+ same directory. Wouldn't want a malicious or buggy server overwriting
+ ~/.profile, /etc/passwd, or anything like that. */
+ if (last_component (newname) != newname)
+ error (1, 0, "protocol error: Copy-file tried to specify directory");
+
+ if (unlink_file (newname) && !existence_error (errno))
+ error (0, errno, "unable to remove %s", newname);
copy_file (filename, newname);
free (newname);
}
@@ -1317,6 +1446,23 @@ static int updated_seen;
/* Filename from an "fname" tagged response within +updated/-updated. */
static char *updated_fname;
+/* This struct is used to hold data when reading the +importmergecmd
+ and -importmergecmd tags. We put the variables in a struct only
+ for namespace issues. FIXME: As noted above, we need to develop a
+ more systematic approach. */
+static struct
+{
+ /* Nonzero if we have seen +importmergecmd and not -importmergecmd. */
+ int seen;
+ /* Number of conflicts, from a "conflicts" tagged response. */
+ int conflicts;
+ /* First merge tag, from a "mergetag1" tagged response. */
+ char *mergetag1;
+ /* Second merge tag, from a "mergetag2" tagged response. */
+ char *mergetag2;
+ /* Repository, from a "repository" tagged response. */
+ char *repository;
+} importmergecmd;
/* Nonzero if we should arrange to return with a failure exit status. */
static int failure_exit;
@@ -1367,7 +1513,7 @@ handle_checksum (args, len)
stored_checksum_valid = 1;
}
-static int stored_mode_valid;
+/* Mode that we got in a "Mode" response (malloc'd), or NULL if none. */
static char *stored_mode;
static void handle_mode PROTO ((char *, int));
@@ -1377,12 +1523,9 @@ handle_mode (args, len)
char *args;
int len;
{
- if (stored_mode_valid)
- error (1, 0, "protocol error: duplicate Mode");
if (stored_mode != NULL)
- free (stored_mode);
+ error (1, 0, "protocol error: duplicate Mode");
stored_mode = xstrdup (args);
- stored_mode_valid = 1;
}
/* Nonzero if time was specified in Mod-time. */
@@ -1622,9 +1765,11 @@ update_entries (data_arg, ent_list, short_pathname, filename)
/* The Mode, Mod-time, and Checksum responses should not carry
over to a subsequent Created (or whatever) response, even
in the error case. */
- stored_mode_valid = 0;
if (stored_mode != NULL)
+ {
free (stored_mode);
+ stored_mode = NULL;
+ }
stored_modtime_valid = 0;
stored_checksum_valid = 0;
@@ -1701,7 +1846,10 @@ update_entries (data_arg, ent_list, short_pathname, filename)
read_from_server (buf, size);
if (use_gzip)
- gunzip_and_write (fd, short_pathname, buf, size);
+ {
+ if (gunzip_and_write (fd, short_pathname, buf, size))
+ error (1, 0, "aborting due to compression error");
+ }
else if (write (fd, buf, size) != size)
error (1, errno, "writing %s", short_pathname);
}
@@ -1747,7 +1895,11 @@ update_entries (data_arg, ent_list, short_pathname, filename)
backup = xmalloc (strlen (filename) + 5);
strcpy (backup, filename);
strcat (backup, "~");
- (void) unlink_file (backup);
+ if (unlink_file (backup) < 0
+ && !existence_error (errno))
+ {
+ error (0, errno, "cannot remove %s", backup);
+ }
if (!isfile (filename))
error (1, 0, "patch original file %s does not exist",
short_pathname);
@@ -1779,12 +1931,12 @@ update_entries (data_arg, ent_list, short_pathname, filename)
run_arg (temp_filename);
retcode = run_exec (DEVNULL, RUN_TTY, RUN_TTY, RUN_NORMAL);
}
- /* FIXME: should we really be silently ignoring errors? */
- (void) unlink_file (temp_filename);
+ if (unlink_file (temp_filename) < 0)
+ error (0, errno, "cannot remove %s", temp_filename);
if (retcode == 0)
{
- /* FIXME: should we really be silently ignoring errors? */
- (void) unlink_file (backup);
+ if (unlink_file (backup) < 0)
+ error (0, errno, "cannot remove %s", backup);
}
else
{
@@ -1798,8 +1950,9 @@ update_entries (data_arg, ent_list, short_pathname, filename)
path_tmp = xmalloc (strlen (filename) + 10);
strcpy (path_tmp, filename);
strcat (path_tmp, ".rej");
- /* FIXME: should we really be silently ignoring errors? */
- (void) unlink_file (path_tmp);
+ if (unlink_file (path_tmp) < 0
+ && !existence_error (errno))
+ error (0, errno, "cannot remove %s", path_tmp);
free (path_tmp);
error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
@@ -1842,15 +1995,16 @@ update_entries (data_arg, ent_list, short_pathname, filename)
{
if (stored_checksum_valid)
{
- struct MD5Context context;
+ struct cvs_MD5Context context;
unsigned char checksum[16];
/* We have a checksum. Check it before writing
the file out, so that we don't have to read it
back in again. */
- MD5Init (&context);
- MD5Update (&context, (unsigned char *) patchedbuf, patchedlen);
- MD5Final (checksum, &context);
+ cvs_MD5Init (&context);
+ cvs_MD5Update (&context,
+ (unsigned char *) patchedbuf, patchedlen);
+ cvs_MD5Final (checksum, &context);
if (memcmp (checksum, stored_checksum, 16) != 0)
{
error (0, 0,
@@ -1887,7 +2041,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (stored_checksum_valid && ! patch_failed)
{
FILE *e;
- struct MD5Context context;
+ struct cvs_MD5Context context;
unsigned char buf[8192];
unsigned len;
unsigned char checksum[16];
@@ -1906,12 +2060,12 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (e == NULL)
error (1, errno, "could not open %s", short_pathname);
- MD5Init (&context);
+ cvs_MD5Init (&context);
while ((len = fread (buf, 1, sizeof buf, e)) != 0)
- MD5Update (&context, buf, len);
+ cvs_MD5Update (&context, buf, len);
if (ferror (e))
error (1, errno, "could not read %s", short_pathname);
- MD5Final (checksum, &context);
+ cvs_MD5Final (checksum, &context);
fclose (e);
@@ -1958,10 +2112,13 @@ update_entries (data_arg, ent_list, short_pathname, filename)
free (buf);
}
- if (stored_mode_valid)
+ if (stored_mode != NULL)
+ {
change_mode (filename, stored_mode, 1);
- stored_mode_valid = 0;
-
+ free (stored_mode);
+ stored_mode = NULL;
+ }
+
if (stored_modtime_valid)
{
struct utimbuf t;
@@ -2263,7 +2420,20 @@ set_sticky (data, ent_list, short_pathname, filename)
FILE *f;
read_line (&tagspec);
- f = open_file (CVSADM_TAG, "w+");
+
+ /* FIXME-update-dir: error messages should include the directory. */
+ f = CVS_FOPEN (CVSADM_TAG, "w+");
+ if (f == NULL)
+ {
+ /* Making this non-fatal is a bit of a kludge (see dirs2
+ in testsuite). A better solution would be to avoid having
+ the server tell us about a directory we shouldn't be doing
+ anything with anyway (e.g. by handling directory
+ addition/removal better). */
+ error (0, errno, "cannot open %s", CVSADM_TAG);
+ free (tagspec);
+ return;
+ }
if (fprintf (f, "%s\n", tagspec) < 0)
error (1, errno, "writing %s", CVSADM_TAG);
if (fclose (f) == EOF)
@@ -2568,6 +2738,22 @@ send_repository (dir, repos, update_dir)
if (client_prune_dirs)
add_prune_candidate (update_dir);
+ /* Add a directory name to the list of those sent to the
+ server. */
+ if (update_dir && (*update_dir != '\0')
+ && (strcmp (update_dir, ".") != 0)
+ && (findnode (dirs_sent_to_server, update_dir) == NULL))
+ {
+ Node *n;
+ n = getnode ();
+ n->type = UNKNOWN;
+ n->key = xstrdup (update_dir);
+ n->data = NULL;
+
+ if (addnode (dirs_sent_to_server, n))
+ error (1, 0, "cannot add directory %s to list", n->key);
+ }
+
/* 80 is large enough for any of CVSADM_*. */
adm_name = xmalloc (strlen (dir) + 80);
@@ -2762,47 +2948,55 @@ send_a_repository (dir, repository, update_dir)
* directories (and cvs invoked on the containing
* directory). I'm not sure the latter case needs to
* work.
+ *
+ * 21 Aug 1998: Well, Mr. Above-Comment-Writer, it
+ * does need to work after all. When we are using the
+ * client in a multi-cvsroot environment, it will be
+ * fairly common that we have the above case (e.g.,
+ * cwd checked out from one repository but
+ * subdirectory checked out from another). We can't
+ * assume that by walking up a directory in our wd we
+ * necessarily walk up a directory in the repository.
*/
/*
* This gets toplevel_repos wrong for "cvs update ../foo"
* but I'm not sure toplevel_repos matters in that case.
*/
- int slashes_in_update_dir;
- int slashes_skipped;
- char *p;
- /*
- * Strip trailing slashes from the name of the update directory.
- * Otherwise, running `cvs update dir/' provokes the failure
- * `protocol error: illegal directory syntax in dir/' when
- * running in client/server mode.
- */
- strip_trailing_slashes (update_dir);
+ int repository_len, update_dir_len;
- slashes_in_update_dir = 0;
- for (p = update_dir; *p != '\0'; ++p)
- if (*p == '/')
- ++slashes_in_update_dir;
+ strip_trailing_slashes (update_dir);
- slashes_skipped = 0;
- p = repository + strlen (repository);
- while (1)
+ repository_len = strlen (repository);
+ update_dir_len = strlen (update_dir);
+
+ /* Try to remove the path components in UPDATE_DIR
+ from REPOSITORY. If the path elements don't exist
+ in REPOSITORY, or the removal of those path
+ elements mean that we "step above"
+ CVSroot_directory, set toplevel_repos to
+ CVSroot_directory. */
+ if ((repository_len > update_dir_len)
+ && (strcmp (repository + repository_len - update_dir_len,
+ update_dir) == 0)
+ /* TOPLEVEL_REPOS shouldn't be above CVSroot_directory */
+ && ((repository_len - update_dir_len)
+ > strlen (CVSroot_directory)))
{
- if (p == repository)
- error (1, 0,
- "internal error: not enough slashes in %s",
- repository);
- if (*p == '/')
- ++slashes_skipped;
- if (slashes_skipped < slashes_in_update_dir + 1)
- --p;
- else
- break;
+ /* The repository name contains UPDATE_DIR. Set
+ toplevel_repos to the repository name without
+ UPDATE_DIR. */
+
+ toplevel_repos = xmalloc (repository_len - update_dir_len);
+ /* Note that we don't copy the trailing '/'. */
+ strncpy (toplevel_repos, repository,
+ repository_len - update_dir_len - 1);
+ toplevel_repos[repository_len - update_dir_len - 1] = '\0';
+ }
+ else
+ {
+ toplevel_repos = xstrdup (CVSroot_directory);
}
- toplevel_repos = xmalloc (p - repository + 1);
- /* Note that we don't copy the trailing '/'. */
- strncpy (toplevel_repos, repository, p - repository);
- toplevel_repos[p - repository] = '\0';
}
}
}
@@ -3047,10 +3241,61 @@ handle_mt (args, len)
case '+':
if (strcmp (tag, "+updated") == 0)
updated_seen = 1;
+ else if (strcmp (tag, "+importmergecmd") == 0)
+ importmergecmd.seen = 1;
break;
case '-':
if (strcmp (tag, "-updated") == 0)
updated_seen = 0;
+ else if (strcmp (tag, "-importmergecmd") == 0)
+ {
+ char buf[80];
+
+ /* Now that we have gathered the information, we can
+ output the suggested merge command. */
+
+ if (importmergecmd.conflicts == 0
+ || importmergecmd.mergetag1 == NULL
+ || importmergecmd.mergetag2 == NULL
+ || importmergecmd.repository == NULL)
+ {
+ error (0, 0,
+ "invalid server: incomplete importmergecmd tags");
+ break;
+ }
+
+ sprintf (buf, "\n%d conflicts created by this import.\n",
+ importmergecmd.conflicts);
+ cvs_output (buf, 0);
+ cvs_output ("Use the following command to help the merge:\n\n",
+ 0);
+ cvs_output ("\t", 1);
+ cvs_output (program_name, 0);
+ if (CVSroot_cmdline != NULL)
+ {
+ cvs_output (" -d ", 0);
+ cvs_output (CVSroot_cmdline, 0);
+ }
+ cvs_output (" checkout -j", 0);
+ cvs_output (importmergecmd.mergetag1, 0);
+ cvs_output (" -j", 0);
+ cvs_output (importmergecmd.mergetag2, 0);
+ cvs_output (" ", 1);
+ cvs_output (importmergecmd.repository, 0);
+ cvs_output ("\n\n", 0);
+
+ /* Clear the static variables so that everything is
+ ready for any subsequent importmergecmd tag. */
+ importmergecmd.conflicts = 0;
+ free (importmergecmd.mergetag1);
+ importmergecmd.mergetag1 = NULL;
+ free (importmergecmd.mergetag2);
+ importmergecmd.mergetag2 = NULL;
+ free (importmergecmd.repository);
+ importmergecmd.repository = NULL;
+
+ importmergecmd.seen = 0;
+ }
break;
default:
if (updated_seen)
@@ -3073,6 +3318,21 @@ handle_mt (args, len)
or they reflect future extensions that we can
safely ignore. */
}
+ else if (importmergecmd.seen)
+ {
+ if (strcmp (tag, "conflicts") == 0)
+ importmergecmd.conflicts = atoi (text);
+ else if (strcmp (tag, "mergetag1") == 0)
+ importmergecmd.mergetag1 = xstrdup (text);
+ else if (strcmp (tag, "mergetag2") == 0)
+ importmergecmd.mergetag2 = xstrdup (text);
+ else if (strcmp (tag, "repository") == 0)
+ importmergecmd.repository = xstrdup (text);
+ /* Swallow all other tags. Either they are text for
+ which we are going to print our own version when we
+ see -importmergecmd, or they are future extensions
+ we can safely ignore. */
+ }
else if (strcmp (tag, "newline") == 0)
printf ("\n");
else if (text != NULL)
@@ -3424,7 +3684,7 @@ supported_request (name)
for (rq = requests; rq->name; rq++)
if (!strcmp (rq->name, name))
- return rq->status == rq_supported;
+ return (rq->flags & RQ_SUPPORTED) != 0;
error (1, 0, "internal error: testing support for unknown option?");
/* NOTREACHED */
return 0;
@@ -3490,7 +3750,6 @@ recv_line (sock, resultp)
int sock;
char **resultp;
{
- int c;
char *result;
size_t input_index = 0;
size_t result_size = 80;
@@ -3500,23 +3759,16 @@ recv_line (sock, resultp)
while (1)
{
char ch;
- if (recv (sock, &ch, 1, 0) < 0)
+ int n;
+ n = recv (sock, &ch, 1, 0);
+ if (n <= 0)
error (1, 0, "recv() from server %s: %s", CVSroot_hostname,
- SOCK_STRERROR (SOCK_ERRNO));
- c = ch;
-
- if (c == EOF)
- {
- free (result);
-
- /* It's end of file. */
- error (1, 0, "end of file from server");
- }
+ n == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO));
- if (c == '\012')
+ if (ch == '\012')
break;
- result[input_index++] = c;
+ result[input_index++] = ch;
while (input_index + 1 >= result_size)
{
result_size *= 2;
@@ -3535,6 +3787,28 @@ recv_line (sock, resultp)
return input_index;
}
+/* Connect to a forked server process. */
+
+void
+connect_to_forked_server (tofdp, fromfdp)
+ int *tofdp, *fromfdp;
+{
+ /* This is pretty simple. All we need to do is choose the correct
+ cvs binary and call piped_child. */
+
+ char *command[3];
+
+ command[0] = getenv ("CVS_SERVER");
+ if (! command[0])
+ command[0] = "cvs";
+
+ command[1] = "server";
+ command[2] = NULL;
+
+ if (! piped_child (command, tofdp, fromfdp))
+ error (1, 0, "could not fork server process");
+}
+
/* Connect to the authenticating server.
If VERIFY_ONLY is non-zero, then just verify that the password is
@@ -3960,6 +4234,13 @@ start_server ()
int tofd, fromfd;
char *log = getenv ("CVS_CLIENT_LOG");
+
+ /* Clear our static variables for this invocation. */
+ if (toplevel_repos != NULL)
+ free (toplevel_repos);
+ toplevel_repos = NULL;
+
+
/* Note that generally speaking we do *not* fall back to a different
way of connecting if the first one does not work. This is slow
(*really* slow on a 14.4kbps link); the clean way to have a CVS
@@ -4020,6 +4301,10 @@ the :server: access method is not supported by this port of CVS");
#endif
break;
+ case fork_method:
+ connect_to_forked_server (&tofd, &fromfd);
+ break;
+
default:
error (1, 0, "\
(start_server internal error): unknown access method");
@@ -4119,7 +4404,11 @@ the :server: access method is not supported by this port of CVS");
free (last_update_dir);
last_update_dir = NULL;
stored_checksum_valid = 0;
- stored_mode_valid = 0;
+ if (stored_mode != NULL)
+ {
+ free (stored_mode);
+ stored_mode = NULL;
+ }
if (strcmp (command_name, "init") != 0)
{
@@ -4648,9 +4937,10 @@ send_modified (file, short_pathname, vers)
{
size_t newsize = 0;
- read_and_gzip (fd, short_pathname, (unsigned char **)&buf,
- &bufsize, &newsize,
- file_gzip_level);
+ if (read_and_gzip (fd, short_pathname, (unsigned char **)&buf,
+ &bufsize, &newsize,
+ file_gzip_level))
+ error (1, 0, "aborting due to compression error");
if (close (fd) < 0)
error (0, errno, "warning: can't close %s", short_pathname);
@@ -5050,7 +5340,7 @@ send_file_names (argc, argv, flags)
int i;
int level;
int max_level;
-
+
/* The fact that we do this here as well as start_recursion is a bit
of a performance hit. Perhaps worth cleaning up someday. */
if (flags & SEND_EXPAND_WILD)
@@ -5091,6 +5381,9 @@ send_file_names (argc, argv, flags)
char *p = argv[i];
char *line = NULL;
+ if (arg_should_not_be_sent_to_server (argv[i]))
+ continue;
+
#ifdef FILENAMES_CASE_INSENSITIVE
/* We want to send the file name as it appears
in CVS/Entries. We put this inside an ifdef
@@ -5224,7 +5517,7 @@ client_import_setup (repository)
*/
int
client_process_import_file (message, vfile, vtag, targc, targv, repository,
- all_files_binary)
+ all_files_binary, modtime)
char *message;
char *vfile;
char *vtag;
@@ -5232,6 +5525,9 @@ client_process_import_file (message, vfile, vtag, targc, targv, repository,
char *targv[];
char *repository;
int all_files_binary;
+
+ /* Nonzero for "import -d". */
+ int modtime;
{
char *update_dir;
char *fullname;
@@ -5281,6 +5577,28 @@ client_process_import_file (message, vfile, vtag, targc, targv, repository,
error (0, 0,
"warning: ignoring -k options due to server limitations");
}
+ if (modtime)
+ {
+ if (supported_request ("Checkin-time"))
+ {
+ struct stat sb;
+ char *rcsdate;
+ char netdate[MAXDATELEN];
+
+ if (CVS_STAT (vfile, &sb) < 0)
+ error (1, errno, "cannot stat %s", fullname);
+ rcsdate = date_from_time_t (sb.st_mtime);
+ date_to_internet (netdate, rcsdate);
+ free (rcsdate);
+
+ send_to_server ("Checkin-time ", 0);
+ send_to_server (netdate, 0);
+ send_to_server ("\012", 1);
+ }
+ else
+ error (0, 0,
+ "warning: ignoring -d option due to server limitations");
+ }
send_modified (vfile, fullname, &vers);
if (vers.options != NULL)
free (vers.options);
@@ -5466,27 +5784,15 @@ option_with_arg (option, arg)
We then convert that to the format required in the protocol
(including the "-D" option) and send it. According to
- cvsclient.texi, RFC 822/1123 format is preferred, but for now we
- use the format that we always have, for
- conservatism/laziness/paranoia. As far as I know all servers
- support the RFC 822/1123 format, so probably there would be no
- particular danger in switching. */
+ cvsclient.texi, RFC 822/1123 format is preferred. */
void
client_senddate (date)
const char *date;
{
- int year, month, day, hour, minute, second;
- char buf[100];
-
- if (sscanf (date, SDATEFORM, &year, &month, &day, &hour, &minute, &second)
- != 6)
- {
- error (1, 0, "client_senddate: sscanf failed on date");
- }
+ char buf[MAXDATELEN];
- sprintf (buf, "%d/%d/%d %d:%d:%d GMT", month, day, year,
- hour, minute, second);
+ date_to_internet (buf, (char *)date);
option_with_arg ("-D", buf);
}
diff --git a/gnu/usr.bin/cvs/src/client.h b/gnu/usr.bin/cvs/src/client.h
index 996dc63366c..c323cf38ffb 100644
--- a/gnu/usr.bin/cvs/src/client.h
+++ b/gnu/usr.bin/cvs/src/client.h
@@ -6,8 +6,6 @@ extern int change_mode PROTO((char *, char *, int));
extern int gzip_level;
extern int file_gzip_level;
-extern int filter_through_gzip PROTO((int, int, int, pid_t *));
-extern int filter_through_gunzip PROTO((int, int, pid_t *));
#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
@@ -195,7 +193,8 @@ extern char *toplevel_wd;
extern void client_import_setup PROTO((char *repository));
extern int client_process_import_file
PROTO((char *message, char *vfile, char *vtag,
- int targc, char *targv[], char *repository, int all_files_binary));
+ int targc, char *targv[], char *repository, int all_files_binary,
+ int modtime));
extern void client_import_done PROTO((void));
extern void client_notify PROTO((char *, char *, char *, int, char *));
#endif /* CLIENT_SUPPORT */
diff --git a/gnu/usr.bin/cvs/src/create_adm.c b/gnu/usr.bin/cvs/src/create_adm.c
index c51785c317c..7f8f581b0b9 100644
--- a/gnu/usr.bin/cvs/src/create_adm.c
+++ b/gnu/usr.bin/cvs/src/create_adm.c
@@ -36,15 +36,13 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
char *reposcopy;
char *tmp;
-#ifdef SERVER_SUPPORT
if (trace)
{
- fprintf (stderr, "%c-> Create_Admin (%s, %s, %s, %s, %s, %d, %d)\n",
- (server_active) ? 'S' : ' ',
+ fprintf (stderr, "%s-> Create_Admin (%s, %s, %s, %s, %s, %d, %d)\n",
+ CLIENT_SERVER_STR,
dir, update_dir, repository, tag ? tag : "",
date ? date : "", nonbranch, warn);
}
-#endif
if (noexec)
return 0;
diff --git a/gnu/usr.bin/cvs/src/cvsrc.c b/gnu/usr.bin/cvs/src/cvsrc.c
index e35ec219b72..accc53fa761 100644
--- a/gnu/usr.bin/cvs/src/cvsrc.c
+++ b/gnu/usr.bin/cvs/src/cvsrc.c
@@ -65,6 +65,11 @@ read_cvsrc (argc, argv, cmdname)
/* determine filename for ~/.cvsrc */
homedir = get_homedir ();
+ /* If we can't find a home directory, ignore ~/.cvsrc. This may
+ make tracking down problems a bit of a pain, but on the other
+ hand it might be obnoxious to complain when CVS will function
+ just fine without .cvsrc (and many users won't even know what
+ .cvsrc is). */
if (!homedir)
return;
@@ -96,7 +101,7 @@ read_cvsrc (argc, argv, cmdname)
/* stop if we match the current command */
if (!strncmp (line, cmdname, command_len)
- && isspace (*(line + command_len)))
+ && isspace ((unsigned char) *(line + command_len)))
{
found = 1;
break;
diff --git a/gnu/usr.bin/cvs/src/diff.c b/gnu/usr.bin/cvs/src/diff.c
index 341c04c248f..aa35885af30 100644
--- a/gnu/usr.bin/cvs/src/diff.c
+++ b/gnu/usr.bin/cvs/src/diff.c
@@ -40,7 +40,13 @@ static enum diff_file diff_file_nodiff PROTO ((struct file_info *finfo,
static int diff_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static void diff_mark_errors PROTO((int err));
+
+/* Global variables. Would be cleaner if we just put this stuff in a
+ struct like log.c does. */
+
+/* Command line tags, from -r option. Points into argv. */
static char *diff_rev1, *diff_rev2;
+/* Command line dates, from -D option. Malloc'd. */
static char *diff_date1, *diff_date2;
static char *use_rev1, *use_rev2;
static int have_rev1_label, have_rev2_label;
@@ -224,15 +230,19 @@ diff (argc, argv)
* non-recursive/recursive diff.
*/
- /* For server, need to be able to do this command more than once
- (according to the protocol spec, even if the current client
- doesn't use it). */
+ /* Clean out our global variables (multiroot can call us multiple
+ times and the server can too, if the client sends several
+ diff commands). */
if (opts == NULL)
{
opts_allocated = 1;
opts = xmalloc (opts_allocated);
}
opts[0] = '\0';
+ diff_rev1 = NULL;
+ diff_rev2 = NULL;
+ diff_date1 = NULL;
+ diff_date2 = NULL;
optind = 0;
while ((c = getopt_long (argc, argv,
@@ -353,17 +363,18 @@ diff (argc, argv)
if (diff_date2)
client_senddate (diff_date2);
- send_file_names (argc, argv, SEND_EXPAND_WILD);
-
/* Send the current files unless diffing two revs from the archive */
if (diff_rev2 == NULL && diff_date2 == NULL)
send_files (argc, argv, local, 0, 0);
else
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
+
send_to_server ("diff\012", 0);
err = get_responses_and_close ();
free (options);
+ options = NULL;
return (err);
}
#endif
@@ -386,6 +397,13 @@ diff (argc, argv)
/* clean up */
free (options);
+ options = NULL;
+
+ if (diff_date1 != NULL)
+ free (diff_date1);
+ if (diff_date2 != NULL)
+ free (diff_date2);
+
return (err);
}
diff --git a/gnu/usr.bin/cvs/src/edit.c b/gnu/usr.bin/cvs/src/edit.c
index aa0f4c48142..9d9a588cd2a 100644
--- a/gnu/usr.bin/cvs/src/edit.c
+++ b/gnu/usr.bin/cvs/src/edit.c
@@ -89,8 +89,8 @@ watch_onoff (argc, argv)
if (local)
send_arg ("-l");
- send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server (turning_on ? "watch-on\012" : "watch-off\012", 0);
return get_responses_and_close ();
}
@@ -876,7 +876,8 @@ notify_do (type, filename, who, val, watches, repository)
error (0, errno, "cannot close %s", usersname);
}
free (usersname);
- free (line);
+ if (line != NULL)
+ free (line);
if (args.notifyee == NULL)
{
@@ -1008,29 +1009,29 @@ editors_fileproc (callerdat, finfo)
if (them == NULL)
return 0;
- fputs (finfo->fullname, stdout);
+ cvs_output (finfo->fullname, 0);
p = them;
while (1)
{
- putc ('\t', stdout);
+ cvs_output ("\t", 1);
while (*p != '>' && *p != '\0')
- putc (*p++, stdout);
+ cvs_output (p++, 1);
if (*p == '\0')
{
/* Only happens if attribute is misformed. */
- putc ('\n', stdout);
+ cvs_output ("\n", 1);
break;
}
++p;
- putc ('\t', stdout);
+ cvs_output ("\t", 1);
while (1)
{
while (*p != '+' && *p != ',' && *p != '\0')
- putc (*p++, stdout);
+ cvs_output (p++, 1);
if (*p == '\0')
{
- putc ('\n', stdout);
+ cvs_output ("\n", 1);
goto out;
}
if (*p == ',')
@@ -1039,9 +1040,9 @@ editors_fileproc (callerdat, finfo)
break;
}
++p;
- putc ('\t', stdout);
+ cvs_output ("\t", 1);
}
- putc ('\n', stdout);
+ cvs_output ("\n", 1);
}
out:;
return 0;
@@ -1086,8 +1087,8 @@ editors (argc, argv)
if (local)
send_arg ("-l");
- send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("editors\012", 0);
return get_responses_and_close ();
}
diff --git a/gnu/usr.bin/cvs/src/entries.c b/gnu/usr.bin/cvs/src/entries.c
index aeab31356c3..7e258a97dc2 100644
--- a/gnu/usr.bin/cvs/src/entries.c
+++ b/gnu/usr.bin/cvs/src/entries.c
@@ -157,7 +157,9 @@ write_entries (list)
rename_file (entfilename, CVSADM_ENT);
/* now, remove the log file */
- unlink_file (CVSADM_ENTLOG);
+ if (unlink_file (CVSADM_ENTLOG) < 0
+ && !existence_error (errno))
+ error (0, errno, "cannot remove %s", CVSADM_ENTLOG);
}
/*
@@ -171,12 +173,8 @@ Scratch_Entry (list, fname)
Node *node;
if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> Scratch_Entry(%s)\n",
- (server_active) ? 'S' : ' ', fname);
-#else
- (void) fprintf (stderr, "-> Scratch_Entry(%s)\n", fname);
-#endif
+ (void) fprintf (stderr, "%s-> Scratch_Entry(%s)\n",
+ CLIENT_SERVER_STR, fname);
/* hashlookup to see if it is there */
if ((node = findnode_fn (list, fname)) != NULL)
@@ -231,18 +229,11 @@ Register (list, fname, vn, ts, options, tag, date, ts_conflict)
if (trace)
{
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
- (server_active) ? 'S' : ' ',
+ (void) fprintf (stderr, "%s-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
+ CLIENT_SERVER_STR,
fname, vn, ts ? ts : "",
ts_conflict ? "+" : "", ts_conflict ? ts_conflict : "",
options, tag ? tag : "", date ? date : "");
-#else
- (void) fprintf (stderr, "-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
- fname, vn, ts ? ts : "",
- ts_conflict ? "+" : "", ts_conflict ? ts_conflict : "",
- options, tag ? tag : "", date ? date : "");
-#endif
}
entnode = Entnode_Create (ENT_FILE, fname, vn, ts, options, tag, date,
@@ -252,7 +243,15 @@ Register (list, fname, vn, ts, options, tag, date, ts_conflict)
if (!noexec)
{
entfilename = CVSADM_ENTLOG;
- entfile = open_file (entfilename, "a");
+ entfile = CVS_FOPEN (entfilename, "a");
+
+ if (entfile == NULL)
+ {
+ /* Warning, not error, as in write_entries. */
+ /* FIXME-update-dir: should be including update_dir in message. */
+ error (0, errno, "cannot open %s", entfilename);
+ return;
+ }
if (fprintf (entfile, "A ") < 0)
error (1, errno, "cannot write %s", entfilename);
@@ -507,7 +506,9 @@ Entries_Open (aflag, update_dir)
(void) AddEntryNode (entries, ent);
}
- fclose (fpin);
+ if (fclose (fpin) < 0)
+ /* FIXME-update-dir: should include update_dir in message. */
+ error (0, errno, "cannot close %s", CVSADM_ENT);
}
fpin = CVS_FOPEN (CVSADM_ENTLOG, "r");
@@ -535,7 +536,9 @@ Entries_Open (aflag, update_dir)
}
}
do_rewrite = 1;
- fclose (fpin);
+ if (fclose (fpin) < 0)
+ /* FIXME-update-dir: should include update_dir in message. */
+ error (0, errno, "cannot close %s", CVSADM_ENTLOG);
}
/* Update the list private data to indicate whether subdirectory
diff --git a/gnu/usr.bin/cvs/src/error.c b/gnu/usr.bin/cvs/src/error.c
index 9dcc162261e..64b686cae44 100644
--- a/gnu/usr.bin/cvs/src/error.c
+++ b/gnu/usr.bin/cvs/src/error.c
@@ -61,8 +61,6 @@ void exit ();
extern char *strerror ();
#endif
-extern int vasprintf ();
-
void
error_exit PROTO ((void))
{
@@ -80,7 +78,10 @@ error_exit PROTO ((void))
}
/* Print the program name and error message MESSAGE, which is a printf-style
- format string with optional args.
+ format string with optional args. This is a very limited printf subset:
+ %s, %d, %c, %x and %% only (without anything between the % and the s,
+ d, &c). Callers who want something fancier can use sprintf.
+
If ERRNUM is nonzero, print its corresponding system error message.
Exit with status EXIT_FAILURE if STATUS is nonzero. If MESSAGE is "",
no need to print a message.
@@ -100,7 +101,7 @@ error_exit PROTO ((void))
/* VARARGS */
void
-#if defined (HAVE_VPRINTF) && defined (__STDC__)
+#if defined (__STDC__)
error (int status, int errnum, const char *message, ...)
#else
error (status, errnum, message, va_alist)
@@ -110,116 +111,84 @@ error (status, errnum, message, va_alist)
va_dcl
#endif
{
- /* Prevent strtoul (via int_vasprintf) from clobbering it. */
int save_errno = errno;
-#ifdef HAVE_VPRINTF
if (message[0] != '\0')
{
va_list args;
- char *mess = NULL;
- char *entire;
- size_t len;
-
- VA_START (args, message);
- vasprintf (&mess, message, args);
- va_end (args);
-
- if (mess == NULL)
+ const char *p;
+ char *q;
+ char *str;
+ int num;
+ unsigned int unum;
+ int ch;
+ unsigned char buf[100];
+
+ cvs_outerr (program_name, 0);
+ if (command_name && *command_name)
{
- entire = NULL;
- status = 1;
+ cvs_outerr (" ", 1);
+ if (status != 0)
+ cvs_outerr ("[", 1);
+ cvs_outerr (command_name, 0);
+ if (status != 0)
+ cvs_outerr (" aborted]", 0);
}
- else
+ cvs_outerr (": ", 2);
+
+ VA_START (args, message);
+ p = message;
+ while ((q = strchr (p, '%')) != NULL)
{
- len = strlen (mess) + strlen (program_name) + 80;
- if (command_name != NULL)
- len += strlen (command_name);
- if (errnum != 0)
- len += strlen (strerror (errnum));
- entire = malloc (len);
- if (entire == NULL)
- {
- free (mess);
- status = 1;
- }
- else
+ static const char msg[] =
+ "\ninternal error: bad % in error()\n";
+ if (q - p > 0)
+ cvs_outerr (p, q - p);
+
+ switch (q[1])
{
- strcpy (entire, program_name);
- if (command_name != NULL && command_name[0] != '\0')
- {
- strcat (entire, " ");
- if (status != 0)
- strcat (entire, "[");
- strcat (entire, command_name);
- if (status != 0)
- strcat (entire, " aborted]");
- }
- strcat (entire, ": ");
- strcat (entire, mess);
- if (errnum != 0)
- {
- strcat (entire, ": ");
- strcat (entire, strerror (errnum));
- }
- strcat (entire, "\n");
- free (mess);
+ case 's':
+ str = va_arg (args, char *);
+ cvs_outerr (str, strlen (str));
+ break;
+ case 'd':
+ num = va_arg (args, int);
+ sprintf (buf, "%d", num);
+ cvs_outerr (buf, strlen (buf));
+ break;
+ case 'x':
+ unum = va_arg (args, unsigned int);
+ sprintf (buf, "%x", unum);
+ cvs_outerr (buf, strlen (buf));
+ break;
+ case 'c':
+ ch = va_arg (args, int);
+ buf[0] = ch;
+ cvs_outerr (buf, 1);
+ break;
+ case '%':
+ cvs_outerr ("%", 1);
+ break;
+ default:
+ cvs_outerr (msg, sizeof (msg) - 1);
+ /* Don't just keep going, because q + 1 might point to the
+ terminating '\0'. */
+ goto out;
}
+ p = q + 2;
}
- cvs_outerr (entire ? entire : "out of memory\n", 0);
- if (entire != NULL)
- free (entire);
- }
-
-#else /* No HAVE_VPRINTF */
- /* I think that all relevant systems have vprintf these days. But
- just in case, I'm leaving this code here. */
-
- if (message[0] != '\0')
- {
- FILE *out = stderr;
+ cvs_outerr (p, strlen (p));
+ out:
+ va_end (args);
- if (error_use_protocol)
+ if (errnum != 0)
{
- out = stdout;
- printf ("E ");
+ cvs_outerr (": ", 2);
+ cvs_outerr (strerror (errnum), 0);
}
-
- if (command_name && *command_name)
- {
- if (status)
- fprintf (out, "%s [%s aborted]: ", program_name, command_name);
- else
- fprintf (out, "%s %s: ", program_name, command_name);
- }
- else
- fprintf (out, "%s: ", program_name);
-
-#ifdef HAVE_VPRINTF
- VA_START (args, message);
- vfprintf (out, message, args);
- va_end (args);
-#else
-#ifdef HAVE_DOPRNT
- _doprnt (message, &args, out);
-#else
- fprintf (out, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
-#endif
- if (errnum)
- fprintf (out, ": %s", strerror (errnum));
- putc ('\n', out);
-
- /* In the error_use_protocol case, this probably does
- something useful. In most other cases, I suspect it is a
- noop (either stderr is line buffered or we haven't written
- anything to stderr) or unnecessary (if stderr is not line
- buffered, maybe there is a reason....). */
- fflush (out);
+ cvs_outerr ("\n", 1);
}
-#endif /* No HAVE_VPRINTF */
-
if (status)
error_exit ();
errno = save_errno;
diff --git a/gnu/usr.bin/cvs/src/expand_path.c b/gnu/usr.bin/cvs/src/expand_path.c
index 5cf414e35d7..25e561cc0e6 100644
--- a/gnu/usr.bin/cvs/src/expand_path.c
+++ b/gnu/usr.bin/cvs/src/expand_path.c
@@ -43,7 +43,7 @@ variable_set (nameval)
Node *node;
p = nameval;
- while (isalnum (*p) || *p == '_')
+ while (isalnum ((unsigned char) *p) || *p == '_')
++p;
if (*p != '=')
error (1, 0, "illegal character in user variable name in %s", nameval);
@@ -133,7 +133,7 @@ expand_path (name, file, line)
{
if (flag
? *s =='}'
- : isalnum (*s) == 0 && *s != '_')
+ : isalnum ((unsigned char) *s) == 0 && *s != '_')
break;
doff = d - mybuf;
expand_string (&mybuf, &mybuf_size, doff + 1);
@@ -214,6 +214,9 @@ expand_path (name, file, line)
t = ps->pw_dir;
#endif
}
+ if (t == NULL)
+ error (1, 0, "cannot find home directory");
+
doff = d - buf;
expand_string (&buf, &buf_size, doff + 1);
d = buf + doff;
@@ -283,7 +286,7 @@ expand_variable (name, file, line)
return Editor;
else if (strcmp (name, "USER") == 0)
return getcaller ();
- else if (isalpha (name[0]))
+ else if (isalpha ((unsigned char) name[0]))
{
/* These names are reserved for future versions of CVS,
so that is why it is an error. */
diff --git a/gnu/usr.bin/cvs/src/filesubr.c b/gnu/usr.bin/cvs/src/filesubr.c
index 1c24b2f64fa..f3da62a5efd 100644
--- a/gnu/usr.bin/cvs/src/filesubr.c
+++ b/gnu/usr.bin/cvs/src/filesubr.c
@@ -34,12 +34,8 @@ copy_file (from, to)
int fdin, fdout;
if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> copy(%s,%s)\n",
- (server_active) ? 'S' : ' ', from, to);
-#else
- (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to);
-#endif
+ (void) fprintf (stderr, "%s-> copy(%s,%s)\n",
+ CLIENT_SERVER_STR, from, to);
if (noexec)
return;
@@ -377,14 +373,9 @@ xchmod (fname, writable)
}
if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> chmod(%s,%o)\n",
- (server_active) ? 'S' : ' ', fname,
+ (void) fprintf (stderr, "%s-> chmod(%s,%o)\n",
+ CLIENT_SERVER_STR, fname,
(unsigned int) mode);
-#else
- (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname,
- (unsigned int) mode);
-#endif
if (noexec)
return;
@@ -401,12 +392,8 @@ rename_file (from, to)
const char *to;
{
if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> rename(%s,%s)\n",
- (server_active) ? 'S' : ' ', from, to);
-#else
- (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to);
-#endif
+ (void) fprintf (stderr, "%s-> rename(%s,%s)\n",
+ CLIENT_SERVER_STR, from, to);
if (noexec)
return;
@@ -422,12 +409,8 @@ unlink_file (f)
const char *f;
{
if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> unlink(%s)\n",
- (server_active) ? 'S' : ' ', f);
-#else
- (void) fprintf (stderr, "-> unlink(%s)\n", f);
-#endif
+ (void) fprintf (stderr, "%s-> unlink(%s)\n",
+ CLIENT_SERVER_STR, f);
if (noexec)
return (0);
@@ -506,6 +489,7 @@ deep_remove_dir (path)
*/
return -1;
+ errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
char *buf;
@@ -539,6 +523,15 @@ deep_remove_dir (path)
}
}
free (buf);
+
+ errno = 0;
+ }
+ if (errno != 0)
+ {
+ int save_errno = errno;
+ closedir (dirp);
+ errno = save_errno;
+ return -1;
}
closedir (dirp);
return rmdir (path);
diff --git a/gnu/usr.bin/cvs/src/find_names.c b/gnu/usr.bin/cvs/src/find_names.c
index 4fa795a1f27..6fb927bf6a9 100644
--- a/gnu/usr.bin/cvs/src/find_names.c
+++ b/gnu/usr.bin/cvs/src/find_names.c
@@ -50,6 +50,11 @@ add_entries_proc (node, closure)
return (0);
}
+/* Find files in the repository and/or working directory. On error,
+ may either print a nonfatal error and return NULL, or just give
+ a fatal error. On success, return non-NULL (even if it is an empty
+ list). */
+
List *
Find_Names (repository, which, aflag, optentries)
char *repository;
@@ -85,7 +90,10 @@ Find_Names (repository, which, aflag, optentries)
{
/* search the repository */
if (find_rcs (repository, files) != 0)
- error (1, errno, "cannot open directory %s", repository);
+ {
+ error (0, errno, "cannot open directory %s", repository);
+ goto error_exit;
+ }
/* search the attic too */
if (which & W_ATTIC)
@@ -93,7 +101,11 @@ Find_Names (repository, which, aflag, optentries)
char *dir;
dir = xmalloc (strlen (repository) + sizeof (CVSATTIC) + 10);
(void) sprintf (dir, "%s/%s", repository, CVSATTIC);
- (void) find_rcs (dir, files);
+ if (find_rcs (dir, files) != 0
+ && !existence_error (errno))
+ /* For now keep this a fatal error, seems less useful
+ for access control than the case above. */
+ error (1, errno, "cannot open directory %s", dir);
free (dir);
}
}
@@ -101,6 +113,9 @@ Find_Names (repository, which, aflag, optentries)
/* sort the list into alphabetical order and return it */
sortlist (files, fsortcmp);
return (files);
+ error_exit:
+ dellist (&files);
+ return NULL;
}
/*
@@ -235,7 +250,9 @@ Find_Directories (repository, which, entries)
/*
* Finds all the ,v files in the argument directory, and adds them to the
* files list. Returns 0 for success and non-zero if the argument directory
- * cannot be opened.
+ * cannot be opened, in which case errno is set to indicate the error.
+ * In the error case LIST is left in some reasonable state (unchanged, or
+ * containing the files which were found before the error occurred).
*/
static int
find_rcs (dir, list)
@@ -251,6 +268,7 @@ find_rcs (dir, list)
return (1);
/* read the dir, grabbing the ,v files */
+ errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
if (CVS_FNMATCH (RCSPAT, dp->d_name, 0) == 0)
@@ -265,6 +283,14 @@ find_rcs (dir, list)
if (addnode (list, p) != 0)
freenode (p);
}
+ errno = 0;
+ }
+ if (errno != 0)
+ {
+ int save_errno = errno;
+ (void) closedir (dirp);
+ errno = save_errno;
+ return 1;
}
(void) closedir (dirp);
return (0);
@@ -275,7 +301,7 @@ find_rcs (dir, list)
* the specified list. Sub-directories without a CVS administration
* directory are optionally ignored. If ENTRIES is not NULL, all
* files on the list are ignored. Returns 0 for success or 1 on
- * error.
+ * error, in which case errno is set to indicate the error.
*/
static int
find_dirs (dir, list, checkadm, entries)
@@ -305,6 +331,7 @@ find_dirs (dir, list, checkadm, entries)
return (1);
/* read the dir, grabbing sub-dirs */
+ errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
if (strcmp (dp->d_name, ".") == 0 ||
@@ -312,34 +339,34 @@ find_dirs (dir, list, checkadm, entries)
strcmp (dp->d_name, CVSATTIC) == 0 ||
strcmp (dp->d_name, CVSLCK) == 0 ||
strcmp (dp->d_name, CVSREP) == 0)
- continue;
+ goto do_it_again;
/* findnode() is going to be significantly faster than stat()
because it involves no system calls. That is why we bother
with the entries argument, and why we check this first. */
if (entries != NULL && findnode (entries, dp->d_name) != NULL)
- continue;
+ goto do_it_again;
if (skip_emptydir
&& strcmp (dp->d_name, CVSNULLREPOS) == 0)
- continue;
+ goto do_it_again;
#ifdef DT_DIR
if (dp->d_type != DT_DIR)
{
if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
- continue;
+ goto do_it_again;
#endif
/* don't bother stating ,v files */
if (CVS_FNMATCH (RCSPAT, dp->d_name, 0) == 0)
- continue;
+ goto do_it_again;
expand_string (&tmp,
&tmp_size,
strlen (dir) + strlen (dp->d_name) + 10);
sprintf (tmp, "%s/%s", dir, dp->d_name);
if (!isdir (tmp))
- continue;
+ goto do_it_again;
#ifdef DT_DIR
}
@@ -354,12 +381,12 @@ find_dirs (dir, list, checkadm, entries)
{
/* we're either unknown or a symlink at this point */
if (dp->d_type == DT_LNK)
- continue;
+ goto do_it_again;
#endif
/* Note that we only get here if we already set tmp
above. */
if (islink (tmp))
- continue;
+ goto do_it_again;
#ifdef DT_DIR
}
#endif
@@ -371,7 +398,7 @@ find_dirs (dir, list, checkadm, entries)
+ sizeof (CVSADM) + 10));
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
if (!isdir (tmp))
- continue;
+ goto do_it_again;
}
/* put it in the list */
@@ -380,6 +407,16 @@ find_dirs (dir, list, checkadm, entries)
p->key = xstrdup (dp->d_name);
if (addnode (list, p) != 0)
freenode (p);
+
+ do_it_again:
+ errno = 0;
+ }
+ if (errno != 0)
+ {
+ int save_errno = errno;
+ (void) closedir (dirp);
+ errno = save_errno;
+ return 1;
}
(void) closedir (dirp);
if (tmp != NULL)
diff --git a/gnu/usr.bin/cvs/src/hardlink.c b/gnu/usr.bin/cvs/src/hardlink.c
index b279aa9c3d0..046cf3a470a 100644
--- a/gnu/usr.bin/cvs/src/hardlink.c
+++ b/gnu/usr.bin/cvs/src/hardlink.c
@@ -66,7 +66,7 @@ lookup_file_by_inode (filepath)
inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1);
if (stat (file, &sb) < 0)
{
- if (errno == ENOENT)
+ if (existence_error (errno))
{
/* The file doesn't exist; we may be doing an update on a
file that's been removed. A nonexistent file has no
diff --git a/gnu/usr.bin/cvs/src/history.c b/gnu/usr.bin/cvs/src/history.c
index 8f1e254720e..bc7d1a64207 100644
--- a/gnu/usr.bin/cvs/src/history.c
+++ b/gnu/usr.bin/cvs/src/history.c
@@ -719,12 +719,8 @@ history_write (type, update_dir, revs, name, repository)
}
if (trace)
-#ifdef SERVER_SUPPORT
- fprintf (stderr, "%c-> fopen(%s,a)\n",
- (server_active) ? 'S' : ' ', fname);
-#else
- fprintf (stderr, "-> fopen(%s,a)\n", fname);
-#endif
+ fprintf (stderr, "%s-> fopen(%s,a)\n",
+ CLIENT_SERVER_STR, fname);
if (noexec)
goto out;
fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
@@ -971,7 +967,7 @@ expand_modules ()
* Return a pointer to the character following the newline.
*/
-#define NEXT_BAR(here) do { while (isspace(*line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return(rtn); *(line - 1) = '\0'; } while (0)
+#define NEXT_BAR(here) do { while (isspace((unsigned char) *line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return(rtn); *(line - 1) = '\0'; } while (0)
static char *
fill_hrec (line, hr)
@@ -985,7 +981,7 @@ fill_hrec (line, hr)
unsigned long date;
memset ((char *) hr, 0, sizeof (*hr));
- while (isspace (*line))
+ while (isspace ((unsigned char) *line))
line++;
if (!(rtn = strchr (line, '\n')))
return ("");
@@ -1062,7 +1058,7 @@ read_hrecs (fname)
*(cp + i) = '\0';
for (cp2 = cp; cp2 - cp < i; cp2++)
{
- if (*cp2 != '\n' && !isprint (*cp2))
+ if (*cp2 != '\n' && !isprint ((unsigned char) *cp2))
*cp2 = ' ';
}
diff --git a/gnu/usr.bin/cvs/src/import.c b/gnu/usr.bin/cvs/src/import.c
index 77c617a195c..862dae1e2d1 100644
--- a/gnu/usr.bin/cvs/src/import.c
+++ b/gnu/usr.bin/cvs/src/import.c
@@ -94,6 +94,17 @@ import (argc, argv)
command_name);
break;
case 'd':
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ {
+ /* CVS 1.10 and older clients will send this, but it
+ doesn't do any good. So tell the user we can't
+ cope, rather than silently losing. */
+ error (0, 0,
+ "warning: not setting the time of import from the file");
+ error (0, 0, "due to client limitations");
+ }
+#endif
use_file_modtime = 1;
break;
case 'b':
@@ -132,6 +143,20 @@ import (argc, argv)
if (argc < 3)
usage (import_usage);
+#ifdef SERVER_SUPPORT
+ /* This is for handling the Checkin-time request. It might seem a
+ bit odd to enable the use_file_modtime code even in the case
+ where Checkin-time was not sent for a particular file. The
+ effect is that we use the time of upload, rather than the time
+ when we call RCS_checkin. Since those times are both during
+ CVS's run, that seems OK, and it is easier to implement than
+ putting the "was Checkin-time sent" flag in CVS/Entries or some
+ such place. */
+
+ if (server_active)
+ use_file_modtime = 1;
+#endif
+
for (i = 1; i < argc; i++) /* check the tags for validity */
{
int j;
@@ -170,7 +195,7 @@ import (argc, argv)
* must only have two dots in it (like "1.1.1").
*/
for (cp = vbranch; *cp != '\0'; cp++)
- if (!isdigit (*cp) && *cp != '.')
+ if (!isdigit ((unsigned char) *cp) && *cp != '.')
error (1, 0, "%s is not a numeric branch", vbranch);
if (numdots (vbranch) != 2)
error (1, 0, "Only branches with two dots are supported: %s", vbranch);
@@ -212,9 +237,6 @@ import (argc, argv)
{
int err;
- if (use_file_modtime)
- send_arg("-d");
-
if (vbranch[0] != '\0')
option_with_arg ("-b", vbranch);
if (message)
@@ -275,29 +297,52 @@ import (argc, argv)
{
if (!really_quiet)
{
- char buf[80];
- sprintf (buf, "\n%d conflicts created by this import.\n",
- conflicts);
- cvs_output (buf, 0);
- cvs_output ("Use the following command to help the merge:\n\n",
- 0);
- cvs_output ("\t", 1);
- cvs_output (program_name, 0);
- cvs_output (" checkout -j", 0);
- cvs_output (argv[1], 0);
- cvs_output (":yesterday -j", 0);
- cvs_output (argv[1], 0);
- cvs_output (" ", 1);
- cvs_output (argv[0], 0);
- cvs_output ("\n\n", 0);
+ char buf[20];
+ char *buf2;
+
+ cvs_output_tagged ("+importmergecmd", NULL);
+ cvs_output_tagged ("newline", NULL);
+ sprintf (buf, "%d", conflicts);
+ cvs_output_tagged ("conflicts", buf);
+ cvs_output_tagged ("text", " conflicts created by this import.");
+ cvs_output_tagged ("newline", NULL);
+ cvs_output_tagged ("text",
+ "Use the following command to help the merge:");
+ cvs_output_tagged ("newline", NULL);
+ cvs_output_tagged ("newline", NULL);
+ cvs_output_tagged ("text", "\t");
+ cvs_output_tagged ("text", program_name);
+ if (CVSroot_cmdline != NULL)
+ {
+ cvs_output_tagged ("text", " -d ");
+ cvs_output_tagged ("text", CVSroot_cmdline);
+ }
+ cvs_output_tagged ("text", " checkout -j");
+ buf2 = xmalloc (strlen (argv[1]) + 20);
+ sprintf (buf2, "%s:yesterday", argv[1]);
+ cvs_output_tagged ("mergetag1", buf2);
+ free (buf2);
+ cvs_output_tagged ("text", " -j");
+ cvs_output_tagged ("mergetag2", argv[1]);
+ cvs_output_tagged ("text", " ");
+ cvs_output_tagged ("repository", argv[0]);
+ cvs_output_tagged ("newline", NULL);
+ cvs_output_tagged ("newline", NULL);
+ cvs_output_tagged ("-importmergecmd", NULL);
}
+ /* FIXME: I'm not sure whether we need to put this information
+ into the loginfo. If we do, then note that it does not
+ report any required -d option. There is no particularly
+ clean way to tell the server about the -d option used by
+ the client. */
(void) fprintf (logfp, "\n%d conflicts created by this import.\n",
conflicts);
(void) fprintf (logfp,
"Use the following command to help the merge:\n\n");
- (void) fprintf (logfp, "\t%s checkout -j%s:yesterday -j%s %s\n\n",
- program_name, argv[1], argv[1], argv[0]);
+ (void) fprintf (logfp, "\t%s checkout ", program_name);
+ (void) fprintf (logfp, "-j%s:yesterday -j%s %s\n\n",
+ argv[1], argv[1], argv[0]);
}
else
{
@@ -340,9 +385,9 @@ import (argc, argv)
return (err);
}
-/*
- * process all the files in ".", then descend into other directories.
- */
+/* Process all the files in ".", then descend into other directories.
+ Returns 0 for success, or >0 on error (in which case a message
+ will have been printed). */
static int
import_descend (message, vtag, targc, targv)
char *message;
@@ -361,25 +406,27 @@ import_descend (message, vtag, targc, targv)
if ((dirp = CVS_OPENDIR (".")) == NULL)
{
+ error (0, errno, "cannot open directory");
err++;
}
else
{
+ errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0)
- continue;
+ goto one_more_time_boys;
#ifdef SERVER_SUPPORT
/* CVS directories are created in the temp directory by
server.c because it doesn't special-case import. So
don't print a message about them, regardless of -I!. */
if (server_active && strcmp (dp->d_name, CVSADM) == 0)
- continue;
+ goto one_more_time_boys;
#endif
if (ign_name (dp->d_name))
{
add_log ('I', dp->d_name);
- continue;
+ goto one_more_time_boys;
}
if (
@@ -418,12 +465,20 @@ import_descend (message, vtag, targc, targv)
vtag, targc, targv,
repository,
keyword_opt != NULL &&
- keyword_opt[0] == 'b');
+ keyword_opt[0] == 'b',
+ use_file_modtime);
else
#endif
err += process_import_file (message, dp->d_name,
vtag, targc, targv);
}
+ one_more_time_boys:
+ errno = 0;
+ }
+ if (errno != 0)
+ {
+ error (0, errno, "cannot read directory");
+ ++err;
}
(void) closedir (dirp);
}
@@ -874,7 +929,7 @@ get_comment (user)
*/
(void) strcpy (suffix_path, cp);
for (cp = suffix_path; *cp; cp++)
- if (isupper (*cp))
+ if (isupper ((unsigned char) *cp))
*cp = tolower (*cp);
suffix = suffix_path;
}
diff --git a/gnu/usr.bin/cvs/src/log.c b/gnu/usr.bin/cvs/src/log.c
index 4502e268bb9..7c57c77ced6 100644
--- a/gnu/usr.bin/cvs/src/log.c
+++ b/gnu/usr.bin/cvs/src/log.c
@@ -233,8 +233,8 @@ cvslog (argc, argv)
for (i = 1; i < argc && argv[i][0] == '-'; i++)
send_arg (argv[i]);
- send_file_names (argc - i, argv + i, SEND_EXPAND_WILD);
send_files (argc - i, argv + i, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc - i, argv + i, SEND_EXPAND_WILD);
send_to_server ("log\012", 0);
err = get_responses_and_close ();
@@ -591,11 +591,11 @@ log_fileproc (callerdat, finfo)
cvs_output ("\n\t", 2);
cp2 = cp;
- while (! isspace (*cp2) && *cp2 != '\0')
+ while (! isspace ((unsigned char) *cp2) && *cp2 != '\0')
++cp2;
cvs_output (cp, cp2 - cp);
cp = cp2;
- while (isspace (*cp) && *cp != '\0')
+ while (isspace ((unsigned char) *cp) && *cp != '\0')
++cp;
}
}
@@ -734,7 +734,7 @@ log_expand_revlist (rcs, revlist, default_branch)
char *branch;
/* Print just the head of the branch. */
- if (isdigit (r->first[0]))
+ if (isdigit ((unsigned char) r->first[0]))
nr->first = RCS_getbranch (rcs, r->first, 1);
else
{
@@ -761,7 +761,7 @@ log_expand_revlist (rcs, revlist, default_branch)
}
else
{
- if (r->first == NULL || isdigit (r->first[0]))
+ if (r->first == NULL || isdigit ((unsigned char) r->first[0]))
nr->first = xstrdup (r->first);
else
{
@@ -780,7 +780,7 @@ log_expand_revlist (rcs, revlist, default_branch)
if (r->last == r->first)
nr->last = xstrdup (nr->first);
- else if (r->last == NULL || isdigit (r->last[0]))
+ else if (r->last == NULL || isdigit ((unsigned char) r->last[0]))
nr->last = xstrdup (r->last);
else
{
@@ -1356,12 +1356,12 @@ version_compare (v1, v2, len)
while (*v1 == '0')
++v1;
- for (d1 = 0; isdigit (v1[d1]); ++d1)
+ for (d1 = 0; isdigit ((unsigned char) v1[d1]); ++d1)
;
while (*v2 == '0')
++v2;
- for (d2 = 0; isdigit (v2[d2]); ++d2)
+ for (d2 = 0; isdigit ((unsigned char) v2[d2]); ++d2)
;
if (d1 != d2)
diff --git a/gnu/usr.bin/cvs/src/login.c b/gnu/usr.bin/cvs/src/login.c
index 4ffce36d0fd..46707e24003 100644
--- a/gnu/usr.bin/cvs/src/login.c
+++ b/gnu/usr.bin/cvs/src/login.c
@@ -48,7 +48,14 @@ construct_cvspass_filename ()
homedir = get_homedir ();
if (! homedir)
{
- error (1, errno, "could not find out home directory");
+ /* FIXME? This message confuses a lot of users, at least
+ on Win95 (which doesn't set HOMEDRIVE and HOMEPATH like
+ NT does). I suppose the answer for Win95 is to store the
+ passwords in the registry or something (??). And .cvsrc
+ and such too? Wonder what WinCVS does (about .cvsrc, the
+ right thing for a GUI is to just store the password in
+ memory only)... */
+ error (1, 0, "could not find out home directory");
return (char *) NULL;
}
@@ -246,7 +253,8 @@ login (argc, argv)
/* FIXME: rename_file would make more sense (e.g. almost
always faster). */
copy_file (tmp_name, passfile);
- unlink_file (tmp_name);
+ if (unlink_file (tmp_name) < 0)
+ error (0, errno, "cannot remove %s", tmp_name);
chmod (passfile, 0600);
free (tmp_name);
@@ -437,6 +445,8 @@ logout (argc, argv)
*/
passfile = construct_cvspass_filename ();
+ /* FIXME: This should not be in /tmp; that is almost surely a security
+ hole. Probably should just keep it in memory. */
tmp_name = cvs_temp_name ();
if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL)
{
@@ -476,14 +486,16 @@ logout (argc, argv)
if (! found)
{
printf ("Entry not found for %s\n", CVSroot_original);
- unlink_file (tmp_name);
+ if (unlink_file (tmp_name) < 0)
+ error (0, errno, "cannot remove %s", tmp_name);
}
else
{
/* FIXME: rename_file would make more sense (e.g. almost
always faster). */
copy_file (tmp_name, passfile);
- unlink_file (tmp_name);
+ if (unlink_file (tmp_name) < 0)
+ error (0, errno, "cannot remove %s", tmp_name);
chmod (passfile, 0600);
}
return 0;
diff --git a/gnu/usr.bin/cvs/src/logmsg.c b/gnu/usr.bin/cvs/src/logmsg.c
index 67194be4f47..6d45ca31cd3 100644
--- a/gnu/usr.bin/cvs/src/logmsg.c
+++ b/gnu/usr.bin/cvs/src/logmsg.c
@@ -446,7 +446,8 @@ do_verify (message, repository)
{
/* Since following error() exits, delete the temp file
now. */
- unlink_file (fname);
+ if (unlink_file (fname) < 0)
+ error (0, errno, "cannot remove %s", fname);
error (1, retcode == -1 ? errno : 0,
"Message verification failed");
@@ -455,7 +456,8 @@ do_verify (message, repository)
/* Delete the temp file */
- unlink_file (fname);
+ if (unlink_file (fname) < 0)
+ error (0, errno, "cannot remove %s", fname);
free (fname);
}
}
diff --git a/gnu/usr.bin/cvs/src/modules.c b/gnu/usr.bin/cvs/src/modules.c
index de95f7eed59..e322086591e 100644
--- a/gnu/usr.bin/cvs/src/modules.c
+++ b/gnu/usr.bin/cvs/src/modules.c
@@ -147,8 +147,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
+ strlen (msg)
+ (where ? strlen (where) : 0)
+ (extra_arg ? strlen (extra_arg) : 0));
- sprintf (buf, "%c-> do_module (%s, %s, %s, %s)\n",
- (server_active) ? 'S' : ' ',
+ sprintf (buf, "%s-> do_module (%s, %s, %s, %s)\n",
+ CLIENT_SERVER_STR,
mname, msg, where ? where : "",
extra_arg ? extra_arg : "");
cvs_outerr (buf, 0);
@@ -192,13 +192,13 @@ do_module (db, mname, m_type, msg, callback_proc, where,
{
do
*cp-- = '\0';
- while (isspace (*cp));
+ while (isspace ((unsigned char) *cp));
}
else
{
/* Always strip trailing spaces */
cp = strchr (val.dptr, '\0');
- while (cp > val.dptr && isspace(*--cp))
+ while (cp > val.dptr && isspace ((unsigned char) *--cp))
*cp = '\0';
}
@@ -315,7 +315,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
{
do
*cp2-- = '\0';
- while (isspace (*cp2));
+ while (isspace ((unsigned char) *cp2));
}
value = val.dptr;
@@ -362,7 +362,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
spec_opt = cp + 1; /* save the options for later */
if (cp != value) /* strip whitespace if necessary */
- while (isspace (*--cp))
+ while (isspace ((unsigned char) *--cp))
*cp = '\0';
if (cp == value)
@@ -609,13 +609,13 @@ module `%s' is a request for a file in a module which is not a directory",
/* strip whitespace off the end */
do
*cp = '\0';
- while (isspace (*--cp));
+ while (isspace ((unsigned char) *--cp));
}
else
next_opt = NULL;
/* strip whitespace from front */
- while (isspace (*spec_opt))
+ while (isspace ((unsigned char) *spec_opt))
spec_opt++;
if (*spec_opt == '\0')
@@ -836,15 +836,15 @@ save_d (k, ks, d, ds)
cp = d;
*(cp + ds) = '\0'; /* Assumes an extra byte at end of static dbm buffer */
- while (isspace (*cp))
+ while (isspace ((unsigned char) *cp))
cp++;
/* Turn <spaces> into one ' ' -- makes the rest of this routine simpler */
while (*cp)
{
- if (isspace (*cp))
+ if (isspace ((unsigned char) *cp))
{
*cp2++ = ' ';
- while (isspace (*cp))
+ while (isspace ((unsigned char) *cp))
cp++;
}
else
diff --git a/gnu/usr.bin/cvs/src/myndbm.c b/gnu/usr.bin/cvs/src/myndbm.c
index 6b15e77412e..f674ac11d9f 100644
--- a/gnu/usr.bin/cvs/src/myndbm.c
+++ b/gnu/usr.bin/cvs/src/myndbm.c
@@ -263,7 +263,7 @@ mydbm_load_file (fp, list)
if (value[0] == '#')
continue; /* comment line */
vp = value;
- while (*vp && isspace (*vp))
+ while (*vp && isspace ((unsigned char) *vp))
vp++;
if (*vp == '\0')
continue; /* empty line */
@@ -277,12 +277,12 @@ mydbm_load_file (fp, list)
char *kp;
kp = vp;
- while (*vp && !isspace (*vp))
+ while (*vp && !isspace ((unsigned char) *vp))
vp++;
*vp++ = '\0'; /* NULL terminate the key */
p->type = NDBMNODE;
p->key = xstrdup (kp);
- while (*vp && isspace (*vp))
+ while (*vp && isspace ((unsigned char) *vp))
vp++; /* skip whitespace to value */
if (*vp == '\0')
{
diff --git a/gnu/usr.bin/cvs/src/no_diff.c b/gnu/usr.bin/cvs/src/no_diff.c
index 078343ea6ed..dfca372f5cb 100644
--- a/gnu/usr.bin/cvs/src/no_diff.c
+++ b/gnu/usr.bin/cvs/src/no_diff.c
@@ -82,13 +82,8 @@ No_Difference (finfo, vers)
/* Need to call unlink myself because the noexec variable
* has been set to 1. */
if (trace)
- (void) fprintf (stderr, "%c-> unlink (%s)\n",
-#ifdef SERVER_SUPPORT
- (server_active) ? 'S' : ' ',
-#else
- ' ',
-#endif
- tocvsPath);
+ (void) fprintf (stderr, "%s-> unlink (%s)\n",
+ CLIENT_SERVER_STR, tocvsPath);
if ( CVS_UNLINK (tocvsPath) < 0)
error (0, errno, "could not remove %s", tocvsPath);
}
diff --git a/gnu/usr.bin/cvs/src/options.h.in b/gnu/usr.bin/cvs/src/options.h.in
index 67e8c40aa04..a3ee047ac3a 100644
--- a/gnu/usr.bin/cvs/src/options.h.in
+++ b/gnu/usr.bin/cvs/src/options.h.in
@@ -88,13 +88,12 @@
* repository, change the contents of CVS/Root files in your
* checked-out code, and CVS will work without problems.
*
- * This is likely to be the default in the future, but we want to give
- * people who may be relying on absolute pathnames time to update
- * their scripts/software.
+ * Therefore, RELATIVE_REPOS is now the default. In the future, this
+ * is likely to disappear entirely as a compile-time (or other) option,
+ * so if you have other software which relies on absolute pathnames,
+ * update them.
*/
-#ifndef RELATIVE_REPOS
-/* #define RELATIVE_REPOS */
-#endif
+#define RELATIVE_REPOS 1
/*
* When committing or importing files, you must enter a log message.
diff --git a/gnu/usr.bin/cvs/src/rcs.h b/gnu/usr.bin/cvs/src/rcs.h
index f92988f4b1e..0a281613848 100644
--- a/gnu/usr.bin/cvs/src/rcs.h
+++ b/gnu/usr.bin/cvs/src/rcs.h
@@ -184,6 +184,7 @@ RCSNode *RCS_parse PROTO((const char *file, const char *repos));
RCSNode *RCS_parsercsfile PROTO((char *rcsfile));
void RCS_fully_parse PROTO((RCSNode *));
void RCS_reparsercsfile PROTO((RCSNode *, FILE **, struct rcsbuffer *));
+extern int RCS_setattic PROTO ((RCSNode *, int));
char *RCS_check_kflag PROTO((const char *arg));
char *RCS_getdate PROTO((RCSNode * rcs, char *date, int force_tag_match));
@@ -211,6 +212,7 @@ char *RCS_branch_head PROTO ((RCSNode *rcs, char *rev));
int RCS_isdead PROTO((RCSNode *, const char *));
char *RCS_getexpand PROTO ((RCSNode *));
+void RCS_setexpand PROTO ((RCSNode *, char *));
int RCS_checkout PROTO ((RCSNode *, char *, char *, char *, char *, char *,
RCSCHECKOUTPROC, void *));
int RCS_checkin PROTO ((RCSNode *rcs, char *workfile, char *message,
diff --git a/gnu/usr.bin/cvs/src/recurse.c b/gnu/usr.bin/cvs/src/recurse.c
index d88bf2be30a..ff8bafd990f 100644
--- a/gnu/usr.bin/cvs/src/recurse.c
+++ b/gnu/usr.bin/cvs/src/recurse.c
@@ -13,9 +13,6 @@
#include "fileattr.h"
#include "edit.h"
-#ifdef CLIENT_SUPPORT
-static int do_argument_proc PROTO((Node * p, void *closure));
-#endif
static int do_dir_proc PROTO((Node * p, void *closure));
static int do_file_proc PROTO((Node * p, void *closure));
static void addlist PROTO((List ** listp, char *key));
@@ -61,23 +58,6 @@ struct frame_and_entries {
List *entries;
};
-#ifdef CLIENT_SUPPORT
-/* This is a callback to send "Argument" commands to the server in the
- case we've done a "cvs update" or "cvs commit" in a top-level
- directory where there is no CVSADM directory. */
-
-static int
-do_argument_proc (p, closure)
- Node *p;
- void *closure;
-{
- char *dir = p->key;
- send_to_server ("Argument ", 0);
- send_to_server (dir, 0);
- send_to_server ("\012", 1);
- return 0;
-}
-#endif
/* Start a recursive command.
@@ -127,6 +107,9 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
int dosrcs;
{
int i, err = 0;
+#ifdef CLIENT_SUPPORT
+ List *args_to_send_when_finished = NULL;
+#endif
List *files_by_dir = NULL;
struct recursion_frame frame;
@@ -169,6 +152,29 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
if (argc == 0)
{
+ int just_subdirs = (which & W_LOCAL) && !isdir (CVSADM);
+
+#ifdef CLIENT_SUPPORT
+ if (!just_subdirs
+ && CVSroot_cmdline == NULL
+ && client_active)
+ {
+ char *root = Name_Root (NULL, update_dir);
+ if (strcmp (root, current_root) != 0)
+ /* We're skipping this directory because it is for
+ a different root. Therefore, we just want to
+ do the subdirectories only. Processing files would
+ cause a working directory from one repository to be
+ processed against a different repository, which could
+ cause all kinds of spurious conflicts and such.
+
+ Question: what about the case of "cvs update foo"
+ where we process foo/bar and not foo itself? That
+ seems to be handled somewhere (else) but why should
+ it be a separate case? Needs investigation... */
+ just_subdirs = 1;
+ }
+#endif
/*
* There were no arguments, so we'll probably just recurse. The
@@ -177,7 +183,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
* process each of the sub-directories, so we pretend like we were
* called with the list of sub-dirs of the current dir as args
*/
- if ((which & W_LOCAL) && !isdir (CVSADM))
+ if (just_subdirs)
{
dirlist = Find_Directories ((char *) NULL, W_LOCAL, (List *) NULL);
/* If there are no sub-directories, there is a certain logic in
@@ -204,17 +210,21 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
appropriate "Argument" commands to the server. In
this case, that won't have happened, so we need to
do it here. While this example uses "update", this
- generalizes to other commands. */
-
- err += walklist (dirlist, do_argument_proc, NULL);
+ generalizes to other commands. */
+
+ /* This is the same call to Find_Directories as above.
+ FIXME: perhaps it would be better to write a
+ function that duplicates a list. */
+ args_to_send_when_finished = Find_Directories ((char *) NULL,
+ W_LOCAL,
+ (List *) NULL);
}
#endif
}
else
addlist (&dirlist, ".");
- err += do_recursion (&frame);
- goto out;
+ goto do_the_work;
}
@@ -335,14 +345,146 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
/* then do_recursion on the dirlist. */
if (dirlist != NULL)
+ {
+ do_the_work:
err += do_recursion (&frame);
-
+ }
+
/* Free the data which expand_wild allocated. */
free_names (&argc, argv);
- out:
free (update_dir);
update_dir = NULL;
+
+#ifdef CLIENT_SUPPORT
+ if (args_to_send_when_finished != NULL)
+ {
+ /* FIXME (njc): in the multiroot case, we don't want to send
+ argument commands for those top-level directories which do
+ not contain any subdirectories which have files checked out
+ from current_root. If we do, and two repositories have a
+ module with the same name, nasty things could happen.
+
+ This is hard. Perhaps we should send the Argument commands
+ later in this procedure, after we've had a chance to notice
+ which directores we're using (after do_recursion has been
+ called once). This means a _lot_ of rewriting, however.
+
+ What we need to do for that to happen is descend the tree
+ and construct a list of directories which are checked out
+ from current_cvsroot. Now, we eliminate from the list all
+ of those directories which are immediate subdirectories of
+ another directory in the list. To say that the opposite
+ way, we keep the directories which are not immediate
+ subdirectories of any other in the list. Here's a picture:
+
+ a
+ / \
+ B C
+ / \
+ D e
+ / \
+ F G
+ / \
+ H I
+
+ The node in capitals are those directories which are
+ checked out from current_cvsroot. We want the list to
+ contain B, C, F, and G. D, H, and I are not included,
+ because their parents are also checked out from
+ current_cvsroot.
+
+ The algorithm should be:
+
+ 1) construct a tree of all directory names where each
+ element contains a directory name and a flag which notes if
+ that directory is checked out from current_cvsroot
+
+ a0
+ / \
+ B1 C1
+ / \
+ D1 e0
+ / \
+ F1 G1
+ / \
+ H1 I1
+
+ 2) Recursively descend the tree. For each node, recurse
+ before processing the node. If the flag is zero, do
+ nothing. If the flag is 1, check the node's parent. If
+ the parent's flag is one, change the current entry's flag
+ to zero.
+
+ a0
+ / \
+ B1 C1
+ / \
+ D0 e0
+ / \
+ F1 G1
+ / \
+ H0 I0
+
+ 3) Walk the tree and spit out "Argument" commands to tell
+ the server which directories to munge.
+
+ Yuck. It's not clear this is worth spending time on, since
+ we might want to disable cvs commands entirely from
+ directories that do not have CVSADM files...
+
+ Anyways, the solution as it stands has modified server.c
+ (dirswitch) to create admin files [via server.c
+ (create_adm_p)] in all path elements for a client's
+ "Directory xxx" command, which forces the server to descend
+ and serve the files there. client.c (send_file_names) has
+ also been modified to send only those arguments which are
+ appropriate to current_root.
+
+ */
+
+ /* Construct a fake argc/argv pair. */
+
+ int our_argc = 0, i;
+ char **our_argv = NULL;
+
+ if (! list_isempty (args_to_send_when_finished))
+ {
+ Node *head, *p;
+
+ head = args_to_send_when_finished->list;
+
+ /* count the number of nodes */
+ i = 0;
+ for (p = head->next; p != head; p = p->next)
+ i++;
+ our_argc = i;
+
+ /* create the argument vector */
+ our_argv = (char **) xmalloc (sizeof (char *) * our_argc);
+
+ /* populate it */
+ i = 0;
+ for (p = head->next; p != head; p = p->next)
+ our_argv[i++] = xstrdup (p->key);
+ }
+
+ /* We don't want to expand widcards, since we've just created
+ a list of directories directly from the filesystem. */
+ send_file_names (our_argc, our_argv, 0);
+
+ /* Free our argc/argv. */
+ if (our_argv != NULL)
+ {
+ for (i = 0; i < our_argc; i++)
+ free (our_argv[i]);
+ free (our_argv);
+ }
+
+ dellist (&args_to_send_when_finished);
+ }
+#endif
+
return (err);
}
@@ -359,6 +501,7 @@ do_recursion (frame)
char *srepository;
List *entries = NULL;
int should_readlock;
+ int process_this_directory = 1;
/* do nothing if told */
if (frame->flags == R_SKIP_ALL)
@@ -410,6 +553,55 @@ do_recursion (frame)
server_pause_check();
#endif
+ /* Check the value in CVSADM_ROOT and see if it's in the list. If
+ not, add it to our lists of CVS/Root directories and do not
+ process the files in this directory. Otherwise, continue as
+ usual. THIS_ROOT might be NULL if we're doing an initial
+ checkout -- check before using it. The default should be that
+ we process a directory's contents and only skip those contents
+ if a CVS/Root file exists.
+
+ If we're running the server, we want to process all
+ directories, since we're guaranteed to have only one CVSROOT --
+ our own. */
+
+#ifdef SERVER_SUPPORT
+ if (! server_active
+
+ /* If -d was specified, it should override CVS/Root.
+
+ In the single-repository case, it is long-standing CVS behavior
+ and makes sense - the user might want another access method,
+ another server (which mounts the same repository), &c.
+
+ In the multiple-repository case, -d overrides all CVS/Root
+ files. That is the only plausible generalization I can
+ think of. */
+ && CVSroot_cmdline == NULL)
+#endif
+ {
+ char *this_root = Name_Root ((char *) NULL, update_dir);
+ if (this_root != NULL)
+ {
+ if (findnode (root_directories, this_root) == NULL)
+ {
+ /* Add it to our list. */
+
+ Node *n = getnode ();
+ n->type = UNKNOWN;
+ n->key = xstrdup (this_root);
+
+ if (addnode (root_directories, n))
+ error (1, 0, "cannot add new CVSROOT %s", this_root);
+
+ }
+
+ process_this_directory = (strcmp (current_root, this_root) == 0);
+
+ free (this_root);
+ }
+ }
+
/*
* Fill in repository with the current repository
*/
@@ -468,12 +660,26 @@ do_recursion (frame)
repository = Name_Repository ((char *) NULL, update_dir);
/* find the files and fill in entries if appropriate */
- filelist = Find_Names (repository, lwhich, frame->aflag, &entries);
+ if (process_this_directory)
+ {
+ filelist = Find_Names (repository, lwhich, frame->aflag,
+ &entries);
+ if (filelist == NULL)
+ {
+ error (0, 0, "skipping directory %s", update_dir);
+ /* Note that Find_Directories and the filesdoneproc
+ in particular would do bad things ("? foo.c" in
+ the case of some filesdoneproc's). */
+ goto skip_directory;
+ }
+ }
}
/* find sub-directories if we will recurse */
if (frame->flags != R_SKIP_DIRS)
- dirlist = Find_Directories (repository, frame->which, entries);
+ dirlist = Find_Directories (
+ process_this_directory ? repository : NULL,
+ frame->which, entries);
}
else
{
@@ -487,7 +693,7 @@ do_recursion (frame)
}
/* process the files (if any) */
- if (filelist != NULL && frame->fileproc)
+ if (process_this_directory && filelist != NULL && frame->fileproc)
{
struct file_info finfo_struct;
struct frame_and_file frfile;
@@ -525,11 +731,12 @@ do_recursion (frame)
}
/* call-back files done proc (if any) */
- if (dodoneproc && frame->filesdoneproc != NULL)
+ if (process_this_directory && dodoneproc && frame->filesdoneproc != NULL)
err = frame->filesdoneproc (frame->callerdat, err, repository,
update_dir[0] ? update_dir : ".",
entries);
+ skip_directory:
fileattr_write ();
fileattr_free ();
@@ -589,7 +796,24 @@ do_file_proc (p, closure)
strcat (finfo->fullname, finfo->file);
if (frfile->frame->dosrcs && repository)
+ {
finfo->rcs = RCS_parse (finfo->file, repository);
+
+ /* OK, without W_LOCAL the error handling becomes relatively
+ simple. The file names came from readdir() on the
+ repository and so we know any ENOENT is an error
+ (e.g. symlink pointing to nothing). Now, the logic could
+ be simpler - since we got the name from readdir, we could
+ just be calling RCS_parsercsfile. */
+ if (finfo->rcs == NULL
+ && !(frfile->frame->which & W_LOCAL))
+ {
+ error (0, 0, "could not read RCS file for %s", finfo->fullname);
+ free (finfo->fullname);
+ cvs_flushout ();
+ return 0;
+ }
+ }
else
finfo->rcs = (RCSNode *) NULL;
ret = frfile->frame->fileproc (frfile->frame->callerdat, finfo);
@@ -625,6 +849,7 @@ do_dir_proc (p, closure)
int err = 0;
struct saved_cwd cwd;
char *saved_update_dir;
+ int process_this_directory = 1;
if (fncmp (dir, CVSADM) == 0)
{
@@ -760,12 +985,60 @@ but CVS uses %s for its own purposes; skipping %s directory",
free (cvsadmdir);
}
+ /* Only process this directory if the root matches. This nearly
+ duplicates code in do_recursion. */
+
+#ifdef SERVER_SUPPORT
+ if (! server_active
+
+ /* If -d was specified, it should override CVS/Root.
+
+ In the single-repository case, it is long-standing CVS behavior
+ and makes sense - the user might want another access method,
+ another server (which mounts the same repository), &c.
+
+ In the multiple-repository case, -d overrides all CVS/Root
+ files. That is the only plausible generalization I can
+ think of. */
+ && CVSroot_cmdline == NULL)
+#endif
+ {
+ char *this_root = Name_Root (dir, update_dir);
+ if (this_root != NULL)
+ {
+ if (findnode (root_directories, this_root) == NULL)
+ {
+ /* Add it to our list. */
+
+ Node *n = getnode ();
+ n->type = UNKNOWN;
+ n->key = xstrdup (this_root);
+
+ if (addnode (root_directories, n))
+ error (1, 0, "cannot add new CVSROOT %s", this_root);
+
+ }
+
+ process_this_directory = (strcmp (current_root, this_root) == 0);
+ free (this_root);
+ }
+ }
+
/* call-back dir entry proc (if any) */
if (dir_return == R_SKIP_ALL)
;
else if (frame->direntproc != NULL)
- dir_return = frame->direntproc (frame->callerdat, dir, newrepos,
- update_dir, frent->entries);
+ {
+ /* If we're doing the actual processing, call direntproc.
+ Otherwise, assume that we need to process this directory
+ and recurse. FIXME. */
+
+ if (process_this_directory)
+ dir_return = frame->direntproc (frame->callerdat, dir, newrepos,
+ update_dir, frent->entries);
+ else
+ dir_return = R_PROCESS;
+ }
else
{
/* Generic behavior. I don't see a reason to make the caller specify
@@ -811,7 +1084,7 @@ but CVS uses %s for its own purposes; skipping %s directory",
(void) strcpy (update_dir, ".");
/* call-back dir leave proc (if any) */
- if (frame->dirleaveproc != NULL)
+ if (process_this_directory && frame->dirleaveproc != NULL)
err = frame->dirleaveproc (frame->callerdat, dir, err, update_dir,
frent->entries);
diff --git a/gnu/usr.bin/cvs/src/release.c b/gnu/usr.bin/cvs/src/release.c
index 82429e0d994..ca7945b0ac1 100644
--- a/gnu/usr.bin/cvs/src/release.c
+++ b/gnu/usr.bin/cvs/src/release.c
@@ -6,10 +6,9 @@
*/
#include "cvs.h"
+#include "savecwd.h"
#include "getline.h"
-static void release_delete PROTO((char *dir));
-
static const char *const release_usage[] =
{
"Usage: %s %s [-d] directories...\n",
@@ -76,6 +75,7 @@ release (argc, argv)
int arg_start_idx;
int err = 0;
short delete_flag = 0;
+ struct saved_cwd cwd;
#ifdef SERVER_SUPPORT
if (server_active)
@@ -111,6 +111,10 @@ release (argc, argv)
/* We're going to run "cvs -n -q update" and check its output; if
* the output is sufficiently unalarming, then we release with no
* questions asked. Else we prompt, then maybe release.
+ * (Well, actually we ask no matter what. Our notion of "sufficiently
+ * unalarming" doesn't take into account "? foo.c" files, so it is
+ * up to the user to take note of them, at least currently
+ * (ignore-193 in testsuite)).
*/
/* Construct the update command. */
update_cmd = xmalloc (strlen (program_path)
@@ -128,6 +132,12 @@ release (argc, argv)
}
#endif /* CLIENT_SUPPORT */
+ /* Remember the directory where "cvs release" was invoked because
+ all args are relative to this directory and we chdir around.
+ */
+ if (save_cwd (&cwd))
+ error_exit ();
+
arg_start_idx = 0;
for (i = arg_start_idx; i < argc; i++)
@@ -146,6 +156,8 @@ release (argc, argv)
{
if (!really_quiet)
error (0, 0, "no repository directory: %s", thisarg);
+ if (restore_cwd (&cwd, NULL))
+ error_exit ();
continue;
}
}
@@ -190,6 +202,9 @@ release (argc, argv)
if ((pclose (fp)) != 0)
{
error (0, 0, "unable to release `%s'", thisarg);
+ free (repository);
+ if (restore_cwd (&cwd, NULL))
+ error_exit ();
continue;
}
@@ -203,6 +218,8 @@ release (argc, argv)
(void) fprintf (stderr, "** `%s' aborted by user choice.\n",
command_name);
free (repository);
+ if (restore_cwd (&cwd, NULL))
+ error_exit ();
continue;
}
}
@@ -239,7 +256,19 @@ release (argc, argv)
}
free (repository);
- if (delete_flag) release_delete (thisarg);
+
+ if (restore_cwd (&cwd, NULL))
+ error_exit ();
+
+ if (delete_flag)
+ {
+ /* FIXME? Shouldn't this just delete the CVS-controlled
+ files and, perhaps, the files that would normally be
+ ignored and leave everything else? */
+
+ if (unlink_file_dir (thisarg) < 0)
+ error (0, errno, "deletion of directory %s failed", thisarg);
+ }
#ifdef CLIENT_SUPPORT
if (client_active)
@@ -247,6 +276,10 @@ release (argc, argv)
#endif /* CLIENT_SUPPORT */
}
+ if (restore_cwd (&cwd, NULL))
+ error_exit ();
+ free_cwd (&cwd);
+
#ifdef CLIENT_SUPPORT
if (client_active)
{
@@ -264,37 +297,3 @@ release (argc, argv)
free (line);
return err;
}
-
-
-/* We want to "rm -r" the working directory, but let us be a little
- paranoid. */
-static void
-release_delete (dir)
- char *dir;
-{
- struct stat st;
- ino_t ino;
-
- (void) CVS_STAT (".", &st);
- ino = st.st_ino;
- (void) CVS_CHDIR ("..");
- (void) CVS_STAT (dir, &st);
- if (ino != st.st_ino)
- {
- /* This test does not work on cygwin32, because under cygwin32
- the st_ino field is not the same when you refer to a file
- by a different name. This is a cygwin32 bug, but then I
- don't see what the point of this test is anyhow. */
-#ifndef __CYGWIN32__
- error (0, 0,
- "Parent dir on a different disk, delete of %s aborted", dir);
- return;
-#endif
- }
- /*
- * XXX - shouldn't this just delete the CVS-controlled files and, perhaps,
- * the files that would normally be ignored and leave everything else?
- */
- if (unlink_file_dir (dir) < 0)
- error (0, errno, "deletion of directory %s failed", dir);
-}
diff --git a/gnu/usr.bin/cvs/src/remove.c b/gnu/usr.bin/cvs/src/remove.c
index 9ed32d72a11..2dacdf15988 100644
--- a/gnu/usr.bin/cvs/src/remove.c
+++ b/gnu/usr.bin/cvs/src/remove.c
@@ -100,9 +100,9 @@ cvsremove (argc, argv)
ign_setup ();
if (local)
send_arg("-l");
- send_file_names (argc, argv, 0);
/* FIXME: Can't we set SEND_NO_CONTENTS here? Needs investigation. */
send_files (argc, argv, local, 0, 0);
+ send_file_names (argc, argv, 0);
send_to_server ("remove\012", 0);
return get_responses_and_close ();
}
@@ -200,7 +200,9 @@ remove_fileproc (callerdat, finfo)
+ sizeof (CVSEXT_LOG)
+ 10);
(void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
- (void) unlink_file (fname);
+ if (unlink_file (fname) < 0
+ && !existence_error (errno))
+ error (0, errno, "cannot remove %s", CVSEXT_LOG);
if (!quiet)
error (0, 0, "removed `%s'", finfo->fullname);
@@ -216,7 +218,7 @@ remove_fileproc (callerdat, finfo)
error (0, 0, "file `%s' already scheduled for removal",
finfo->fullname);
}
- else if (vers->tag != NULL && isdigit (*vers->tag))
+ else if (vers->tag != NULL && isdigit ((unsigned char) *vers->tag))
{
/* Commit will just give an error, and so there seems to be
little reason to allow the remove. I mean, conflicts that
diff --git a/gnu/usr.bin/cvs/src/root.c b/gnu/usr.bin/cvs/src/root.c
index 050e168041e..c650646ecff 100644
--- a/gnu/usr.bin/cvs/src/root.c
+++ b/gnu/usr.bin/cvs/src/root.c
@@ -18,7 +18,7 @@
Watch out if the enum is changed in cvs.h! */
char *method_names[] = {
- "local", "server (rsh)", "pserver", "kserver", "gserver", "ext"
+ "local", "server (rsh)", "pserver", "kserver", "gserver", "ext", "fork"
};
#ifndef DEBUG
@@ -268,6 +268,11 @@ error 0 Server configuration missing --allow-root in inetd.conf\n");
return 0;
}
+/* This global variable holds the global -d option. It is NULL if -d
+ was not used, which means that we must get the CVSroot information
+ from the CVSROOT environment variable or from a CVS/Root file. */
+
+char *CVSroot_cmdline;
/* Parse a CVSROOT variable into its constituent parts -- method,
* username, hostname, directory. The prototypical CVSROOT variable
@@ -287,30 +292,6 @@ char *CVSroot_username; /* the username or NULL if method == local */
char *CVSroot_hostname; /* the hostname or NULL if method == local */
char *CVSroot_directory; /* the directory name */
-#ifdef AUTH_SERVER_SUPPORT
-/* Die if CVSroot_directory and Pserver_Repos don't match. */
-static void
-check_root_consistent ()
-{
- /* FIXME: Should be using a deferred error, as the rest of
- serve_root does. As it is now the call to error could conceivably
- cause deadlock, as noted in server_cleanup. Best solution would
- presumably be to write some code so that error() automatically
- defers the error in those cases where that is needed. */
- /* FIXME? Possible that the wording should be more clear (e.g.
- Root says "%s" but pserver protocol says "%s"
- or something which would aid people who are writing implementations
- of the client side of the CVS protocol. I don't see any security
- problem with revealing that information. */
- if ((Pserver_Repos != NULL) && (CVSroot_directory != NULL))
- if (strcmp (Pserver_Repos, CVSroot_directory) != 0)
- error (1, 0, "repository mismatch: \"%s\" vs \"%s\"",
- Pserver_Repos, CVSroot_directory);
-}
-
-#endif /* AUTH_SERVER_SUPPORT */
-
-
int
parse_cvsroot (CVSroot)
char *CVSroot;
@@ -335,8 +316,9 @@ parse_cvsroot (CVSroot)
/* Access method specified, as in
* "cvs -d :pserver:user@host:/path",
- * "cvs -d :local:e:\path", or
- * "cvs -d :kserver:user@host:/path".
+ * "cvs -d :local:e:\path",
+ * "cvs -d :kserver:user@host:/path", or
+ * "cvs -d :fork:/path".
* We need to get past that part of CVSroot before parsing the
* rest of it.
*/
@@ -363,6 +345,8 @@ parse_cvsroot (CVSroot)
CVSroot_method = server_method;
else if (strcmp (method, "ext") == 0)
CVSroot_method = ext_method;
+ else if (strcmp (method, "fork") == 0)
+ CVSroot_method = fork_method;
else
{
error (0, 0, "unknown method in CVSroot: %s", CVSroot);
@@ -391,7 +375,8 @@ parse_cvsroot (CVSroot)
CVSroot_username = NULL;
CVSroot_hostname = NULL;
- if (CVSroot_method != local_method)
+ if ((CVSroot_method != local_method)
+ && (CVSroot_method != fork_method))
{
/* Check to see if there is a username in the string. */
@@ -416,9 +401,6 @@ parse_cvsroot (CVSroot)
}
CVSroot_directory = cvsroot_copy;
-#ifdef AUTH_SERVER_SUPPORT
- check_root_consistent ();
-#endif /* AUTH_SERVER_SUPPORT */
#if ! defined (CLIENT_SUPPORT) && ! defined (DEBUG)
if (CVSroot_method != local_method)
@@ -442,10 +424,12 @@ parse_cvsroot (CVSroot)
switch (CVSroot_method)
{
case local_method:
+ case fork_method:
if (CVSroot_username || CVSroot_hostname)
{
error (0, 0, "can't specify hostname and username in CVSROOT");
- error (0, 0, "when using local access method");
+ error (0, 0, "when using %s access method",
+ CVSroot_method == local_method ? "local" : "fork");
error (0, 0, "(%s)", CVSroot);
return 1;
}
@@ -464,18 +448,20 @@ parse_cvsroot (CVSroot)
error (0, 0, "but your CVS executable doesn't support it");
error (0, 0, "(%s)", CVSroot);
return 1;
-#endif
+#else
check_hostname = 1;
break;
+#endif
case gserver_method:
#ifndef HAVE_GSSAPI
error (0, 0, "Your CVSROOT is set for a GSSAPI access method");
error (0, 0, "but your CVS executable doesn't support it");
error (0, 0, "(%s)", CVSroot);
return 1;
-#endif
+#else
check_hostname = 1;
break;
+#endif
case server_method:
case ext_method:
case pserver_method:
@@ -504,18 +490,17 @@ parse_cvsroot (CVSroot)
/* Set up the global CVSroot* variables as if we're using the local
- repository DIR. */
+ repository DIR. DIR must point to storage which will last for the
+ rest of the CVS invocation (for example, the caller might malloc it
+ and never free it, or free it just before exiting CVS). */
void
set_local_cvsroot (dir)
char *dir;
{
- CVSroot_original = xstrdup (dir);
+ CVSroot_original = dir;
CVSroot_method = local_method;
CVSroot_directory = CVSroot_original;
-#ifdef AUTH_SERVER_SUPPORT
- check_root_consistent ();
-#endif /* AUTH_SERVER_SUPPORT */
CVSroot_username = NULL;
CVSroot_hostname = NULL;
client_active = 0;
@@ -523,7 +508,11 @@ set_local_cvsroot (dir)
#ifdef DEBUG
-/* This is for testing the parsing function. */
+/* This is for testing the parsing function. Use
+
+ gcc -I. -I.. -I../lib -DDEBUG root.c -o root
+
+ to compile. */
#include <stdio.h>
@@ -531,6 +520,30 @@ char *CVSroot;
char *program_name = "testing";
char *command_name = "parse_cvsroot"; /* XXX is this used??? */
+/* Toy versions of various functions when debugging under unix. Yes,
+ these make various bad assumptions, but they're pretty easy to
+ debug when something goes wrong. */
+
+void
+error_exit PROTO ((void))
+{
+ exit (1);
+}
+
+char *
+xstrdup (str)
+ const char *str;
+{
+ return strdup (str);
+}
+
+int
+isabsolute (dir)
+ const char *dir;
+{
+ return (dir && (*dir == '/'));
+}
+
void
main (argc, argv)
int argc;
@@ -546,7 +559,7 @@ main (argc, argv)
if (parse_cvsroot (argv[1]))
{
- fprintf (stderr, "%s: Parsing failed.", program_name);
+ fprintf (stderr, "%s: Parsing failed.\n", program_name);
exit (1);
}
printf ("CVSroot: %s\n", argv[1]);
diff --git a/gnu/usr.bin/cvs/src/rtag.c b/gnu/usr.bin/cvs/src/rtag.c
index 3207c1b3c3c..5fd825f471d 100644
--- a/gnu/usr.bin/cvs/src/rtag.c
+++ b/gnu/usr.bin/cvs/src/rtag.c
@@ -64,7 +64,7 @@ static int force_tag_move; /* don't move existing tags by default *
static const char *const rtag_usage[] =
{
- "Usage: %s %s [-aflRnF] [-b] [-d] [-r tag|-D date] tag modules...\n",
+ "Usage: %s %s [-aflRnF] [-b] [-d] [-r rev|-D date] tag modules...\n",
"\t-a\tClear tag from removed files that would not otherwise be tagged.\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, not recursive\n",
@@ -388,9 +388,16 @@ check_fileproc (callerdat, finfo)
{
if (delete_flag)
{
+ /* Deleting a tag which did not exist is a noop and
+ should not be logged. */
addit = 0;
}
}
+ else if (delete_flag)
+ {
+ free (p->data);
+ p->data = xstrdup (oversion);
+ }
else if (strcmp(oversion, p->data) == 0)
{
addit = 0;
@@ -458,7 +465,7 @@ pretag_proc(repository, filter)
s = xstrdup(filter);
for (cp=s; *cp; cp++)
{
- if (isspace(*cp))
+ if (isspace ((unsigned char) *cp))
{
*cp = '\0';
break;
@@ -583,7 +590,9 @@ rtag_fileproc (callerdat, finfo)
}
return (0);
}
- if (numtag && isdigit (*numtag) && strcmp (numtag, version) != 0)
+ if (numtag
+ && isdigit ((unsigned char) *numtag)
+ && strcmp (numtag, version) != 0)
{
/*
diff --git a/gnu/usr.bin/cvs/src/run.c b/gnu/usr.bin/cvs/src/run.c
index dc35a78216c..6d2c3b1cec6 100644
--- a/gnu/usr.bin/cvs/src/run.c
+++ b/gnu/usr.bin/cvs/src/run.c
@@ -175,10 +175,11 @@ run_exec (stin, stout, sterr, flags)
/* The output files, if any, are now created. Do the fork and dups.
- We use vfork not so much for the sake of unices without
- copy-on-write (such systems are rare these days), but for the
- sake of systems without an MMU, which therefore can't do
- copy-on-write (e.g. Amiga). The other solution is spawn (see
+ We use vfork not so much for a performance boost (the
+ performance boost, if any, is modest on most modern unices),
+ but for the sake of systems without a memory management unit,
+ which find it difficult or impossible to implement fork at all
+ (e.g. Amiga). The other solution is spawn (see
windows-NT/run.c). */
#ifdef HAVE_VFORK
@@ -365,12 +366,8 @@ run_popen (cmd, mode)
const char *mode;
{
if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> run_popen(%s,%s)\n",
- (server_active) ? 'S' : ' ', cmd, mode);
-#else
- (void) fprintf (stderr, "-> run_popen(%s,%s)\n", cmd, mode);
-#endif
+ (void) fprintf (stderr, "%s-> run_popen(%s,%s)\n",
+ CLIENT_SERVER_STR, cmd, mode);
if (noexec)
return (NULL);
@@ -440,77 +437,3 @@ close_on_exec (fd)
error (1, errno, "can't set close-on-exec flag on %d", fd);
#endif
}
-
-/*
- * dir = 0 : main proc writes to new proc, which writes to oldfd
- * dir = 1 : main proc reads from new proc, which reads from oldfd
- *
- * Returns: a file descriptor. On failure (i.e., the exec fails),
- * then filter_stream_through_program() complains and dies.
- */
-
-int
-filter_stream_through_program (oldfd, dir, prog, pidp)
- int oldfd, dir;
- char **prog;
- pid_t *pidp;
-{
- int p[2], newfd;
- pid_t newpid;
-
- if (pipe (p))
- error (1, errno, "cannot create pipe");
-#ifdef USE_SETMODE_BINARY
- setmode (p[0], O_BINARY);
- setmode (p[1], O_BINARY);
-#endif
-
-#ifdef HAVE_VFORK
- newpid = vfork ();
-#else
- newpid = fork ();
-#endif
- if (pidp)
- *pidp = newpid;
- switch (newpid)
- {
- case -1:
- error (1, errno, "cannot fork");
- case 0:
- /* child */
- if (dir)
- {
- /* write to new pipe */
- close (p[0]);
- dup2 (oldfd, 0);
- dup2 (p[1], 1);
- }
- else
- {
- /* read from new pipe */
- close (p[1]);
- dup2 (p[0], 0);
- dup2 (oldfd, 1);
- }
- /* Should I be blocking some signals here? */
- execvp (prog[0], prog);
- error (1, errno, "couldn't exec %s", prog[0]);
- default:
- /* parent */
- close (oldfd);
- if (dir)
- {
- /* read from new pipe */
- close (p[1]);
- newfd = p[0];
- }
- else
- {
- /* write to new pipe */
- close (p[0]);
- newfd = p[1];
- }
- close_on_exec (newfd);
- return newfd;
- }
-}
diff --git a/gnu/usr.bin/cvs/src/sanity.sh b/gnu/usr.bin/cvs/src/sanity.sh
index f97e0369a05..690398441ea 100644
--- a/gnu/usr.bin/cvs/src/sanity.sh
+++ b/gnu/usr.bin/cvs/src/sanity.sh
@@ -43,6 +43,15 @@
# required to make this script work properly.
unset CVSREAD
+# We want to invoke a predictable set of i18n behaviors, not whatever
+# the user running this script might have set.
+# In particular:
+# 'sort' and tabs and spaces (LC_COLLATE).
+# Messages from getopt (LC_MESSAGES) (in the future, CVS itself might
+# also alter its messages based on LC_MESSAGES).
+LC_ALL=C
+export LC_ALL
+
# The default value of /tmp/cvs-sanity for TESTDIR is dubious,
# because it loses if two people/scripts try to run the tests
# at the same time. Some possible solutions:
@@ -69,12 +78,6 @@ echo 'This test should produce no other output than this line, and a final "OK".
if test x"$1" = x"-r"; then
shift
remote=yes
- # If we're going to do remote testing, make sure 'rsh' works first.
- host="`hostname`"
- if test "x`${CVS_RSH-rsh} $host -n 'echo hi'`" != "xhi"; then
- echo "ERROR: cannot test remote CVS, because \`rsh $host' fails." >&2
- exit 1
- fi
else
remote=no
fi
@@ -477,7 +480,8 @@ dotest_fail ()
fail "$1"
else
: so far so good
- fi
+ fi 2>${TESTDIR}/dotest.tmp1
+ cat ${TESTDIR}/dotest.tmp1 >>${TESTDIR}/dotest.tmp
dotest_internal "$@"
}
@@ -553,25 +557,33 @@ RCSINIT=; export RCSINIT
if test x"$*" = x; then
# Basic/miscellaneous functionality
- tests="basica basicb basicc basic1 deep basic2 commit-readonly"
+ tests="basica basicb basicc basic1 deep basic2 files commit-readonly"
# Branching, tagging, removing, adding, multiple directories
- tests="${tests} rdiff death death2 branches branches2"
+ tests="${tests} rdiff diff death death2 rmadd rmadd2 dirs dirs2"
+ tests="${tests} branches branches2 tagc"
tests="${tests} rcslib multibranch import importb importc"
- tests="${tests} join join2 join3"
+ tests="${tests} import-after-initial"
+ tests="${tests} join join2 join3 join-readonly-conflict"
tests="${tests} new newb conflicts conflicts2 conflicts3"
# Checking out various places (modules, checkout -d, &c)
tests="${tests} modules modules2 modules3 modules4"
+ tests="${tests} mkmodules-temp-file-removal"
tests="${tests} cvsadm emptydir abspath toplevel toplevel2"
# Log messages, error messages.
tests="${tests} mflag editor errmsg1 errmsg2"
# Watches, binary files, history browsing, &c.
tests="${tests} devcom devcom2 devcom3 watch4"
tests="${tests} unedit-without-baserev"
- tests="${tests} ignore binfiles binfiles2 mcopy binwrap binwrap2"
+ tests="${tests} ignore binfiles binfiles2 binfiles3"
+ tests="${tests} mcopy binwrap binwrap2"
tests="${tests} binwrap3 mwrap info taginfo config"
- tests="${tests} serverpatch log log2 ann ann-id crerepos rcs rcs2"
+ tests="${tests} serverpatch log log2 ann ann-id"
+ # Repository Storage (RCS file format, CVS lock files, creating
+ # a repository without "cvs init", &c).
+ tests="${tests} crerepos rcs rcs2 rcs3 lockfiles"
+ # More history browsing, &c.
tests="${tests} history"
- tests="${tests} big modes modes2 stamps"
+ tests="${tests} big modes modes2 modes3 stamps"
# PreservePermissions stuff: permissions, symlinks et al.
tests="${tests} perms symlinks hardlinks"
# More tag and branch tests, keywords.
@@ -581,6 +593,11 @@ if test x"$*" = x; then
tests="${tests} admin reserved"
# Nuts and bolts of diffing/merging (diff library, &c)
tests="${tests} diffmerge1 diffmerge2"
+ # Release of multiple directories
+ tests="${tests} release"
+ # Multiple root directories and low-level protocol tests.
+ tests="${tests} multiroot multiroot2 multiroot3 multiroot4"
+ tests="${tests} reposmv pserver server client"
else
tests="$*"
fi
@@ -629,10 +646,13 @@ directory_cmp ()
CVSROOT_DIRNAME=${TESTDIR}/cvsroot
CVSROOT=${CVSROOT_DIRNAME} ; export CVSROOT
if test "x$remote" = xyes; then
- # Use rsh so we can test it without having to muck with inetd
- # or anything like that. Also needed to get CVS_SERVER to
- # work.
- CVSROOT=:ext:`hostname`:${CVSROOT_DIRNAME} ; export CVSROOT
+ # Currently we test :fork: and :ext: (see crerepos test).
+ # Testing :pserver: would be hard (inetd issues).
+ # Also :ext: and :fork support CVS_SERVER in a convenient way.
+ # If you want to edit this script to change the next line to
+ # :ext:, you can run the tests that way. There is a known
+ # difference in modes-15 (see comments there).
+ CVSROOT=:fork:${CVSROOT_DIRNAME} ; export CVSROOT
CVS_SERVER=${testcvs}; export CVS_SERVER
fi
@@ -725,8 +745,8 @@ ${PROG} \[[a-z]* aborted\]: failed to set tag BASE to revision 1\.1 in ${TESTDIR
RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v
retrieving revision 1\.1
diff -c -r1\.1 ssfile
-\*\*\* ssfile [0-9/]* [0-9:]* 1\.1
---- ssfile [0-9/]* [0-9:]*
+\*\*\* sdir/ssdir/ssfile [0-9/]* [0-9:]* 1\.1
+--- sdir/ssdir/ssfile [0-9/]* [0-9:]*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
--- 1,2 ----
@@ -738,8 +758,8 @@ ${PLUS} ssfile line 2"
RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v
retrieving revision 1\.1
diff -c -r1\.1 ssfile
-\*\*\* ssfile [0-9/]* [0-9:]* 1\.1
---- ssfile [0-9/]* [0-9:]*
+\*\*\* sdir/ssdir/ssfile [0-9/]* [0-9:]* 1\.1
+--- sdir/ssdir/ssfile [0-9/]* [0-9:]*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
--- 1,2 ----
@@ -1140,6 +1160,8 @@ Directory ${TESTDIR}/cvsroot/second-dir added to the repository"
# and then blow it away (don't complain if it does not
# exist). But that is perfectly legal; people who are used
# to the old behavior especially may be interested.
+ # FIXME: this test is intended for the TopLevelAdmin=yes case;
+ # should adjust/move it accordingly.
rm -rf CVS
dotest basicc-4 "echo *" "first-dir second-dir"
dotest basicc-5 "${testcvs} update" \
@@ -1149,8 +1171,28 @@ ${PROG} [a-z]*: Updating second-dir" \
${PROG} [a-z]*: Updating first-dir
${PROG} [a-z]*: Updating second-dir"
+ cd first-dir
+ dotest basicc-6 "${testcvs} release -d" ""
+ dotest basicc-7 "test -d ../first-dir" ""
+ dotest basicc-8 "${testcvs} -Q release -d ." \
+"${PROG} release: deletion of directory \. failed: .*"
+ dotest basicc-9 "test -d ../second-dir" ""
+ dotest basicc-10 "test -d ../first-dir" ""
+ # For CVS to make a syntactic check for "." wouldn't suffice.
+ dotest basicc-11 "${testcvs} -Q release -d ./." \
+"${PROG} release: deletion of directory \./\. failed: .*"
cd ..
- rm -r 1
+ cd ..
+
+ mkdir 2; cd 2
+ dotest basicc-12 "${testcvs} -Q co ." ""
+ dotest basicc-13 "echo *" "CVS CVSROOT first-dir second-dir"
+ dotest basicc-14 "${testcvs} -Q release first-dir second-dir" ""
+ dotest basicc-15 "${testcvs} -Q release -d first-dir second-dir" ""
+ dotest basicc-16 "echo *" "CVS CVSROOT"
+
+ cd ..
+ rm -r 1 2
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -2047,6 +2089,108 @@ O [0-9/]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-di
rm -rf ${CVSROOT_DIRNAME}/second-dir
;;
+ files)
+ # Test of how we specify files on the command line
+ # (recurse.c and that sort of thing). Vaguely similar to
+ # tests like basic* and deep. See modules and such tests
+ # for what happens when we throw in modules and co -d, &c.
+
+ # This particular test is fairly carefully crafted, to spot
+ # one particular issue with remote.
+ mkdir 1; cd 1
+ dotest files-1 "${testcvs} -q co -l ." ""
+ mkdir first-dir
+ dotest files-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ touch tfile
+ dotest files-3 "${testcvs} add tfile" \
+"${PROG} [a-z]*: scheduling file .tfile. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest files-4 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/tfile,v
+done
+Checking in tfile;
+${TESTDIR}/cvsroot/first-dir/tfile,v <-- tfile
+initial revision: 1\.1
+done"
+ dotest files-5 "${testcvs} -q tag -b C" "T tfile"
+ dotest files-6 "${testcvs} -q update -r C" ""
+ mkdir dir
+ dotest files-7 "${testcvs} add dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir added to the repository
+--> Using per-directory sticky tag .C'"
+ cd dir
+ touch .file
+ dotest files-6 "${testcvs} add .file" \
+"${PROG} [a-z]*: scheduling file .\.file' for addition on branch .C.
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ mkdir sdir
+ dotest files-7 "${testcvs} add sdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir/sdir added to the repository
+--> Using per-directory sticky tag .C'"
+ cd sdir
+ mkdir ssdir
+ dotest files-8 "${testcvs} add ssdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir added to the repository
+--> Using per-directory sticky tag .C'"
+ cd ssdir
+ touch .file
+ dotest files-9 "${testcvs} add .file" \
+"${PROG} [a-z]*: scheduling file .\.file' for addition on branch .C.
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ cd ../..
+ dotest files-10 "${testcvs} -q ci -m test" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v
+done
+Checking in \.file;
+${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+RCS file: ${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v
+done
+Checking in sdir/ssdir/\.file;
+${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done"
+ dotest files-11 \
+"${testcvs} commit -m test -f ./.file ./sdir/ssdir/.file" \
+"Checking in \.file;
+${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
+done
+Checking in \./sdir/ssdir/\.file;
+${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
+done"
+ if test "$remote" = yes; then
+ # This is a bug, looks like that toplevel_repos cruft in
+ # client.c is coming back to haunt us.
+ # May want to think about the whole issue, toplevel_repos
+ # has always been crufty and trying to patch it up again
+ # might be a mistake.
+ dotest_fail files-12 \
+"${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \
+"${PROG} server: Up-to-date check failed for .\.file'
+${PROG} \[server aborted\]: correct above errors first!"
+ else
+ dotest files-12 \
+"${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \
+"Checking in \./sdir/ssdir/\.file;
+${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file
+new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
+done
+Checking in \.file;
+${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file
+new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
+done"
+ fi
+ cd ../../..
+
+ rm -r 1
+ rm -rf ${CVSROOT_DIRECTORY}/first-dir
+ ;;
+
commit-readonly)
mkdir 1; cd 1
module=x
@@ -2194,6 +2338,31 @@ diff -c /dev/null trdiff/new:1\.1
rm -rf ${CVSROOT_DIRNAME}/trdiff
;;
+ diff)
+ # Various tests specific to the "cvs diff" command.
+ # Related tests:
+ # death2: -N
+ # rcslib: cvs diff and $Name.
+ # rdiff: cvs rdiff.
+ # diffmerge*: nuts and bolts (stuff within diff library)
+ mkdir 1; cd 1
+ dotest diff-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest diff-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+
+ # diff is anomalous. Most CVS commands print the "nothing
+ # known" message (or worse yet, no message in some cases) but
+ # diff says "I know nothing". Shrug.
+ dotest_fail diff-3 "${testcvs} diff xyzpdq" \
+"${PROG} [a-z]*: I know nothing about xyzpdq"
+
+ cd ../..
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ rm -r 1
+ ;;
+
death)
# next dive. test death support.
@@ -2894,6 +3063,473 @@ ${PLUS} first revision"
cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
;;
+ rmadd)
+ # More tests of adding and removing files.
+ # In particular ci -r.
+ # Other ci -r tests:
+ # * editor-9: checking in a modified file,
+ # where "ci -r" means a branch.
+ # * basica-8a1: checking in a modified file with numeric revision.
+ # * basica-8a2: likewise.
+ # * keywordlog-4: adding a new file with numeric revision.
+ mkdir 1; cd 1
+ dotest rmadd-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest rmadd-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ echo first file1 >file1
+ dotest rmadd-3 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+
+ dotest_fail rmadd-4 "${testcvs} -q ci -r 1.2.2.4 -m add" \
+"${PROG} [a-z]*: cannot add file .file1' with revision .1\.2\.2\.4'; must be on trunk
+${PROG} \[[a-z]* aborted\]: correct above errors first!"
+ dotest_fail rmadd-5 "${testcvs} -q ci -r 1.2.2 -m add" \
+"${PROG} [a-z]*: cannot add file .file1' with revision .1\.2\.2'; must be on trunk
+${PROG} \[[a-z]* aborted\]: correct above errors first!"
+ dotest_fail rmadd-6 "${testcvs} -q ci -r mybranch -m add" \
+"${PROG} \[[a-z]* aborted\]: no such tag mybranch"
+
+ # The thing with the trailing periods strikes me as a very
+ # bizarre behavior, but it would seem to be intentional
+ # (see commit.c). It probably could go away....
+ dotest rmadd-7 "${testcvs} -q ci -r 7.... -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+done
+Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+initial revision: 7\.1
+done"
+ if test "$remote" = yes; then
+ # I guess remote doesn't set a sticky tag in this case.
+ # Kind of odd, in the sense that rmadd-24a does set one
+ # both local and remote.
+ dotest_fail rmadd-7a "test -f CVS/Tag"
+ echo T7 >CVS/Tag
+ else
+ dotest rmadd-7a "cat CVS/Tag" "T7"
+ fi
+
+ dotest rmadd-8 "${testcvs} -q tag -b mybranch" "T file1"
+ dotest rmadd-9 "${testcvs} -q tag mynonbranch" "T file1"
+
+ touch file2
+ # The previous "cvs ci -r" set a sticky tag of '7'. Seems a
+ # bit odd, and I guess commit.c (findmaxrev) makes '7' sticky
+ # tags unnecessary (?). I kind of suspect that it should be
+ # saying "sticky tag is not a branch" like keywordlog-4b.
+ # Or something.
+ dotest rmadd-10 "${testcvs} add file2" \
+"${PROG} [a-z]*: scheduling file .file2. for addition on branch .7'
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ # As in the previous example, CVS is confused....
+ dotest rmadd-11 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v
+done
+Checking in file2;
+${TESTDIR}/cvsroot/first-dir/file2,v <-- file2
+initial revision: 7\.1
+done"
+
+ dotest rmadd-12 "${testcvs} -q update -A" ""
+ touch file3
+ dotest rmadd-13 "${testcvs} add file3" \
+"${PROG} [a-z]*: scheduling file .file3. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ # Huh? file2 is not up to date? Seems buggy to me....
+ dotest_fail rmadd-14 "${testcvs} -q ci -r mybranch -m add" \
+"${PROG} [a-z]*: Up-to-date check failed for .file2'
+${PROG} \[[a-z]* aborted\]: correct above errors first!"
+ # Whatever, let's not let file2 distract us....
+ dotest rmadd-15 "${testcvs} -q ci -r mybranch -m add file3" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file3,v
+done
+Checking in file3;
+${TESTDIR}/cvsroot/first-dir/Attic/file3,v <-- file3
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done"
+
+ touch file4
+ dotest rmadd-16 "${testcvs} add file4" \
+"${PROG} [a-z]*: scheduling file .file4. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ # Same "Up-to-date check" issues as in rmadd-14.
+ # The "no such tag" thing is due to the fact that we only
+ # update val-tags when the tag is used (might be more of a
+ # bug than a feature, I dunno).
+ dotest_fail rmadd-17 \
+"${testcvs} -q ci -r mynonbranch -m add file4" \
+"${PROG} \[[a-z]* aborted\]: no such tag mynonbranch"
+ # Try to make CVS write val-tags.
+ dotest rmadd-18 "${testcvs} -q update -p -r mynonbranch file1" \
+"first file1"
+ # Oops, -p suppresses writing val-tags (probably a questionable
+ # behavior).
+ dotest_fail rmadd-19 \
+"${testcvs} -q ci -r mynonbranch -m add file4" \
+"${PROG} \[[a-z]* aborted\]: no such tag mynonbranch"
+ # Now make CVS write val-tags for real.
+ dotest rmadd-20 "${testcvs} -q update -r mynonbranch file1" ""
+ # Oops - CVS isn't distinguishing between a branch tag and
+ # a non-branch tag.
+ dotest rmadd-21 \
+"${testcvs} -q ci -r mynonbranch -m add file4" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file4,v
+done
+Checking in file4;
+${TESTDIR}/cvsroot/first-dir/Attic/file4,v <-- file4
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done"
+
+ # OK, we add this one in a vanilla way, but then check in
+ # a modification with ci -r and sniff around for sticky tags.
+ echo file5 >file5
+ dotest rmadd-22 "${testcvs} add file5" \
+"${PROG} [a-z]*: scheduling file .file5. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ if test "$remote" = yes; then
+ # Interesting bug (or missing feature) here. findmaxrev
+ # gets the major revision from the Entries. Well, remote
+ # doesn't send the entries for files which are not involved.
+ dotest rmadd-23 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file5,v
+done
+Checking in file5;
+${TESTDIR}/cvsroot/first-dir/file5,v <-- file5
+initial revision: 1\.1
+done"
+ dotest rmadd-23-workaround \
+"${testcvs} -q ci -r 7 -m bump-it file5" \
+"Checking in file5;
+${TESTDIR}/cvsroot/first-dir/file5,v <-- file5
+new revision: 7\.1; previous revision: 1\.1
+done"
+ else
+ dotest rmadd-23 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file5,v
+done
+Checking in file5;
+${TESTDIR}/cvsroot/first-dir/file5,v <-- file5
+initial revision: 7\.1
+done"
+ fi
+ echo change it >file5
+ dotest_fail rmadd-24 "${testcvs} -q ci -r 4.8 -m change file5" \
+"Checking in file5;
+${TESTDIR}/cvsroot/first-dir/file5,v <-- file5
+${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1
+${PROG} [a-z]*: could not check in file5
+7\.1 unlocked"
+ dotest rmadd-24a "${testcvs} -q ci -r 8.4 -m change file5" \
+"Checking in file5;
+${TESTDIR}/cvsroot/first-dir/file5,v <-- file5
+new revision: 8\.4; previous revision: 7\.1
+done"
+ # I'm not really sure that a sticky tag make sense here.
+ # It seems to be longstanding behavior for what that is worth.
+ dotest rmadd-25 "${testcvs} status file5" \
+"===================================================================
+File: file5 Status: Up-to-date
+
+ Working revision: 8\.4.*
+ Repository revision: 8\.4 ${TESTDIR}/cvsroot/first-dir/file5,v
+ Sticky Tag: 8\.4
+ Sticky Date: (none)
+ Sticky Options: (none)"
+
+ cd ../..
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
+ rmadd2)
+ # Tests of undoing commits, including in the presence of
+ # adding and removing files. See join for a list of -j tests.
+ mkdir 1; cd 1
+ dotest rmadd2-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest rmadd2-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ echo 'initial contents' >file1
+ dotest rmadd2-3 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest rmadd2-4 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+done
+Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ dotest rmadd2-5 "${testcvs} rm -f file1" \
+"${PROG} [a-z]*: scheduling .file1. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+ dotest rmadd2-6 "${testcvs} -q ci -m remove" \
+"Removing file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: delete; previous revision: 1\.1
+done"
+ dotest rmadd2-7 "${testcvs} -q update -j 1.2 -j 1.1 file1" "U file1"
+ dotest rmadd2-8 "${testcvs} -q ci -m readd" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.3; previous revision: 1\.2
+done"
+ echo 'new contents' >file1
+ dotest rmadd2-9 "${testcvs} -q ci -m modify" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.4; previous revision: 1\.3
+done"
+ dotest rmadd2-10 "${testcvs} -q update -j 1.4 -j 1.3 file1" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+retrieving revision 1\.4
+retrieving revision 1\.3
+Merging differences between 1\.4 and 1\.3 into file1"
+ dotest rmadd2-11 "${testcvs} -q ci -m undo" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.5; previous revision: 1\.4
+done"
+ dotest rmadd2-12 "cat file1" "initial contents"
+ dotest rmadd2-13 "${testcvs} -q update -p -r 1.3" "initial contents"
+
+ # Hmm, might be a bit odd that this works even if 1.3 is not
+ # the head.
+ dotest rmadd2-14 "${testcvs} -q update -j 1.3 -j 1.2 file1" \
+"${PROG} [a-z]*: scheduling file1 for removal"
+ dotest rmadd2-15 "${testcvs} -q ci -m re-remove" \
+"Removing file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: delete; previous revision: 1\.5
+done"
+ cd ../..
+
+ rm -r 1
+ rm -rf ${TESTDIR}/cvsroot/first-dir
+ ;;
+
+ dirs)
+ # Tests related to removing and adding directories.
+ # See also:
+ # conflicts (especially dir1 in conflicts-130): What happens if
+ # directory exists in repository and a non-CVS-controlled
+ # directory in the working directory?
+ # conflicts3-15. More cases, especially where CVS directory
+ # exists but without CVS/Repository and friends.
+ # conflicts3-22. Similar to conflicts-130 but there is a file
+ # in the directory.
+ # dirs2. Sort of similar to conflicts3-22 but somewhat different.
+ mkdir imp-dir; cd imp-dir
+ echo file1 >file1
+ mkdir sdir
+ echo sfile >sdir/sfile
+ dotest_sort dirs-1 \
+"${testcvs} import -m import-it dir1 vend rel" "
+
+N dir1/file1
+N dir1/sdir/sfile
+No conflicts created by this import
+${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/dir1/sdir"
+ cd ..
+
+ mkdir 1; cd 1
+ dotest dirs-2 "${testcvs} -Q co dir1" ""
+
+ # Various CVS administrators are in the habit of removing
+ # the repository directory for things they don't want any
+ # more. I've even been known to do it myself (on rare
+ # occasions). Not the usual recommended practice, but we want
+ # to try to come up with some kind of reasonable/documented/sensible
+ # behavior.
+ rm -rf ${CVSROOT_DIRNAME}/dir1/sdir
+
+ dotest dirs-3 "${testcvs} update" \
+"${PROG} [a-z]*: Updating dir1
+${PROG} [a-z]*: Updating dir1/sdir
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/dir1/sdir: No such file or directory
+${PROG} [a-z]*: skipping directory dir1/sdir"
+ dotest dirs-3a "${testcvs} update -d" \
+"${PROG} [a-z]*: Updating dir1
+${PROG} [a-z]*: Updating dir1/sdir
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/dir1/sdir: No such file or directory
+${PROG} [a-z]*: skipping directory dir1/sdir"
+
+ # If we say "yes", then CVS gives errors about not being able to
+ # create lock files.
+ if echo no | ${testcvs} release -d dir1/sdir \
+ >${TESTDIR}/output.tmp 2>&1; then
+ pass dirs-4
+ else
+ fail dirs-4
+ fi
+ # The fact that it says "skipping directory " rather than
+ # "skipping directory dir1/sdir" is some kind of bug.
+ dotest dirs-4a "cat ${TESTDIR}/output.tmp" \
+"${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/dir1/sdir: No such file or directory
+${PROG} [a-z]*: skipping directory
+You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .dir1/sdir': .. .release' aborted by user choice."
+
+ # OK, if "cvs release" won't help, we'll try it the other way...
+ rm -r dir1/sdir
+
+ dotest dirs-5 "cat dir1/CVS/Entries" \
+"/file1/1.1.1.1/[a-zA-Z0-9 :]*//
+D/sdir////"
+ dotest dirs-6 "${testcvs} update" "${PROG} [a-z]*: Updating dir1"
+ dotest dirs-7 "cat dir1/CVS/Entries" \
+"/file1/1.1.1.1/[a-zA-Z0-9 :]*//
+D/sdir////"
+ dotest dirs-8 "${testcvs} update -d dir1" \
+"${PROG} [a-z]*: Updating dir1"
+
+ cd ..
+
+ rm -r imp-dir 1
+ rm ${TESTDIR}/output.tmp
+
+ # clean up our repositories
+ rm -rf ${CVSROOT_DIRNAME}/dir1
+ ;;
+
+ dirs2)
+ # See "dirs" for a list of tests involving adding and
+ # removing directories.
+ mkdir 1; cd 1
+ dotest dirs2-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest dirs2-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ mkdir sdir
+ dotest dirs2-3 "${testcvs} add sdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository"
+ touch sdir/file1
+ dotest dirs2-4 "${testcvs} add sdir/file1" \
+"${PROG} [a-z]*: scheduling file .sdir/file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest dirs2-5 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/file1,v
+done
+Checking in sdir/file1;
+${TESTDIR}/cvsroot/first-dir/sdir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ rm -r sdir/CVS
+ if test "$remote" = yes; then
+ # This is just like conflicts3-23
+ dotest_fail dirs2-6 "${testcvs} update -d" \
+"${QUESTION} sdir
+${PROG} server: Updating \.
+${PROG} update: in directory sdir:
+${PROG} update: cannot open CVS/Entries for reading: No such file or directory
+${PROG} server: Updating sdir
+${PROG} update: move away sdir/file1; it is in the way
+C sdir/file1"
+ rm sdir/file1
+
+ # This is where things are not just like conflicts3-23
+ # As with conflicts3-23, all these CVS/Entries* warnings
+ # are somewhat doubtful, and we probably should think some
+ # about whether they should be changed/fixed.
+ dotest dirs2-7 "${testcvs} update -d" \
+"${QUESTION} sdir
+${PROG} server: Updating \.
+${PROG} update: in directory sdir:
+${PROG} update: cannot open CVS/Entries for reading: No such file or directory
+${PROG} server: Updating sdir
+U sdir/file1
+${PROG} update: cannot open CVS/Entries.Log: No such file or directory"
+ else
+ dotest dirs2-6 "${testcvs} update -d" \
+"${PROG} update: Updating \.
+${QUESTION} sdir"
+ rm sdir/file1
+ dotest dirs2-7 "${testcvs} update -d" \
+"${PROG} update: Updating \.
+${QUESTION} sdir"
+ fi
+ cd ../..
+
+ # Now, the same thing (more or less) on a branch.
+ mkdir 2; cd 2
+ dotest dirs2-8 "${testcvs} -q co first-dir" 'U first-dir/sdir/file1'
+ cd first-dir
+ dotest dirs2-9 "${testcvs} -q tag -b br" "T sdir/file1"
+ rm -r sdir/CVS
+ if test "$remote" = yes; then
+ # Cute little quirk of val-tags; if we don't recurse into
+ # the directories where the tag is defined, val-tags won't
+ # get updated.
+ dotest_fail dirs2-10 "${testcvs} update -d -r br" \
+"${QUESTION} sdir
+${PROG} \[server aborted\]: no such tag br"
+ dotest dirs2-10-rem \
+"${testcvs} -q rdiff -u -r 1.1 -r br first-dir/sdir/file1" \
+""
+ dotest_fail dirs2-10-again "${testcvs} update -d -r br" \
+"${QUESTION} sdir
+${PROG} server: Updating \.
+${PROG} update: in directory sdir:
+${PROG} update: cannot open CVS/Entries for reading: No such file or directory
+${PROG} update: cannot open CVS/Tag: No such file or directory
+${PROG} update: cannot open CVS/Tag: No such file or directory
+${PROG} server: Updating sdir
+${PROG} update: move away sdir/file1; it is in the way
+C sdir/file1
+${PROG} update: cannot open CVS/Tag: No such file or directory"
+ else
+ dotest_fail dirs2-10 "${testcvs} update -d -r br" \
+"${PROG} update: in directory sdir:
+${PROG} \[update aborted\]: there is no version here; do 'cvs checkout' first"
+ fi
+ cd ../..
+
+ # OK, the above tests make the situation somewhat harder
+ # than it might be, in the sense that they actually have a
+ # file which is alive on the branch we are updating. Let's
+ # try it where it is just a directory where all the files
+ # have been removed.
+ mkdir 3; cd 3
+ dotest dirs2-11 "${testcvs} -q co -r br first-dir" \
+"U first-dir/sdir/file1"
+ cd first-dir
+ # Hmm, this doesn't mention the branch like add does. That's
+ # an odd non-orthogonality.
+ dotest dirs2-12 "${testcvs} rm -f sdir/file1" \
+"${PROG} [a-z]*: scheduling .sdir/file1. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+ dotest dirs2-13 "${testcvs} -q ci -m remove" \
+"Removing sdir/file1;
+${TESTDIR}/cvsroot/first-dir/sdir/file1,v <-- file1
+new revision: delete; previous revision: 1\.1\.2
+done"
+ cd ../../2/first-dir
+ if test "$remote" = yes; then
+ dotest dirs2-14 "${testcvs} update -d -r br" \
+"${QUESTION} sdir
+${PROG} server: Updating \.
+${PROG} update: in directory sdir:
+${PROG} update: cannot open CVS/Entries for reading: No such file or directory
+${PROG} update: cannot open CVS/Tag: No such file or directory
+${PROG} update: cannot open CVS/Tag: No such file or directory
+${PROG} server: Updating sdir
+${PROG} update: cannot open CVS/Tag: No such file or directory"
+ else
+ dotest dirs2-14 "${testcvs} update -d -r br" \
+"${PROG} update: Updating \.
+${QUESTION} sdir"
+ fi
+ cd ../..
+
+ rm -r 1 2 3
+ rm -rf ${TESTDIR}/cvsroot/first-dir
+ ;;
+
branches)
# More branch tests, including branches off of branches
mkdir ${CVSROOT_DIRNAME}/first-dir
@@ -3389,6 +4025,58 @@ File: file5 Status: Up-to-date
rm -r trunk b1a b1b
;;
+ tagc)
+ # Test the tag -c option.
+ mkdir 1; cd 1
+ dotest tagc-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest tagc-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ touch file1
+ dotest tagc-3 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest tagc-4 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+done
+Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ dotest tagc-5 "${testcvs} -q tag -c tag1" "T file1"
+ touch file1
+ dotest tagc-6 "${testcvs} -q tag -c tag2" "T file1"
+ # Avoid timestamp granularity bugs (FIXME: CVS should be
+ # doing the sleep, right?).
+ sleep 1
+ echo myedit >>file1
+ dotest_fail tagc-7 "${testcvs} -q tag -c tag3" \
+"${PROG} [a-z]*: file1 is locally modified
+${PROG} \[[a-z]* aborted\]: correct the above errors first!"
+ cd ../..
+ mkdir 2
+ cd 2
+ dotest tagc-8 "${testcvs} -q co first-dir" "U first-dir/file1"
+ cd ../1/first-dir
+ dotest tagc-9 "${testcvs} -q ci -m modify" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.2; previous revision: 1\.1
+done"
+ cd ../../2/first-dir
+ # That this is an error is a bug. Although the bug has existed
+ # since tag -c was created, I don't think there would be a
+ # compatibility problem with just fixing it.
+ dotest_fail tagc-10 "${testcvs} -q tag -c tag4" \
+"${PROG} [a-z]*: file1 is locally modified
+${PROG} \[[a-z]* aborted\]: correct the above errors first!"
+ cd ../..
+
+ rm -r 1 2
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
rcslib)
# Test librarification of RCS.
# First: test whether `cvs diff' handles $Name expansion
@@ -3603,7 +4291,46 @@ two
${TESTDIR}/cvsroot/first-dir/file1,v <-- file2
new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
- dotest rcslib-symlink-4 "test -L ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ dotest rcslib-symlink-4 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
+".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
+ # Test 5 reveals a problem with having symlinks in the
+ # repository. CVS will try to tag both of the files
+ # separately. After processing one, it will do the same
+ # operation to the other, which is actually the same file,
+ # so the tag will already be there. FIXME: do we bother
+ # changing operations to notice cases like this? This
+ # strikes me as a difficult problem. -Noel
+ dotest rcslib-symlink-5 "${testcvs} tag the_tag" \
+"${PROG} [a-z]*: Tagging .
+T file1
+W file2 : the_tag already exists on version 1.1.2.1 : NOT MOVING tag to version 1.1.2.2"
+ dotest rcslib-symlink-6 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
+".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
+
+ # Symlinks tend to interact poorly with the Attic.
+ cd ..
+ mkdir 2; cd 2
+ dotest rcslib-symlink-7 "${testcvs} -q co first-dir" \
+"U first-dir/file1
+U first-dir/file2"
+ cd first-dir
+ dotest rcslib-symlink-8 "${testcvs} rm -f file2" \
+"${PROG} [a-z]*: scheduling .file2. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+ dotest rcslib-symlink-9 "${testcvs} -q ci -m rm-it" \
+"Removing file2;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file2
+new revision: delete; previous revision: 1\.2
+done"
+ # OK, why this message happens twice is relatively clear
+ # (the check_* and rtag_* calls to start_recursion).
+ # Why it happens a third time I didn't try to find out.
+ dotest rcslib-symlink-10 \
+"${testcvs} -q rtag -b -r the_tag brtag first-dir" \
+"${PROG} [a-z]*: could not read RCS file for file2
+${PROG} [a-z]*: could not read RCS file for first-dir/file2
+${PROG} [a-z]*: could not read RCS file for first-dir/file2"
+ cd ..
cd ..
@@ -3613,7 +4340,7 @@ done"
fi
rm -rf ${CVSROOT_DIRNAME}/first-dir
- rm -r first-dir
+ rm -r first-dir 2
;;
multibranch)
@@ -3718,7 +4445,7 @@ modify-on-br1
mkdir import-dir ; cd import-dir
for i in 1 2 3 4 ; do
- echo imported file"$i" > imported-f"$i"
+ echo imported file"$i" > imported-f"$i"
done
# This directory should be on the default ignore list,
@@ -3729,157 +4456,164 @@ modify-on-br1
echo 'import should not expand $''Id$' >>imported-f2
cp imported-f2 ../imported-f2-orig.tmp
- if ${CVS} import -m first-import first-dir vendor-branch junk-1_0 ; then
- pass 96
- else
- fail 96
- fi
+ dotest_sort import-96 \
+"${testcvs} import -m first-import first-dir vendor-branch junk-1_0" \
+"
+
+I first-dir/RCS
+N first-dir/imported-f1
+N first-dir/imported-f2
+N first-dir/imported-f3
+N first-dir/imported-f4
+No conflicts created by this import"
+
+ dotest import-96.5 "cmp ../imported-f2-orig.tmp imported-f2" ''
- if cmp ../imported-f2-orig.tmp imported-f2; then
- pass 96.5
- else
- fail 96.5
- fi
cd ..
# co
- if ${CVS} co first-dir ; then
- pass 97
- else
- fail 97
- fi
+ dotest import-97 "${testcvs} -q co first-dir" \
+"U first-dir/imported-f1
+U first-dir/imported-f2
+U first-dir/imported-f3
+U first-dir/imported-f4"
cd first-dir
+
for i in 1 2 3 4 ; do
- if test -f imported-f"$i" ; then
- pass 98-$i
- else
- fail 98-$i
- fi
+ dotest import-98-$i "test -f imported-f$i" ''
done
- if test -d RCS; then
- fail 98.5
- else
- pass 98.5
- fi
+ dotest_fail import-98.5 "test -d RCS" ''
# remove
rm imported-f1
- if ${CVS} rm imported-f1 2>> ${LOGFILE}; then
- pass 99
- else
- fail 99
- fi
+ dotest import-99 "${testcvs} rm imported-f1" \
+"${PROG}"' [a-z]*: scheduling `imported-f1'\'' for removal
+'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently'
# change
echo local-change >> imported-f2
# commit
- if ${CVS} ci -m local-changes >> ${LOGFILE} 2>&1; then
- pass 100
- else
- fail 100
- fi
+ dotest import-100 "${testcvs} ci -m local-changes" \
+"${PROG} [a-z]*: Examining .
+Removing imported-f1;
+${TESTDIR}/cvsroot/first-dir/imported-f1,v <-- imported-f1
+new revision: delete; previous revision: 1\.1\.1\.1
+done
+Checking in imported-f2;
+${TESTDIR}/cvsroot/first-dir/imported-f2,v <-- imported-f2
+new revision: 1\.2; previous revision: 1\.1
+done"
# log
- if ${CVS} log imported-f1 | grep '1.1.1.2 (dead)' ; then
- fail 101
- else
- pass 101
- fi
+ dotest import-101 "${testcvs} log imported-f1" \
+"
+RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/imported-f1,v
+Working file: imported-f1
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ junk-1_0: 1\.1\.1\.1
+ vendor-branch: 1\.1\.1
+keyword substitution: kv
+total revisions: 3; selected revisions: 3
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: dead; lines: ${PLUS}0 -0
+local-changes
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+branches: 1\.1\.1;
+Initial revision
+----------------------------
+revision 1\.1\.1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}0 -0
+first-import
+============================================================================="
# update into the vendor branch.
- if ${CVS} update -rvendor-branch ; then
- pass 102
- else
- fail 102
- fi
+ dotest import-102 "${testcvs} update -rvendor-branch" \
+"${PROG} [a-z]*: Updating .
+[UP] imported-f1
+[UP] imported-f2"
# remove file4 on the vendor branch
rm imported-f4
-
- if ${CVS} rm imported-f4 2>> ${LOGFILE}; then
- pass 103
- else
- fail 103
- fi
+ dotest import-103 "${testcvs} rm imported-f4" \
+"${PROG}"' [a-z]*: scheduling `imported-f4'\'' for removal
+'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently'
# commit
- if ${CVS} ci -m vendor-removed imported-f4 >>${LOGFILE}; then
- pass 104
- else
- fail 104
- fi
+ dotest import-104 \
+"${testcvs} ci -m vendor-removed imported-f4" \
+"Removing imported-f4;
+${TESTDIR}/cvsroot/first-dir/imported-f4,v <-- imported-f4
+new revision: delete; previous revision: 1\.1\.1\.1
+done"
# update to main line
- if ${CVS} update -A 2>> ${LOGFILE}; then
- pass 105
- else
- fail 105
- fi
+ dotest import-105 "${testcvs} -q update -A" \
+"${PROG} [a-z]*: warning: imported-f1 is not (any longer) pertinent
+[UP] imported-f2"
# second import - file4 deliberately unchanged
cd ../import-dir
for i in 1 2 3 ; do
- echo rev 2 of file $i >> imported-f"$i"
+ echo rev 2 of file $i >> imported-f"$i"
done
cp imported-f2 ../imported-f2-orig.tmp
- if ${CVS} import -m second-import first-dir vendor-branch junk-2_0 ; then
- pass 106
- else
- fail 106
- fi
- if cmp ../imported-f2-orig.tmp imported-f2; then
- pass 106.5
- else
- fail 106.5
- fi
+ dotest_sort import-106 \
+"${testcvs} import -m second-import first-dir vendor-branch junk-2_0" \
+"
+
+
+ ${PROG} checkout -jvendor-branch:yesterday -jvendor-branch first-dir
+2 conflicts created by this import.
+C first-dir/imported-f1
+C first-dir/imported-f2
+I first-dir/RCS
+U first-dir/imported-f3
+U first-dir/imported-f4
+Use the following command to help the merge:"
+
+ dotest import-106.5 "cmp ../imported-f2-orig.tmp imported-f2" \
+''
+
cd ..
+
rm imported-f2-orig.tmp
# co
- if ${CVS} co first-dir ; then
- pass 107
- else
- fail 107
- fi
+ dotest import-107 "${testcvs} co first-dir" \
+"${PROG} [a-z]*: Updating first-dir
+[UP] first-dir/imported-f3
+[UP] first-dir/imported-f4"
cd first-dir
- if test -f imported-f1 ; then
- fail 108
- else
- pass 108
- fi
+ dotest_fail import-108 "test -f imported-f1" ''
for i in 2 3 ; do
- if test -f imported-f"$i" ; then
- pass 109-$i
- else
- fail 109-$i
- fi
+ dotest import-109-$i "test -f imported-f$i" ''
done
# check vendor branch for file4
- if ${CVS} update -rvendor-branch ; then
- pass 110
- else
- fail 110
- fi
+ dotest import-110 "${testcvs} -q update -rvendor-branch" \
+"[UP] imported-f1
+[UP] imported-f2"
- if test -f imported-f4 ; then
- pass 111
- else
- fail 111
- fi
+ dotest import-111 "test -f imported-f4" ''
# update to main line
- if ${CVS} update -A 2>> ${LOGFILE}; then
- pass 112
- else
- fail 112
- fi
+ dotest import-112 "${testcvs} -q update -A" \
+"${PROG} [a-z]*: warning: imported-f1 is not (any longer) pertinent
+[UP] imported-f2"
cd ..
@@ -3894,18 +4628,10 @@ rcsmerge: warning: conflicts during merge"
cd first-dir
- if test -f imported-f1 ; then
- fail 114
- else
- pass 114
- fi
+ dotest_fail import-114 "test -f imported-f1" ''
for i in 2 3 ; do
- if test -f imported-f"$i" ; then
- pass 115-$i
- else
- fail 115-$i
- fi
+ dotest import-115-$i "test -f imported-f$i" ''
done
dotest import-116 'cat imported-f2' \
@@ -3950,12 +4676,14 @@ 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).
+ # We use an explicit -d option to test that it is reflected
+ # in the suggested checkout.
dotest_sort importb-2 \
-"${testcvs} import -m add -b 1.1.3 first-dir freemunger freemunger-1_0" \
+"${testcvs} -d ${CVSROOT} import -m add -b 1.1.3 first-dir freemunger freemunger-1_0" \
"
- ${PROG} checkout -jfreemunger:yesterday -jfreemunger first-dir
+ ${PROG} -d ${CVSROOT} checkout -jfreemunger:yesterday -jfreemunger first-dir
2 conflicts created by this import.
C first-dir/file1
C first-dir/file2
@@ -4024,16 +4752,25 @@ add
importc)
# Test importing a bunch o' files in a bunch o' directories.
+ # Also the -d option.
mkdir 1; cd 1
mkdir adir bdir cdir
mkdir adir/sub1 adir/sub2
mkdir adir/sub1/ssdir
mkdir bdir/subdir
touch adir/sub1/file1 adir/sub2/file2 adir/sub1/ssdir/ssfile
- touch bdir/subdir/file1
- touch cdir/cfile
+ # If I'm correctly reading the Single Unix Specification,
+ # version 2, then "touch -t 197107040343" or "touch -t 203412251801"
+ # should work. But GNU touch seems to have other ideas.
+ # I sort of wonder if this is lossage by the standards bodies,
+ # I'm not sure.
+ # Note that some versions of touch when used without -t don't handle
+ # y2k and/or set the seconds reliably.
+ # We should probably find a different way of doing this.
+ touch 0704034371 bdir/subdir/file1
+ touch 1225180134 cdir/cfile
dotest_sort importc-1 \
-"${testcvs} import -m import-it first-dir vendor release" \
+"${testcvs} import -d -m import-it first-dir vendor release" \
"
N first-dir/adir/sub1/file1
@@ -4092,6 +4829,63 @@ ${TESTDIR}/cvsroot/first-dir/cdir/cfile,v <-- cfile
new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1
done"
fi
+
+ # TODO: should also be testing "import -d" when we update
+ # an existing file.
+ dotest importc-8 "${testcvs} -q log cdir/cfile" "
+RCS file: ${TESTDIR}/cvsroot/first-dir/cdir/cfile,v
+Working file: cdir/cfile
+head: 1\.1
+branch: 1\.1\.1
+locks: strict
+access list:
+symbolic names:
+ wip_test: 1\.1\.1\.1\.0\.2
+ release: 1\.1\.1\.1
+ vendor: 1\.1\.1
+keyword substitution: kv
+total revisions: 3; selected revisions: 3
+description:
+----------------------------
+revision 1\.1
+date: 2034/12/2[4-6] [0-9][0-9]:01:[0-9][0-9]; author: ${username}; state: Exp;
+branches: 1\.1\.1;
+Initial revision
+----------------------------
+revision 1\.1\.1\.1
+date: 2034/12/2[4-6] [0-9][0-9]:01:[0-9][0-9]; author: ${username}; state: Exp; lines: ${PLUS}0 -0
+branches: 1\.1\.1\.1\.2;
+import-it
+----------------------------
+revision 1\.1\.1\.1\.2\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+modify
+============================================================================="
+
+ dotest importc-9 "${testcvs} -q log bdir/subdir/file1" "
+RCS file: ${TESTDIR}/cvsroot/first-dir/bdir/subdir/file1,v
+Working file: bdir/subdir/file1
+head: 1\.1
+branch: 1\.1\.1
+locks: strict
+access list:
+symbolic names:
+ wip_test: 1\.1\.1\.1\.0\.2
+ release: 1\.1\.1\.1
+ vendor: 1\.1\.1
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.1
+date: 1971/07/0[3-5] [0-9][0-9]:43:[0-9][0-9]; author: ${username}; state: Exp;
+branches: 1\.1\.1;
+Initial revision
+----------------------------
+revision 1\.1\.1\.1
+date: 1971/07/0[3-5] [0-9][0-9]:43:[0-9][0-9]; author: ${username}; state: Exp; lines: ${PLUS}0 -0
+import-it
+============================================================================="
cd ..
cd ..
@@ -4099,6 +4893,62 @@ done"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ import-after-initial)
+ # Properly handle the case in which the first version of a
+ # file is created by a regular cvs add and commit, and there
+ # is a subsequent cvs import of the same file. cvs update with
+ # a date tag must resort to searching the vendor branch only if
+ # the initial version of the file was created at the same time
+ # as the initial version on the vendor branch.
+
+ mkdir 1; cd 1
+ module=x
+
+ echo > unused-file
+
+ # Create the module.
+ dotest import-after-initial-1 \
+ "$testcvs -Q import -m. $module X Y" ''
+
+ file=m
+ # Check it out and add a file.
+ dotest import-after-initial-2 "$testcvs -Q co $module" ''
+ cd $module
+ echo original > $file
+ dotest import-after-initial-3 "${testcvs} -Q add $file" \
+"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+ dotest import-after-initial-4 "${testcvs} -Q ci -m. $file" \
+"RCS file: ${TESTDIR}/cvsroot/$module/$file,v
+done
+Checking in $file;
+${TESTDIR}/cvsroot/$module/$file,v <-- $file
+initial revision: 1\.1
+done"
+
+ # Delay a little so the following import isn't done in the same
+ # second as the preceding commit.
+ sleep 2
+
+ # Do the first import of $file *after* $file already has an
+ # initial version.
+ mkdir sub
+ cd sub
+ echo newer-via-import > $file
+ dotest import-after-initial-5 \
+ "$testcvs -Q import -m. $module X Y2" ''
+ cd ..
+
+ # Sleep a second so we're sure to be after the second of the import.
+ sleep 1
+
+ dotest import-after-initial-6 \
+ "$testcvs -Q update -p -D now $file" 'original'
+
+ cd ../..
+ rm -rf 1
+ rm -rf ${CVSROOT_DIRNAME}/$module
+ ;;
+
join)
# Test doing joins which involve adding and removing files.
# Variety of scenarios (see list below), in the context of:
@@ -4108,6 +4958,8 @@ done"
# See also binfile2, which does similar things with binary files.
# See also join2, which tests joining (and update -A) on only
# a single file, rather than a directory.
+ # See also rmadd2, which tests -j cases not involving branches
+ # (e.g. undoing a commit)
# See also join3, which tests some cases involving the greatest
# common ancestor. Here is a list of tests according to branch
# topology:
@@ -4728,6 +5580,60 @@ br2:line1
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ join-readonly-conflict)
+ # Demonstrate that cvs-1.9.29 can fail on 2nd and subsequent
+ # conflict-evoking join attempts.
+ # Even with that version of CVS, This test failed only in
+ # client-server mode, and would have been noticed in normal
+ # operation only for files that were read-only (either due to
+ # use of cvs' global -r option, setting the CVSREAD envvar,
+ # or use of watch lists).
+ mkdir 1; cd 1
+ dotest join-readonly-conflict-1 "$testcvs -q co -l ." ''
+ module=x
+ mkdir $module
+ $testcvs -q add $module >>$LOGFILE 2>&1
+ cd $module
+
+ file=m
+ echo trunk > $file
+ $testcvs -q add $file >>$LOGFILE 2>&1
+ $testcvs -q ci -m . $file >>$LOGFILE 2>&1
+
+ $testcvs tag -b B $file >>$LOGFILE 2>&1
+ $testcvs -q update -rB $file >>$LOGFILE 2>&1
+ echo branch B > $file
+ $testcvs ci -m . $file >>$LOGFILE 2>&1
+
+ rm $file
+ $testcvs update -A $file >>$LOGFILE 2>&1
+ # Make sure $file is read-only. This can happen more realistically
+ # via patch -- which could be used to apply a delta, yet would
+ # preserve a file's read-only permissions.
+ echo conflict > $file; chmod u-w $file
+ $testcvs update -r B $file >>$LOGFILE 2>&1
+
+ rm -f $file
+ $testcvs update -A $file >>$LOGFILE 2>&1
+ # This one would fail because cvs couldn't open the existing
+ # (and read-only) .# file for writing.
+ echo conflict > $file
+
+ test -w ".#$file.1.1" && fail "$file is writable"
+ dotest join-readonly-conflict-2 "$testcvs update -r B $file" \
+"RCS file: ${TESTDIR}/cvsroot/$module/$file,v
+retrieving revision 1\.1
+retrieving revision 1\.1\.2\.1
+Merging differences between 1\.1 and 1\.1\.2\.1 into $file
+rcsmerge: warning: conflicts during merge
+${PROG} [a-z]*: conflicts found in $file
+C m"
+
+ cd ../..
+ rm -rf 1
+ rm -rf ${CVSROOT_DIRNAME}/$module
+ ;;
+
new) # look for stray "no longer pertinent" messages.
mkdir ${CVSROOT_DIRNAME}/first-dir
@@ -4973,6 +5879,14 @@ File: a Status: Needs Merge
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)"
+ dotest conflicts-129a "${testcvs} -nq update a" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/a,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into a
+rcsmerge: warning: conflicts during merge
+${PROG} [a-z]*: conflicts found in a
+C a"
dotest conflicts-130 "${testcvs} -q update" \
"RCS file: ${TESTDIR}/cvsroot/first-dir/a,v
retrieving revision 1\.1
@@ -5163,6 +6077,9 @@ done"
U first-dir/abc'
cd ..
+ # BEGIN TESTS USING THE FILE A
+ # FIXME: would be cleaner to separate them out into their own
+ # tests; conflicts2 is getting long.
# Now test that if one person modifies and commits a
# file and a second person removes it, it is a
# conflict
@@ -5186,7 +6103,46 @@ C a"
dotest conflicts2-142b5 "${testcvs} add a" "U a
${PROG} [a-z]*: a, version 1\.1, resurrected"
dotest conflicts2-142b6 "${testcvs} -q update" ''
+
+ # Now one level up.
+ cd ..
+ dotest conflicts2-142b7 "${testcvs} rm -f first-dir/a" \
+"${PROG} [a-z]*: scheduling .first-dir/a. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+
+ if test "$remote" = no; then
+ # The "nothing known" is a bug. Correct behavior is for a to get
+ # created, as above. Cause is pretty obvious - add.c
+ # calls update() without dealing with the fact we are chdir'd.
+ # Also note that resurrecting 1.2 instead of 1.1 is also a
+ # bug, I think (the same part of add.c has a comment which says
+ # "XXX - bugs here; this really resurrect the head" which
+ # presumably refers to this).
+ # The fix for both is presumably to call RCS_checkout() or
+ # something other than update().
+ dotest conflicts2-142b8 "${testcvs} add first-dir/a" \
+"${PROG} [a-z]*: nothing known about first-dir
+${PROG} [a-z]*: first-dir/a, version 1\.2, resurrected"
+ cd first-dir
+ # Now recover from the damage that the 142b8 test did.
+ dotest conflicts2-142b9 "${testcvs} rm -f a" \
+"${PROG} [a-z]*: scheduling .a. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+ else
+ # Haven't investigated this one.
+ dotest_fail conflicts2-142b8 "${testcvs} add first-dir/a" \
+"${PROG} add: in directory \.:
+${PROG} \[add aborted\]: there is no version here; do 'cvs checkout' first"
+ cd first-dir
+ fi
+
+ # As before, 1.2 instead of 1.1 is a bug.
+ dotest conflicts2-142b10 "${testcvs} add a" "U a
+${PROG} [a-z]*: a, version 1\.2, resurrected"
+ # As with conflicts2-142b6, check that things are normal again.
+ dotest conflicts2-142b11 "${testcvs} -q update" ''
cd ../..
+ # END TESTS USING THE FILE A
# Now test that if one person removes a file and
# commits it, and a second person removes it, is it
@@ -5438,7 +6394,7 @@ ${PROG} [a-z]*: ignoring first-dir/sdir (CVS/Entries missing)"
dotest conflicts3-21 "${testcvs} -q update -d sdir" "U sdir/sfile"
rm -r sdir/CVS
- dotest conflicts3-22 "${testcvs} -q update" "? sdir"
+ dotest conflicts3-22 "${testcvs} -q update" "${QUESTION} 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
@@ -5456,6 +6412,37 @@ C sdir/sfile"
"${QUESTION} sdir"
fi
+ # Not that it should really affect much, but let's do the case
+ # where sfile has been removed. For example, suppose that sdir
+ # had been a CVS-controlled directory which was then removed
+ # by removing each file (and using update -P or some such). Then
+ # suppose that the build process creates an sdir directory which
+ # is not supposed to be under CVS.
+ rm -r sdir
+ dotest conflicts3-24 "${testcvs} -q update -d sdir" "U sdir/sfile"
+ rm sdir/sfile
+ dotest conflicts3-25 "${testcvs} rm sdir/sfile" \
+"${PROG} [a-z]*: scheduling .sdir/sfile. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+ dotest conflicts3-26 "${testcvs} ci -m remove sdir/sfile" \
+"Removing sdir/sfile;
+${TESTDIR}/cvsroot/first-dir/sdir/sfile,v <-- sfile
+new revision: delete; previous revision: 1\.1
+done"
+ rm -r sdir/CVS
+ dotest conflicts3-27 "${testcvs} -q update" "${QUESTION} sdir"
+ if test "x$remote" = xyes; then
+ # Regarding "cannot open CVS/Entries", see comments at
+ # conflicts3-23.
+ dotest conflicts3-28 "${testcvs} -q update -PdA" \
+"${QUESTION} sdir
+${PROG} update: in directory sdir:
+${PROG} update: cannot open CVS/Entries for reading: No such file or directory"
+ else
+ dotest conflicts3-28 "${testcvs} -q update -PdA" \
+"${QUESTION} sdir"
+ fi
+
cd ../..
rm -r 1 2
@@ -5906,10 +6893,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
dotest modules2-5 "test -d ampermodule/second-dir" ''
# Test ability of cvs release to handle multiple arguments
- # Other CVS release tests:
- # info-cleanup-0 for "cvs -n release".
- # ignore-193 for the text of the question that cvs release asks.
- # Also for interactions with cvsignore.
+ # See comment at "release" for list of other cvs release tests.
cd ampermodule
if ${testcvs} release -d first-dir second-dir <<EOF >>${LOGFILE}
yes
@@ -5983,26 +6967,15 @@ U first-dir/amper1"
dotest modules2-16 "test -f combmodule/first-dir/amper1" ""
cd combmodule
rm -r first-dir
- # Might be possible to have a more graceful error message,
- # but at least for now there is no way to tell CVS that
+ # At least for now there is no way to tell CVS that
# some files/subdirectories come from one repository directory,
# and others from another.
- if test "$remote" = no; then
- dotest_fail modules2-17 "${testcvs} update -d" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating first-dir
-${PROG} \[[a-z]* aborted\]: cannot open directory ${TESTDIR}/cvsroot/third-dir/first-dir: No such file or directory"
- # Clean up the droppings left by the previous command.
- # This should definitely not be necessary (I think).
- rm -r first-dir
- else
- # This seems like a pretty sensible behavior to me, in the
- # sense that first-dir doesn't "really" exist within
- # third-dir, so CVS just acts as if there is nothing there
- # to do.
- dotest modules2-17 "${testcvs} update -d" \
-"${PROG} server: Updating \."
- fi
+ # This seems like a pretty sensible behavior to me, in the
+ # sense that first-dir doesn't "really" exist within
+ # third-dir, so CVS just acts as if there is nothing there
+ # to do.
+ dotest modules2-17 "${testcvs} update -d" \
+"${PROG} [a-z]*: Updating \."
cd ..
dotest modules2-18 "${testcvs} -q co combmodule" \
@@ -6332,6 +7305,30 @@ add-it
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ mkmodules-temp-file-removal)
+ # When a file listed in checkoutlist doesn't exist, cvs-1.10.4
+ # would fail to remove the CVSROOT/.#[0-9]* temporary file it
+ # creates while mkmodules is in the process of trying to check
+ # out the missing file.
+
+ mkdir 1; cd 1
+ dotest mtfr-1 "${testcvs} -Q co CVSROOT" ''
+ cd CVSROOT
+ echo no-such-file >> checkoutlist
+ dotest mtfr-2 "${testcvs} -Q ci -m. checkoutlist" \
+"Checking in checkoutlist;
+$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist
+new revision: 1\.2; previous revision: 1\.1
+done
+$PROG [a-z]*: Rebuilding administrative file database"
+
+ dotest mtfr-3 "echo $CVSROOT_DIRNAME/CVSROOT/.#[0-9]*" \
+ "$CVSROOT_DIRNAME/CVSROOT/\.#\[0-9\]\*"
+
+ cd ../..
+ rm -rf 1
+ ;;
+
cvsadm)
# These test check the content of CVS' administrative
# files as they are checked out in various configurations.
@@ -7812,22 +8809,15 @@ done"
U dir2d1/sub2d1/file1"
cd dir2d1
touch emptyfile
- # The fact that CVS lets us add a file here is a CVS bug, right?
- # I can just make this an error message (on the add and/or the
- # commit) without getting flamed, right?
- # Right?
- # Right?
+ # It doesn't make any sense to add a file (or do much of anything
+ # else) in Emptydir; Emptydir is a placeholder indicating that
+ # the working directory doesn't correspond to anything in
+ # the repository.
dotest emptydir-7 "${testcvs} add emptyfile" \
"${PROG} [a-z]*: scheduling file .emptyfile. for addition
${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
- dotest emptydir-8 "${testcvs} -q ci -m add" \
-"RCS file: ${TESTDIR}/cvsroot/CVSROOT/Emptydir/emptyfile,v
-done
-Checking in emptyfile;
-${TESTDIR}/cvsroot/CVSROOT/Emptydir/emptyfile,v <-- emptyfile
-initial revision: 1\.1
-done
-${PROG} [a-z]*: Rebuilding administrative file database"
+ dotest_fail emptydir-8 "${testcvs} -q ci -m add" \
+"${PROG} \[[a-z]* aborted\]: cannot check in to ${TESTDIR}/cvsroot/CVSROOT/Emptydir"
cd ..
rm -rf CVS dir2d1
@@ -8806,17 +9796,7 @@ done"
pass 177
fi
- if ${testcvs} editors >../ans178.tmp; then
- pass 178
- else
- fail 178
- fi
- cat ../ans178.tmp >>${LOGFILE}
- if test -s ../ans178.tmp; then
- fail 178a
- else
- pass 178a
- fi
+ dotest devcom-178 "${testcvs} editors" ""
if ${testcvs} edit abb; then
pass 179
@@ -8824,17 +9804,13 @@ done"
fail 179
fi
- if ${testcvs} editors >../ans180.tmp; then
- pass 180
- else
- fail 180
- fi
- cat ../ans180.tmp >>${LOGFILE}
- if test -s ../ans180.tmp; then
- pass 181
- else
- fail 181
- fi
+ # Here we test for the traditional ISO C ctime() date format.
+ # We assume the C locale; I guess that works provided we set
+ # LC_ALL at the start of this script but whether these
+ # strings should vary based on locale does not strike me as
+ # self-evident.
+ dotest devcom-180 "${testcvs} editors" \
+"abb ${username} [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] GMT [-a-zA-Z_.0-9]* ${TESTDIR}/2/first-dir"
echo aaaa >>abb
if ${testcvs} ci -m modify abb >>${LOGFILE} 2>&1; then
@@ -8845,17 +9821,7 @@ done"
# Unedit of a file not being edited should be a noop.
dotest 182.5 "${testcvs} unedit abb" ''
- if ${testcvs} editors >../ans183.tmp; then
- pass 183
- else
- fail 183
- fi
- cat ../ans183.tmp >>${LOGFILE}
- if test -s ../ans183.tmp; then
- fail 184
- else
- pass 184
- fi
+ dotest devcom-183 "${testcvs} editors" ""
if test -w abb; then
fail 185
@@ -9083,7 +10049,7 @@ D _watched="
Fw2 _watched="
# Now write a few more lines, just as if we were a newer version
# of CVS implementing some new feature.
- cat <<EOF >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr
+ cat <<'EOF' >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr
Enew line here
G@#$^!@#=&
EOF
@@ -9250,7 +10216,7 @@ ${PROG} unedit: run update to complete the unedit"
# SunOS4.1.4 systems make it this far, but with a corrupted
# CVS/Entries file. Demonstrate the corruption!
dotest unedit-without-baserev-5 "cat CVS/Entries" \
- "/$file/1\.1\.1\.1/.*"
+ "/$file/1\.1\.1\.1/${DOTSTAR}"
if test "$remote" = yes; then
dotest unedit-without-baserev-6 "${testcvs} -q update" "U m"
@@ -9476,11 +10442,18 @@ Are you sure you want to release (and delete) directory .second-dir': "
binfiles)
# Test cvs's ability to handle binary files.
+ # List of binary file tests:
+ # * conflicts, "cvs admin": binfiles
+ # * branching and joining: binfiles2
+ # * adding and removing files: binfiles3
+ # * -k wrappers: binwrap, binwrap2, binwrap3
+ # * "cvs import" and wrappers: binwrap, binwrap2, binwrap3
+ # * -k option to "cvs import": none yet, as far as I know.
mkdir ${CVSROOT_DIRNAME}/first-dir
mkdir 1; cd 1
dotest binfiles-1 "${testcvs} -q co first-dir" ''
- awk 'BEGIN { printf "%c%c%c%c%c%c", 2, 10, 137, 0, 13, 10 }' \
- </dev/null >binfile.dat
+ awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
+ </dev/null | tr '@' '\000' >binfile.dat
cat binfile.dat binfile.dat >binfile2.dat
cd first-dir
cp ../binfile.dat binfile
@@ -9577,7 +10550,6 @@ done"
dotest binfiles-13 "${testcvs} -q update -A" ''
cd ../..
- rm -r 1
mkdir 3
cd 3
@@ -9713,8 +10685,14 @@ keyword substitution: v
total revisions: 1
============================================================================="
+ # Check that the contents were right. This isn't the hard case
+ # (in which RCS_delete_revs does a diff), but might as well.
+ dotest binfiles-o4 "${testcvs} -q update binfile" "U binfile"
+ dotest binfiles-o5 "cmp binfile ../../1/binfile.dat" ""
+
cd ../..
rm -rf ${CVSROOT_DIRNAME}/first-dir
+ rm -r 1
rm -r 2
;;
@@ -9746,8 +10724,8 @@ total revisions: 1
# each be distinct from each other. We also make sure to include
# a few likely end-of-line patterns to make sure nothing is
# being munged as if in text mode.
- awk 'BEGIN { printf "%c%c%c%c%c%c", 2, 10, 137, 0, 13, 10 }' \
- </dev/null >../binfile
+ awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
+ </dev/null | tr '@' '\000' >../binfile
cat ../binfile ../binfile >../binfile2
cat ../binfile2 ../binfile >../binfile3
@@ -9902,6 +10880,96 @@ checkin
rm -r 1
;;
+ binfiles3)
+ # More binary file tests, especially removing, adding, &c.
+ # See "binfiles" for a list of binary file tests.
+ mkdir ${CVSROOT_DIRNAME}/first-dir
+ mkdir 1; cd 1
+ dotest binfiles3-1 "${testcvs} -q co first-dir" ''
+ awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
+ </dev/null | tr '@' '\000' >binfile.dat
+ cd first-dir
+ echo hello >file1
+ dotest binfiles3-2 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest binfiles3-3 "${testcvs} -q ci -m add-it" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+done
+Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ rm file1
+ dotest binfiles3-4 "${testcvs} rm file1" \
+"${PROG} [a-z]*: scheduling .file1. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+ dotest binfiles3-5 "${testcvs} -q ci -m remove-it" \
+"Removing file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: delete; previous revision: 1\.1
+done"
+ cp ../binfile.dat file1
+ dotest binfiles3-6 "${testcvs} add -kb file1" \
+"${PROG} [a-z]*: re-adding file file1 (in place of dead revision 1\.2)
+${PROG} [a-z]*: use .cvs commit. to add this file permanently"
+ # The idea behind this test is to make sure that the file
+ # gets opened in binary mode to send to "cvs ci".
+ dotest binfiles3-6a "cat CVS/Entries" \
+"/file1/0/[A-Za-z0-9 :]*/-kb/
+D"
+ # TODO: This just tests the case where the old keyword
+ # expansion mode is the default (RCS_getexpand == NULL
+ # in checkaddfile()); should also test the case in which
+ # we are changing it from one non-default value to another.
+ dotest binfiles3-7 "${testcvs} -q ci -m readd-it" \
+"${PROG} [a-z]*: changing keyword expansion mode to -kb
+Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.3; previous revision: 1\.2
+done"
+ dotest binfiles3-8 "${testcvs} -q log -h -N file1" "
+RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+Working file: file1
+head: 1\.3
+branch:
+locks: strict
+access list:
+keyword substitution: b
+total revisions: 3
+============================================================================="
+
+ # OK, now test admin -o on a binary file. See "admin"
+ # test for a more complete list of admin -o tests.
+ cp ${TESTDIR}/1/binfile.dat ${TESTDIR}/1/binfile4.dat
+ echo '%%$$##@@!!jjiiuull' | tr j '\000' >>${TESTDIR}/1/binfile4.dat
+ cp ${TESTDIR}/1/binfile4.dat ${TESTDIR}/1/binfile5.dat
+ echo 'aawwee%$$##@@!!jjil' | tr w '\000' >>${TESTDIR}/1/binfile5.dat
+
+ cp ../binfile4.dat file1
+ dotest binfiles3-9 "${testcvs} -q ci -m change" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.4; previous revision: 1\.3
+done"
+ cp ../binfile5.dat file1
+ dotest binfiles3-10 "${testcvs} -q ci -m change" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.5; previous revision: 1\.4
+done"
+ dotest binfiles3-11 "${testcvs} admin -o 1.3::1.5 file1" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+deleting revision 1\.4
+done"
+ dotest binfiles3-12 "${testcvs} -q update -r 1.3 file1" "U file1"
+ dotest binfiles3-13 "cmp file1 ${TESTDIR}/1/binfile.dat" ""
+
+ cd ../..
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
mcopy)
# See comment at "mwrap" test for list of other wrappers tests.
# Test cvs's ability to handle nonmergeable files specified with
@@ -10447,7 +11515,24 @@ done"
cd ../..
cd m1/first-dir
echo "changed in m1" >aa
- dotest_fail mwrap-7 "${testcvs} -nq update" "C aa"
+ if test "$remote" = no; then
+ dotest mwrap-7 "${testcvs} -nq update" \
+"U aa
+${PROG} [a-z]*: nonmergeable file needs merge
+${PROG} [a-z]*: revision 1\.2 from repository is now in aa
+${PROG} [a-z]*: file from working directory is now in \.#aa\.1\.1
+C aa"
+ else
+ # The tagged text code swallows up "U aa" but isn't yet up to
+ # trying to figure out how it interacts with the "C aa" and
+ # other stuff. The whole deal of having both is pretty iffy.
+ dotest mwrap-7 "${testcvs} -nq update" \
+"${PROG} [a-z]*: nonmergeable file needs merge
+${PROG} [a-z]*: revision 1\.2 from repository is now in aa
+${PROG} [a-z]*: file from working directory is now in \.#aa\.1\.1
+C aa
+U aa"
+ fi
dotest mwrap-8 "${testcvs} -q update" \
"U aa
${PROG} [a-z]*: nonmergeable file needs merge
@@ -10630,6 +11715,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
fi
cd ..
rm -r wnt
+ rm $HOME/.cvsrc
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -10639,8 +11725,6 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
# Tests to add:
# -F to move
- # -d
- # rtag
mkdir 1; cd 1
dotest taginfo-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}"
@@ -10708,6 +11792,16 @@ ${PROG} \[[a-z]* aborted\]: correct the above errors first!"
# specified or not.
dotest taginfo-13 "${testcvs} -nq tag would-be-tag" "T file1"
+ # Deleting: the cases are basically either the tag existed,
+ # or it didn't exist.
+ dotest taginfo-14 "${testcvs} -q tag -d tag1" "D file1"
+ dotest taginfo-15 "${testcvs} -q tag -d tag1" ""
+
+ # Likewise with rtag.
+ dotest taginfo-16 "${testcvs} -q rtag tag1 first-dir" ""
+ dotest taginfo-17 "${testcvs} -q rtag -d tag1 first-dir" ""
+ dotest taginfo-18 "${testcvs} -q rtag -d tag1 first-dir" ""
+
# The "br" example should be passing 1.1.2 or 1.1.0.2.
# But it turns out that is very hard to implement, since
# check_fileproc doesn't know what branch number it will
@@ -10722,7 +11816,12 @@ ${PROG} \[[a-z]* aborted\]: correct the above errors first!"
dotest taginfo-examine "cat ${TESTDIR}/1/taglog" \
"tag1 add ${TESTDIR}/cvsroot/first-dir file1 1.1
br add ${TESTDIR}/cvsroot/first-dir file1 1.1
-brtag mov ${TESTDIR}/cvsroot/first-dir file1 1.1.2.1"
+brtag mov ${TESTDIR}/cvsroot/first-dir file1 1.1.2.1
+tag1 del ${TESTDIR}/cvsroot/first-dir file1 1.1
+tag1 del ${TESTDIR}/cvsroot/first-dir
+tag1 add ${TESTDIR}/cvsroot/first-dir file1 1.1
+tag1 del ${TESTDIR}/cvsroot/first-dir file1 1.1
+tag1 del ${TESTDIR}/cvsroot/first-dir"
cd ..
cd CVSROOT
@@ -10859,6 +11958,7 @@ U file1'
# -N: log, log2, admin-19a-log
# -b, -r: log
# -d: rcs
+ # -s, -R: rcs3
# Check in a file with a few revisions and branches.
mkdir ${CVSROOT_DIRNAME}/first-dir
@@ -11003,6 +12103,28 @@ description:
${log_rev3}
${log_trailer}"
+ dotest log-14a "${testcvs} log -rHEAD file1" \
+"${log_header}
+${log_tags}
+${log_header2}
+total revisions: 5; selected revisions: 1
+description:
+${log_rev3}
+${log_trailer}"
+
+ # The user might not realize that "-r" must not take a space.
+ # In the error message, HEAD is a file name, not a tag name (which
+ # might be confusing itself).
+ dotest_fail log-14b "${testcvs} log -r HEAD file1" \
+"${PROG} [a-z]*: nothing known about HEAD
+${log_header}
+${log_tags}
+${log_header2}
+total revisions: 5; selected revisions: 1
+description:
+${log_rev3}
+${log_trailer}"
+
dotest log-15 "${testcvs} log -r1.2 file1" \
"${log_header}
${log_tags}
@@ -11182,6 +12304,9 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
dotest log2-7 "${testcvs} admin -t${TESTDIR}/descrip file1" \
"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
done"
+ dotest_fail log2-7a "${testcvs} admin -t${TESTDIR}/nonexist file1" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+${PROG} \[[a-z]* aborted\]: can't stat ${TESTDIR}/nonexist: No such file or directory"
dotest log2-8 "${testcvs} log -N file1" "
RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
Working file: file1
@@ -11204,6 +12329,11 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
# See comments in cvs.texinfo for a few more notes on this.
if test "x$remote" = xno; then
+ # TODO: `cvs admin -t "my message" file1' is a request to
+ # read the message from stdin and to operate on two files.
+ # Should test that there is an error because "my message"
+ # doesn't exist.
+
if echo change from stdin | ${testcvs} admin -t -q file1
then
pass log2-9
@@ -11240,6 +12370,7 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
# Tests of "cvs annotate". See also:
# basica-10 A simple annotate test
# rcs Annotate and the year 2000
+ # keywordlog Annotate and $Log.
mkdir 1; cd 1
dotest ann-1 "${testcvs} -q co -l ." ''
mkdir first-dir
@@ -11471,8 +12602,26 @@ ${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then
mkdir crerepos
mkdir crerepos/CVSROOT
+ # Use :ext: rather than :fork:. Most of the tests use :fork:,
+ # so we want to make sure that we test :ext: _somewhere_.
+
+ # Maybe a bit dubious in the sense that people need to
+ # have rsh working to run the tests, but at least it
+ # isn't inetd :-). Might want to think harder about this -
+ # maybe try :ext:, and if it fails, print a (single, nice)
+ # message and fall back to :fork:. Maybe testing :ext:
+ # with our own CVS_RSH rather than worrying about a system one
+ # would do the trick.
+
+ # Note that we set CVS_SERVER at the beginning.
CREREPOS_ROOT=:ext:`hostname`:${TESTDIR}/crerepos
+ # If we're going to do remote testing, make sure 'rsh' works first.
+ host="`hostname`"
+ if test "x`${CVS_RSH-rsh} $host -n 'echo hi'`" != "xhi"; then
+ echo "ERROR: cannot test remote CVS, because \`rsh $host' fails." >&2
+ exit 1
+ fi
fi
if test "x$remote" = "xno"; then
@@ -11491,6 +12640,10 @@ ${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then
else # remote
# Test that CVS rejects a relative path in CVSROOT.
mkdir 1; cd 1
+ # Note that having the client reject the pathname (as :fork:
+ # does), does _not_ test for the bugs we are trying to catch
+ # here. The point is that malicious clients might send all
+ # manner of things and the server better protect itself.
dotest_fail crerepos-6a \
"${testcvs} -q -d :ext:`hostname`:../crerepos get ." \
"Root ../crerepos must be an absolute pathname"
@@ -11560,31 +12713,17 @@ U first-dir/file1"
dotest crerepos-17 "${testcvs} -d ${CREREPOS_ROOT} co crerepos-dir" \
"${PROG} [a-z]*: Updating crerepos-dir
U crerepos-dir/cfile"
-
- if test x`cat crerepos-dir/CVS/Repository` = xcrerepos-dir; then
- # RELATIVE_REPOS
- # Fatal error so that we don't go traipsing through the
- # directories which happen to have the same names from the
- # wrong repository.
- dotest_fail crerepos-18 "${testcvs} -q update" \
-"${PROG} \[[a-z]* aborted\]: cannot open directory ${TESTDIR}/cvsroot/crerepos-dir: .*" ''
- else
- if test "$remote" = no; then
- # The lack of an error doesn't mean CVS is really
- # working (things are getting logged to the wrong
- # history file and such).
- dotest crerepos-18 "${testcvs} -q update" ''
- else
- # Fatal error so that we don't go traipsing through the
- # directories which happen to have the same names from the
- # wrong repository.
- dotest_fail crerepos-18 "${testcvs} -q update" \
-"protocol error: directory .${TESTDIR}/crerepos/crerepos-dir. not within root .${TESTDIR}/cvsroot."
- fi
- fi
+ dotest crerepos-18 "${testcvs} update" \
+"${PROG} [a-z]*: Updating first-dir
+${PROG} [a-z]*: Updating crerepos-dir"
cd ..
+ if test "$keep" = yes; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
rm -r 1
rm -rf ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/crerepos
;;
@@ -12145,6 +13284,32 @@ EOF
dotest rcs2-5 "cat ${TESTDIR}/rcs4.tmp" \
"${PROG} \[[a-z]* aborted\]: Can't parse date/time: 2003-02-29 11:30 UT"
fi
+
+ dotest rcs2-6 "${testcvs} -q update -p -D 2007-01-07 file1" \
+"head revision"
+ # This assumes that the clock of the machine running the tests
+ # is set to at least the year 1998 or so. There don't seem
+ # to be a lot of ways to test the relative date code (short
+ # of something like LD_LIBRARY_PRELOAD'ing in our own
+ # getttimeofday, or hacking the CVS source with testing
+ # features, which always seems to be problematic since then
+ # someone feels like documenting them and things go downhill
+ # from there).
+ if ${testcvs} -q update -p -D '100 months' file1 \
+ >${TESTDIR}/rcs4.tmp 2>&1
+ then
+ dotest rcs2-7 "cat ${TESTDIR}/rcs4.tmp" "head revision"
+ else
+ fail rcs2-7
+ fi
+ if ${testcvs} -q update -p -D '8 years' file1 \
+ >${TESTDIR}/rcs4.tmp 2>&1
+ then
+ dotest rcs2-8 "cat ${TESTDIR}/rcs4.tmp" "head revision"
+ else
+ fail rcs2-8
+ fi
+
rm ${TESTDIR}/rcs4.tmp
cd ..
@@ -12152,6 +13317,149 @@ EOF
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ rcs3)
+ # More RCS file tests, in particular at least some of the
+ # error handling issues.
+ mkdir ${CVSROOT_DIRNAME}/first-dir
+ cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
+head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
+; author jeremiah ;state ; branches; next;desc@@1.1log@@text@head@
+EOF
+ mkdir 1; cd 1
+ # CVS requires whitespace between "desc" and its value.
+ # The rcsfile(5) manpage doesn't really seem to answer the
+ # question one way or the other (it has a grammar but almost
+ # nothing about lexical analysis).
+ dotest_fail rcs3-1 "${testcvs} -q co first-dir" \
+"${PROG} \[[a-z]* aborted\]: unexpected end of file reading ${TESTDIR}/cvsroot/first-dir/file1,v"
+ cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
+head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
+; author jeremiah ;state ; branches; next;desc @@1.1log@@text@head@
+EOF
+ # Whitespace issues, likewise.
+ dotest_fail rcs3-2 "${testcvs} -q co first-dir" \
+"${PROG} \[[a-z]* aborted\]: unexpected '.x6c' reading revision number in RCS file ${TESTDIR}/cvsroot/first-dir/file1,v"
+ cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
+head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
+; author jeremiah ;state ; branches; next;desc @@1.1 log@@text@head@
+EOF
+ # Charming array of different messages for similar
+ # whitespace issues (depending on where the whitespace is).
+ dotest_fail rcs3-3 "${testcvs} -q co first-dir" \
+"${PROG} \[[a-z]* aborted\]: EOF while looking for value in RCS file ${TESTDIR}/cvsroot/first-dir/file1,v"
+ cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
+head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
+; author jeremiah ;state ; branches; next;desc @@1.1 log @@text @head@
+EOF
+ dotest rcs3-4 "${testcvs} -q co first-dir" 'U first-dir/file1'
+ if test "$remote" = no; then
+ # Ouch, didn't expect this one. FIXCVS. Or maybe just remove
+ # the feature, if this is a -s problem?
+ dotest_fail rcs3-5 "${testcvs} log -s nostate first-dir/file1" \
+".*[Aa]ssertion.*failed${DOTSTAR}" ".*failed assertion${DOTSTAR}"
+ else # remote
+ # Is this a reaction to the lack of TopLevelAdmin or something?
+ # Seems pretty strange to me. Seems vaguely similar to the
+ # "no repository" message in errmsg2-16 although I'm leaving
+ # it here in case there is a difference between "cvs add" and a
+ # normal start_recursion command like "cvs log".
+ dotest_fail rcs3-5 "${testcvs} log -s nostate first-dir/file1" \
+"${PROG} log: cannot open CVS/Entries for reading: No such file or directory
+${PROG} \[log aborted\]: no repository"
+ cd first-dir
+ dotest_fail rcs3-5a "${testcvs} log -s nostate file1" \
+"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}"
+ cd ..
+ fi # remote
+
+ # See remote code above for rationale for cd.
+ cd first-dir
+ dotest rcs3-6 "${testcvs} log -R file1" \
+"${TESTDIR}/cvsroot/first-dir/file1,v"
+
+ # OK, now put an extraneous '\0' at the end.
+ awk </dev/null 'BEGIN { printf "@%c", 10 }' | tr '@' '\000' \
+ >>${CVSROOT_DIRNAME}/first-dir/file1,v
+ dotest_fail rcs3-7 "${testcvs} log -s nostate file1" \
+"${PROG} \[[a-z]* aborted\]: unexpected '.x0' reading revision number in RCS file ${TESTDIR}/cvsroot/first-dir/file1,v"
+
+ cd ../..
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
+ lockfiles)
+ # Tests of CVS lock files.
+ # TODO-maybe: Add a test where we arrange for a loginfo
+ # script (or some such) to ensure that locks are in place
+ # so then we can see how they are behaving.
+
+ mkdir 1; cd 1
+ mkdir sdir
+ mkdir sdir/ssdir
+ echo file >sdir/ssdir/file1
+ dotest lockfiles-1 \
+"${testcvs} -Q import -m import-it first-dir bar baz" ""
+ cd ..
+
+ mkdir 2; cd 2
+ dotest lockfiles-2 "${testcvs} -q co first-dir" \
+"U first-dir/sdir/ssdir/file1"
+ dotest lockfiles-3 "${testcvs} -Q co CVSROOT" ""
+ cd CVSROOT
+ echo "LockDir=${TESTDIR}/locks" >config
+ dotest lockfiles-4 "${testcvs} -q ci -m config-it" \
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ../first-dir/sdir/ssdir
+ # The error message appears twice because Lock_Cleanup only
+ # stops recursing after the first attempt.
+ dotest_fail lockfiles-5 "${testcvs} -q update" \
+"${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory
+${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory"
+ mkdir ${TESTDIR}/locks
+ chmod u=rwx,g=r,o= ${TESTDIR}/locks
+ umask 0077
+ CVSUMASK=0077; export CVSUMASK
+ dotest lockfiles-6 "${testcvs} -q update" ""
+ # TODO: should also be testing that CVS continues to honor the
+ # umask and CVSUMASK normally. In the case of the umask, CVS
+ # doesn't seem to use it for much (although it perhaps should).
+ dotest lockfiles-7 "ls ${TESTDIR}/locks/first-dir/sdir/ssdir" ""
+
+ # The policy is that when CVS creates new lock directories, they
+ # inherit the permissions from the parent directory. CVSUMASK
+ # isn't right, because typically the reason for LockDir is to
+ # use a different set of permissions.
+ dotest lockfiles-7a "ls -ld ${TESTDIR}/locks/first-dir" \
+"drwxr----- .*first-dir"
+ dotest lockfiles-7b "ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir" \
+"drwxr----- .*first-dir/sdir/ssdir"
+
+ cd ../../..
+ dotest lockfiles-8 "${testcvs} -q update" ""
+
+ cd CVSROOT
+ echo "# nobody here but us comments" >config
+ dotest lockfiles-cleanup-1 "${testcvs} -q ci -m config-it" \
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ../..
+ # Perhaps should restore the umask and CVSUMASK to what they
+ # were before. But the other tests "should" not care about them...
+ umask 0077
+ unset CVSUMASK
+ rm -r ${TESTDIR}/locks
+ rm -r 1 2
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
history)
# CVSROOT/history tests:
# history: various "cvs history" invocations
@@ -12368,10 +13676,13 @@ done"
if test "x$remote" = xyes; then
# The problem here is that the CVSUMASK environment variable
# needs to be set on the server (e.g. .bashrc). This is, of
- # course, bogus, but that is the way it is currently.
+ # course, bogus, but that is the way it is currently. The
+ # first match is for the :ext: method (where the CVSUMASK
+ # won't be set), while the second is for the :fork: method
+ # (where it will be).
dotest modes-15 \
"ls -l ${TESTDIR}/cvsroot/first-dir/Attic/ac,v" \
-"-r--r--r--.*"
+"-r--r--r--.*" "-r--r-----.*"
else
dotest modes-15 \
"ls -l ${TESTDIR}/cvsroot/first-dir/Attic/ac,v" \
@@ -12431,6 +13742,64 @@ done"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ modes3)
+ # Repository permissions. Particularly, what happens if we
+ # can't read/write in the repository.
+ # TODO: the case where we can access the repository, just not
+ # the attic (may that one can remain a fatal error, seems less
+ # useful for access control).
+ mkdir 1; cd 1
+ dotest modes-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir second-dir
+ dotest modes-2 "${testcvs} add first-dir second-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository
+Directory ${TESTDIR}/cvsroot/second-dir added to the repository"
+ touch first-dir/aa second-dir/ab
+ dotest modes-3 "${testcvs} add first-dir/aa second-dir/ab" \
+"${PROG} [a-z]*: scheduling file .first-dir/aa. for addition
+${PROG} [a-z]*: scheduling file .second-dir/ab. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+ dotest modes-4 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/aa,v
+done
+Checking in first-dir/aa;
+${TESTDIR}/cvsroot/first-dir/aa,v <-- aa
+initial revision: 1\.1
+done
+RCS file: ${TESTDIR}/cvsroot/second-dir/ab,v
+done
+Checking in second-dir/ab;
+${TESTDIR}/cvsroot/second-dir/ab,v <-- ab
+initial revision: 1\.1
+done"
+ chmod a= ${TESTDIR}/cvsroot/first-dir
+ dotest modes-5 "${testcvs} update" \
+"${PROG} [a-z]*: Updating \.
+${PROG} [a-z]*: Updating first-dir
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/first-dir: Permission denied
+${PROG} [a-z]*: skipping directory first-dir
+${PROG} [a-z]*: Updating second-dir"
+
+ # OK, I can see why one might say the above case could be a
+ # fatal error, because normally users without access to first-dir
+ # won't have it in their working directory. But the next
+ # one is more of a problem if it is fatal.
+ rm -r first-dir
+ dotest modes-6 "${testcvs} update -dP" \
+"${PROG} [a-z]*: Updating .
+${PROG} [a-z]*: Updating CVSROOT
+U ${DOTSTAR}
+${PROG} [a-z]*: Updating first-dir
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/first-dir: Permission denied
+${PROG} [a-z]*: skipping directory first-dir
+${PROG} [a-z]*: Updating second-dir"
+
+ cd ..
+ rm -r 1
+ chmod u+rwx ${TESTDIR}/cvsroot/first-dir
+ rm -rf ${TESTDIR}/cvsroot/first-dir ${TESTDIR}/cvsroot/second-dir
+ ;;
+
stamps)
# Test timestamps.
mkdir 1; cd 1
@@ -12873,6 +14242,8 @@ U file1" "U file1"
# "binfiles" (and this test) test "cvs update -k".
# "binwrap" tests setting the mode from wrappers.
# I don't think any test is testing "cvs import -k".
+ # Other keyword expansion tests:
+ # keywordlog - $Log.
mkdir 1; cd 1
dotest keyword-1 "${testcvs} -q co -l ." ''
mkdir first-dir
@@ -13071,22 +14442,18 @@ done"
dotest keywordlog-2 "${testcvs} add first-dir" \
"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
cd first-dir
- echo change >file1
+ echo initial >file1
dotest keywordlog-3 "${testcvs} add file1" \
"${PROG} [a-z]*: scheduling file .file1. for addition
${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
- # Note that we wanted to try "ci -r 1.3 -m add file1" and CVS
- # seemed to get all confused, thinking it was adding on a branch
- # or something. FIXME? Do something about this? Document it
- # in BUGS or someplace?
-
- dotest keywordlog-4 "${testcvs} -q ci -m add file1" \
+ # See "rmadd" for a list of other tests of cvs ci -r.
+ dotest keywordlog-4 "${testcvs} -q ci -r 1.3 -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
+initial revision: 1\.3
done"
cd ../..
@@ -13094,21 +14461,29 @@ done"
dotest keywordlog-4a "${testcvs} -q co first-dir" "U first-dir/file1"
cd ../1/first-dir
- echo 'xx $''Log$' > file1
+ echo 'xx $''Log$' >> file1
cat >${TESTDIR}/comment.tmp <<EOF
First log line
Second log line
EOF
+ # As with rmadd-25, "cvs ci -r" sets a sticky tag.
+ dotest_fail keywordlog-4b \
+"${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \
+"${PROG} [a-z]*: sticky tag .1\.3. for file .file1. is not a branch
+${PROG} \[[a-z]* aborted\]: correct above errors first!"
+ dotest keywordlog-4c "${testcvs} -q update -A" "M file1"
+
dotest keywordlog-5 "${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \
"Checking in file1;
${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
-new revision: 1\.2; previous revision: 1\.1
+new revision: 1\.4; previous revision: 1\.3
done"
rm -f ${TESTDIR}/comment.tmp
dotest keywordlog-6 "${testcvs} -q tag -b br" "T file1"
dotest keywordlog-7 "cat file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx"
@@ -13116,8 +14491,9 @@ xx"
cd ../../2/first-dir
dotest keywordlog-8 "${testcvs} -q update" "[UP] file1"
dotest keywordlog-9 "cat file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx"
@@ -13127,14 +14503,15 @@ xx"
dotest keywordlog-10 "${testcvs} ci -m modify file1" \
"Checking in file1;
${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
-new revision: 1\.3; previous revision: 1\.2
+new revision: 1\.5; previous revision: 1\.4
done"
dotest keywordlog-11 "cat file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.3 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.5 [0-9/]* [0-9:]* ${username}
xx modify
xx
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx
@@ -13143,11 +14520,12 @@ change"
cd ../../2/first-dir
dotest keywordlog-12 "${testcvs} -q update" "[UP] file1"
dotest keywordlog-13 "cat file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.3 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.5 [0-9/]* [0-9:]* ${username}
xx modify
xx
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx
@@ -13159,14 +14537,15 @@ change"
dotest keywordlog-15 "${testcvs} -q ci -m br-modify" \
"Checking in file1;
${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
-new revision: 1\.2\.2\.1; previous revision: 1\.2
+new revision: 1\.4\.2\.1; previous revision: 1\.4
done"
dotest keywordlog-16 "cat file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.2\.2\.1 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.4\.2\.1 [0-9/]* [0-9:]* ${username}
xx br-modify
xx
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx
@@ -13174,43 +14553,79 @@ br-change"
cd ../../2/first-dir
dotest keywordlog-17 "${testcvs} -q update -r br" "[UP] file1"
dotest keywordlog-18 "cat file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.2\.2\.1 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.4\.2\.1 [0-9/]* [0-9:]* ${username}
xx br-modify
xx
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx
br-change"
cd ../..
dotest keywordlog-19 "${testcvs} -q co -p -r br first-dir/file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.2\.2\.1 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.4\.2\.1 [0-9/]* [0-9:]* ${username}
xx br-modify
xx
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx
br-change"
dotest keywordlog-20 "${testcvs} -q co -p first-dir/file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.3 [0-9/]* [0-9:]* ${username}
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.5 [0-9/]* [0-9:]* ${username}
xx modify
xx
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx
change"
- dotest keywordlog-21 "${testcvs} -q co -p -r 1.2 first-dir/file1" \
-"xx "'\$'"Log: file1,v "'\$'"
-xx Revision 1\.2 [0-9/]* [0-9:]* ${username}
+ dotest keywordlog-21 "${testcvs} -q co -p -r 1.4 first-dir/file1" \
+"initial
+xx "'\$'"Log: file1,v "'\$'"
+xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
xx First log line
xx Second log line
xx"
+ cd 2/first-dir
+ # OK, the basic rule for keyword expansion is that it
+ # happens on checkout. And the rule for annotate is that
+ # it annotates a checked-in revision, rather than a checked-out
+ # file. So, although it is kind of confusing that the latest
+ # revision does not appear in the annotated output, and the
+ # annotated output does not quite match what you'd get with
+ # update or checkout, the behavior is more or less logical.
+ # The same issue occurs with annotate and other keywords,
+ # I think, although it is particularly noticeable for $Log.
+ dotest keywordlog-22 "${testcvs} ann -r br file1" \
+"Annotations for file1
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+1\.3 (${username} *[0-9a-zA-Z-]*): initial
+1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
+1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
+1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx First log line
+1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx Second log line
+1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx
+1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): br-change"
+ dotest keywordlog-23 "${testcvs} ann -r HEAD file1" \
+"Annotations for file1
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+1\.3 (${username} *[0-9a-zA-Z-]*): initial
+1\.5 (${username} *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
+1\.5 (${username} *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
+1\.5 (${username} *[0-9a-zA-Z-]*): xx First log line
+1\.5 (${username} *[0-9a-zA-Z-]*): xx Second log line
+1\.5 (${username} *[0-9a-zA-Z-]*): xx
+1\.5 (${username} *[0-9a-zA-Z-]*): change"
+ cd ../..
+
rm -r 1 2
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -13621,14 +15036,13 @@ done"
dotest tag8k-15 "$testcvs -Q tag $t-9 $file" ''
dotest tag8k-16 "$testcvs -Q tag $t-a $file" ''
- # Determine the length of the author value.
+ # Extract the author value.
name=`sed -n 's/.*; author \([^;]*\);.*/\1/p' ${TESTDIR}/cvsroot/$module/$file,v|head -1`
- name_len=`expr length $name`
+ # Form a suffix string of length (16 - length($name)).
# CAREFUL: this will lose if $name is longer than 16.
- # Then, form a string of length 16 - $name_len.
- add_len=`expr 16 - $name_len`
- suffix=`expr substr 1234567890123456 1 $add_len`
+ sed_pattern=`echo $name|sed s/././g`
+ suffix=`echo 1234567890123456|sed s/$sed_pattern//`
# Add a final tag with length chosen so that it will push the
# offset of the `;' in the 2nd occurrence of `;\tauthor' in the
@@ -13663,7 +15077,8 @@ done"
# head-o1 (::branch, where this deletes a revision or is noop)
# branches-o1 (::branch, similar, with different branch topology)
# log-o1 (1.3.2.1::)
- # binfiles-o1 (1.3:: and ::1.3)
+ # binfiles-o1 (1.3:: and ::1.3; binary files)
+ # binfiles3-9 (binary files)
# Also could be testing:
# 1.3.2.6::1.3.2.8
# 1.3.2.6::1.3.2
@@ -13803,6 +15218,7 @@ modify-on-branch
# test for what CVS actually exports, and figure we can revise
# the check as needed (within the confines of the RCS5 format as
# documented in RCSFILES).
+ # Note that we must accept either 2 or 4 digit year.
dotest admin-13 "cat ${CVSROOT_DIRNAME}/first-dir/file1,v" \
"head 1\.1;
branch 1\.1\.2;
@@ -13817,13 +15233,13 @@ comment @xx@;
1\.1
-date [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
+date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
branches
1\.1\.2\.1;
next ;
1\.1\.2\.1
-date [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state foo;
+date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state foo;
branches;
next ;
@@ -14222,13 +15638,13 @@ comment @xx@;
1\.1
-date [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
+date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
branches
1\.1\.2\.1;
next ;
1\.1\.2\.1
-date [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state foo;
+date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state foo;
branches;
next ;
@@ -14393,17 +15809,17 @@ comment @# @;
1\.4
-date [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
+date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
branches;
next 1\.3;
1\.3
-date [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
+date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
branches;
next 1\.2;
1\.2
-date [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
+date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp;
branches;
next ;
@@ -15496,6 +16912,1976 @@ d472 12
rm -rf ${CVSROOT_DIRNAME}/diffmerge2
;;
+ release)
+ # Tests of "cvs release", particularly multiple arguments.
+ # Other CVS release tests:
+ # info-cleanup-0 for "cvs -n release".
+ # ignore-193 for the text of the question that cvs release asks.
+ # Also for interactions with cvsignore.
+ # basicc: "-d .", global -Q, no arguments (is a noop),
+ # "cvs release" without -d, multiple arguments.
+ # dirs-4: repository directory has been deleted.
+ # modules2-6: multiple arguments.
+
+ # First the usual setup; create a directory first-dir.
+ mkdir 1; cd 1
+ dotest release-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest release-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ mkdir dir1
+ dotest release-3 "${testcvs} add dir1" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir1 added to the repository"
+ mkdir dir2
+ dotest release-4 "${testcvs} add dir2" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir2 added to the repository"
+ cd dir2
+ mkdir dir3
+ dotest release-5 "${testcvs} add dir3" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir2/dir3 added to the repository"
+
+ cd ../..
+ dotest release-6 "${testcvs} release -d first-dir/dir2/dir3 first-dir/dir1" \
+"You have .0. altered files in this repository.
+Are you sure you want to release (and delete) directory .first-dir/dir2/dir3.: \
+You have .0. altered files in this repository.
+Are you sure you want to release (and delete) directory .first-dir/dir1.: " <<EOF
+yes
+yes
+EOF
+ dotest_fail release-7 "test -d first-dir/dir1" ''
+ dotest_fail release-8 "test -d first-dir/dir2/dir3" ''
+ dotest release-9 "${testcvs} update" \
+"${PROG} [a-z]*: Updating \.
+${PROG} [a-z]*: Updating first-dir
+${PROG} [a-z]*: Updating first-dir/dir2"
+
+ cd first-dir
+ mkdir dir1
+ dotest release-10 "${testcvs} add dir1" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir1 added to the repository"
+ cd dir2
+ mkdir dir3
+ dotest release-11 "${testcvs} add dir3" \
+"Directory ${TESTDIR}/cvsroot/first-dir/dir2/dir3 added to the repository"
+
+ cd ../..
+ dotest release-12 "${testcvs} release first-dir/dir2/dir3 first-dir/dir1" \
+"You have .0. altered files in this repository.
+Are you sure you want to release directory .first-dir/dir2/dir3.: .. .release. aborted by user choice.
+You have .0. altered files in this repository.
+Are you sure you want to release directory .first-dir/dir1.: " <<EOF
+no
+yes
+EOF
+ dotest release-13 "${testcvs} release first-dir/dir2/dir3 first-dir/dir2" \
+"You have .0. altered files in this repository.
+Are you sure you want to release directory .first-dir/dir2/dir3.: \
+You have .0. altered files in this repository.
+Are you sure you want to release directory .first-dir/dir2.: " <<EOF
+yes
+yes
+EOF
+ dotest release-14 "test -d first-dir/dir1" ''
+ dotest release-15 "test -d first-dir/dir2/dir3" ''
+ rm -rf first-dir/dir1 first-dir/dir2
+
+ dotest release-16 "${testcvs} update" \
+"${PROG} [a-z]*: Updating \.
+${PROG} [a-z]*: Updating first-dir"
+ cd ..
+ rm -rf 1
+ ;;
+
+ multiroot)
+
+ #
+ # set up two repositories
+ #
+
+ CVSROOT1_DIRNAME=${TESTDIR}/root1
+ CVSROOT2_DIRNAME=${TESTDIR}/root2
+ CVSROOT1=${CVSROOT1_DIRNAME} ; export CVSROOT1
+ CVSROOT2=${CVSROOT2_DIRNAME} ; export CVSROOT2
+ if test "x$remote" = xyes; then
+ CVSROOT1=:fork:${CVSROOT1_DIRNAME} ; export CVSROOT1
+ CVSROOT2=:fork:${CVSROOT2_DIRNAME} ; export CVSROOT2
+ fi
+ testcvs1="${testcvs} -d ${CVSROOT1}"
+ testcvs2="${testcvs} -d ${CVSROOT2}"
+
+ dotest multiroot-setup-1 "mkdir ${CVSROOT1_DIRNAME} ${CVSROOT2_DIRNAME}" ""
+ dotest multiroot-setup-2 "${testcvs1} init" ""
+ dotest multiroot-setup-3 "${testcvs2} init" ""
+
+ #
+ # create some directories in root1
+ #
+ mkdir 1; cd 1
+ dotest multiroot-setup-4 "${testcvs1} co -l ." "${PROG} [a-z]*: Updating ."
+ mkdir mod1-1 mod1-2
+ dotest multiroot-setup-5 "${testcvs1} add mod1-1 mod1-2" \
+"Directory ${CVSROOT1_DIRNAME}/mod1-1 added to the repository
+Directory ${CVSROOT1_DIRNAME}/mod1-2 added to the repository"
+ echo file1-1 > mod1-1/file1-1
+ echo file1-2 > mod1-2/file1-2
+ dotest multiroot-setup-6 "${testcvs1} add mod1-1/file1-1 mod1-2/file1-2" \
+"${PROG} [a-z]*: scheduling file .mod1-1/file1-1. for addition
+${PROG} [a-z]*: scheduling file .mod1-2/file1-2. for addition
+${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+ dotest multiroot-setup-7 "${testcvs1} commit -m is" \
+"${PROG} [a-z]*: Examining \.
+${PROG} [a-z]*: Examining mod1-1
+${PROG} [a-z]*: Examining mod1-2
+RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v
+done
+Checking in mod1-1/file1-1;
+${CVSROOT1_DIRNAME}/mod1-1/file1-1,v <-- file1-1
+initial revision: 1.1
+done
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+done
+Checking in mod1-2/file1-2;
+${CVSROOT1_DIRNAME}/mod1-2/file1-2,v <-- file1-2
+initial revision: 1.1
+done"
+ cd ..
+ rm -rf 1
+
+ #
+ # create some directories in root2
+ #
+ mkdir 1; cd 1
+ dotest multiroot-setup-8 "${testcvs2} co -l ." "${PROG} [a-z]*: Updating ."
+ mkdir mod2-1 mod2-2
+ dotest multiroot-setup-9 "${testcvs2} add mod2-1 mod2-2" \
+"Directory ${CVSROOT2_DIRNAME}/mod2-1 added to the repository
+Directory ${CVSROOT2_DIRNAME}/mod2-2 added to the repository"
+ echo file2-1 > mod2-1/file2-1
+ echo file2-2 > mod2-2/file2-2
+ dotest multiroot-setup-6 "${testcvs2} add mod2-1/file2-1 mod2-2/file2-2" \
+"${PROG} [a-z]*: scheduling file .mod2-1/file2-1. for addition
+${PROG} [a-z]*: scheduling file .mod2-2/file2-2. for addition
+${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+ dotest multiroot-setup-10 "${testcvs2} commit -m anyone" \
+"${PROG} [a-z]*: Examining \.
+${PROG} [a-z]*: Examining mod2-1
+${PROG} [a-z]*: Examining mod2-2
+RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v
+done
+Checking in mod2-1/file2-1;
+${CVSROOT2_DIRNAME}/mod2-1/file2-1,v <-- file2-1
+initial revision: 1.1
+done
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+done
+Checking in mod2-2/file2-2;
+${CVSROOT2_DIRNAME}/mod2-2/file2-2,v <-- file2-2
+initial revision: 1.1
+done"
+ cd ..
+ rm -rf 1
+
+ # check out a few directories, from simple/shallow to
+ # complex/deep
+ mkdir 1; cd 1
+
+ # OK, this case is kind of weird. If we just run things from
+ # here, without CVS/Root, then CVS will contact the server
+ # mentioned in CVSROOT (which is irrelevant) which will print
+ # some messages. Our workaround is to make sure we have a
+ # CVS/Root file at top level. In the future, it is possible
+ # the best behavior will be to extend the existing behavior
+ # ("being called from a directory without CVS administration
+ # has always meant to process each of the sub-dirs") to also
+ # do that if there is no CVSROOT, CVS/Root, or -d at top level.
+ #
+ # The local case could stumble through the tests without creating
+ # the top-level CVS/Root, but we create it for local and for
+ # remote to reduce special cases later in the test.
+ dotest multiroot-workaround "${testcvs1} -q co -l ." ""
+
+ dotest multiroot-setup-11 "${testcvs1} co mod1-1 mod1-2" \
+"${PROG} [a-z]*: Updating mod1-1
+U mod1-1/file1-1
+${PROG} [a-z]*: Updating mod1-2
+U mod1-2/file1-2"
+ dotest multiroot-setup-12 "${testcvs2} co mod2-1 mod2-2" \
+"${PROG} [a-z]*: Updating mod2-1
+U mod2-1/file2-1
+${PROG} [a-z]*: Updating mod2-2
+U mod2-2/file2-2"
+ cd mod1-2
+ dotest multiroot-setup-13 "${testcvs2} co mod2-2" \
+"${PROG} [a-z]*: Updating mod2-2
+U mod2-2/file2-2"
+ cd ..
+ cd mod2-2
+ dotest multiroot-setup-14 "${testcvs1} co mod1-2" \
+"${PROG} [a-z]*: Updating mod1-2
+U mod1-2/file1-2"
+ cd ..
+
+ # Try to determine whether RELATIVE_REPOS is defined
+ # so that we can make the following a lot less
+ # verbose.
+
+ echo "${CVSROOT1_DIRNAME}/mod1-1" > dotest.abs
+ echo "mod1-1" > dotest.rel
+ if cmp dotest.abs mod1-1/CVS/Repository >/dev/null 2>&1; then
+ AREP1="${CVSROOT1_DIRNAME}/"
+ AREP2="${CVSROOT2_DIRNAME}/"
+ elif cmp dotest.rel mod1-1/CVS/Repository >/dev/null 2>&1; then
+ AREP1=""
+ AREP2=""
+ else
+ fail "Cannot figure out if RELATIVE_REPOS is defined."
+ fi
+ rm -f dotest.abs dotest.rel
+
+ #
+ # Make sure that the Root and Repository files contain the
+ # correct information.
+ #
+ dotest multiroot-cvsadm-1a "cat mod1-1/CVS/Root" "${CVSROOT1}"
+ dotest multiroot-cvsadm-1b "cat mod1-1/CVS/Repository" "${AREP1}mod1-1"
+ dotest multiroot-cvsadm-2a "cat mod2-1/CVS/Root" "${CVSROOT2}"
+ dotest multiroot-cvsadm-2b "cat mod2-1/CVS/Repository" "${AREP2}mod2-1"
+ dotest multiroot-cvsadm-3a "cat mod1-2/CVS/Root" "${CVSROOT1}"
+ dotest multiroot-cvsadm-3b "cat mod1-2/CVS/Repository" "${AREP1}mod1-2"
+ dotest multiroot-cvsadm-3c "cat mod1-2/mod2-2/CVS/Root" "${CVSROOT2}"
+ dotest multiroot-cvsadm-3d "cat mod1-2/mod2-2/CVS/Repository" "${AREP2}mod2-2"
+ dotest multiroot-cvsadm-4a "cat mod2-2/CVS/Root" "${CVSROOT2}"
+ dotest multiroot-cvsadm-4b "cat mod2-2/CVS/Repository" "${AREP2}mod2-2"
+ dotest multiroot-cvsadm-4c "cat mod2-2/mod1-2/CVS/Root" "${CVSROOT1}"
+ dotest multiroot-cvsadm-4d "cat mod2-2/mod1-2/CVS/Repository" "${AREP1}mod1-2"
+
+ #
+ # Start testing various cvs commands. Begin with commands
+ # without extra arguments (e.g. "cvs update", "cvs diff",
+ # etc.
+ #
+
+ # Do at least one command with both CVSROOTs to make sure
+ # that there's not some kind of unexpected dependency on the
+ # choice of which CVSROOT is specified on the command line.
+
+ if test "${AREP1}" = ""; then
+ # RELATIVE_REPOS.
+ dotest multiroot-update-1a "${testcvs1} update" \
+"${PROG} [a-z]*: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: Updating mod1-2/mod2-2
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/root1/mod2-2: No such file or directory
+${PROG} [a-z]*: skipping directory mod1-2/mod2-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/root1/mod2-1: No such file or directory
+${PROG} [a-z]*: skipping directory mod2-1
+${PROG} [a-z]*: Updating mod2-2
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/root1/mod2-2: No such file or directory
+${PROG} [a-z]*: skipping directory mod2-2"
+
+ # Same deal but with -d ${CVSROOT2}.
+ dotest multiroot-update-1b "${testcvs2} update" \
+"${PROG} [a-z]*: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/root2/mod1-1: No such file or directory
+${PROG} [a-z]*: skipping directory mod1-1
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/root2/mod1-2: No such file or directory
+${PROG} [a-z]*: skipping directory mod1-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: Updating mod2-2
+${PROG} [a-z]*: Updating mod2-2/mod1-2
+${PROG} [a-z]*: cannot open directory ${TESTDIR}/root2/mod1-2: No such file or directory
+${PROG} [a-z]*: skipping directory mod2-2/mod1-2"
+ else
+ # non-RELATIVE_REPOS.
+ if test "$remote" = no; then
+ # The basic idea is that -d overrides CVS/Root.
+ # With RELATIVE_REPOS, CVS could print an error when it
+ # tries to recurse to mod2-2, which doesn't exist in
+ # this repository (?) With absolute, CVS will just look at the
+ # CVS/Repository for the other root (and log to the wrong
+ # history file and that sort of thing).
+ dotest multiroot-update-1a "${testcvs1} update" \
+"${PROG} update: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: Updating mod1-2/mod2-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: Updating mod2-2
+${PROG} [a-z]*: Updating mod2-2/mod1-2"
+ else
+ # Hmm, this one is specific to non-RELATIVE_REPOS too I think.
+ dotest_fail multiroot-update-1a "${testcvs1} update" \
+"protocol error: directory '${TESTDIR}/root2/mod2-2' not within root '${TESTDIR}/root1'"
+ fi # non-remote
+
+ # Same deal but with -d ${CVSROOT2}.
+ if test "$remote" = no; then
+ dotest multiroot-update-1b "${testcvs2} update" \
+"${PROG} update: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: Updating mod1-2/mod2-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: Updating mod2-2
+${PROG} [a-z]*: Updating mod2-2/mod1-2"
+ else
+ dotest_fail multiroot-update-1b "${testcvs2} update" \
+"protocol error: directory '${TESTDIR}/root1' not within root '${TESTDIR}/root2'"
+ fi # non-remote
+ fi # non-RELATIVE_REPOS
+
+ # modify all files and do a diff
+
+ echo bobby >> mod1-1/file1-1
+ echo brown >> mod1-2/file1-2
+ echo goes >> mod2-1/file2-1
+ echo down >> mod2-2/file2-2
+
+ dotest_status multiroot-diff-1 1 "${testcvs} diff" \
+"${PROG} diff: Diffing \.
+${PROG} [a-z]*: Diffing mod1-1
+Index: mod1-1/file1-1
+===================================================================
+RCS file: ${TESTDIR}/root1/mod1-1/file1-1,v
+retrieving revision 1\.1
+diff -r1\.1 file1-1
+1a2
+> bobby
+${PROG} [a-z]*: Diffing mod1-2
+Index: mod1-2/file1-2
+===================================================================
+RCS file: ${TESTDIR}/root1/mod1-2/file1-2,v
+retrieving revision 1\.1
+diff -r1\.1 file1-2
+1a2
+> brown
+${PROG} [a-z]*: Diffing mod2-2/mod1-2
+${PROG} [a-z]*: Diffing mod1-2/mod2-2
+${PROG} [a-z]*: Diffing mod2-1
+Index: mod2-1/file2-1
+===================================================================
+RCS file: ${TESTDIR}/root2/mod2-1/file2-1,v
+retrieving revision 1\.1
+diff -r1\.1 file2-1
+1a2
+> goes
+${PROG} [a-z]*: Diffing mod2-2
+Index: mod2-2/file2-2
+===================================================================
+RCS file: ${TESTDIR}/root2/mod2-2/file2-2,v
+retrieving revision 1\.1
+diff -r1\.1 file2-2
+1a2
+> down" \
+"${PROG} server: Diffing \.
+${PROG} [a-z]*: Diffing mod1-1
+Index: mod1-1/file1-1
+===================================================================
+RCS file: ${TESTDIR}/root1/mod1-1/file1-1,v
+retrieving revision 1\.1
+diff -r1\.1 file1-1
+1a2
+> bobby
+${PROG} [a-z]*: Diffing mod1-2
+Index: mod1-2/file1-2
+===================================================================
+RCS file: ${TESTDIR}/root1/mod1-2/file1-2,v
+retrieving revision 1\.1
+diff -r1\.1 file1-2
+1a2
+> brown
+${PROG} [a-z]*: Diffing mod2-2
+${PROG} [a-z]*: Diffing mod2-2/mod1-2
+${PROG} [a-z]*: Diffing mod1-2
+${PROG} [a-z]*: Diffing mod1-2/mod2-2
+${PROG} [a-z]*: Diffing mod2-1
+Index: mod2-1/file2-1
+===================================================================
+RCS file: ${TESTDIR}/root2/mod2-1/file2-1,v
+retrieving revision 1\.1
+diff -r1\.1 file2-1
+1a2
+> goes
+${PROG} [a-z]*: Diffing mod2-2
+Index: mod2-2/file2-2
+===================================================================
+RCS file: ${TESTDIR}/root2/mod2-2/file2-2,v
+retrieving revision 1\.1
+diff -r1\.1 file2-2
+1a2
+> down"
+
+
+ dotest multiroot-commit-1 "${testcvs} commit -m actually" \
+"${PROG} [a-z]*: Examining \.
+${PROG} [a-z]*: Examining mod1-1
+${PROG} [a-z]*: Examining mod1-2
+${PROG} [a-z]*: Examining mod2-2/mod1-2
+Checking in mod1-1/file1-1;
+${TESTDIR}/root1/mod1-1/file1-1,v <-- file1-1
+new revision: 1.2; previous revision: 1.1
+done
+Checking in mod1-2/file1-2;
+${TESTDIR}/root1/mod1-2/file1-2,v <-- file1-2
+new revision: 1.2; previous revision: 1.1
+done
+${PROG} [a-z]*: Examining mod1-2/mod2-2
+${PROG} [a-z]*: Examining mod2-1
+${PROG} [a-z]*: Examining mod2-2
+Checking in mod2-1/file2-1;
+${TESTDIR}/root2/mod2-1/file2-1,v <-- file2-1
+new revision: 1.2; previous revision: 1.1
+done
+Checking in mod2-2/file2-2;
+${TESTDIR}/root2/mod2-2/file2-2,v <-- file2-2
+new revision: 1.2; previous revision: 1.1
+done"
+
+ dotest multiroot-update-2 "${testcvs} update" \
+"${PROG} update: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: Updating mod2-2/mod1-2
+U mod2-2/mod1-2/file1-2
+${PROG} [a-z]*: Updating mod1-2/mod2-2
+U mod1-2/mod2-2/file2-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: Updating mod2-2" \
+"${PROG} server: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: Updating mod2-2
+${PROG} [a-z]*: Updating mod2-2/mod1-2
+P mod2-2/mod1-2/file1-2
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: Updating mod1-2/mod2-2
+P mod1-2/mod2-2/file2-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: Updating mod2-2"
+
+ dotest multiroot-tag-1 "${testcvs} tag cattle" \
+"${PROG} tag: Tagging \.
+${PROG} [a-z]*: Tagging mod1-1
+T mod1-1/file1-1
+${PROG} [a-z]*: Tagging mod1-2
+T mod1-2/file1-2
+${PROG} [a-z]*: Tagging mod2-2/mod1-2
+${PROG} [a-z]*: Tagging mod1-2/mod2-2
+T mod1-2/mod2-2/file2-2
+${PROG} [a-z]*: Tagging mod2-1
+T mod2-1/file2-1
+${PROG} [a-z]*: Tagging mod2-2" \
+"${PROG} server: Tagging \.
+${PROG} [a-z]*: Tagging mod1-1
+T mod1-1/file1-1
+${PROG} [a-z]*: Tagging mod1-2
+T mod1-2/file1-2
+${PROG} [a-z]*: Tagging mod2-2
+${PROG} [a-z]*: Tagging mod2-2/mod1-2
+${PROG} [a-z]*: Tagging mod1-2
+${PROG} [a-z]*: Tagging mod1-2/mod2-2
+T mod1-2/mod2-2/file2-2
+${PROG} [a-z]*: Tagging mod2-1
+T mod2-1/file2-1
+${PROG} [a-z]*: Tagging mod2-2"
+
+ echo anotherfile1-1 > mod1-1/anotherfile1-1
+ echo anotherfile2-1 > mod2-1/anotherfile2-1
+ echo anotherfile1-2 > mod2-2/mod1-2/anotherfile1-2
+ echo anotherfile2-2 > mod1-2/mod2-2/anotherfile2-2
+
+ if test "x$remote" = xno; then
+ dotest multiroot-add-1 "${testcvs} add mod1-1/anotherfile1-1 mod2-1/anotherfile2-1 mod2-2/mod1-2/anotherfile1-2 mod1-2/mod2-2/anotherfile2-2" \
+"${PROG} [a-z]*: scheduling file .mod1-1/anotherfile1-1. for addition
+${PROG} [a-z]*: scheduling file .mod2-1/anotherfile2-1. for addition
+${PROG} [a-z]*: scheduling file .mod2-2/mod1-2/anotherfile1-2. for addition
+${PROG} [a-z]*: scheduling file .mod1-2/mod2-2/anotherfile2-2. for addition
+${PROG} [a-z]*: use 'cvs commit' to add these files permanently"
+ else
+ cd mod1-1
+ dotest multiroot-add-1a "${testcvs} add anotherfile1-1" \
+"${PROG} [a-z]*: scheduling file .anotherfile1-1. for addition
+${PROG} [a-z]*: use 'cvs commit' to add this file permanently"
+ cd ../mod2-1
+ dotest multiroot-add-1b "${testcvs} add anotherfile2-1" \
+"${PROG} [a-z]*: scheduling file .anotherfile2-1. for addition
+${PROG} [a-z]*: use 'cvs commit' to add this file permanently"
+ cd ../mod2-2/mod1-2
+ dotest multiroot-add-1c "${testcvs} add anotherfile1-2" \
+"${PROG} [a-z]*: scheduling file .anotherfile1-2. for addition
+${PROG} [a-z]*: use 'cvs commit' to add this file permanently"
+ cd ../../mod1-2/mod2-2
+ dotest multiroot-add-1d "${testcvs} add anotherfile2-2" \
+"${PROG} [a-z]*: scheduling file .anotherfile2-2. for addition
+${PROG} [a-z]*: use 'cvs commit' to add this file permanently"
+ cd ../..
+ fi
+
+ dotest multiroot-status-1 "${testcvs} status -v" \
+"${PROG} status: Examining \.
+${PROG} [a-z]*: Examining mod1-1
+===================================================================
+File: anotherfile1-1 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file1-1 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod1-2
+===================================================================
+File: file1-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod2-2/mod1-2
+===================================================================
+File: anotherfile1-2 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file1-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod1-2/mod2-2
+===================================================================
+File: anotherfile2-2 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file2-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod2-1
+===================================================================
+File: anotherfile2-1 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file2-1 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod2-2
+===================================================================
+File: file2-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)" \
+"${PROG} server: Examining \.
+${PROG} [a-z]*: Examining mod1-1
+===================================================================
+File: anotherfile1-1 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file1-1 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod1-2
+===================================================================
+File: file1-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod2-2
+${PROG} [a-z]*: Examining mod2-2/mod1-2
+===================================================================
+File: anotherfile1-2 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file1-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod1-2
+${PROG} [a-z]*: Examining mod1-2/mod2-2
+===================================================================
+File: anotherfile2-2 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file2-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod2-1
+===================================================================
+File: anotherfile2-1 Status: Locally Added
+
+ Working revision: New file!
+ Repository revision: No revision control file
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file2-1 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)
+
+${PROG} [a-z]*: Examining mod2-2
+===================================================================
+File: file2-2 Status: Up-to-date
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+ Existing Tags:
+ cattle (revision: 1\.2)"
+
+ dotest multiroot-commit-2 "${testcvs} commit -m reading" \
+"${PROG} [a-z]*: Examining \.
+${PROG} [a-z]*: Examining mod1-1
+${PROG} [a-z]*: Examining mod1-2
+${PROG} [a-z]*: Examining mod2-2/mod1-2
+RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v
+done
+Checking in mod1-1/anotherfile1-1;
+${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v <-- anotherfile1-1
+initial revision: 1\.1
+done
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
+done
+Checking in mod2-2/mod1-2/anotherfile1-2;
+${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v <-- anotherfile1-2
+initial revision: 1\.1
+done
+${PROG} [a-z]*: Examining mod1-2/mod2-2
+${PROG} [a-z]*: Examining mod2-1
+${PROG} [a-z]*: Examining mod2-2
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
+done
+Checking in mod1-2/mod2-2/anotherfile2-2;
+${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v <-- anotherfile2-2
+initial revision: 1\.1
+done
+RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v
+done
+Checking in mod2-1/anotherfile2-1;
+${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v <-- anotherfile2-1
+initial revision: 1\.1
+done"
+
+ dotest multiroot-update-3 "${testcvs} update" \
+"${PROG} update: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: Updating mod1-2
+U mod1-2/anotherfile1-2
+${PROG} [a-z]*: Updating mod2-2/mod1-2
+${PROG} [a-z]*: Updating mod1-2/mod2-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: Updating mod2-2
+U mod2-2/anotherfile2-2" \
+"${PROG} server: Updating \.
+${PROG} [a-z]*: Updating mod1-1
+${PROG} [a-z]*: Updating mod1-2
+U mod1-2/anotherfile1-2
+${PROG} [a-z]*: Updating mod2-2
+${PROG} [a-z]*: Updating mod2-2/mod1-2
+${PROG} [a-z]*: Updating mod1-2
+${PROG} [a-z]*: Updating mod1-2/mod2-2
+${PROG} [a-z]*: Updating mod2-1
+${PROG} [a-z]*: Updating mod2-2
+U mod2-2/anotherfile2-2"
+
+ dotest multiroot-log-1 "${testcvs} log" \
+"${PROG} log: Logging \.
+${PROG} [a-z]*: Logging mod1-1
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v
+Working file: mod1-1/anotherfile1-1
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v
+Working file: mod1-1/file1-1
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+is
+=============================================================================
+${PROG} [a-z]*: Logging mod1-2
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
+Working file: mod1-2/anotherfile1-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+Working file: mod1-2/file1-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+is
+=============================================================================
+${PROG} [a-z]*: Logging mod2-2/mod1-2
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
+Working file: mod2-2/mod1-2/anotherfile1-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+Working file: mod2-2/mod1-2/file1-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+is
+=============================================================================
+${PROG} [a-z]*: Logging mod1-2/mod2-2
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
+Working file: mod1-2/mod2-2/anotherfile2-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+Working file: mod1-2/mod2-2/file2-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+anyone
+=============================================================================
+${PROG} [a-z]*: Logging mod2-1
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v
+Working file: mod2-1/anotherfile2-1
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v
+Working file: mod2-1/file2-1
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+anyone
+=============================================================================
+${PROG} [a-z]*: Logging mod2-2
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
+Working file: mod2-2/anotherfile2-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+Working file: mod2-2/file2-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+anyone
+=============================================================================" \
+"${PROG} server: Logging \.
+${PROG} [a-z]*: Logging mod1-1
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v
+Working file: mod1-1/anotherfile1-1
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v
+Working file: mod1-1/file1-1
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+is
+=============================================================================
+${PROG} [a-z]*: Logging mod1-2
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
+Working file: mod1-2/anotherfile1-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+Working file: mod1-2/file1-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+is
+=============================================================================
+${PROG} [a-z]*: Logging mod2-2
+${PROG} [a-z]*: Logging mod2-2/mod1-2
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
+Working file: mod2-2/mod1-2/anotherfile1-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
+Working file: mod2-2/mod1-2/file1-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+is
+=============================================================================
+${PROG} [a-z]*: Logging mod1-2
+${PROG} [a-z]*: Logging mod1-2/mod2-2
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
+Working file: mod1-2/mod2-2/anotherfile2-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+Working file: mod1-2/mod2-2/file2-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+anyone
+=============================================================================
+${PROG} [a-z]*: Logging mod2-1
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v
+Working file: mod2-1/anotherfile2-1
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v
+Working file: mod2-1/file2-1
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+anyone
+=============================================================================
+${PROG} [a-z]*: Logging mod2-2
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
+Working file: mod2-2/anotherfile2-2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+reading
+=============================================================================
+
+RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
+Working file: mod2-2/file2-2
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ cattle: 1\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+actually
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+anyone
+============================================================================="
+
+
+ # After the simple cases, let's execute some commands which
+ # refer to parts of our checked-out tree (e.g. "cvs update
+ # mod1-1 mod2-2")
+
+ if test "$keep" = yes; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ # clean up after ourselves
+ cd ..
+ rm -r 1
+
+ # clean up our repositories
+ rm -rf root1 root2
+ ;;
+
+ multiroot2)
+ # More multiroot tests. In particular, nested directories.
+
+ CVSROOT1_DIRNAME=${TESTDIR}/root1
+ CVSROOT2_DIRNAME=${TESTDIR}/root2
+ CVSROOT1=${CVSROOT1_DIRNAME} ; export CVSROOT1
+ CVSROOT2=${CVSROOT2_DIRNAME} ; export CVSROOT2
+ if test "x$remote" = xyes; then
+ CVSROOT1=:fork:${CVSROOT1_DIRNAME} ; export CVSROOT1
+ CVSROOT2=:fork:${CVSROOT2_DIRNAME} ; export CVSROOT2
+ fi
+
+ dotest multiroot2-1 "${testcvs} -d ${CVSROOT1} init" ""
+ dotest multiroot2-2 "${testcvs} -d ${CVSROOT2} init" ""
+
+ mkdir imp-dir; cd imp-dir
+ echo file1 >file1
+ mkdir sdir
+ echo sfile >sdir/sfile
+ mkdir sdir/ssdir
+ echo ssfile >sdir/ssdir/ssfile
+ dotest_sort multiroot2-3 \
+"${testcvs} -d ${CVSROOT1} import -m import-to-root1 dir1 vend rel" "
+
+N dir1/file1
+N dir1/sdir/sfile
+N dir1/sdir/ssdir/ssfile
+No conflicts created by this import
+${PROG} [a-z]*: Importing ${TESTDIR}/root1/dir1/sdir
+${PROG} [a-z]*: Importing ${TESTDIR}/root1/dir1/sdir/ssdir"
+ cd sdir
+ dotest_sort multiroot2-4 \
+"${testcvs} -d ${CVSROOT2} import -m import-to-root2 sdir vend2 rel2" "
+
+N sdir/sfile
+N sdir/ssdir/ssfile
+No conflicts created by this import
+${PROG} [a-z]*: Importing ${TESTDIR}/root2/sdir/ssdir"
+ cd ../..
+
+ mkdir 1; cd 1
+ # Get TopLevelAdmin-like behavior.
+ dotest multiroot2-5 "${testcvs} -d ${CVSROOT1} -q co -l ."
+ dotest multiroot2-5 "${testcvs} -d ${CVSROOT1} -q co dir1" \
+"U dir1/file1
+U dir1/sdir/sfile
+U dir1/sdir/ssdir/ssfile"
+ cd dir1
+ dotest multiroot2-6 "${testcvs} -Q release -d sdir" ""
+ dotest multiroot2-7 "${testcvs} -d ${CVSROOT2} -q co sdir" \
+"U sdir/sfile
+U sdir/ssdir/ssfile"
+ cd ..
+ # This has one subtle effect - it deals with Entries.Log
+ # so that the next test doesn't get trace messages for
+ # Entries.Log
+ dotest multiroot2-8 "${testcvs} update" \
+"${PROG} update: Updating \.
+${PROG} update: Updating dir1
+${PROG} update: Updating dir1/sdir
+${PROG} update: Updating dir1/sdir/ssdir" \
+"${PROG} server: Updating \.
+${PROG} server: Updating dir1
+${PROG} server: Updating dir1
+${PROG} server: Updating dir1/sdir
+${PROG} server: Updating dir1/sdir/ssdir"
+ # Two reasons we don't run this on the server: (1) the server
+ # also prints some trace messages, and (2) the server trace
+ # messages are subject to out-of-order bugs (this one is hard
+ # to work around).
+ if test "$remote" = no; then
+ dotest multiroot2-9 "${testcvs} -t update" \
+"${PROG} update: notice: main loop with CVSROOT=${TESTDIR}/root1
+${PROG} update: Updating \.
+${PROG} update: Updating dir1
+${PROG} update: notice: main loop with CVSROOT=${TESTDIR}/root2
+${PROG} update: Updating dir1/sdir
+${PROG} update: Updating dir1/sdir/ssdir"
+ fi
+
+ dotest multiroot2-9 "${testcvs} -q tag tag1" \
+"T dir1/file1
+T dir1/sdir/sfile
+T dir1/sdir/ssdir/ssfile"
+ echo "change it" >>dir1/file1
+ echo "change him too" >>dir1/sdir/sfile
+ dotest multiroot2-10 "${testcvs} -q ci -m modify" \
+"Checking in dir1/file1;
+${TESTDIR}/root1/dir1/file1,v <-- file1
+new revision: 1\.2; previous revision: 1\.1
+done
+Checking in dir1/sdir/sfile;
+${TESTDIR}/root2/sdir/sfile,v <-- sfile
+new revision: 1\.2; previous revision: 1\.1
+done"
+ dotest multiroot2-11 "${testcvs} -q tag tag2" \
+"T dir1/file1
+T dir1/sdir/sfile
+T dir1/sdir/ssdir/ssfile"
+ dotest_status multiroot2-12 1 \
+"${testcvs} -q diff -u -r tag1 -r tag2" \
+"Index: dir1/file1
+===================================================================
+RCS file: ${TESTDIR}/root1/dir1/file1,v
+retrieving revision 1\.1\.1\.1
+retrieving revision 1\.2
+diff -u -r1\.1\.1\.1 -r1\.2
+--- dir1/file1 [0-9/]* [0-9:]* 1\.1\.1\.1
+${PLUS}${PLUS}${PLUS} dir1/file1 [0-9/]* [0-9:]* 1\.2
+@@ -1 ${PLUS}1,2 @@
+ file1
+${PLUS}change it
+Index: dir1/sdir/sfile
+===================================================================
+RCS file: ${TESTDIR}/root2/sdir/sfile,v
+retrieving revision 1\.1\.1\.1
+retrieving revision 1\.2
+diff -u -r1\.1\.1\.1 -r1\.2
+--- dir1/sdir/sfile [0-9/]* [0-9:]* 1\.1\.1\.1
+${PLUS}${PLUS}${PLUS} dir1/sdir/sfile [0-9/]* [0-9:]* 1\.2
+@@ -1 ${PLUS}1,2 @@
+ sfile
+${PLUS}change him too"
+
+ if test "$keep" = yes; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ # clean up after ourselves
+ cd ..
+ rm -r imp-dir 1
+
+ # clean up our repositories
+ rm -rf root1 root2
+ ;;
+
+ multiroot3)
+ # More multiroot tests. Directories are side-by-side, not nested.
+ # Not drastically different from multiroot but it covers somewhat
+ # different stuff.
+
+ if test "x$remote" = xyes; then
+ CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1
+ CVSROOT2=:fork:${TESTDIR}/root2 ; export CVSROOT2
+ else
+ CVSROOT1=${TESTDIR}/root1 ; export CVSROOT1
+ CVSROOT2=${TESTDIR}/root2 ; export CVSROOT2
+ fi
+
+ mkdir 1; cd 1
+ dotest multiroot3-1 "${testcvs} -d ${CVSROOT1} init" ""
+ dotest multiroot3-2 "${testcvs} -d ${CVSROOT1} -q co -l ." ""
+ mkdir dir1
+ dotest multiroot3-3 "${testcvs} add dir1" \
+"Directory ${TESTDIR}/root1/dir1 added to the repository"
+ dotest multiroot3-4 "${testcvs} -d ${CVSROOT2} init" ""
+ rm -r CVS
+ dotest multiroot3-5 "${testcvs} -d ${CVSROOT2} -q co -l ." ""
+ mkdir dir2
+
+ # OK, the problem is that CVS/Entries doesn't look quite right,
+ # I suppose because of the "rm -r".
+ # For local this fixes it up.
+ dotest multiroot3-6 "${testcvs} -d ${CVSROOT1} -q co dir1" ""
+ if test "$remote" = yes; then
+ # For remote that doesn't do it. Use the quick and dirty fix.
+ echo "D/dir1////" >CVS/Entries
+ echo "D/dir2////" >>CVS/Entries
+ fi
+
+ dotest multiroot3-7 "${testcvs} add dir2" \
+"Directory ${TESTDIR}/root2/dir2 added to the repository"
+
+ touch dir1/file1 dir2/file2
+ if test "$remote" = yes; then
+ # Trying to add them both in one command doesn't work,
+ # because add.c doesn't do multiroot (it doesn't use recurse.c).
+ # Furthermore, it can't deal with the parent directory
+ # having a different root from the child, hence the cd.
+ cd dir1
+ dotest multiroot3-8 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ cd ..
+ dotest multiroot3-8a "${testcvs} add dir2/file2" \
+"${PROG} [a-z]*: scheduling file .dir2/file2. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ else
+ dotest multiroot3-8 "${testcvs} add dir1/file1 dir2/file2" \
+"${PROG} [a-z]*: scheduling file .dir1/file1. for addition
+${PROG} [a-z]*: scheduling file .dir2/file2. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+ fi
+
+ dotest multiroot3-9 "${testcvs} -q ci -m add-them" \
+"RCS file: ${TESTDIR}/root2/dir2/file2,v
+done
+Checking in dir2/file2;
+${TESTDIR}/root2/dir2/file2,v <-- file2
+initial revision: 1\.1
+done
+RCS file: ${TESTDIR}/root1/dir1/file1,v
+done
+Checking in dir1/file1;
+${TESTDIR}/root1/dir1/file1,v <-- file1
+initial revision: 1\.1
+done"
+
+ if test "`cat dir1/CVS/Repository`" = "dir1"; then
+ # RELATIVE_REPOS
+ # That this is an error is good - we are asking CVS to do
+ # something which doesn't make sense.
+ dotest_fail multiroot3-10 \
+"${testcvs} -q -d ${CVSROOT1} diff dir1/file1 dir2/file2" \
+"${PROG} [a-z]*: failed to create lock directory in repository .${TESTDIR}/root1/dir2': No such file or directory
+${PROG} [a-z]*: failed to obtain dir lock in repository .${TESTDIR}/root1/dir2'
+${PROG} \[[a-z]* aborted\]: read lock failed - giving up"
+ else
+ # Not RELATIVE_REPOS.
+ if test "$remote" = yes; then
+ # This is good behavior - we are asking CVS to do something
+ # which doesn't make sense.
+ dotest_fail multiroot3-10 \
+"${testcvs} -q -d ${CVSROOT1} diff dir1/file1 dir2/file2" \
+"protocol error: directory '${TESTDIR}/root2/dir2' not within root '${TESTDIR}/root1'"
+ else
+ # Local isn't as picky as we'd want in terms of getting
+ # the wrong root.
+ dotest multiroot3-10 \
+"${testcvs} -q -d ${CVSROOT1} diff dir1/file1 dir2/file2" ""
+ fi
+ fi
+ # This one is supposed to work.
+ dotest multiroot3-11 "${testcvs} -q diff dir1/file1 dir2/file2" ""
+
+ cd ..
+
+ if test "$keep" = yes; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ rm -r 1
+ rm -rf ${TESTDIR}/root1 ${TESTDIR}/root2
+ unset CVSROOT1
+ unset CVSROOT2
+ ;;
+
+ multiroot4)
+ # More multiroot tests, in particular we have two roots with
+ # similarly-named directories and we try to see that CVS can
+ # keep them separate.
+ if test "x$remote" = xyes; then
+ CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1
+ CVSROOT2=:fork:${TESTDIR}/root2 ; export CVSROOT2
+ else
+ CVSROOT1=${TESTDIR}/root1 ; export CVSROOT1
+ CVSROOT2=${TESTDIR}/root2 ; export CVSROOT2
+ fi
+
+ mkdir 1; cd 1
+ dotest multiroot4-1 "${testcvs} -d ${CVSROOT1} init" ""
+ dotest multiroot4-2 "${testcvs} -d ${CVSROOT1} -q co -l ." ""
+ mkdir dircom
+ dotest multiroot4-3 "${testcvs} add dircom" \
+"Directory ${TESTDIR}/root1/dircom added to the repository"
+ cd dircom
+ touch file1
+ dotest multiroot4-4 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest multiroot4-5 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/root1/dircom/file1,v
+done
+Checking in file1;
+${TESTDIR}/root1/dircom/file1,v <-- file1
+initial revision: 1\.1
+done"
+ cd ../..
+ mkdir 2; cd 2
+ dotest multiroot4-6 "${testcvs} -d ${CVSROOT2} init" ""
+ dotest multiroot4-7 "${testcvs} -d ${CVSROOT2} -q co -l ." ""
+ mkdir dircom
+ dotest multiroot4-8 "${testcvs} add dircom" \
+"Directory ${TESTDIR}/root2/dircom added to the repository"
+ cd dircom
+ touch file2
+ dotest multiroot4-9 "${testcvs} add file2" \
+"${PROG} [a-z]*: scheduling file .file2. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest multiroot4-10 "${testcvs} -q ci -m add" \
+"RCS file: ${TESTDIR}/root2/dircom/file2,v
+done
+Checking in file2;
+${TESTDIR}/root2/dircom/file2,v <-- file2
+initial revision: 1\.1
+done"
+
+ cd ../..
+ cd 1/dircom
+ # This may look contrived; the real world example which inspired
+ # it was that a user was changing from local to remote. Cases
+ # like switching servers (among those mounting the same
+ # repository) and so on would also look the same.
+ mkdir sdir2
+ dotest multiroot4-11 "${testcvs} -d ${CVSROOT2} add sdir2" \
+"Directory ${TESTDIR}/root2/dircom/sdir2 added to the repository"
+
+ dotest multiroot4-12 "${testcvs} -q update" ""
+ cd ..
+ dotest multiroot4-13 "${testcvs} -q update dircom" ""
+ cd ..
+
+ rm -r 1 2
+ rm -rf ${TESTDIR}/root1 ${TESTDIR}/root2
+ unset CVSROOT1
+ unset CVSROOT2
+ ;;
+
+ reposmv)
+ # More tests of repositories and specifying them.
+ # Similar to crerepos but that test is probably getting big
+ # enough.
+
+ if test "x$remote" = xyes; then
+ CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1
+ CVSROOT_MOVED=:fork:${TESTDIR}/root-moved ; export CVSROOT1
+ else
+ CVSROOT1=${TESTDIR}/root1 ; export CVSROOT1
+ CVSROOT_MOVED=${TESTDIR}/root-moved ; export CVSROOT1
+ fi
+
+ dotest reposmv-setup-1 "${testcvs} -d ${CVSROOT1} init" ""
+ mkdir imp-dir; cd imp-dir
+ echo file1 >file1
+ dotest reposmv-setup-2 \
+"${testcvs} -d ${CVSROOT1} import -m add dir1 vendor release" \
+"N dir1/file1
+
+No conflicts created by this import"
+ cd ..
+
+ mkdir 1; cd 1
+ dotest reposmv-1 "${testcvs} -d ${CVSROOT1} -Q co dir1" ""
+ mv ${TESTDIR}/root1 ${TESTDIR}/root-moved
+ cd dir1
+
+ # If we didn't have a relative repository, get one now.
+ dotest reposmv-1a "cat CVS/Repository" \
+"${TESTDIR}/root1/dir1" "dir1"
+ echo dir1 >CVS/Repository
+
+ # There were some duplicated warnings and such; only test
+ # for the part of the error message which makes sense.
+ # Bug: "skipping directory " without filename.
+ if test "$remote" = no; then
+ dotest reposmv-2 "${testcvs} update" "${DOTSTAR}
+${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1
+${PROG} update: cannot open directory ${TESTDIR}/cvsroot/dir1: No such file or directory
+${PROG} update: skipping directory "
+ else
+ dotest_fail reposmv-2 "${testcvs} update" \
+"Cannot access ${TESTDIR}/root1/CVSROOT
+No such file or directory"
+ fi
+
+ # CVS/Root overrides $CVSROOT
+ if test "$remote" = no; then
+ CVSROOT_SAVED=${CVSROOT}
+ CVSROOT=${TESTDIR}/root-moved; export CVSROOT
+ dotest reposmv-3 "${testcvs} update" \
+"${DOTSTAR}
+${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1
+${PROG} update: Updating \.
+${DOTSTAR}"
+ CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ else
+ CVSROOT_SAVED=${CVSROOT}
+ CVSROOT=:fork:${TESTDIR}/root-moved; export CVSROOT
+ dotest_fail reposmv-3 "${testcvs} update" \
+"Cannot access ${TESTDIR}/root1/CVSROOT
+No such file or directory"
+ CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ fi
+
+ if test "$remote" = no; then
+ # CVS/Root doesn't seem to quite completely override $CVSROOT
+ # Bug? Not necessarily a big deal if it only affects error
+ # messages.
+ CVSROOT_SAVED=${CVSROOT}
+ CVSROOT=${TESTDIR}/root-none; export CVSROOT
+ dotest_fail reposmv-4 "${testcvs} update" \
+"${PROG} update: in directory \.:
+${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1
+${PROG} \[update aborted\]: ${TESTDIR}/root-none/CVSROOT: No such file or directory"
+ CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ else
+ CVSROOT_SAVED=${CVSROOT}
+ CVSROOT=:fork:${TESTDIR}/root-none; export CVSROOT
+ dotest_fail reposmv-4 "${testcvs} update" \
+"Cannot access ${TESTDIR}/root1/CVSROOT
+No such file or directory"
+ CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ fi
+
+ # -d overrides CVS/Root
+ #
+ # Oddly enough, with CVS 1.10 I think this didn't work for
+ # local (that is, it would appear that CVS/Root would not
+ # get used, but would produce an error if it didn't exist).
+ dotest reposmv-5 "${testcvs} -d ${CVSROOT_MOVED} update" \
+"${PROG} [a-z]*: Updating \."
+
+ # TODO: could also test various other things, like what if the
+ # user removes CVS/Root (which is legit). Or another set of
+ # tests would be if both repositories exist but we want to make
+ # sure that CVS is using the correct one.
+
+ cd ../..
+ rm -r imp-dir 1
+ rm -rf root1 root2
+ unset CVSROOT1
+ ;;
+
+ pserver)
+ # Test basic pserver functionality.
+ if test "$remote" = yes; then
+ # First set SystemAuth=no. Not really necessary, I don't
+ # think, but somehow it seems like the clean thing for
+ # the testsuite.
+ mkdir 1; cd 1
+ dotest pserver-1 "${testcvs} -Q co CVSROOT" ""
+ cd CVSROOT
+ echo "SystemAuth=no" >config
+ dotest pserver-2 "${testcvs} -q ci -m config-it" \
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ echo "testme:q6WV9d2t848B2:`id -un`" \
+ >${CVSROOT_DIRNAME}/CVSROOT/passwd
+ ${testcvs} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d
+END AUTH REQUEST
+EOF
+ dotest pserver-3 "cat ${TESTDIR}/pserver.tmp" \
+"error 0 Server configuration missing --allow-root in inetd.conf"
+
+ # Sending the Root and noop before waiting for the
+ # "I LOVE YOU" is bogus, but hopefully we can get
+ # away with it.
+ ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d
+END AUTH REQUEST
+Root ${CVSROOT_DIRNAME}
+noop
+EOF
+ dotest pserver-4 "cat ${TESTDIR}/pserver.tmp" \
+"I LOVE YOU${DOTSTAR}ok"
+
+ ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d
+END AUTH REQUEST
+Root ${TESTDIR}/1
+noop
+EOF
+ dotest pserver-5 "cat ${TESTDIR}/pserver.tmp" \
+"I LOVE YOU${DOTSTAR}E Protocol error: Root says \"${TESTDIR}/1\" but pserver says \"${CVSROOT_DIRNAME}\"
+error "
+
+ ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d^b?hd
+END AUTH REQUEST
+EOF
+ dotest pserver-6 "cat ${TESTDIR}/pserver.tmp" \
+"I HATE YOU"
+
+ # Clean up.
+ echo "# comments only" >config
+ dotest pserver-cleanup-1 "${testcvs} -q ci -m config-it" \
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ../..
+ rm -r 1
+ rm ${CVSROOT_DIRNAME}/CVSROOT/passwd
+ fi # skip the whole thing for local
+ ;;
+
+ server)
+ # Some tests of the server (independent of the client).
+ if test "$remote" = yes; then
+ if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+Directory bogus
+mumble/bar
+update
+EOF
+ dotest server-1 "cat ${TESTDIR}/server.tmp" \
+"E Protocol error: Root request missing
+error "
+ else
+ echo "exit status was $?" >>${LOGFILE}
+ fail server-1
+ fi
+
+ # Could also test for relative pathnames here (so that crerepos-6a
+ # and crerepos-6b can use :fork:).
+ if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+Set OTHER=variable
+Set MYENV=env-value
+init ${TESTDIR}/crerepos
+EOF
+ dotest server-2 "cat ${TESTDIR}/server.tmp" "ok"
+ else
+ echo "exit status was $?" >>${LOGFILE}
+ fail server-2
+ fi
+ dotest server-3 "test -d ${TESTDIR}/crerepos/CVSROOT" ""
+
+ # Now some tests of gzip-file-contents (used by jCVS).
+ awk 'BEGIN {
+printf "%c%c%c%c%c%c.6%c%c+I-.%c%c%c%c5%c;%c%c%c%c",
+31, 139, 8, 64, 5, 7, 64, 3, 225, 2, 64, 198, 185, 5, 64, 64, 64}' \
+ </dev/null | tr '\100' '\000' >gzipped.dat
+ echo Root ${TESTDIR}/crerepos >session.dat
+ # Note that the CVS client sends "-b 1.1.1", and this
+ # test doesn't. But the server also defaults to that.
+ cat <<EOF >>session.dat
+UseUnchanged
+gzip-file-contents 3
+Argument -m
+Argument msg
+Argumentx
+Argument dir1
+Argument tag1
+Argument tag2
+Directory .
+in-real-life-this-is-funky-but-server-seems-to-ignore-it
+Modified file1
+u=rw,g=r,o=r
+z25
+EOF
+ cat gzipped.dat >>session.dat
+ echo import >>session.dat
+ if ${testcvs} server >${TESTDIR}/server.tmp <session.dat; then
+ dotest server-4 "cat ${TESTDIR}/server.tmp" "M N dir1/file1
+M
+M No conflicts created by this import
+M
+ok"
+ else
+ echo "exit status was $?" >>${LOGFILE}
+ fail server-4
+ fi
+ dotest server-5 \
+"${testcvs} -q -d ${TESTDIR}/crerepos co -p dir1/file1" "test"
+
+ if test "$keep" = yes; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ rm -rf ${TESTDIR}/crerepos
+ rm gzipped.dat session.dat
+ rm ${TESTDIR}/server.tmp
+ fi # skip the whole thing for local
+ ;;
+
+ client)
+ # Some tests of the client (independent of the server).
+ if test "$remote" = yes; then
+ cat >${TESTDIR}/serveme <<EOF
+#!${TESTSHELL}
+# This is admittedly a bit cheezy, in the sense that we make lots
+# of assumptions about what the client is going to send us.
+# We don't mention Repository, because current clients don't require it.
+# Sending these at our own pace, rather than waiting for the client to
+# make the requests, is bogus, but hopefully we can get away with it.
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "M special message"
+echo "Created first-dir/"
+echo "${TESTDIR}/cvsroot/first-dir/file1"
+echo "/file1/1.1///"
+echo "u=rw,g=rw,o=rw"
+echo "4"
+echo "xyz"
+echo "ok"
+cat >/dev/null
+EOF
+ chmod +x ${TESTDIR}/serveme
+ CVS_SERVER=${TESTDIR}/serveme; export CVS_SERVER
+ mkdir 1; cd 1
+ dotest_fail client-1 "${testcvs} -q co first-dir" \
+"${PROG} \[checkout aborted\]: This server does not support the global -q option\."
+ dotest client-2 "${testcvs} co first-dir" "special message"
+
+ cat >${TESTDIR}/serveme <<EOF
+#!${TESTSHELL}
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "M merge-it"
+echo "Copy-file ./"
+echo "${TESTDIR}/cvsroot/first-dir/file1"
+echo "${TESTDIR}/bogus/.#file1.1.1"
+echo "Merged ./"
+echo "${TESTDIR}/cvsroot/first-dir/file1"
+echo "/file1/1.2///"
+echo "u=rw,g=rw,o=rw"
+echo "4"
+echo "abd"
+echo "ok"
+cat >/dev/null
+EOF
+ cd first-dir
+ mkdir ${TESTDIR}/bogus
+ dotest_fail client-3 "${testcvs} update" "merge-it
+${PROG} \[update aborted\]: protocol error: Copy-file tried to specify directory"
+ cat >${TESTDIR}/serveme <<EOF
+#!${TESTSHELL}
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "M merge-it"
+echo "Copy-file ./"
+echo "${TESTDIR}/cvsroot/first-dir/file1"
+echo ".#file1.1.1"
+echo "Merged ./"
+echo "${TESTDIR}/cvsroot/first-dir/file1"
+echo "/file1/1.2///"
+echo "u=rw,g=rw,o=rw"
+echo "4"
+echo "abc"
+echo "ok"
+cat >/dev/null
+EOF
+ dotest client-4 "${testcvs} update" "merge-it"
+ dotest client-5 "cat .#file1.1.1" "xyz"
+ dotest client-6 "cat CVS/Entries" "/file1/1.2/[A-Za-z0-9 :]*//
+D"
+ dotest client-7 "cat file1" "abc"
+
+ cat >${TESTDIR}/serveme <<EOF
+#!${TESTSHELL}
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "M OK, whatever"
+echo "ok"
+cat >${TESTDIR}/client.tmp
+EOF
+ chmod u=rw,go= file1
+ # By specifying the time zone in local time, we don't
+ # know exactly how that will translate to GMT.
+ dotest client-8 "${testcvs} update -D 99-10-04" "OK, whatever"
+ dotest client-9 "cat ${TESTDIR}/client.tmp" \
+"Root ${TESTDIR}/cvsroot
+Valid-responses [-a-zA-Z ]*
+valid-requests
+Argument -D
+Argument [34] Oct 1999 [0-9][0-9]:00:00 -0000
+Directory \.
+${TESTDIR}/cvsroot/first-dir
+Entry /file1/1\.2///
+Modified file1
+u=rw,g=,o=
+4
+abc
+update"
+
+ cd ../..
+ rm -r 1
+ rmdir ${TESTDIR}/bogus
+ rm ${TESTDIR}/serveme
+ CVS_SERVER=${testcvs}; export CVS_SERVER
+ fi # skip the whole thing for local
+ ;;
+
*)
echo $what is not the name of a test -- ignored
;;
@@ -15535,6 +18921,13 @@ echo "OK, all tests completed."
# server (e.g. set CVS_SERVER to "foobar").
# * Test the contents of adm files other than Root and Repository.
# Entries seems the next most important thing.
+# * Test the following compatibility issues:
+# - The filler fields in "D" entries in CVS/Entries get preserved
+# (per cvs.texinfo).
+# - Unrecognized entry types in CVS/Entries get ignored (looks like
+# this needs to be documented in cvs.texinfo, but is not)
+# - Test that unrecognized files in CVS directories (e.g. CVS/Foobar)
+# are ignored (per cvs.texinfo).
# End of TODO list.
# Remove the test directory, but first change out of it.
diff --git a/gnu/usr.bin/cvs/src/server.h b/gnu/usr.bin/cvs/src/server.h
index f94b7aa32a4..caeff8a7ccc 100644
--- a/gnu/usr.bin/cvs/src/server.h
+++ b/gnu/usr.bin/cvs/src/server.h
@@ -7,6 +7,16 @@
#define STDERR_FILENO 2
#endif
+
+/*
+ * Expand to `S', ` ', or the empty string. Used in `%s-> ...' trace printfs.
+ */
+#ifdef SERVER_SUPPORT
+# define CLIENT_SERVER_STR ((server_active) ? "S" : " ")
+#else
+# define CLIENT_SERVER_STR ""
+#endif
+
#ifdef SERVER_SUPPORT
/*
@@ -139,38 +149,30 @@ struct request
void (*func) PROTO((char *args));
#endif
- /* Stuff for use by the client. */
- enum {
- /*
- * Failure to implement this request can imply a fatal
- * error. This should be set only for commands which were in the
- * original version of the protocol; it should not be set for new
- * commands.
- */
- rq_essential,
-
- /* Some servers might lack this request. */
- rq_optional,
-
- /*
- * Set by the client to one of the following based on what this
- * server actually supports.
- */
- rq_supported,
- rq_not_supported,
-
- /*
- * If the server supports this request, and we do too, tell the
- * server by making the request.
- */
- rq_enableme
- } status;
+ /* One or more of the RQ_* flags described below. */
+ int flags;
+
+ /* If set, failure to implement this request can imply a fatal
+ error. This should be set only for commands which were in the
+ original version of the protocol; it should not be set for new
+ commands. */
+#define RQ_ESSENTIAL 1
+
+ /* Set by the client if the server we are talking to supports it. */
+#define RQ_SUPPORTED 2
+
+ /* If set, and client and server both support the request, the
+ client should tell the server by making the request. */
+#define RQ_ENABLEME 4
+
+ /* The server may accept this request before "Root". */
+#define RQ_ROOTLESS 8
};
/* Table of requests ending with an entry with a NULL name. */
extern struct request requests[];
/* Gzip library, see zlib.c. */
-extern void gunzip_and_write PROTO ((int, char *, unsigned char *, size_t));
-extern void read_and_gzip PROTO ((int, char *, unsigned char **, size_t *,
- size_t *, int));
+extern int gunzip_and_write PROTO ((int, char *, unsigned char *, size_t));
+extern int read_and_gzip PROTO ((int, char *, unsigned char **, size_t *,
+ size_t *, int));
diff --git a/gnu/usr.bin/cvs/src/status.c b/gnu/usr.bin/cvs/src/status.c
index 541a969a711..c405c454515 100644
--- a/gnu/usr.bin/cvs/src/status.c
+++ b/gnu/usr.bin/cvs/src/status.c
@@ -77,8 +77,6 @@ cvsstatus (argc, argv)
if (local)
send_arg("-l");
- send_file_names (argc, argv, SEND_EXPAND_WILD);
-
/* For a while, we tried setting SEND_NO_CONTENTS here so this
could be a fast operation. That prevents the
server from updating our timestamp if the timestamp is
@@ -94,6 +92,8 @@ cvsstatus (argc, argv)
send_files (argc, argv, local, 0, 0);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
+
send_to_server ("status\012", 0);
err = get_responses_and_close ();
@@ -242,7 +242,7 @@ status_fileproc (callerdat, finfo)
}
else
{
- if (isdigit (edata->tag[0]))
+ if (isdigit ((unsigned char) edata->tag[0]))
{
cvs_output (" Sticky Tag:\t\t", 0);
cvs_output (edata->tag, 0);
diff --git a/gnu/usr.bin/cvs/src/subr.c b/gnu/usr.bin/cvs/src/subr.c
index 07d516f684c..b2e250c0e40 100644
--- a/gnu/usr.bin/cvs/src/subr.c
+++ b/gnu/usr.bin/cvs/src/subr.c
@@ -64,7 +64,11 @@ xrealloc (ptr, bytes)
memory which is likely to get as big as MAX_INCR shouldn't be doing
it in one block which must be contiguous, but since getrcskey does
so, we might as well limit the wasted memory to MAX_INCR or so
- bytes. */
+ bytes.
+
+ MIN_INCR and MAX_INCR should both be powers of two and we generally
+ try to keep our allocations to powers of two for the most part.
+ Most malloc implementations these days tend to like that. */
#define MIN_INCR 1024
#define MAX_INCR (2*1024*1024)
@@ -84,11 +88,15 @@ expand_string (strptr, n, newsize)
while (*n < newsize)
{
if (*n < MIN_INCR)
- *n += MIN_INCR;
- else if (*n > MAX_INCR)
+ *n = MIN_INCR;
+ else if (*n >= MAX_INCR)
*n += MAX_INCR;
else
+ {
*n *= 2;
+ if (*n > MAX_INCR)
+ *n = MAX_INCR;
+ }
}
*strptr = xrealloc (*strptr, *n);
}
@@ -487,7 +495,7 @@ check_numeric (rev, argc, argv)
int argc;
char **argv;
{
- if (rev == NULL || !isdigit (*rev))
+ if (rev == NULL || !isdigit ((unsigned char) *rev))
return;
/* Note that the check for whether we are processing more than one
@@ -534,7 +542,7 @@ make_message_rcslegal (message)
}
/* Backtrack to last non-space at end of string, and truncate. */
- while (dp > dst && isspace (dp[-1]))
+ while (dp > dst && isspace ((unsigned char) dp[-1]))
--dp;
*dp = '\0';
@@ -684,3 +692,49 @@ get_file (name, fullname, mode, buf, bufsize, len)
(*buf)[nread] = '\0';
}
}
+
+
+/* Follow a chain of symbolic links to its destination. FILENAME
+ should be a handle to a malloc'd block of memory which contains the
+ beginning of the chain. This routine will replace the contents of
+ FILENAME with the destination (a real file). */
+
+void
+resolve_symlink (filename)
+ char **filename;
+{
+ if ((! filename) || (! *filename))
+ return;
+
+ while (islink (*filename))
+ {
+ char *newname;
+#ifdef HAVE_READLINK
+ /* The clean thing to do is probably to have each filesubr.c
+ implement this (with an error if not supported by the
+ platform, in which case islink would presumably return 0).
+ But that would require editing each filesubr.c and so the
+ expedient hack seems to be looking at HAVE_READLINK. */
+ newname = xreadlink (*filename);
+#else
+ error (1, 0, "internal error: islink doesn't like readlink");
+#endif
+
+ if (isabsolute (newname))
+ {
+ free (*filename);
+ *filename = newname;
+ }
+ else
+ {
+ char *oldname = last_component (*filename);
+ int dirlen = oldname - *filename;
+ char *fullnewname = xmalloc (dirlen + strlen (newname) + 1);
+ strncpy (fullnewname, *filename, dirlen);
+ strcpy (fullnewname + dirlen, newname);
+ free (newname);
+ free (*filename);
+ *filename = fullnewname;
+ }
+ }
+}
diff --git a/gnu/usr.bin/cvs/src/tag.c b/gnu/usr.bin/cvs/src/tag.c
index a5b8794fe10..fa713455d96 100644
--- a/gnu/usr.bin/cvs/src/tag.c
+++ b/gnu/usr.bin/cvs/src/tag.c
@@ -59,7 +59,7 @@ static List *tlist;
static const char *const tag_usage[] =
{
- "Usage: %s %s [-lRF] [-b] [-d] [-c] [-r tag|-D date] tag [files...]\n",
+ "Usage: %s %s [-lRF] [-b] [-d] [-c] [-r rev|-D date] tag [files...]\n",
"\t-l\tLocal directory only, not recursive.\n",
"\t-R\tProcess directories recursively.\n",
"\t-d\tDelete the given tag.\n",
@@ -178,15 +178,13 @@ cvstag (argc, argv)
send_arg (symtag);
- send_file_names (argc, argv, SEND_EXPAND_WILD);
-
- /* SEND_NO_CONTENTS has a mildly bizarre interaction with
- check_uptodate; if the timestamp is modified but the file
- is unmodified, the check will fail, only to have "cvs diff"
- show no differences (and one must do "update" or something to
- reset the client's notion of the timestamp). */
+ send_files (argc, argv, local, 0,
- send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+ /* I think the -c case is like "cvs status", in
+ which we really better be correct rather than
+ being fast; it is just too confusing otherwise. */
+ check_uptodate ? 0 : SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("tag\012", 0);
return get_responses_and_close ();
}
@@ -297,9 +295,16 @@ check_fileproc (callerdat, finfo)
{
if (delete_flag)
{
+ /* Deleting a tag which did not exist is a noop and
+ should not be logged. */
addit = 0;
}
}
+ else if (delete_flag)
+ {
+ free (p->data);
+ p->data = xstrdup (oversion);
+ }
else if (strcmp(oversion, p->data) == 0)
{
addit = 0;
@@ -367,7 +372,7 @@ pretag_proc(repository, filter)
s = xstrdup(filter);
for (cp=s; *cp; cp++)
{
- if (isspace(*cp))
+ if (isspace ((unsigned char) *cp))
{
*cp = '\0';
break;
@@ -747,12 +752,12 @@ tag_check_valid (name, argc, argv, local, aflag, repository)
int which;
/* Numeric tags require only a syntactic check. */
- if (isdigit (name[0]))
+ if (isdigit ((unsigned char) name[0]))
{
char *p;
for (p = name; *p != '\0'; ++p)
{
- if (!(isdigit (*p) || *p == '.'))
+ if (!(isdigit ((unsigned char) *p) || *p == '.'))
error (1, 0, "\
Numeric tag %s contains characters other than digits and '.'", name);
}
@@ -903,7 +908,7 @@ tag_check_valid_join (join_tag, argc, argv, local, aflag, repository)
s = strchr (c, ':');
if (s != NULL)
{
- if (isdigit (join_tag[0]))
+ if (isdigit ((unsigned char) join_tag[0]))
error (1, 0,
"Numeric join tag %s may not contain a date specifier",
join_tag);
diff --git a/gnu/usr.bin/cvs/src/vers_ts.c b/gnu/usr.bin/cvs/src/vers_ts.c
index be0f588b419..e1ba32d2c4c 100644
--- a/gnu/usr.bin/cvs/src/vers_ts.c
+++ b/gnu/usr.bin/cvs/src/vers_ts.c
@@ -34,6 +34,10 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
struct stickydirtag *sdtp;
Entnode *entdata;
+#ifdef UTIME_EXPECTS_WRITABLE
+ int change_it_back = 0;
+#endif
+
/* get a new Vers_TS struct */
vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS));
memset ((char *) vers_ts, 0, sizeof (*vers_ts));
@@ -209,12 +213,28 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
{
t.actime = t.modtime;
+#ifdef UTIME_EXPECTS_WRITABLE
+ if (!iswritable (finfo->file))
+ {
+ xchmod (finfo->file, 1);
+ change_it_back = 1;
+ }
+#endif /* UTIME_EXPECTS_WRITABLE */
+
/* This used to need to ignore existence_errors
(for cases like where update.c now clears
set_time if noexec, but didn't used to). I
think maybe now it doesn't (server_modtime does
not like those kinds of cases). */
(void) utime (finfo->file, &t);
+
+#ifdef UTIME_EXPECTS_WRITABLE
+ if (change_it_back == 1)
+ {
+ xchmod (finfo->file, 0);
+ change_it_back = 0;
+ }
+#endif /* UTIME_EXPECTS_WRITABLE */
}
}
}
diff --git a/gnu/usr.bin/cvs/src/version.c b/gnu/usr.bin/cvs/src/version.c
index 479e5e6af77..ca5a98b21b4 100644
--- a/gnu/usr.bin/cvs/src/version.c
+++ b/gnu/usr.bin/cvs/src/version.c
@@ -12,8 +12,7 @@
#include "cvs.h"
-/* NOTE: remember to remove `Halibut' when patching this code. */
-char *version_string = "\nConcurrent Versions System (CVS) 1.10 `Halibut'";
+char *version_string = "\nConcurrent Versions System (CVS) 1.10.5";
#ifdef CLIENT_SUPPORT
#ifdef SERVER_SUPPORT
diff --git a/gnu/usr.bin/cvs/src/watch.c b/gnu/usr.bin/cvs/src/watch.c
index d9ba1d74171..b2935ac3dd0 100644
--- a/gnu/usr.bin/cvs/src/watch.c
+++ b/gnu/usr.bin/cvs/src/watch.c
@@ -337,8 +337,8 @@ watch_addremove (argc, argv)
send_arg ("-a");
send_arg ("none");
}
- send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server (the_args.adding ?
"watch-add\012" : "watch-remove\012",
0);
@@ -437,29 +437,29 @@ watchers_fileproc (callerdat, finfo)
if (them == NULL)
return 0;
- fputs (finfo->fullname, stdout);
+ cvs_output (finfo->fullname, 0);
p = them;
while (1)
{
- putc ('\t', stdout);
+ cvs_output ("\t", 1);
while (*p != '>' && *p != '\0')
- putc (*p++, stdout);
+ cvs_output (p++, 1);
if (*p == '\0')
{
/* Only happens if attribute is misformed. */
- putc ('\n', stdout);
+ cvs_output ("\n", 1);
break;
}
++p;
- putc ('\t', stdout);
+ cvs_output ("\t", 1);
while (1)
{
while (*p != '+' && *p != ',' && *p != '\0')
- putc (*p++, stdout);
+ cvs_output (p++, 1);
if (*p == '\0')
{
- putc ('\n', stdout);
+ cvs_output ("\n", 1);
goto out;
}
if (*p == ',')
@@ -468,9 +468,9 @@ watchers_fileproc (callerdat, finfo)
break;
}
++p;
- putc ('\t', stdout);
+ cvs_output ("\t", 1);
}
- putc ('\n', stdout);
+ cvs_output ("\n", 1);
}
out:;
return 0;
@@ -515,8 +515,8 @@ watchers (argc, argv)
if (local)
send_arg ("-l");
- send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("watchers\012", 0);
return get_responses_and_close ();
}
diff --git a/gnu/usr.bin/cvs/src/wrapper.c b/gnu/usr.bin/cvs/src/wrapper.c
index e7c540d63cf..2d53c7a981d 100644
--- a/gnu/usr.bin/cvs/src/wrapper.c
+++ b/gnu/usr.bin/cvs/src/wrapper.c
@@ -118,6 +118,11 @@ void wrap_setup()
/* Then add entries found in home dir, (if user has one) and file
exists. */
homedir = get_homedir ();
+ /* If we can't find a home directory, ignore ~/.cvswrappers. This may
+ make tracking down problems a bit of a pain, but on the other
+ hand it might be obnoxious to complain when CVS will function
+ just fine without .cvswrappers (and many users won't even know what
+ .cvswrappers is). */
if (homedir != NULL)
{
char *file;
@@ -348,9 +353,11 @@ wrap_add (line, isTemp)
memset (&e, 0, sizeof(e));
/* Search for the wild card */
- while(*line && isspace(*line))
+ while (*line && isspace ((unsigned char) *line))
++line;
- for(temp=line;*line && !isspace(*line);++line)
+ for (temp = line;
+ *line && !isspace ((unsigned char) *line);
+ ++line)
;
if(temp==line)
return;
@@ -423,8 +430,6 @@ wrap_add (line, isTemp)
error (1, 0, "Correct above errors first");
break;
case 'm':
- /* FIXME: look into whether this option is still relevant given
- the 24 Jun 96 change to merge_file. */
if(*temp=='C' || *temp=='c')
e.mergeMethod=WRAP_COPY;
else
diff --git a/gnu/usr.bin/cvs/src/zlib.c b/gnu/usr.bin/cvs/src/zlib.c
index ca50130261a..fa0c2ad40d0 100644
--- a/gnu/usr.bin/cvs/src/zlib.c
+++ b/gnu/usr.bin/cvs/src/zlib.c
@@ -430,18 +430,14 @@ compress_buffer_shutdown_output (closure)
/* Here is our librarified gzip implementation. It is very minimal
but attempts to be RFC1952 compliant. */
-/* Note that currently only the client uses the gzip library. If we
- make the server use it too (which should be straightforward), then
- filter_stream_through_program, filter_through_gzip, and
- filter_through_gunzip can go away. */
/* BUF should contain SIZE bytes of gzipped data (RFC1952/RFC1951).
We are to uncompress the data and write the result to the file
- descriptor FD. If something goes wrong, give an error message
- mentioning FULLNAME as the name of the file for FD (and make it a
- fatal error if we can't recover from it). */
+ descriptor FD. If something goes wrong, give a nonfatal error message
+ mentioning FULLNAME as the name of the file for FD. Return 1 if
+ it is an error we can't recover from. */
-void
+int
gunzip_and_write (fd, fullname, buf, size)
int fd;
char *fullname;
@@ -455,9 +451,15 @@ gunzip_and_write (fd, fullname, buf, size)
unsigned long crc;
if (buf[0] != 31 || buf[1] != 139)
- error (1, 0, "gzipped data does not start with gzip identification");
+ {
+ error (0, 0, "gzipped data does not start with gzip identification");
+ return 1;
+ }
if (buf[2] != 8)
- error (1, 0, "only the deflate compression method is supported");
+ {
+ error (0, 0, "only the deflate compression method is supported");
+ return 1;
+ }
/* Skip over the fixed header, and then skip any of the variable-length
fields. */
@@ -496,9 +498,15 @@ gunzip_and_write (fd, fullname, buf, size)
zstr.next_out = outbuf;
zstatus = inflate (&zstr, Z_NO_FLUSH);
if (zstatus != Z_STREAM_END && zstatus != Z_OK)
- compress_error (1, zstatus, &zstr, fullname);
+ {
+ compress_error (0, zstatus, &zstr, fullname);
+ return 1;
+ }
if (write (fd, outbuf, sizeof (outbuf) - zstr.avail_out) < 0)
- error (1, errno, "writing decompressed file %s", fullname);
+ {
+ error (0, errno, "writing decompressed file %s", fullname);
+ return 1;
+ }
crc = crc32 (crc, outbuf, sizeof (outbuf) - zstr.avail_out);
} while (zstatus != Z_STREAM_END);
zstatus = inflateEnd (&zstr);
@@ -509,23 +517,31 @@ gunzip_and_write (fd, fullname, buf, size)
+ (buf[zstr.total_in + 11] << 8)
+ (buf[zstr.total_in + 12] << 16)
+ (buf[zstr.total_in + 13] << 24)))
- error (1, 0, "CRC error uncompressing %s", fullname);
+ {
+ error (0, 0, "CRC error uncompressing %s", fullname);
+ return 1;
+ }
if (zstr.total_out != (buf[zstr.total_in + 14]
+ (buf[zstr.total_in + 15] << 8)
+ (buf[zstr.total_in + 16] << 16)
+ (buf[zstr.total_in + 17] << 24)))
- error (1, 0, "invalid length uncompressing %s", fullname);
+ {
+ error (0, 0, "invalid length uncompressing %s", fullname);
+ return 1;
+ }
+
+ return 0;
}
/* Read all of FD and put the gzipped data (RFC1952/RFC1951) into *BUF,
replacing previous contents of *BUF. *BUF is malloc'd and *SIZE is
its allocated size. Put the actual number of bytes of data in
- *LEN. If something goes wrong, give an error message mentioning
- FULLNAME as the name of the file for FD (and make it a fatal error
- if we can't recover from it). LEVEL is the compression level (1-9). */
+ *LEN. If something goes wrong, give a nonfatal error mentioning
+ FULLNAME as the name of the file for FD, and return 1 if we can't
+ recover from it). LEVEL is the compression level (1-9). */
-void
+int
read_and_gzip (fd, fullname, buf, size, len, level)
int fd;
char *fullname;
@@ -542,8 +558,16 @@ read_and_gzip (fd, fullname, buf, size, len, level)
if (*size < 1024)
{
+ unsigned char *newbuf;
+
*size = 1024;
- *buf = (unsigned char *) xrealloc (*buf, *size);
+ newbuf = realloc (*buf, *size);
+ if (newbuf == NULL)
+ {
+ error (0, 0, "out of memory");
+ return 1;
+ }
+ *buf = newbuf;
}
(*buf)[0] = 31;
(*buf)[1] = 139;
@@ -559,7 +583,10 @@ read_and_gzip (fd, fullname, buf, size, len, level)
Z_DEFAULT_STRATEGY);
crc = crc32 (0, NULL, 0);
if (zstatus != Z_OK)
- compress_error (1, zstatus, &zstr, fullname);
+ {
+ compress_error (0, zstatus, &zstr, fullname);
+ return 1;
+ }
zstr.avail_out = *size;
zstr.next_out = *buf + 10;
@@ -569,7 +596,10 @@ read_and_gzip (fd, fullname, buf, size, len, level)
nread = read (fd, inbuf, sizeof inbuf);
if (nread < 0)
- error (1, errno, "cannot read %s", fullname);
+ {
+ error (0, errno, "cannot read %s", fullname);
+ return 1;
+ }
else if (nread == 0)
/* End of file. */
finish = 1;
@@ -588,9 +618,17 @@ read_and_gzip (fd, fullname, buf, size, len, level)
if (zstr.avail_out < 4096)
{
+ unsigned char *newbuf;
+
offset = zstr.next_out - *buf;
*size *= 2;
- *buf = xrealloc (*buf, *size);
+ newbuf = realloc (*buf, *size);
+ if (newbuf == NULL)
+ {
+ error (0, 0, "out of memory");
+ return 1;
+ }
+ *buf = newbuf;
zstr.next_out = *buf + offset;
zstr.avail_out = *size - offset;
}
@@ -618,5 +656,7 @@ read_and_gzip (fd, fullname, buf, size, len, level)
zstatus = deflateEnd (&zstr);
if (zstatus != Z_OK)
compress_error (0, zstatus, &zstr, fullname);
+
+ return 0;
}
#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */
diff --git a/gnu/usr.bin/cvs/tools/ChangeLog b/gnu/usr.bin/cvs/tools/ChangeLog
index 8cd177e81e0..99c3af733fd 100644
--- a/gnu/usr.bin/cvs/tools/ChangeLog
+++ b/gnu/usr.bin/cvs/tools/ChangeLog
@@ -1,3 +1,9 @@
+1998-09-09 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * README: Update now that pcl-cvs is no longer here.
+ * pcl-cvs: Remove this subdirectory and all its contents.
+ * Makefile.in: Remove references to pcl-cvs directory.
+
Sat Feb 21 22:02:12 1998 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (clean): Change "/bin/rm" to "rm".
diff --git a/gnu/usr.bin/cvs/tools/Makefile.in b/gnu/usr.bin/cvs/tools/Makefile.in
index 578b210d053..752224dc3ba 100644
--- a/gnu/usr.bin/cvs/tools/Makefile.in
+++ b/gnu/usr.bin/cvs/tools/Makefile.in
@@ -54,7 +54,7 @@ clean:
.PHONY: clean
distclean: clean
- rm -f Makefile pcl-cvs/Makefile
+ rm -f Makefile
.PHONY: distclean
realclean: distclean
@@ -65,7 +65,6 @@ dist-dir:
for i in ${DISTFILES}; do \
ln $(srcdir)/$${i} ${DISTDIR}; \
done
- cd pcl-cvs; ${MAKE} dist-dir DISTDIR="../${DISTDIR}/pcl-cvs"
.PHONY: dist-dir
subdir = tools
diff --git a/gnu/usr.bin/cvs/tools/README b/gnu/usr.bin/cvs/tools/README
index af7bd7e49bb..e8e73b365fd 100644
--- a/gnu/usr.bin/cvs/tools/README
+++ b/gnu/usr.bin/cvs/tools/README
@@ -1,5 +1,11 @@
- This subdirectory contains tools that can be used with CVS.
-Note that they will not necessarily be installed when you "make
-install" from the top-level of the CVS source tree.
+This subdirectory formerly contained tools that can be used with CVS.
+In particular, it used to contain a copy of pcl-cvs version 1.x.
+Pcl-cvs is an Emacs interface to CVS.
-pcl-cvs ............................. an Emacs interface to CVS.
+If you are looking for pcl-cvs, we'd suggest pcl-cvs version 2.x, at:
+ ftp://ftp.weird.com/pub/local/
+
+Both of the following CVS sites have a page about pcl-cvs:
+ http://www.loria.fr/~molli/cvs-index.html
+ http://www.cyclic.com/
+They also have much information about CVS tools more generally.
diff --git a/gnu/usr.bin/cvs/windows-NT/ChangeLog b/gnu/usr.bin/cvs/windows-NT/ChangeLog
index 7ccf78d80a4..574a7658309 100644
--- a/gnu/usr.bin/cvs/windows-NT/ChangeLog
+++ b/gnu/usr.bin/cvs/windows-NT/ChangeLog
@@ -1,3 +1,31 @@
+1998-10-13 Jim Kingdon
+
+ * README: Update information about make/project files, cygwin and
+ the (lack of) need for RCS 5.7. Tweak a few more things.
+
+1998-10-03 Jim Kingdon
+
+ * win32.c: Include cvs.h and only check server_active if
+ SERVER_SUPPORT is defined.
+
+1998-10-02 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ (This was reported by someone else but I don't remember who).
+ * config.h: Define SYSTEM_CLEANUP.
+ * win32.c (wnt_cleanup): New function, implements it.
+
+1998-09-28 Johannes Stezenbach <johannes.stezenbach@propack-data.de>
+ and Jim Kingdon
+
+ * config.h (CVS_RENAME): Define.
+ * filesubr.c, config.h (wnt_rename): New function.
+ * filesubr.c (rename_file): Call CVS_RENAME not rename.
+
+1998-09-04 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * win32.c (gethostname): Expand comment about gethostname
+ vs. GetComputerName (reported by Randy Coulman).
+
1998-07-01 Jim Kingdon <kingdon@harvey.cyclic.com>
* startserver.c (wnt_shutdown_server): Check for errors from close().
diff --git a/gnu/usr.bin/cvs/windows-NT/README b/gnu/usr.bin/cvs/windows-NT/README
index 60321e659a1..440f99d0bc8 100644
--- a/gnu/usr.bin/cvs/windows-NT/README
+++ b/gnu/usr.bin/cvs/windows-NT/README
@@ -1,6 +1,5 @@
Concurrent Versions System (CVS)
ported to Microsoft Windows NT
- Cyclic Software
Check the ../INSTALL file for information on the most recent version
of CVS which has been known to be tested with NT and/or Win95.
@@ -17,16 +16,26 @@ confuse the makefile for Visual C++.
To compile, use Microsoft Visual C++ on the file cvsnt.mak in the
distribution's top directory. At least with the tar port I'm using,
the sources get extracted without carriage returns and you must add
-carriage returns to the end of every line in cvsnt.mak. I also had to
-add them to src/server.c. It doesn't seem to be necessary to add them
-to any other file. This makefile was generated with Visual C++ 4.x.
-For Visual C++ 5.x use cvsnet.dsp (which is probably more likely to be
-up to date than cvsnt.mak anyway). For Visual C++ 2.x you probably
-are in the position of digging through old versions of CVS for a
-cvsnt.mak and then updating it. Feel free to let us know about
-problems of this sort as with other bug reports; our impression thus
-far is that relatively few people care about which versions of Visual
-C++ work.
+carriage returns to the end of every line in cvsnt.mak. It doesn't
+seem to be necessary to add them to any other file. This makefile was
+generated with Visual C++ 4.x. For Visual C++ 5.x you can try
+cvsnet.dsp. For Visual C++ 2.x you probably are in the position of
+digging through old versions of CVS for a cvsnt.mak and then updating
+it. Feel free to let us know about problems of this sort as with
+other bug reports.
+
+Update as of 13 Oct 1998: I (Jim Kingdon) do build CVS successfully
+with Visual C++ on a regular basis. The builds on download.cyclic.com
+(CVS 1.10, CVS 1.10.3, &c) are built using Visual C++ 4.0 and
+cvsnt.mak from the Debug (not release) configuration. I have pretty
+much given up on getting the Visual C++ IDE to generate a makefile
+that works for anyone except me :-(. If I knew an easy fix for this,
+I'd do it, but it is easier to just complain about Microsoft's finicky
+IDE and makefile/project file format du jour :-). Having people send
+in "fixed" versions of cvsnt.mak and cvsnt.dsp regularly, as has been
+happening, is fine but it isn't an "easy fix", unfortunately, as it is
+rarely clear to me whether a particular submission will improve things
+or not.
Send bug reports to bug-cvs@gnu.org.
@@ -43,30 +52,11 @@ of CVS (1.8 and older), you also need gzip. Note that you do NOT need
an rsh client if you are using the :server: access method (which uses
the internal rsh client), except perhaps for debugging.
-To operate in local mode, you will need GNU patch, GNU diffutils,
-and rcs version 5.7 installed on your system. Make
-sure NOT to get a version of rcs less than 5.7 (gr564bnt.zip was
-particularly bad), because those versions insist on putting their
-files in their own directory structure, making them incompatible with
-CVS.
+To operate in local mode, you should need nothing other than CVS (that
+is, you no longer need RCS, diff, &c, in order to run CVS).
-Noel Cragg, who did the latest mods to the Windows NT port, used the
-following packages:
-
- ftp://wuarchive.wustl.edu/systems/ibmpc/gnuish/patch212.zip
- ftp://ftp.netcom.com/pub/al/alexande/rcs57nt.zip
- ftp://ftp.netcom.com/pub/al/alexande/diff57nt.zip
-
-Copies of these zip files can be also be found in the windows-nt
-directory for the latest CVS release (cvs-1.9/windows-nt, for example)
-under:
-
- ftp://ftp.cyclic.com/pub/cvs/ or
- http://www.cyclic.com/archive/pub/cvs/
-
-If you want to try other versions of these utilities, you might have
-luck with the Congruent ports of these packages to Windows NT, binary
-and source:
+One useful site may be the Congruent ports of various packages to
+Windows NT, binary and source:
ftp://microlib.cc.utexas.edu/microlib/nt/gnu/
@@ -75,9 +65,10 @@ which support long file names, which you will need to unpack the CVS
source distribution.
The CYGWIN32 package is a port of various GNU tools for NT, providing
-bash as the shell and gcc as the compiler. The tools are still in
-development, but they are useful for running a modified version of
-sanity.sh:
+bash as the shell and gcc as the compiler. Basically, you don't want
+the stuff in this directory for CVS running under cygwin32; you want
+the same stuff as for unix (../configure, Makefile.in, &c). For
+cygwin32 information see
http://www.cygnus.com/misc/gnu-win32/
@@ -106,6 +97,8 @@ The following harmless warnings are known:
.\lib\getdate.c(1612) : warning C4102: 'yyerrlab' : unreferenced label
.\lib\getdate.c(1612) : warning C4102: 'yynewstate' : unreferenced label
+Oct 1998 update: there are more now. I've gotten lax about removing
+the warnings lately :-( -kingdon.
CODING STANDARDS for Windows
diff --git a/gnu/usr.bin/cvs/windows-NT/SCC/ChangeLog b/gnu/usr.bin/cvs/windows-NT/SCC/ChangeLog
index a4f44c3acd8..babd748a8c4 100644
--- a/gnu/usr.bin/cvs/windows-NT/SCC/ChangeLog
+++ b/gnu/usr.bin/cvs/windows-NT/SCC/ChangeLog
@@ -1,3 +1,7 @@
+1998-09-21 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * README.txt: Also mention HAHTsite.
+
1998-03-22 Jim Kingdon <kingdon@harvey.cyclic.com>
* pubscc.h: Describe how SccGetCommandOptions works.
diff --git a/gnu/usr.bin/cvs/windows-NT/SCC/README.txt b/gnu/usr.bin/cvs/windows-NT/SCC/README.txt
index 3d89711e22a..8273da6b43f 100644
--- a/gnu/usr.bin/cvs/windows-NT/SCC/README.txt
+++ b/gnu/usr.bin/cvs/windows-NT/SCC/README.txt
@@ -71,6 +71,7 @@ relying on it.
5.03 but not version 4, version 5.0, or 16 bit Powerbuilder.).
* Premia's CodeWright editor
(versions 5.00b and 5.00c; not sure about older versions).
+* HAHTsite (not sure what versions).
SPECIFICATIONS OR OTHER DOCUMENTS DESCRIBING THE SCC
diff --git a/gnu/usr.bin/cvs/windows-NT/config.h b/gnu/usr.bin/cvs/windows-NT/config.h
index 11542164097..69b0fe75c61 100644
--- a/gnu/usr.bin/cvs/windows-NT/config.h
+++ b/gnu/usr.bin/cvs/windows-NT/config.h
@@ -240,6 +240,9 @@ extern int wnt_stat ();
#define CVS_LSTAT wnt_lstat
extern int wnt_lstat ();
+#define CVS_RENAME wnt_rename
+extern int wnt_rename (const char *, const char *);
+
/* This function doesn't exist under Windows NT; we
provide a stub. */
extern int readlink (char *path, char *buf, int buf_size);
@@ -288,6 +291,8 @@ extern void wnt_shutdown_server (int fd);
#define SYSTEM_INITIALIZE(pargc,pargv) init_winsock()
extern void init_winsock();
+#define SYSTEM_CLEANUP() wnt_cleanup
+extern void wnt_cleanup (void);
#define HAVE_WINSOCK_H
diff --git a/gnu/usr.bin/cvs/windows-NT/filesubr.c b/gnu/usr.bin/cvs/windows-NT/filesubr.c
index 44df75b4b27..9dae900176b 100644
--- a/gnu/usr.bin/cvs/windows-NT/filesubr.c
+++ b/gnu/usr.bin/cvs/windows-NT/filesubr.c
@@ -369,6 +369,41 @@ readlink (char *path, char *buf, int buf_size)
return -1;
}
+/* Rename for NT which works for read only files. Apparently if we are
+ accessing FROM and TO via a Novell network, this is an issue. */
+int
+wnt_rename (from, to)
+ const char *from;
+ const char *to;
+{
+ int result, save_errno;
+ int readonly = !iswritable (from);
+
+ if (readonly)
+ {
+ if (chmod (from, S_IWRITE) < 0)
+ return -1;
+ }
+ result = rename (from, to);
+ save_errno = errno;
+ if (readonly)
+ {
+ if (result == 0)
+ {
+ if (chmod (to, S_IREAD) < 0)
+ return -1;
+ }
+ else
+ {
+ /* We have a choice of which error to report, if there is
+ one here too; report the one from rename (). */
+ chmod (from, S_IREAD);
+ }
+ errno = save_errno;
+ }
+ return result;
+}
+
/*
* Rename a file and die if it fails
*/
@@ -390,7 +425,7 @@ rename_file (from, to)
/* Win32 unlink is stupid --- it fails if the file is read-only */
chmod(to, S_IWRITE);
unlink(to);
- if (rename (from, to) < 0)
+ if (CVS_RENAME (from, to) < 0)
error (1, errno, "cannot rename file %s to %s", from, to);
}
diff --git a/gnu/usr.bin/cvs/windows-NT/win32.c b/gnu/usr.bin/cvs/windows-NT/win32.c
index 8a25aa6e6ba..88e7e7f8062 100644
--- a/gnu/usr.bin/cvs/windows-NT/win32.c
+++ b/gnu/usr.bin/cvs/windows-NT/win32.c
@@ -15,6 +15,8 @@
#include <winsock.h>
#include <stdlib.h>
+#include "cvs.h"
+
void
init_winsock ()
{
@@ -27,6 +29,25 @@ init_winsock ()
}
}
+void
+wnt_cleanup (void)
+{
+ if (WSACleanup ())
+ {
+#ifdef SERVER_ACTIVE
+ if (server_active || error_use_protocol)
+ /* FIXME: how are we supposed to report errors? As of now
+ (Sep 98), error() can in turn call us (if it is out of
+ memory) and in general is built on top of lots of
+ stuff. */
+ ;
+ else
+#endif
+ fprintf (stderr, "cvs: cannot WSACleanup: %s\n",
+ sock_strerror (WSAGetLastError ()));
+ }
+}
+
unsigned sleep(unsigned seconds)
{
Sleep(1000*seconds);
@@ -34,7 +55,15 @@ unsigned sleep(unsigned seconds)
}
#if 0
-/* This is available from the WinSock library. */
+
+/* WinSock has a gethostname. But note that WinSock gethostname may
+ want to talk to the network, which is kind of bogus in the
+ non-client/server case. I'm not sure I can think of any obvious
+ solution. Most of the ways I can think of to figure out whether
+ to call gethostname or GetComputerName seem kind of kludgey, and/or
+ might result in picking the name in a potentially confusing way
+ (I'm not sure exactly how the name(s) are set). */
+
int gethostname(char* name, int namelen)
{
DWORD dw = namelen;