This is Info file cvs.info, produced by Makeinfo-1.64 from the input file ../../work/ccvs/doc/cvs.texinfo. Copyright (C) 1992, 1993 Signum Support AB Copyright (C) 1993, 1994 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled "GNU General Public License" is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled "GNU General Public License" and this permission notice may be included in translations approved by the Free Software Foundation instead of in the original English.  File: cvs.info, Node: Kerberos authenticated, Prev: Password authenticated, Up: Remote repositories Direct connection with kerberos ------------------------------- The main disadvantage of using rsh is that all the data needs to pass through additional programs, so it may be slower. So if you have kerberos installed you can connect via a direct TCP connection, authenticating with kerberos. To do this, CVS needs to be compiled with kerberos support; when configuring CVS it tries to detect whether kerberos is present or you can use the `--with-krb4' flag to configure. The data transmitted is *not* encrypted by default. Encryption support must be compiled into both the client and server; use the `--enable-encryption' configure option to turn it on. You must then use the `-x' global option to request encryption. You need to edit `inetd.conf' on the server machine to run `cvs kserver'. The client uses port 1999 by default; if you want to use another port specify it in the `CVS_CLIENT_PORT' environment variable on the client. When you want to use CVS, get a ticket in the usual way (generally `kinit'); it must be a ticket which allows you to log into the server machine. Then you are ready to go: cvs -d :kserver:chainsaw.brickyard.com:/user/local/cvsroot checkout foo Previous versions of CVS would fall back to a connection via rsh; this version will not do so.  File: cvs.info, Node: Read-only access, Prev: Remote repositories, Up: Repository Read-only repository access =========================== It is possible to grant read-only repository access to people using the password-authenticated server (*note Password authenticated::.). (The other access methods do not have explicit support for read-only users because those methods all assume login access to the repository machine anyway, and therefore the user can do whatever local file permissions allow her to do.) A user who has read-only access can do only those CVS operations which do not modify the repository, except for certain "administrative" files (such as lock files and the history file). It may be desirable to use this feature in conjunction with user-aliasing (*note Password authentication server::.). However, note that read-only access does not repeal the existing security considerations in *Note Password authentication security::. There are two ways to specify read-only access for a user: by inclusion, and by exclusion. "Inclusion" means listing that user specifically in the `$CVSROOT/CVSROOT/readers' file, which is simply a newline-separated list of users. Here is a sample `readers' file: melissa splotnik jrandom (Don't forget the newline after the last user.) "Exclusion" means explicitly listing everyone who has *write* access--if the `$CVSROOT/CVSROOT/writers' file exists, then only those users listed in it have write access, and everyone else has read-only access (of course, even the read-only users still need to be listed in the `$CVSROOT/CVSROOT/passwd' file). The `writers' file has the same format as the `readers' file. Note: if your `$CVSROOT/CVSROOT/passwd' file maps cvs users onto system users (*note Password authentication server::.), make sure you deny or grant read-only access using the *cvs* usernames, not the system usernames. That is, the `readers' and `writers' files contain cvs usernames, which may or may not be the same as system usernames. Here is a complete description of the server's behavior in deciding whether to grant read-only or read-write access: If `readers' exists, and this user is listed in it, then she gets read-only access. Or if `writers' exists, and this user is NOT listed in it, then she also gets read-only access (this is true even if `readers' exists but she is not listed there). Otherwise, she gets full read-write access. Of course there is a conflict if the user is listed in both files. This is resolved in the more conservative way, it being better to protect the repository too much than too little: such a user gets read-only access.  File: cvs.info, Node: Starting a new project, Next: Multiple developers, Prev: Repository, Up: Top Starting a project with CVS *************************** Because renaming files and moving them between directories is somewhat inconvenient, the first thing you do when you start a new project should be to think through your file organization. It is not impossible to rename or move files, but it does increase the potential for confusion and CVS does have some quirks particularly in the area of renaming directories. *Note Moving files::. What to do next depends on the situation at hand. * Menu: * Setting up the files:: Getting the files into the repository * Defining the module:: How to make a module of the files  File: cvs.info, Node: Setting up the files, Next: Defining the module, Up: Starting a new project Setting up the files ==================== The first step is to create the files inside the repository. This can be done in a couple of different ways. * Menu: * From files:: This method is useful with old projects where files already exists. * From other version control systems:: Old projects where you want to preserve history from another system. * From scratch:: Creating a directory tree from scratch.  File: cvs.info, Node: From files, Next: From other version control systems, Up: Setting up the files Creating a directory tree from a number of files ------------------------------------------------ When you begin using CVS, you will probably already have several projects that can be put under CVS control. In these cases the easiest way is to use the `import' command. An example is probably the easiest way to explain how to use it. If the files you want to install in CVS reside in `WDIR', and you want them to appear in the repository as `$CVSROOT/yoyodyne/RDIR', you can do this: $ cd WDIR $ cvs import -m "Imported sources" yoyodyne/RDIR yoyo start Unless you supply a log message with the `-m' flag, CVS starts an editor and prompts for a message. The string `yoyo' is a "vendor tag", and `start' is a "release tag". They may fill no purpose in this context, but since CVS requires them they must be present. *Note Tracking sources::, for more information about them. You can now verify that it worked, and remove your original source directory. $ cd .. $ mv DIR DIR.orig $ cvs checkout yoyodyne/DIR # Explanation below $ diff -r DIR.orig yoyodyne/DIR $ rm -r DIR.orig Erasing the original sources is a good idea, to make sure that you do not accidentally edit them in DIR, bypassing CVS. Of course, it would be wise to make sure that you have a backup of the sources before you remove them. The `checkout' command can either take a module name as argument (as it has done in all previous examples) or a path name relative to `$CVSROOT', as it did in the example above. It is a good idea to check that the permissions CVS sets on the directories inside `$CVSROOT' are reasonable, and that they belong to the proper groups. *Note File permissions::. If some of the files you want to import are binary, you may want to use the wrappers features to specify which files are binary and which are not. *Note Wrappers::.  File: cvs.info, Node: From other version control systems, Next: From scratch, Prev: From files, Up: Setting up the files Creating Files From Other Version Control Systems ------------------------------------------------- If you have a project which you are maintaining with another version control system, such as RCS, you may wish to put the files from that project into CVS, and preserve the revision history of the files. From RCS If you have been using RCS, find the RCS files--usually a file named `foo.c' will have its RCS file in `RCS/foo.c,v' (but it could be other places; consult the RCS documentation for details). Then create the appropriate directories in CVS if they do not already exist. Then copy the files into the appropriate directories in the CVS repository (the name in the repository must be the name of the source file with `,v' added; the files go directly in the appopriate directory of the repository, not in an `RCS' subdirectory). This is one of the few times when it is a good idea to access the CVS repository directly, rather than using CVS commands. Then you are ready to check out a new working directory. The RCS file should not be locked when you move it into CVS; if it is, CVS will have trouble letting you operate on it. From another version control system Many version control systems have the ability to export RCS files in the standard format. If yours does, export the RCS files and then follow the above instructions. From SCCS There is a script in the `contrib' directory of the CVS source distribution called `sccs2rcs' which converts SCCS files to RCS files. Note: you must run it on a machine which has both SCCS and RCS installed, and like everything else in contrib it is unsupported (your mileage may vary).  File: cvs.info, Node: From scratch, Prev: From other version control systems, Up: Setting up the files Creating a directory tree from scratch -------------------------------------- For a new project, the easiest thing to do is probably to create an empty directory structure, like this: $ mkdir tc $ mkdir tc/man $ mkdir tc/testing After that, you use the `import' command to create the corresponding (empty) directory structure inside the repository: $ cd tc $ cvs import -m "Created directory structure" yoyodyne/DIR yoyo start Then, use `add' to add files (and new directories) as they appear. Check that the permissions CVS sets on the directories inside `$CVSROOT' are reasonable.  File: cvs.info, Node: Defining the module, Prev: Setting up the files, Up: Starting a new project Defining the module =================== The next step is to define the module in the `modules' file. This is not strictly necessary, but modules can be convenient in grouping together related files and directories. In simple cases these steps are sufficient to define a module. 1. Get a working copy of the modules file. $ cvs checkout CVSROOT/modules $ cd CVSROOT 2. Edit the file and insert a line that defines the module. *Note Intro administrative files::, for an introduction. *Note modules::, for a full description of the modules file. You can use the following line to define the module `tc': tc yoyodyne/tc 3. Commit your changes to the modules file. $ cvs commit -m "Added the tc module." modules 4. Release the modules module. $ cd .. $ cvs release -d CVSROOT  File: cvs.info, Node: Multiple developers, Next: Revisions and branches, Prev: Starting a new project, Up: Top Multiple developers ******************* When more than one person works on a software project things often get complicated. Often, two people try to edit the same file simultaneously. One solution, known as "file locking" or "reserved checkouts", is to allow only one person to edit each file at a time. This is the only solution with some version control systems, including RCS and SCCS. Currently the usual way to get reserved checkouts with CVS is the `cvs admin -l' command (*note admin options::.). This is not as nicely integrated into CVS as the watch features, described below, but it seems that most people with a need for reserved checkouts find it adequate. It also may be possible to use the watches features described below, together with suitable procedures (not enforced by software), to avoid having two people edit at the same time. The default model with CVS is known as "unreserved checkouts". In this model, developers can edit their own "working copy" of a file simultaneously. The first person that commits his changes has no automatic way of knowing that another has started to edit it. Others will get an error message when they try to commit the file. They must then use CVS commands to bring their working copy up to date with the repository revision. This process is almost automatic. CVS also supports mechanisms which facilitate various kinds of communcation, without actually enforcing rules like reserved checkouts do. The rest of this chapter describes how these various models work, and some of the issues involved in choosing between them. * Menu: * File status:: A file can be in several states * Updating a file:: Bringing a file up-to-date * Conflicts example:: An informative example * Informing others:: To cooperate you must inform * Concurrency:: Simultaneous repository access * Watches:: Mechanisms to track who is editing files * Choosing a model:: Reserved or unreserved checkouts?  File: cvs.info, Node: File status, Next: Updating a file, Up: Multiple developers File status =========== Based on what operations you have performed on a checked out file, and what operations others have performed to that file in the repository, one can classify a file in a number of states. The states, as reported by the `status' command, are: Up-to-date The file is identical with the latest revision in the repository for the branch in use. Locally Modified You have edited the file, and not yet committed your changes. Locally Added You have added the file with `add', and not yet committed your changes. Locally Removed You have removed the file with `remove', and not yet committed your changes. Needs Checkout Someone else has committed a newer revision to the repository. The name is slightly misleading; you will ordinarily use `update' rather than `checkout' to get that newer revision. Needs Patch Like Needs Checkout, but the CVS server will send a patch rather than the entire file. Sending a patch or sending an entire file accomplishes the same thing. Needs Merge Someone else has committed a newer revision to the repository, and you have also made modifications to the file. File had conflicts on merge This is like Locally Modified, except that a previous `update' command gave a conflict. If you have not already done so, you need to resolve the conflict as described in *Note Conflicts example::. Unknown CVS doesn't know anything about this file. For example, you have created a new file and have not run `add'. To help clarify the file status, `status' also reports the `Working revision' which is the revision that the file in the working directory derives from, and the `Repository revision' which is the latest revision in the repository for the branch in use. For information on the options to `status', see *Note status::. For information on its `Sticky tag' and `Sticky date' output, see *Note Sticky tags::. For information on its `Sticky options' output, see the `-k' option in *Note update options::.  File: cvs.info, Node: Updating a file, Next: Conflicts example, Prev: File status, Up: Multiple developers Bringing a file up to date ========================== When you want to update or merge a file, use the `update' command. For files that are not up to date this is roughly equivalent to a `checkout' command: the newest revision of the file is extracted from the repository and put in your working copy of the module. Your modifications to a file are never lost when you use `update'. If no newer revision exists, running `update' has no effect. If you have edited the file, and a newer revision is available, CVS will merge all changes into your working copy. For instance, imagine that you checked out revision 1.4 and started editing it. In the meantime someone else committed revision 1.5, and shortly after that revision 1.6. If you run `update' on the file now, CVS will incorporate all changes between revision 1.4 and 1.6 into your file. If any of the changes between 1.4 and 1.6 were made too close to any of the changes you have made, an "overlap" occurs. In such cases a warning is printed, and the resulting file includes both versions of the lines that overlap, delimited by special markers. *Note update::, for a complete description of the `update' command.  File: cvs.info, Node: Conflicts example, Next: Informing others, Prev: Updating a file, Up: Multiple developers Conflicts example ================= Suppose revision 1.4 of `driver.c' contains this: #include void main() { parse(); if (nerr == 0) gencode(); else fprintf(stderr, "No code generated.\n"); exit(nerr == 0 ? 0 : 1); } Revision 1.6 of `driver.c' contains this: #include int main(int argc, char **argv) { parse(); if (argc != 1) { fprintf(stderr, "tc: No args expected.\n"); exit(1); } if (nerr == 0) gencode(); else fprintf(stderr, "No code generated.\n"); exit(!!nerr); } Your working copy of `driver.c', based on revision 1.4, contains this before you run `cvs update': #include #include void main() { init_scanner(); parse(); if (nerr == 0) gencode(); else fprintf(stderr, "No code generated.\n"); exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } You run `cvs update': $ cvs update driver.c RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v retrieving revision 1.4 retrieving revision 1.6 Merging differences between 1.4 and 1.6 into driver.c rcsmerge warning: overlaps during merge cvs update: conflicts found in driver.c C driver.c CVS tells you that there were some conflicts. Your original working file is saved unmodified in `.#driver.c.1.4'. The new version of `driver.c' contains this: #include #include int main(int argc, char **argv) { init_scanner(); parse(); if (argc != 1) { fprintf(stderr, "tc: No args expected.\n"); exit(1); } if (nerr == 0) gencode(); else fprintf(stderr, "No code generated.\n"); <<<<<<< driver.c exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE); ======= exit(!!nerr); >>>>>>> 1.6 } Note how all non-overlapping modifications are incorporated in your working copy, and that the overlapping section is clearly marked with `<<<<<<<', `=======' and `>>>>>>>'. You resolve the conflict by editing the file, removing the markers and the erroneous line. Suppose you end up with this file: #include #include int main(int argc, char **argv) { init_scanner(); parse(); if (argc != 1) { fprintf(stderr, "tc: No args expected.\n"); exit(1); } if (nerr == 0) gencode(); else fprintf(stderr, "No code generated.\n"); exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } You can now go ahead and commit this as revision 1.7. $ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c Checking in driver.c; /usr/local/cvsroot/yoyodyne/tc/driver.c,v <-- driver.c new revision: 1.7; previous revision: 1.6 done For your protection, CVS will refuse to check in a file if a conflict occurred and you have not resolved the conflict. Currently to resolve a conflict, you must change the timestamp on the file, and must also insure that the file contains no conflict markers. If your file legitimately contains conflict markers (that is, occurrences of `>>>>>>> ' at the start of a line that don't mark a conflict), then CVS has trouble handling this and you need to start hacking on the `CVS/Entries' file or other such workarounds. If you use release 1.04 or later of pcl-cvs (a GNU Emacs front-end for CVS) you can use an Emacs package called emerge to help you resolve conflicts. See the documentation for pcl-cvs.  File: cvs.info, Node: Informing others, Next: Concurrency, Prev: Conflicts example, Up: Multiple developers Informing others about commits ============================== It is often useful to inform others when you commit a new revision of a file. The `-i' option of the `modules' file, or the `loginfo' file, can be used to automate this process. *Note modules::. *Note loginfo::. You can use these features of CVS to, for instance, instruct CVS to mail a message to all developers, or post a message to a local newsgroup.  File: cvs.info, Node: Concurrency, Next: Watches, Prev: Informing others, Up: Multiple developers Several developers simultaneously attempting to run CVS ======================================================= If several developers try to run CVS at the same time, one may get the following message: [11:43:23] waiting for bach's lock in /usr/local/cvsroot/foo CVS will try again every 30 seconds, and either continue with the operation or print the message again, if it still needs to wait. If a lock seems to stick around for an undue amount of time, find the person holding the lock and ask them about the cvs command they are running. If they aren't running a cvs command, look in the repository directory mentioned in the message and remove files which they own whose names start with `#cvs.tfl', `#cvs.rfl', or `#cvs.wfl'. Note that these locks are to protect CVS's internal data structures and have no relationship to the word "lock" in the sense used by RCS--which refers to reserved checkouts (*note Multiple developers::.). Any number of people can be reading from a given repository at a time; only when someone is writing do the locks prevent other people from reading or writing. One might hope for the following property If someone commits some changes in one cvs command, then an update by someone else will either get all the changes, or none of them. but CVS does *not* have this property. For example, given the files a/one.c a/two.c b/three.c b/four.c if someone runs cvs ci a/two.c b/three.c and someone else runs `cvs update' at the same time, the person running `update' might get only the change to `b/three.c' and not the change to `a/two.c'.  File: cvs.info, Node: Watches, Next: Choosing a model, Prev: Concurrency, Up: Multiple developers Mechanisms to track who is editing files ======================================== For many groups, use of CVS in its default mode is perfectly satisfactory. Users may sometimes go to check in a modification only to find that another modification has intervened, but they deal with it and proceed with their check in. Other groups prefer to be able to know who is editing what files, so that if two people try to edit the same file they can choose to talk about who is doing what when rather than be surprised at check in time. The features in this section allow such coordination, while retaining the ability of two developers to edit the same file at the same time. For maximum benefit developers should use `cvs edit' (not `chmod') to make files read-write to edit them, and `cvs release' (not `rm') to discard a working directory which is no longer in use, but CVS is not able to enforce this behavior. * Menu: * Setting a watch:: Telling CVS to watch certain files * Getting Notified:: Telling CVS to notify you * Editing files:: How to edit a file which is being watched * Watch information:: Information about who is watching and editing * Watches Compatibility:: Watches interact poorly with CVS 1.6 or earlier  File: cvs.info, Node: Setting a watch, Next: Getting Notified, Up: Watches Telling CVS to watch certain files ---------------------------------- To enable the watch features, you first specify that certain files are to be watched. - Command: cvs watch on [`-l'] FILES ... Specify that developers should run `cvs edit' before editing FILES. CVS will create working copies of FILES read-only, to remind developers to run the `cvs edit' command before working on them. If FILES includes the name of a directory, CVS arranges to watch all files added to the corresponding repository directory, and sets a default for files added in the future; this allows the user to set notification policies on a per-directory basis. The contents of the directory are processed recursively, unless the `-l' option is given. If FILES is omitted, it defaults to the current directory. - Command: cvs watch off [`-l'] FILES ... Do not provide notification about work on FILES. CVS will create working copies of FILES read-write. The FILES and `-l' arguments are processed as for `cvs watch on'.  File: cvs.info, Node: Getting Notified, Next: Editing files, Prev: Setting a watch, Up: Watches Telling CVS to notify you ------------------------- You can tell CVS that you want to receive notifications about various actions taken on a file. You can do this without using `cvs watch on' for the file, but generally you will want to use `cvs watch on', so that developers use the `cvs edit' command. - Command: cvs watch add [`-a' ACTION] [`-l'] FILES ... Add the current user to the list of people to receive notification of work done on FILES. The `-a' option specifies what kinds of events CVS should notify the user about. ACTION is one of the following: `edit' Another user has applied the `cvs edit' command (described below) to a file. `unedit' Another user has applied the `cvs unedit' command (described below) or the `cvs release' command to a file, or has deleted the file and allowed `cvs update' to recreate it. `commit' Another user has committed changes to a file. `all' All of the above. `none' None of the above. (This is useful with `cvs edit', described below.) The `-a' option may appear more than once, or not at all. If omitted, the action defaults to `all'. The FILES and `-l' option are processed as for the `cvs watch' commands. - Command: cvs watch remove [`-a' ACTION] [`-l'] FILES ... Remove a notification request established using `cvs watch add'; the arguments are the same. If the `-a' option is present, only watches for the specified actions are removed. When the conditions exist for notification, CVS calls the `notify' administrative file. Edit `notify' as one edits the other administrative files (*note Intro administrative files::.). This file follows the usual conventions for administrative files (*note syntax::.), where each line is a regular expression followed by a command to execute. The command should contain a single ocurrence of `%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 standard thing to put in the `notify' file is the single line: ALL mail %s -s \"CVS notification\" This causes users to be notified by electronic mail. Note that if you set this up in the straightforward way, users receive notifications on the server machine. One could of course write a `notify' script which directed notifications elsewhere, but to make this easy, CVS allows you to associate a notification address for each user. To do so create a file `users' in `CVSROOT' with a line for each user in the format USER:VALUE. Then instead of passing the name of the user to be notified to `notify', CVS will pass the VALUE (normally an email address on some other machine). CVS does not notify you for your own changes. Currently this check is done based on whether the user name of the person taking the action which triggers notification matches the user name of the person getting notification. In fact, in general, the watches features only track one edit by each user. It probably would be more useful if watches tracked each working directory separately, so this behavior might be worth changing.  File: cvs.info, Node: Editing files, Next: Watch information, Prev: Getting Notified, Up: Watches How to edit a file which is being watched ----------------------------------------- Since a file which is being watched is checked out read-only, you cannot simply edit it. To make it read-write, and inform others that you are planning to edit it, use the `cvs edit' command. Some systems call this a "checkout", but CVS uses that term for obtaining a copy of the sources (*note Getting the source::.), an operation which those systems call a "get" or a "fetch". - Command: cvs edit [OPTIONS] FILES ... Prepare to edit the working files FILES. CVS makes the FILES read-write, and notifies users who have requested `edit' notification for any of FILES. The `cvs edit' command accepts the same OPTIONS as the `cvs watch add' command, and establishes a temporary watch for the user on FILES; CVS will remove the watch when FILES are `unedit'ed or `commit'ted. If the user does not wish to receive notifications, she should specify `-a none'. The FILES and `-l' option are processed as for the `cvs watch' commands. Normally when you are done with a set of changes, you use the `cvs commit' command, which checks in your changes and returns the watched files to their usual read-only state. But if you instead decide to abandon your changes, or not to make any changes, you can use the `cvs unedit' command. - Command: cvs unedit [`-l'] FILES ... Abandon work on the working files FILES, and revert them to the repository versions on which they are based. CVS makes those FILES read-only for which users have requested notification using `cvs watch on'. CVS notifies users who have requested `unedit' notification for any of FILES. The FILES and `-l' option are processed as for the `cvs watch' commands. If watches are not in use, the `unedit' command probably does not work, and the way to revert to the repository version is to remove the file and then use `cvs update' to get a new copy. The meaning is not precisely the same; removing and updating may also bring in some changes which have been made in the repository since the last time you updated. When using client/server CVS, you can use the `cvs edit' and `cvs unedit' commands even if CVS is unable to succesfully communicate with the server; the notifications will be sent upon the next successful CVS command.  File: cvs.info, Node: Watch information, Next: Watches Compatibility, Prev: Editing files, Up: Watches Information about who is watching and editing --------------------------------------------- - Command: cvs watchers [`-l'] FILES ... List the users currently watching changes to FILES. The report includes the files being watched, and the mail address of each watcher. The FILES and `-l' arguments are processed as for the `cvs watch' commands. - Command: cvs editors [`-l'] FILES ... List the users currently working on FILES. The report includes the mail address of each user, the time when the user began working with the file, and the host and path of the working directory containing the file. The FILES and `-l' arguments are processed as for the `cvs watch' commands.  File: cvs.info, Node: Watches Compatibility, Prev: Watch information, Up: Watches Using watches with old versions of CVS -------------------------------------- If you use the watch features on a repository, it creates `CVS' directories in the repository and stores the information about watches in that directory. If you attempt to use CVS 1.6 or earlier with the repository, you get an error message such as cvs update: cannot open CVS/Entries for reading: No such file or directory and your operation will likely be aborted. To use the watch features, you must upgrade all copies of CVS which use that repository in local or server mode. If you cannot upgrade, use the `watch off' and `watch remove' commands to remove all watches, and that will restore the repository to a state which CVS 1.6 can cope with.  File: cvs.info, Node: Choosing a model, Prev: Watches, Up: Multiple developers Choosing between reserved or unreserved checkouts ================================================= Reserved and unreserved checkouts each have pros and cons. Let it be said that a lot of this is a matter of opinion or what works given different groups' working styles, but here is a brief description of some of the issues. There are many ways to organize a team of developers. CVS does not try to enforce a certain organization. It is a tool that can be used in several ways. Reserved checkouts can be very counter-productive. If two persons want to edit different parts of a file, there may be no reason to prevent either of them from doing so. Also, it is common for someone to take out a lock on a file, because they are planning to edit it, but then forget to release the lock. People, especially people who are familiar with reserved checkouts, often wonder how often conflicts occur if unreserved checkouts are used, and how difficult they are to resolve. The experience with many groups is that they occur rarely and usually are relatively straightforward to resolve. The rarity of serious conflicts may be surprising, until one realizes that they occur only when two developers disagree on the proper design for a given section of code; such a disagreement suggests that the team has not been communicating properly in the first place. In order to collaborate under *any* source management regimen, developers must agree on the general design of the system; given this agreement, overlapping changes are usually straightforward to merge. In some cases unreserved checkouts are clearly inappropriate. If no merge tool exists for the kind of file you are managing (for example word processor files or files edited by Computer Aided Design programs), and it is not desirable to change to a program which uses a mergeable data format, then resolving conflicts is going to be unpleasant enough that you generally will be better off to simply avoid the conflicts instead, by using reserved checkouts. The watches features described above in *Note Watches:: can be considered to be an intermediate model between reserved checkouts and unreserved checkouts. When you go to edit a file, it is possible to find out who else is editing it. And rather than having the system simply forbid both people editing the file, it can tell you what the situation is and let you figure out whether it is a problem in that particular case or not. Therefore, for some groups it can be considered the best of both the reserved checkout and unreserved checkout worlds.  File: cvs.info, Node: Revisions and branches, Next: Merging, Prev: Multiple developers, Up: Top Revisions and branches ********************** For many uses of CVS, one doesn't need to worry too much about revision numbers; CVS assigns numbers such as `1.1', `1.2', and so on, and that is all one needs to know. However, some people prefer to have more knowledge and control concerning how CVS assigns revision numbers. If one wants to keep track of a set of revisions involving more than one file, such as which revisions went into a particular release, one uses a "tag", which is a symbolic revision which can be assigned to a numeric revision in each file. Another useful feature, especially when maintaining several releases of a software product at once, is the ability to make branches on the revision tree. * Menu: * Revision numbers:: The meaning of a revision number * Versions revisions releases:: Terminology used in this manual * Assigning revisions:: Assigning revisions * Tags:: Tags-Symbolic revisions * Branches motivation:: What branches are good for * Creating a branch:: Creating a branch * Sticky tags:: Sticky tags  File: cvs.info, Node: Revision numbers, Next: Versions revisions releases, Up: Revisions and branches Revision numbers ================ Each version of a file has a unique "revision number". Revision numbers look like `1.1', `1.2', `1.3.2.2' or even `1.3.2.2.4.5'. A revision number always has an even number of period-separated decimal integers. By default revision 1.1 is the first revision of a file. Each successive revision is given a new number by increasing the rightmost number by one. The following figure displays a few revisions, with newer revisions to the right. +-----+ +-----+ +-----+ +-----+ +-----+ ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! +-----+ +-----+ +-----+ +-----+ +-----+ CVS is not limited to linear development. The "revision tree" can be split into "branches", where each branch is a self-maintained line of development. Changes made on one branch can easily be moved back to the main trunk. Each branch has a "branch number", consisting of an odd number of period-separated decimal integers. The branch number is created by appending an integer to the revision number where the corresponding branch forked off. Having branch numbers allows more than one branch to be forked off from a certain revision. All revisions on a branch have revision numbers formed by appending an ordinal number to the branch number. The following figure illustrates branching with an example. +-------------+ 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 !----! 1.2.2.4 ! / +---------+ +---------+ +---------+ +---------+ / / +-----+ +-----+ +-----+ +-----+ +-----+ ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk +-----+ +-----+ +-----+ +-----+ +-----+ ! ! ! +---------+ +---------+ +---------+ Branch 1.2.4 -> +---! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.3 ! +---------+ +---------+ +---------+ The exact details of how the branch number is constructed is not something you normally need to be concerned about, but here is how it works: When CVS creates a branch number it picks the first unused even integer, starting with 2. So when you want to create a branch from revision 6.4 it will be numbered 6.4.2. All branch numbers ending in a zero (such as 6.4.0) are used internally by CVS (*note Magic branch numbers::.). The branch 1.1.1 has a special meaning. *Note Tracking sources::.  File: cvs.info, Node: Versions revisions releases, Next: Assigning revisions, Prev: Revision numbers, Up: Revisions and branches Versions, revisions and releases ================================ A file can have several versions, as described above. Likewise, a software product can have several versions. A software product is often given a version number such as `4.1.1'. Versions in the first sense are called "revisions" in this document, and versions in the second sense are called "releases". To avoid confusion, the word "version" is almost never used in this document.  File: cvs.info, Node: Assigning revisions, Next: Tags, Prev: Versions revisions releases, Up: Revisions and branches Assigning revisions =================== By default, CVS will assign numeric revisions by leaving the first number the same and incrementing the second number. For example, `1.1', `1.2', `1.3', etc. When adding a new file, the second number will always be one and the first number will equal the highest first number of any file in that directory. For example, the current directory contains files whose highest numbered revisions are `1.7', `3.1', and `4.12', then an added file will be given the numeric revision `4.1'. Normally there is no reason to care about the revision numbers--it is easier to treat them as internal numbers that CVS maintains, and tags provide a better way to distinguish between things like release 1 versus release 2 of your product (*note Tags::.). However, if you want to set the numeric revisions, the `-r' option to `cvs commit' can do that. For example, to bring all your files up to the RCS revision 3.0 (including those that haven't changed), you might invoke: $ cvs commit -r 3.0 Note that the number you specify with `-r' must be larger than any existing revision number. That is, if revision 3.0 exists, you cannot `cvs commit -r 1.3'. If you want to maintain several releases in parallel, you need to use a branch (*note Revisions and branches::.).  File: cvs.info, Node: Tags, Next: Branches motivation, Prev: Assigning revisions, Up: Revisions and branches Tags-Symbolic revisions ======================= The revision numbers live a life of their own. They need not have anything at all to do with the release numbers of your software product. Depending on how you use CVS the revision numbers might change several times between two releases. As an example, some of the source files that make up RCS 5.6 have the following revision numbers: ci.c 5.21 co.c 5.9 ident.c 5.3 rcs.c 5.12 rcsbase.h 5.11 rcsdiff.c 5.10 rcsedit.c 5.11 rcsfcmp.c 5.9 rcsgen.c 5.10 rcslex.c 5.11 rcsmap.c 5.2 rcsutil.c 5.10 You can use the `tag' command to give a symbolic name to a certain revision of a file. You can use the `-v' flag to the `status' command to see all tags that a file has, and which revision numbers they represent. Tag names must start with an uppercase or lowercase letter and can contain uppercase and lowercase letters, digits, `-', and `_'. The two tag names `BASE' and `HEAD' are reserved for use by CVS. It is expected that future names which are special to CVS will be specially named, for example by starting with `.', rather than being named analogously to `BASE' and `HEAD', to avoid conflicts with actual tag names. You'll want to choose some convention for naming tags, based on information such as the name of the program and the version number of the release. For example, one might take the name of the program, immediately followed by the version number with `.' changed to `-', so that CVS 1.9 would be tagged with the name `cvs1-9'. If you choose a consistent convention, then you won't constantly be guessing whether a tag is `cvs-1-9' or `cvs1_9' or what. You might even want to consider enforcing your convention in the taginfo file (*note user-defined logging::.). 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 command in the directory where `backend.c' resides. $ cvs tag release-0-4 backend.c T backend.c $ cvs status -v backend.c =================================================================== File: backend.c Status: Up-to-date Version: 1.4 Tue Dec 1 14:39:01 1992 RCS Version: 1.4 /usr/local/cvsroot/yoyodyne/tc/backend.c,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) Existing Tags: release-0-4 (revision: 1.4) 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 is made. $ cvs tag release-1-0 . cvs tag: Tagging . T Makefile T backend.c T driver.c T frontend.c T parser.c (When you give CVS a directory as argument, it generally applies the operation to all the files in that directory, and (recursively), to any subdirectories that it may contain. *Note Recursive behavior::.) The `checkout' command has a flag, `-r', that lets you check out a certain revision of a module. This flag makes it easy to retrieve the sources that make up release 1.0 of the module `tc' at any time in the future: $ cvs checkout -r release-1-0 tc 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. *Note checkout options::. When you tag more than one file with the same tag you can think about the tag as "a curve drawn through a matrix of filename vs. revision number." Say we have 5 files with the following revisions: file1 file2 file3 file4 file5 1.1 1.1 1.1 1.1 /--1.1* <-*- TAG 1.2*- 1.2 1.2 -1.2*- 1.3 \- 1.3*- 1.3 / 1.3 1.4 \ 1.4 / 1.4 \-1.5*- 1.5 1.6 At some time in the past, the `*' versions were tagged. You can think of the tag as a handle attached to the curve drawn through the tagged revisions. When you pull on the handle, you get all the tagged revisions. Another way to look at it is that you "sight" through a set of revisions that is "flat" along the tagged revisions, like this: file1 file2 file3 file4 file5 1.1 1.2 1.1 1.3 _ 1.1 1.2 1.4 1.1 / 1.2*----1.3*----1.5*----1.2*----1.1 (--- <--- Look here 1.3 1.6 1.3 \_ 1.4 1.4 1.5  File: cvs.info, Node: Branches motivation, Next: Creating a branch, Prev: Tags, Up: Revisions and branches What branches are good for ========================== Suppose that release 1.0 of tc has been made. You are continuing to develop tc, planning to create release 1.1 in a couple of months. After a while your customers start to complain about a fatal bug. You check out release 1.0 (*note Tags::.) and find the bug (which turns out to have a trivial fix). However, the current revision of the sources are in a state of flux and are not expected to be stable for at least another month. There is no way to make a bugfix release based on the newest sources. The thing to do in a situation like this is to create a "branch" on the revision trees for all the files that make up release 1.0 of tc. You can then make modifications to the branch without disturbing the main trunk. When the modifications are finished you can select to either incorporate them on the main trunk, or leave them on the branch.