diff options
Diffstat (limited to 'contrib/cvs/FAQ')
-rw-r--r-- | contrib/cvs/FAQ | 8596 |
1 files changed, 8585 insertions, 11 deletions
diff --git a/contrib/cvs/FAQ b/contrib/cvs/FAQ index c7fcdd7..20912dd 100644 --- a/contrib/cvs/FAQ +++ b/contrib/cvs/FAQ @@ -1,11 +1,8585 @@ -This file formerly contained a CVS FAQ, maintained by David Grubbs. -However, it has been out of date for a long time, he officially gave up -maintaining it in the fall of 1995, and noone else has taken it over. -Most of the information which used to be in it can be found in the CVS -manual, doc/cvs.texinfo in this distribution. For information on -questions like "what is the latest version of CVS?" and "what about GUIs -for CVS?", see the CVS web site, -http://www.loria.fr/~molli/cvs-index.html. There are many web sites on -Configuration Management packages (of which CVS is an example); for -example see the "Configuration Management" category at http://www.yahoo.com/ -or see http://www.iac.honeywell.com/Pub/Tech/CM/index.html. +This file contains a CVS FAQ. Until 1995 it was maintained by David +Grubbs. It was out of date and not being maintained, but it had a +certain following and in 1997 Pascal Molli decided to start +maintaining it with the FAQ-O-Matic package which allows any +contributor with a web browser to help maintain it. The following +text is (mostly automatically) extracted from the FAQ-O-Matic. The +odds are good that the file that you are currently reading is out of +date with respect to the online FAQ-O-Matic, which is part of Pascal +Molli's CVS web site at http://www.loria.fr/~molli/cvs-index.html +(currently under "Documentation"). The online version is also +somewhat better in terms of things like tables of contents (at least +until someone can write some code to extract data from a FAQ-O-Matic +and insert things like tables of contents). + +The answers which are dated "6/13/1997" below are really from the 1995 +FAQ, for the most part. Many of them are out of date. If you have +some time, you are encouraged to double-check them against other +sources like the Cederqvist manual and update the FAQ. If you don't +have such time, take them with a grain of salt or a few. + + Category: /, all questions + + Category: / + + " [INLINE] " + + 1. About FAQ-O-Matic + +This is FAQ-O-Matic, a quick-and-dirty Perl hack (aren't they all?) by +Jon Howell. + +It seems like most FAQ maintainers make a valiant initial effort, then get +a life and don't have time to keep their FAQs up to date. Also, I often +find out a solution to a problem, and feel like I could write a single +FAQ answer on it in a few minutes, but where to post it? + +Thus the FAQ-O-Matic was born. FAQ-O-Matic is a couple sleazy Perl scripts +that allow people to submit FAQ answers to this database, so it can stay +current, with just a tiny bit of work on any one person's part. + +Yes, a bad guy could come along and wipe out all the FAQ entries. Please don't. +But to give the good guys some measure of comfort, each submission is stored +in an RCS file, so if someone does tamper, we can recover the database. + +Guidelines for submissions: + +1. Please _try to be fairly unbiased in matters of opinion._ Mailing lists are +the place to start flame wars (just kidding :v), but definitely not here. + +2. Please _use HTML only conservatively_ in your entries. Links are appropriate +, +but put the URL in the plaintext also so it's useable on printed versions of +the FAQ. Inline images pointing off this site are inappropriate, as is much +fancy formatting. This is meant to be bandwidth-light and dumb-browser-friendly +. + +3. If you feel there's a place for a _new category, or a reorganization of +existing questions_, don't hesitate to mail me (molli@loria.fr). +Category changes need to be done from my end. + +4. Please _leave an email address_ at the bottom of your submission so that oth +ers +can drop you a note. + +5. _If you only have a question_, not an answer, you should probably post +it to a mailing list, not here. If there are frequently asked questions to whic +h +the answer is not forthcoming on mailing lists (or perhaps there's no +useful answer yet other than "no one knows"), then it's appropriate to +post here, in hopes that someone will see it and know the answer. + +6. Please refrain from crude or inconsiderate language. Please don't use +this as a forum for advertising. However, mention of worthy commercial +products is certainly appropriate (even if you sell said product). Just +don't overdo it. :v) + + Last modified: _6/13/1997_ + + 2. Adding a new category ? + +just send me a mail at +molli@loria.fr + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/ + + " Advanced Topics " + + Category: /Advanced_Topics_/Branching_and_Mergin/ + + " + Branching and Merging" + + 1. What is a branch? + + Unfortunately, the word "branch" is an overloaded technical + term. It is used in too many different ways in three + categories. It might help to understand some of the issues by + going through the categories: + + How Humans use the word "branch": + + Most development starts with everyone working on the same + software, making changes and heading toward a single goal. This + is called something like "Main Line Development". Note that + though many people do main line development on CVS's "Main + Branch", that is a choice, not a requirement. + + After a release or when one or more developers want to go off + and work on some project for a while, the Software Engineers + assigned to deal with large software issues generate a "Branch + in Development" to support the release or project. (Keep in + mind that a programmer is no more a Software Engineer than a + carpenter is a Civil Engineer.) + + Essentially, the word "branch" implies a way to allow + simultaneous development on the same files by multiple people. + + The above terms are human-oriented. They refer to actions that + people would like to take. They do *not* imply any particular + implementation or set of procedures. Branches in development + can be supported in many different ways. + + How CVS uses the word "branch": + + 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 + '-A' option to "update". + + Important Note: The CVS "Main Branch" is *not* the same as the + RCS concept with the same name. If you are using Vendor + 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". + + The concepts overlap, but they are not equivalent. + + 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 + branch is the same as the CVS Main branch. If you use the "-r + <branch_tag>" option to the "checkout" command, you will record + 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 + branch. It is used to support the CVS idea of a "Main Branch" + and it must either point to the RCS Main Branch, or the Vendor + Branch (1.1.1) if you haven't made any changes to the file + since you executed "import". + + Last modified: _6/13/1997_ + + 2. Why (or when) would I want to create a branch? + + Remember that you can think of your working directory as a "branch for + one". You can consider yourself to be on a branch all the time because + you can work without interfering with others until your project (big + or small) is done. + + The four major situations when you should create a branch: + + When you expect to take a long time or make a large set of changes + that the merging process will be difficult. Both "long" and "large" + are defined in your own environment. + + When you want to be able to "commit" and "tag" your work repeatedly + without affecting others. + + If you ever think you need Source Control for your own work, but don't + want your changes to affect others, create a private branch. (Put your + username in the branch tag, to make it obvious that it is private.) + + When you need to share code among a group of developers, but not the + whole development organization working on the files. + + Rather than trying to share a working directory, you can move onto a + branch and share your work with others by "committing" your work onto + the branch. Developers not working on the branch won't see your work + unless they switch to your branch or explicitly merge your branch into + theirs. + + When you need to make minor changes to a released system. + + Normally a "release" is labeled by a branch tag, allowing later work + on the released files. If the release is labeled by a non-branch tag, + it is easy to add a branch tag to a previously tagged module with the + "rtag" command. If the release is not tagged, you made a mistake. + Recovery requires identifying all revisions involved in the release + and adding a tag to them. + + Last modified: _6/13/1997_ + + 3. How do I create and checkout a branch? + + Suggested technique: + + Attach a non-branch tag to all the revisions you want to branch + from. (i.e. the branch point revisions) + + When you decide you really need a branch, attach a branch tag to the + same revisions marked by the non-branch tag. + + "Checkout" or "update" your working directory onto the branch. + + Suggested procedure when using modules: + + cvs rtag <branch_point_tag> module + + cvs rtag -b -r <branch_point_tag> <branch_tag> <module> + + cvs checkout -r <branch_tag> module + + Suggested procedure when using your working directory, which + contains the revisions of your working files you want to branch from: + + cvs tag <branch_point_tag> + + cvs rtag -b -r <branch_point_tag> <branch_tag> <module> + + cvs update -r <branch_tag> + + In each procedure above, Step #1 applies a non-branch tag to all the + branch point revisions in the module/directory. Though this is not + strictly necessary, if you don't add a non-branch tag to the revisions + you branch from, you won't be able to refer to the branch point in the + future. + + Between steps 1 & 2 you may commit changes. The result would be same + because "rtag -r <oldtag> <newtag>" applies <newtag> to the same + revision that <oldtag> is attached to. You can use this technique to + avoid attaching *any* branch tags until you need them. + + Step B.2 has two corollaries: + + If you plan to create the branch tag before committing anything in + your working directory, you can use "cvs tag -b <branch_tag>" instead + of the "rtag" command. + + The <module> can be a relative path to a directory from which your + working directory was checked out. + + If you have trouble figuring out what <module> to use (or pathname to + use in its place), you can aim it at whatever parent directories you + believe will cover all your work. + + If you are sure the <branch_tag> is not being used anywhere else, you + can even aim it at the whole Repository ($CVSROOT), if you have to. It + might take some extra time, but assuming that your <tag> is a unique + string and you don't use the '-f' option to "rtag -r", "rtag" will + only add a <tag> to files in which it actually *finds* the earlier + <tag>. + + In each procedure above, Step #3 may occur any time after step 2. + Unless you explicitly remove them with "tag -d", a <tag> is permanent. + + The <branch_tag> is an unusual creature. It labels a branch in a way + that allows you to "checkout" the branch, to "commit" files to the end + of the branch and to refer to the end of the branch. It does not label + the base of the branch (the branch point). + + There are two obvious ways to choose the <branch_point_tag> and + <branch_tag> names. But keep in mind that the <branch_tag> is typed by + any developer who wants to work on the branch -- you should make it + mean something to them. + + Style #1 presumes that the simple version string refers to a set of + designed, documented or promised features, not to a specific set of + files. In this case, you tag the branch with the generic Version + string and assume that whenever you refer to "Version", you want the + "latest" set of files associated with that Version, including all + patches. (You can substitute whatever you like for "bp_", as long as + your <branch_point_tag> is some modification of the <branch_tag>.) + + <branch_point_tag> Matching <branch_tag> + + bp_V1_3 V1_3 + bp_Release2-3-5 Release2-3-5 + bp_Production4_5 Release4_5 + + Style #2 presumes that the simple version string refers to the + specific set of files used to construct the first release of + "version". In this case, you tag the branch-point revisions with the + generic Version string and assume that whenever you refer to this + Version, you want the original set of released revisions. To get the + latest patched revisions of the release, you refer to the branch tag + "latest_<branch_point_tag>". (You can substitute what ever you like + for "latest_", as long as your <branch_tag> is some modification of + the <branch_point_tag>.) + + <branch_point_tag> Matching <branch_tag> + + V1_3 latest_V1_3 + Release2-3-5 latest_Release2-3-5 + Release4_5 latest_Production4_5 + + In both styles you can find out what you had to change since the + original release of this Version by typing: + + cvs diff -r <branch_point_tag> -r <branch_tag> + + For Style 1, this is: + + cvs diff -r bp_<branch_tag> -r <branch_tag> + + For Style 2, this is: + + cvs diff -r <branch_point_tag> -r latest_<branch_point_tag> + + Notes on "being on a branch": + + - "update -r <tag>" tells CVS to attach a "sticky tag" to working + 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". + + Last modified: _6/13/1997_ + + 4. Once created, how do I manage a branch? + + The most important thing you should know about managing a branch is + that the creation of a branch is not a lightweight act. When you + create a branch, you must also create a set of procedures to keep + track of it. + + 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 + which other branches. + + The simplest way to deal with branches is to limit their number, + "collapse" them back into the main line as quickly as is reasonable + and forget them. If a group wants to continue working, tell them to + create another branch off the fully merged main line. + + Remember that CVS is just a tool. Over time, it will probably handle + branching better, requiring less careful attendance. But no matter how + good it becomes, the whole idea of "branching" is a complicated + management problem. Don't take it lightly. + + Last modified: _6/13/1997_ + + 5. Are there any extra issues in managing multiple branches? + + If you plan to split from the "main line" and merge back after a time, + the only problem will be scheduling the order of branch merges. As + each branch is merged, the main line must be rebuilt and tested. + Merging multiple branches (i.e. "lines of development") before + building and testing creates more problems than you are ready for. + + If you plan to collapse some branches into others, then move the + combined branches back into the main line, you have to be careful with + the revisions and tags you hand to your "update -j" command, but it + shouldn't be much trouble. + + If you plan to allow every branch to incrementally take the work done + on other branches, you are creating an almost insurmountable + bookkeeping problem. Every developer will say "Hey, I can handle + taking just this little bit," but for the system as a whole it is + disaster. Try it once and see. If you are forced into this situation, + you will need to keep track of the beginning and end points of every + merge ever done. Good Luck. + + Last modified: _6/13/1997_ + + 6. How do I merge a whole branch back into the trunk? + + If you don't have a working directory, you can checkout and merge in + one command: + + cvs checkout -j <branch_tag> <module> + cd <module> + + If you already have a working directory: + + cd <working_directory> + cvs update <== Optional, to bring it up to date. + cvs update -j <branch_tag> + + CVS will print lines beginning with + + 'U' for files that you hadn't changed, but the branch did. + + 'M' for files that you changed and the branch didn't + *and* for files that you both changed that were merged + without overlaps. (This overload is unfortunate.) + + 'C' for files that you both changed in a way that conflicts + with each other. + + You need to go edit all the 'C' files and clean up the conflicts. Then + you must commit them. + + Last modified: _6/13/1997_ + + 7. How do I merge changes from the trunk into my branch or between + branches? + + The idea is similar to the above, but since CVS doesn't treat the main + branch like other branches, you'll have to be more careful. There are + 5 different ways to look at the problem. + + The way to merge *all* changes made on the trunk into a working + branch is to move to the branch you want via "checkout -r" or "update + -r": + + cvs update -r <branch_tag> {optional files} + + Then merge the changes from the trunk into your working branch using + the pseudo-tag named "HEAD": + + cvs up -j HEAD {optional files} + + You will get everything from the branch point of the branch named + <branch_tag> up to the HEAD of the main branch. This is still kind of + strange. If the file is on a branch, HEAD should be the latest thing + on the branch, not the HEAD of MAIN. But that's not the way CVS + (currently) works. + + If you run "cvs up -j HEAD" again after adding more revisions to the + trunk, you may get overlaps for the text you have already merged. It + depends on your version of your RCS "merge" command (actually the "co + -j" option, which depends on the version of "diff3" you configured RCS + to use). + + You can merge the difference between any two <tags> using two "-j" + options on "update" or "checkout". + + Identify the two tags on the branch you want to merge from. + + cvs update -j <tag1> -j <tag2> {optional files} + + This step assumes you were careful about tagging milestones. You can + use this technique for any two <tags> on the same branch, even the + trunk. It is also possible to use tags on different branches, but + you'll have to ponder the meaning of the difference between those two + tags. + + In place of one of the <tags>, you can use a <branch_tag> to refer to + the latest revision on that branch. See 4C.11 and 4C.3 for info on + branch points. + + Merges can also be performed by handing RCS revisions to the '-j' + options, but since revision numbers aren't the same in all files, + merging by number is normally limited to one file. Sets of files with + the exact same trees of branches and revision numbers would work too, + but that's a rare situation. + + To "take" revisions from other branches instead of merging them, see + 4C.19 for an idea. + + A way to gain the effect of merging the main to the branch is to + merge the branch into the main using the normal + + cvs update -A {optional files} + cvs update -j <branch_tag> {optional files} + cvs commit + cvs tag -F -b <same_branch_tag> {optional files} + + See part B of 4D.5 + + Other oddities. + + This also works, but is probably not officially supported: + + cvs update -j N {optional files} + + where N is a number. This will merge all the changes from the branch + point up to the highest revision on the main branch starting with N. + For example, if your highest trunk revision is 1.52, you can use this + to grab revisions from the trunk: + + cvs update -j 1 {optional files} + + Another example: Say you have a branch point at rev 1.2 for a branch + named "BR1" and trunk revisions 1.3, 1.4, 2.1, 2.2, 2.3, 3.1, 3.2. + Then: + + cvs update -j 1 {optional files} + + will merge the changes from 1.2 to 1.4 + + cvs update -j 2 {optional files} + + will merge the changes from 1.2 to 2.3 + + cvs update -j 3 {optional files} + + will merge the changes from 1.2 to 3.2, which in this example, is + equivalent to the use of "-j HEAD" in part A above. + + The intuitive (at least to me): + + cvs up -j MAIN (or TRUNK) {optional files} + + doesn't work. If the trunk (i.e. "main branch") had an implicit branch + named "MAIN", you could use: + + cvs up -j MAIN:10/26 -j MAIN:now {optional files} + + and refer to date-stamped revisions on the trunk using the + <branch_tag>:<date> support that works on other branches. + + You might also think you could place an explicit tag on branch 1 (or + higher) (e.g. MAINHACK:1) and use it in place of the implicit "MAIN", + but I haven't found the right combination. + + [[If you find working techniques, I'll add them here.]] + + Last modified: _6/13/1997_ + + 8. How do I merge onto the Main Branch a file that exists only on a branch + other than the Main Branch? (i.e. it is in the Attic) + + For how such a file can exist, see 3A.2 and 3A.3. + + For how to avoid creating such a file, see 3A.5. + + Though you might think that the "update -j" command could perform the + "merge" of a file from the side branch to the Main Branch, it isn't + (yet) smart enough. Unfortunately, there is no single CVS command to + do this -- it takes three steps: + + To move something onto the Main Branch from the Attic, you have to + physically move the file from the Attic to the main Repository + directory associated with your working directory. + + It is exactly like resurrecting a removed file. See 3L.4 + + I use something like this: (csh-like syntax) + + set repos = `cat ./CVS/Repository` mv $repos/Attic/filename,v + $repos/filename,v + + (If you use relative paths in your Repository files, that first line + becomes: set repos = $CVSROOT/`cat ./CVS/Repository`) + + Now that the file is physically in the right place within the + Repository, "update -A" will make it appear in your working directory + on the Main Branch. Do that now. + + You now have a choice. The act of physically moving the file has + fused together the <branch_tag> branch and the Main Branch for this + file. You can continue that way, making changes along the RCS Main + Branch which CVS will (for this type of file only) treat as both the + Main Branch and the <branch_tag> branch. + + The other choice, which I would suggest, is to re-tag the file with + <branch_tag>, restoring a normal-looking magic branch tag to the file: + + cvs tag -F -b <branch_tag> <file> + + After you have done the above, you can run "update -A" or "update -r + <branch_tag>" to resume whatever you were doing before you started + this procedure. + + Caveat: The final result is a file whose revision tree doesn't look + like it was ever on any branch but the Main Branch until the above + "tag -F -b" command was executed. CVS and RCS have no way of saving + the history of the actions you have just performed. + + Last modified: _6/13/1997_ + + 9. How do I know what branch I'm (working) on? + + Type: + cvs status + + and look at the "Sticky Tag" field for each file. If: + + The *same* tag is on *every* file in your working tree, *and* + + That tag matches the contents of the ./CVS/Tag file, *and* + + That tag is a branch tag, + + then you know what branch you are working on. You can get sticky Tag + information directly from the ./CVS/Entries file instead of "cvs + status". + + If all the sticky Tags don't agree, then your directory is temporarily + inconsistent. This is a feature allowing you to make changes (or + perform merges) to individual files on multiple branches without + checking out the whole directory. + + The sticky Tag on each file in the ./CVS/Entries file (as displayed by + the "status" command) indicates what branch the working file is on. + New files are added to the Tag stored in ./CVS/Tag. + + To force your entire working directory onto the same branch, type: + + cvs update -r <branch_tag> + + Last modified: _6/13/1997_ + + 10. Do I really have to know the name of the branch I'm working on? + + If a developer can't be relied on to know what branch of development + to work on, then either the developer's manager isn't planning + branches properly or the developer has serious problems. + + I have found that one of the hardest concepts to get across to + developers (and some managers) is that "a branch in development" (as + opposed to the use of RCS branches to support some other scheme) is a + heavyweight act. Every time you create a real branch in development, + you must spawn a set of managerial procedures and a schedule by which + you plan to merge each branch into each other branch. Unless you plan + to keep it simple and collapse (by merging and forgetting) branches + quickly, they are not to be created lightly. + + In other words, if you don't regularly attend group meetings in which + the branch to be worked on is a major topic of discussion, then the + group is not managing branches properly. + + We created a couple major branches a few months ago and even the + customer service people refer to the "XYZ branch" as a shorthand for + "continuing development on the XYZ project". + + Last modified: _6/13/1997_ + + 11. How do I refer to the revision where I branched so I can see what + changed since the Branch Point on another branch? + + Given the current <branch_tag> format, there is no direct way to refer + to the branch point, which is more useful in many ways than referring + to the branch, which always refers to the latest revision on the + branch. + + When CVS adds a branch tag, it attaches an RCS symbol to a + non-existent revision number containing the revision number of the + branch point as a prefix. (See Section 3O, on the "tag" command.) RCS + can't use the CVS magic branch tag and many of the CVS commands can't + refer to it. + + To be certain of your ability to refer to a branch point, you must + create a "branch point" tag at the same time as the Branch tag. See + 4C.3. + + Last modified: _6/13/1997_ + + 12. Why didn't the command "cvs admin -bBRANCH1 *" create a branch? + + Because your command creates an RCS branch, not a CVS branch. See the + above discussion on branches. RCS branches are used to support CVS + branches, but they are not the same. You can't act as if you have + direct control over the RCS files. + + The "admin" command was placed there as a convenience to allow you to + execute raw "rcs" commands on the Repository, taking advantage of + CVS's ability to find the files in the Repository. + + But you have to remember that you are using RCS commands on a CVS + Repository, which is not generally safe unless you know exactly what + CVS depends on. + + For one thing, CVS insists on control of the default branch. It is set + either to the Main branch or the Vendor branch depending on whether + you have changed the Vendor's code. If you change the default branch, + you are monkeying with the internals and you will get unexpected + results. + + To set your "default CVS branch" to BRANCH1, you must use "checkout" + or "update" with the "-r BRANCH1" option. Then you have changed CVS's + idea of your "default branch", which has little to do with RCS's + default branch. + + Last modified: _6/13/1997_ + + 13. Is it possible to set the "default CVS branch" for everyone? + + No. It doesn't work that way. + + When using CVS, all administrative information (such as what branch + you checked out) is stored in CVS sub-directories, local to the user. + There is no global state, other than the description and logging files + in the $CVSROOT/CVSROOT directory. + + You tell "checkout" or "update" what branch you want to check out via + the "-r <tag>" option. The default is CVS's "Main Branch". + + I don't see a problem in *designing* a new way to indicate what branch + you get by default, instead of the main one, but that's not how it + currently works. + + Last modified: _6/13/1997_ + + 14. How do I perform a large merge? + + Large merges require a bit more planning to be able to track what has + happened in the inevitable cases where something goes wrong. No tool + can force a "merge" to make perfect sense. + + Though you can handle the details in many different ways, the two ends + of the spectrum of merge techniques are: gonzo and paranoid. + + The gonzo method assumes that you know everything about your sources + so that recovery from failures is "just a matter of typing." You + created the branch this way: + + cvs checkout <module> + cd <module> + cvs tag -b <branch_tag> + cvs update -r <branch_tag> + >>> Edit away. + cvs commit <<== Onto branch + + Now you want to merge your branch back into the Main branch, you are + certain you can make it work, or at least detect all the failures, so + you dive in and hack away: (For simplicity, we will assume you are + collapsing (i.e. merging and forgetting) a side-branch into the Main + branch from your single working directory.) + + cvs update -A + cvs update -j <branch_tag> + >>> Edit the 'C' files and remove the overlaps. + >>> Edit some more to make it all compile and work. + cvs commit + + Looks simple. For more details on the output from the "update -j" + command, see 3P.2 and 4C.6. + + Note: You could also checkout a whole new working directory and + perform the merge at the same time by replacing the two + update commands with these two commands: + + cvs checkout -j <branch_tag> <module> + cd <module> + + The paranoid way is more difficult, but it can catch all sorts of + problems. You created the branch this way: + + cvs checkout <module> + cd <module> + cvs tag <branch_point_tag> + cvs tag -b <branch_tag> + cvs update -r <branch_tag> + >>> Edit away. + cvs commit <<== Onto branch + + The extra tag command places a non-branch tag on the Branch Point, an + act that makes it easier to do "diffs" later. Now we decide to perform + the merge: + + cvs tag <latest_on_branch_tag> + cvs update -A + *1* cvs diff -r <branch_point_tag> -r <latest_on_branch_tag> + >>> *1* shows all the changes on the branch. + *2* cvs diff -r <branch_point_tag> -r HEAD + >>> *2* shows the changes on the trunk since branching. + cvs tag <premerge_tag> + cvs update -j <branch_tag> + >>> Edit the 'C' files and remove the overlaps. + *3* cvs diff + >>> Verify that *3* matches *1*, except for line numbers. + cvs commit + cvs tag <just_merge_changes_tag> + >>> Edit some more to make it all compile and work. + cvs commit + cvs tag <after_merge_cleanup_tag> + + The reason *3* and *1* match so closely is that they are the + differences between two pairs of starting points and ending points + after the same data was inserted. If they are significantly different, + you will want to figure out why. + + NOTE: You will have to tell everyone to stay the hell out of the + Repository while you do this. If they commit something while you are + in the middle of a merge, your job will be much more difficult. If + they "update" at the wrong time, their work will be randomized until + you finish. It's better to call a halt. + + See 3H.13 for some more information about dealing with merges after + import. The last part of the procedure is applicable to any large + merge. + + Last modified: _6/13/1997_ + + 15. Is a Vendor merge any different from a branch merge? + + No. In most ways, a Vendor branch is exactly the same as any other + branch. In a Vendor merge, the data is append to the branch by the + "import" command, rather than by hand-editing, but the merge process + is the same. + + See the "import" command in section 3H. + + Last modified: _6/13/1997_ + + 16. How do I go back to a previous version of the code on a branch? + + + + + You can avoid digging into RCS revision numbers (executing "update + -r (rev)" on each file) by trying one of these: + +Use non-branch tags as you normally would. Non-branch tags + attach to specific revisions, so a "tag (tag)" command would + mark the revisions you have in your working directory, which + are on your branch. If you need to retrieve them, use "update + -r (non-branch-tag)" + + Doing this overrides the sticky (branch-tag) attached to your + working directory with a non-branch tag, which means you won't + be able to commit until you again move forward to the end of + the branch with "update -r (branch-tag)". + +Use the "update -r (branch-tag):(date)" trick. + + This is almost like using the '-D' option, but it looks for + revisions extant on (date) only along the given branch. + + As in #1, you can't commit to this kind of working area, + because it has a sticky date referring to revisions in the + middle of a branch. + +[comment from the audience: You are dreaming.. +this does not work.. try it, you get +No such tag: "MYTAG:May 1" +or similar. I wish it did because I need it. julian@whistle.com] + + +You can branch a branch. + + If you add a branch tag to file in a working directory that was + checked out on a branch, you will branch the branch. This + works just fine, though you'll have to play some games to merge + everything back together again. You'll also create 6-part + revision numbers. (They'll be 8-part revision numbers if you + branch a branch that started out with some unmodified files on + the Vendor branch. Think about it. How does revision + 1.2.4.2.4.2.2.1 grab you?) + + +(fixed formatting, kingdon@cyclic.com) + + Last modified: _9/8/1997_ + + 17. Once I've found the files I want, how do I start changing them? I keep + getting warnings about sticky tags. + + What you probably did was type "cvs update -r <tag>" where <tag> is a + non-branch tag. "update" created a sticky tag for a specific revision, + not a branch. To start working right there, you have to create a + branch to work on. + + You have two choices. + + You can do it in place and keep working: + + cvs tag -b <branch_tag> <<== To tag the current files. + cvs update -r <branch_tab> <<== To move onto the branch. + + You can do it "externally" and create a new working directory: + + cvs rtag -b -r <tag> <branch_tag> <module> + cvs checkout -r <branch_tag> <module> + + <module> can be a relative path within the Repository. + + <tag> in the above is the non-branch tag you placed earlier + that caused the error in your question. Be warned that + if <tag> is not set on all the files (or all the right + revisions) you won't get exactly what you wanted. + + Last modified: _6/13/1997_ + + 18. Why do I get the latest files on the branch when I tried to "update -r + <tag>"? + + If "update -r <tag>" always retrieves the latest files on a branch, + then <tag> is really a <branch_tag>. A branch tag is supposed to be + used to grab a branch to work on. Since you can't modify a file in the + middle of a branch, checking out a <branch_tag> will give you the + latest revision on the branch. + + If you want to "checkout" a specific collection of revisions, you must + use a "non-branch" tag. See the first part of 4C.16. + + Last modified: _6/13/1997_ + + 19. How can I avoid a merge? I just want to move the latest revision on my + working branch directly onto the trunk. + + There is no direct way to do this using CVS, though the technique is + not difficult using shell commands. Here's one way: + + Move your working directory to the Main Branch. + + cvs update -A + + Use "update -p" to grab the latest revision on the branch and write + it over your working files. Make sure you don't have an modified files + -- you will lose them. The following is in "csh" syntax. Change the + wildcard to grab the files you want + + foreach i (Makefile *.cc *.hh) + cvs update -p -r <branch_tag> $i > $i + end + + Commit all the working files onto the Main Branch. + + cvs commit -m 'Moved branch <branch_tag> onto MAIN' + + You should experiment with the above before blasting everything. + + Last modified: _6/13/1997_ + + 20. How to I avoid merge collisions in the RCS $\Log$ data? + + In short, you can't. The RCS $\Log$ keyword is handled differently + from all other RCS keywords. + + On the info-cvs mailing list, there is a periodic discussion that goes + something like this: + + Question: How do I deal with $\Log$? Answer1: You can't do much with + it. Here's how it works. . . Answer2: I've found a limited way to use + it. . . Answer3: Get rid of it. $\Log$ is an abomination. + + I tend to lean toward answer #3. There are only two sets of people who + would ever have access to logs stored within sources files, developers + and source customers. + + For developers: + + Log entries within sources files are notoriously incomplete, rushed, + poorly phrased and in many cases incorrect, making them useless for + debugging or file maintenance. I remember a maxim from "Software + Tools" (I believe): "Read the code, not the comments." No managerial + order or plan for programmer discipline will affect this in the real + world. + + Log entries are usually in an unreadable mixture of styles. Many log + entries are just plain meaningless. Some are foolish. Some are even + insulting. Examples: + + "Corrected spelling of misspelling." "Bug fix." "Reversed stupid + change in previous revisions." "If Joe could do his job, this would + already have worked." + + Log entries are not managed well by the tools. Any merge can cause + conflicts in the $\Log$ data. Branch merges produce incomplete logs. + They can be edited into chaos and they are not regenerated. They waste + space duplicating information available to the developer with a single + command. + + Even if correct when originally entered, as changes are made to the + file, log entries become false over time. Humans are not good at + reading down through a list and remembering only the last change + affecting something. Over time *most* of the log is wrong. + + Even if still correct, the log data is almost useless to developers + without the code diffs. If you can get code diffs, you can display the + log. + + For source customers the problem is even worse. The last thing you + want to show customers is a hodge-podge of tiny comments about large + changes followed by a series of emergency fixes before delivery. If + you distribute sources, then you should provide documentation, or + changelogs reviewed by people who won't let comments like "Fixed for + stupid customer." out the door. + + Conclusion: Though some people would prefer to see in this FAQ + techniques for making the $\Log$ entries the best they can be, I + believe them to be a lost cause. My suggestion is to hunt down, root + out and destroy all occurrences of $\Log$ and the unusable data + attached to it wherever you may find it. + + Last modified: _6/13/1997_ + + 21. Why should I trust automatic merges? + + Some developers have the feeling that three-way merging doesn't work. + They fear and distrust the way the "update" command automatically + merges committed changes from the Repository into the working file. + + Experience has shown that most merges are utterly painless and most of + the rest are easily resolved. The few conflicts that cause headaches + are nearly all due to poor communication between developers, a problem + no source control system can obviate. + + Some developers were troubled in the past by flaky Unix software. I + can't say that everything is perfect, but the tools CVS depends on + (RCS and diff, mainly) are fairly solid nowadays. They work. + + Since it does seem to work for most of us, the algorithm is unlikely + to change soon. Why not test it on a couple trouble spots and if it + works for you, use it for a while? Then you can make an informed + decision. + + Last modified: _6/13/1997_ + + 22. How does CVS decide if it can safely perform a merge? + + CVS can merge any text file, possibly discovering a conflict and + leaving overlaps for you to edit. Editing the conflict markers out of + the file is a moment's work, but resolving the conflict could take an + arbitrary amount of time. CVS works to determine if it *should* merge, + not if it *can*. + + See 2B.6 for how the merge proceeds. + + Last modified: _6/13/1997_ + + 23. After resolving merge conflicts in a file, what if I want to keep my + previous version, and not take any of the branch changes? + + If you want to retain your previous version, a version on the MAIN + branch greater than 1.1 (one you committed there), just throw the + merged file away and "cvs update" the file. + + You don't need to commit something to remember it. The tags you place + before and after the merge should give all the handles you need to + find various versions. You don't have to create a new version of the + file. + + If you want to retain the previous Vendor revision, you can grab a + copy of it using "cvs update -p" and commit it or use the technique + described in 3B.3 to revert back to the Vendor branch. + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/Engineering/ + + " + Engineering" + + 1. Where can I find out about Software Engineering? + + A couple different people suggested this book: + + Software Configuration Management: Coordination for Team Productivity; + Wayne A. Babich; Addison Wesley; 1986; ISBN 0-201-10161-0 + + A number of others suggested Appendix B of the book "Decline and Fall + of the American Programmer" by Ed Yourdon, called "The Programmer's + Bookshelf". It list 87 books you are expected to have read. Since they + publish many of the books, Prentice-Hall distributes this list as + "Prentice Hall Professional Technical reference PTR-125-AA3. + + One interesting item from the Yourdon book: The total number of + professional computer books sold is less than the number of + programmers currently in the United States. It wasn't clear from the + book whether this meant "per year" or not, but it is still + frightening. + + Last modified: _6/13/1997_ + + 2. How do I flexibly arrange the modules file to describe my sources? + + An equivalent question might be, "How do I structure my sources?" This + can be a difficult question especially in the areas that are more + political than technical. + + Generally you want to think about which pieces of your system need to + be checked out together, built as one system or tagged as a consistent + whole. You should certainly create module names that correspond to + complete, buildable collections that you would tag and release as one + "product". It is also convenient to create module names for small + sections of the Repository containing files that will all be worked on + at the same time by the same person or group. + + Once you have defined the structure of your work, you can usually see + how to lay it out in a Repository. After that the modules file is + easy. You set up module names and aliases to match what you need to + check out by name. If you like relative directories, it is possible, + but not recommended, to work completely without a modules file. See + 1D.11 and 2C.7 for some info about the modules file. + + Here are a few types of modules. You should experiment to see what + kind of structure each of these produces. They all have different + uses. + + Connected projects in one group with two separate helper + directories. The helper directories can contain build tools, header + files, libraries, or whatever you like. + + These are all aliases that checkout relative pathnames. The equivalent + results could be produced by placing the selected relative pathnames + on the "cvs checkout" command line. + + pr1 -a P1 HELPERS + pr2 -a P2 HELPERS + pr3 -a P3 HELPERS + pr12 -a P1 P2 HELPERS + pr13 -a P1 P3 HELPERS + pr23 -a P2 P3 HELPERS + + P1 -a group1/proj1 + P2 -a group1/proj2 + P3 -a group1/proj3 + HELPERS -a group1/helper1 group1/helper2 MAKEFILE + MAKEFILE -a group1/Makefile + + Actual Repository directory structure: (from $CVSROOT down) + + group1/ Makefile The top level Makefile. helper1/ helper2/ Helper + files and dirs proj1/ Files and dirs proj2/ Files and dirs proj3/ + Files and dirs + + "checkout group1" produces a duplicate of the above. "checkout projX" + produces all but "projY" and "projZ". "checkout projXY" produces all + but "projZ". + + Here is the exact same set of module names describing the same + Repository layout using module names (and aliases containing module + names) instead of merely aliases for relative pathnames. + + There is one difference in the result. The name of the top level + directory in the checked out working tree will match the "module" name + (e.g. pr1) instead of always being "group1" as it was in the first + example above. + + pr1 group1 proj1 &HELPERS + pr2 group1 proj2 &HELPERS + pr3 group1 proj3 &HELPERS + pr12 group1 proj1 proj2 &HELPERS + pr13 group1 proj1 proj3 &HELPERS + pr23 group1 proj2 proj3 &HELPERS + + HELPERS -a helper1 helper2 group1-Makefile + helper1 group1/helper1 + helper2 group1/helper2 + group1-Makefile -d . group1 Makefile + + The above line (with the -d in it) says that when the module named + "group1-Makefile" is checked out, the file named Makefile file will be + found in a directory named $CVSROOT/group1 and will be checked out + into a directory named '.', which obviously already exists. + + The & references say to interpret those pathnames relative to the + directory where the whole module is stored. For the "pr1" module, that + directory is "group1", so the &HELPERS reference winds up placing + Makefile in '.' relative to "group1". + + A short one containing the basic "module" actions: + + m1 head/path file1 dir2 file3 dir4 file5 + + When checked out, a directory named "m1" appears in your current + directory. Elements named file1, dir2, file3, dir4, and file5 appear + in it. They were originally taken as relative paths from + $CVSROOT/head/path. + + Here's another way to construct a working directory out of pieces of + the Repository: + + projX projX Makefile &projX_inc &projX_src &projX_doc + + # The first line selects a single file within projX, plus + # the contents of three other modules. Those three other + # modules rename their directories. + + projX_inc -d include projX/inc projX_src -d source projX/src projX_doc + -d documentation projX/doc + + A Unix tree. This is similar to what CVS was developed for and the + way I have used it for years. + + # Top level + unix unix + u_bin unix/bin + u_etc unix/etc + u_man unix/man + usr-bin unix/usr.bin + + # Subdirs of top level dirs. (tiny subset) + ls unix/bin/ls + fsck unix/etc/fsck + man8 unix/man/man8 + + # Programs without subdirs. (tiny subset) + cat unix/bin Makefile cat.c + uniq unix/usr.bin Makefile uniq.c + + # /usr/local/src + localsrc localsrc + gnu localsrc/gnu + public localsrc/public + X11 localsrc/X11 + + # GNU and PD tools + cvs localsrc/gnu/cvs + emacs localsrc/gnu/emacs + rcs localsrc/gnu/rcs + btoa localsrc/public/btoa + tcsh localsrc/public/tcsh + + # X11 related items. + tvtwm localsrc/X11/contrib/tvtwm + + "unix" was checked out and built from the top down, using a set of + Makefiles that knew about the whole structure. "localsrc" was kept + checked out in /usr/local/src. + + At any time I could run "checkout ls" or "checkout cat" and get a + simple directory with only that tool in it, plus a subset Makefile + that knew how to build that tool against the installed (or alternate, + via environment variables) headers and libraries. + + I found it very handy to be able to run "ls" and see the three tools I + was porting that week. + + Last modified: _6/13/1997_ + + 3. Can I have multiple source repositories, one for each project? + + Yes, you can have as many Repositories as you like. But each + Repository must be managed separately, creating additional work. + + Question 4A.1 provides a short description of setting up a single + Repository. A few additional considerations: + + It is a good idea to start by creating a single Repository and split + it up (or create additional Repositories) only if you believe it is + really necessary. I would only create a new Repository if the data is + completely disconnected from the rest of the main Repository. + + If there is a lot of overlap among the developers working on the + collections of files you want to place in different Repositories, or + if there is any connection between those collections, I would go out + of my way to create a single Repository. It is much easier to manage. + + Disk space should not be a factor since you can build up a + Repository using symbolic links and/or remote mounts. + + Each Repository is completely distinct. You can't check out modules + from different Repositories at the same time. A better way of looking + at it is that if you *can* check out two modules or directories with a + single "checkout" command (without contortions or explicit absolute + pathnames), then they are in the same Repository. + + To "checkout" modules from multiple Repositories, you must use the + "cvs -d" option on all CVS commands or alter your $CVSROOT variable + when you change focus to another Repository. If you work with multiple + Repositories, it is a good idea to configure CVS to use absolute + pathnames in the ./CVS/Repository file, since most commands (other + than "checkout") will use that file rather than $CVSROOT. + + If you configure CVS to use relative pathnames in your + ./CVS/Repository files, you must always be careful to set your + $CVSROOT properly or you will get unexpected results. + + If you have two modules or directories by the same name at the same + relative path inside two different Repositories, you are asking for + disaster. You could unexpectedly update a directory with completely + unrelated files. This is not a fanciful example -- a Repository is + occasionally duplicated for release purposes in which case *all* the + paths in the two Repositories are the same. + + Last modified: _6/13/1997_ + + 4. Who should administer the Repository and manage the modules file? + + This is a "management style" question. In large or traditional groups, + the CVS procedures are warped to conform to local conventions. In + small groups, in groups with strong personalities or on new projects + the choice of source control procedures can help create some of the + working environment. Here is a taxonomy of environments I have worked + in or helped set up: + + Situation 1. + + A small number of competent developers working on a medium size + project. We all got along and we all respected each other (at least + technically). Anyone edited anything. + + Modules and Repository admin was mostly left to me. I never found a + problem in minor changes made by anyone else. + + Situation 2. + + A large number of experienced developers sprinkled with wackos. Many + of the developers didn't want to deal with any kind of source control. + They wanted a full-service source control system that caused them zero + thought. + + I learned "big stick" diplomacy here. There was a small number of + "designated" (by me) people who were allowed to do *anything* other + than "update" and "commit". Even "checkouts" were controlled. This is + where I found "history" and "release" the most useful. + + Situation 3. + + A small number of developers who wanted me to "help", but who didn't + want to deal with anything other than their favorite algorithms. + + I didn't have the time to baby-sit this group, so I designated one of + them to be my official contact and made him do it all. He felt sullied + by the requirement to pay attention to anything other than his pet + coding projects, but enjoyed the "status" of being the only one who + could touch the control files without my kicking the chair out from + under him. + + Situation 4. + + A huge number of developers of covering the whole spectrum of + competence and experience split into 20 groups, none of which + cooperated with the others, working on 57 different projects, most of + which didn't inter-operate. + + Managing it in any coherent way was not my responsibility (and beyond + my tolerance for chaos). Too many people. So I privately designated a + person in each group to be the contact and kept watch on the + Repository activity. When something went wrong, I notified the contact + for the group and told him what was happening and *he* kept his troops + in line. They were tougher with their own group that I would have + been. + + Eventually only a few people were willing to touch the control files, + since they were flamed from all directions if they screwed up. + + Situation 5. + + In a medium group of really *serious*, and seriously overworked, + people, someone else was designated the "master". I convinced the + master I knew what I was doing and went on my way. + + No one else in the world was allowed to touch anything. + + Situation 6. + + In a large amorphous group of beginners, experts and clowns, over whom + no one had official control, I was forced to employ a group of + relative beginners (who became experts rather quickly) to police the + world. The ultimate in locking the barn after the horse was stolen, we + kept Chaos from destroying us only by use of superior firepower. + + My choice, if allowed, is to let anyone touch anything. I keep backups + of important items and let people know individually whether I want + them to touch things or not. If someone on my "no touch" list touches + and succeeds, they are allowed more slack. If they screw up after + being warned, their screwup becomes public. After a few months, I + usually have no trouble keeping the world running smoothly, at least + from my (and CVS's) perspective. + + Last modified: _6/13/1997_ + + 5. Isn't disk space a big factor? CVS copies files out of the Repository, + duplicating everything. + + Everyone knows that disk space is getting cheaper. How do we reconcile + this with the equally well-known problem that *all* disk is *always* + filled up? + + In my opinion, the main reason disk space will never be an unlimited + resource is that it is the major variable in organizational time/space + tradeoffs. It isn't a problem of waste or an aspect of Murphy's law, + as some claim it is, but rather a direct consequence of good + management. Disk space is, and will always be, a limited resource. + + First, the cost of *deploying* that disk is not dropping as fast as + the cost of the storage medium. The cost of machines to hold the disks + and the networks to connect them are dropping more slowly than disk + media. And the cost of the human time necessary to manage the + machines, networks, disks, and the developers using them, is not + dropping at all. The cost of human time continues to rise. + + If management decides that expensive human time can be saved by using + all that new disk space to keep the last three releases online, then + that's what it will be used for. If each release takes up a Gigabyte + and you support 30 platforms, a simple time-saving suggestion has just + grabbed 100 Gigabytes of disk space. And we've ignored the potential + disk storage needed to support "better Customer Service", another + management refrain. + + Even at 30 cents per Megabyte (next year's price), you've just used up + $30,000 of disk space. And that doesn't count the computers, tape + drives and humans necessary to maintain and deploy all of it. Spending + money to save time has its own overhead, too. + + Binaries are getting bigger. Graphics and data collection devices can + eat up any amount of disk. There are more tools available, more + libraries, more raw data than you can ever store. My home computer has + a Gigabyte of disk on it. It could easily handle 30. + + The "economy" of disk storage media will never remove the need to + manage disk space. + + 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. + + 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> + + #!/bin/csh -f + set f = $1 + if (! -l $f) then + echo "file $f is not a symlink" + exit 1 + endif + rm $f + set rev = `grep "^/$f/" CVS/Entries | awk -F/ '{print $3}'` + cvs update -p -r $rev $f > $f + + You can't do a plain "cvs update" since that would grab newer + revisions from the Repository, not the revision you wanted to start + with. After the file is no longer a symlink, you can work normally. + 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: + + ./<file> is a symlink. + + ./CVS/Entries says you are revision 1.2. + + The corresponding CVS/Entries file in /master/build says the latest + revision is 1.3. + + cvs update <file> shows a 'C' conflict flag. + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/Installing_CVS/ + + " + Installing CVS" + + 1. What do I have to do before I install CVS? + + You must decide where to set up a Repository. + + Though you can construct a Repository tree structure using links and + mount points, there must be a single copy of each real file across + your entire organization. You may not "rdist" files and expect to edit + both copies. + + CVS does not support a truly distributed Repository. You can have + multiple Repositories, but each one must be mounted (not copied or + "rdist"ed) from a single place onto all machines where it will be + used. + + Initially, a Repository takes about same amount of disk space as the + sources you want to put into it, plus a bit of overhead for the RCS + files. + + See Section 4B. For multiple Repositories, see 4G.3 + + You need a directory in everyone's $PATH variable where you can + install all the executables. /usr/local/bin is a common place. + + You need some helper tools besides CVS such as "RCS" and a good set + of "diff" and "diff3" programs. See 1B.4 for suggestions. + + Read the README, INSTALL and ChangeLog files to see what you are + getting into. + + Make sure you have versions of all the programs mentioned in the + "cvs/src/options.h" and "cvs/src/rcs.h" files. + + Though you can probably muddle along without it, you should appoint + one or more "Repository Administrators" who will be responsible for + maintaining the Repository structure, administrative files and the + "modules" interface. + + Someone at your site should probably be on the info-cvs mailing list. + See 1B.5. + + Last modified: _6/13/1997_ + + 2. How do I configure the CVS programs? + + You should certainly start by reading the README file, the INSTALL + files and possibly the ChangeLogs in each directory, the Makefile.in + files and the "cvsinit.sh" program. + + Edit the "options.h" file in the "src" directory. + + You might need to specify a few site-specific pieces of information + including the names of a number of functions. + + Hint1: You probably want to set the DIFF macro to use your version of + the GNU diff program with the '-a' option. Ours is set to "gdiff -a". + + Hint2: You want to use RCS 5.6.0.1 or greater and set the "HAVE_RCS5" + macro. + + Execute the ./configure command. + + Type "make". + + After running "make" you might try running the "sanity.sh" script: + ./src/sanity.sh `pwd`/src/cvs + + It writes into /tmp/cvs-sanity by default. + + Finish reading the INSTALL file and test out the system. + + Last modified: _6/13/1997_ + + 3. What do I have to install? + + Install the "cvs" executable and "mkmodules" from the CVS sources. + The man page is useful too. If you plan to report bugs, you should + also install "cvsbug". + + Make sure you have versions of all the programs mentioned in the + options.h file, most of which are included in a standard Unix system. + + Unless you plan to reimplement RCS [:-)], you must install RCS. + + It is a very good idea to examine the RCS installation instructions + and make sure you are using the GNU versions of "diff" and "diff3" or + merges (an important part of CVS) will not work as well as you'd like. + + Set your $CVSROOT environment variable and create the Repository + (which you planned out in 4A.1) with the "cvsinit" command at the top + of the CVS sources. + + You'll need to edit the Repository control files created by + "cvsinit". + + Install any helper programs mentioned in the modules file. + + Last modified: _6/13/1997_ + + 4. How do I work around the merge problems in GNU diff version 2.1 or + later? + + See 1B.4 If you use recent versions of RCS and "diff", you won't run + into the above. If you do, see 5B.8 + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/Internal_errors/ + + " + Internal errors" + + 1. Explain: "ci error: unexpected EOF in diff output" + + 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. + + The solution is to upgrade to RCS 5.5 or later. (Of course, this won't + fix filesystem failures. It will merely allow RCS (and therefore CVS) + to handle the file without error.) + + Last modified: _6/13/1997_ + + 2. Explain: "RCS file /Repository/module/file.c,v is in use" + + This is an RCS error that occurs when its internal lock file has been + left around by an RCS command interrupted by some sort of system + crash, disk failure or SIGKILL signal. + + Go into the Repository and look for files with names similar to + "file.c,v", usually starting with ',', '_' or '#'. Make sure they are + really crash remnants and do not belong to transactions in progress -- + a recent last-modified timestamp is a good indicator of a live + transaction. Delete them if they are old. + + Last modified: _6/13/1997_ + + 3. Explain: "co error, line 2: Missing access list" + + This is an error message from RCS Version 3 when it tries to read a + file created by a later version of RCS. + + HP decided to "standardize" on an ancient version of RCS some time + ago. You can't use it for CVS. See 4H.6. + + Since the error comes from having a later version of RCS than HP + supports, you probably did install the later version but must have + recently changed your $PATH or installed the HP package that has RCS + in it. + + You should either reconfigure CVS to use absolute pathnames to the + proper versions of the RCS programs that CVS uses, or change your PATH + to look there first. If you haven't installed the latest version of + RCS, you should upgrade. See 1B.4 + + Last modified: _6/13/1997_ + + 4. Explain: "error: RCS file name `xyz .c' contains white space" + + RCS 5.6 doesn't allow white space in filenames. Apparently this + restriction will be removed in RCS 5.7, but CVS may still require that + filenames have no white space in them. + + Last modified: _6/13/1997_ + + 5. Explain: cvs checkout: warning: <X> is not (any longer) pertinent + + This message occurs in three instances: + + When there is an entry in the ./CVS/Entries for file <X> and there + is no RCS file in the Repository to back it up. + + If the working file exists, and hasn't changed (determined from the + timestamp) it is removed. + + When you try to check out a piece of the Repository with: + + cvs checkout some/place/in/repository/tree + + and at least the first element of the path (i.e. "some" in the above) + exists, but some part of the rest of it does not. + + The checkout command checks the modules file first for the whole path, + then for a prefix of the path as a module name. If it doesn't find + *any* portion of your path in the modules file, it says: + + cvs checkout: cannot find module `<module/path>' - ignored + + If it finds some set of prefix directories, it prints the message you + see. + + In practice this is usually a spelling error. + + If the Repository files you are trying to check out or update are + not readable by you, the same problems can occur. Check the + permissions on the files involved. + + Last modified: _6/13/1997_ + + 6. Why did a Repository file change from <file>,v to ,<file>,? + + This is an RCS problem, since the ,<file>, syntax for file names is + used by RCS and not CVS. + + RCS constructs a new <file>,v in a temporary file named ,<file>, + (which doubles as a lock file) then renames it to <file>,v when it is + done. The only way this is reliable is if your system's version of + rename(2) is an atomic, as required by POSIX. + + If your system has a non-atomic (and therefore non-POSIX) rename(2) + system call, RCS runs uses an internal version of this algorithm to + approximate the atomic rename: + + rm <file>,v; ln ,<file>, <file>,v; rm ,<file>, + + If the system crashes, or you lose your NFS connection between the + first "rm", but before the "ln", you can be left only with the + ,<file>, file. If the crash or network failure occurs between the "ln" + and the final "rm", you could be left with a pair of linked names. + + 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. + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/Other_Systems/ + + " + Other Systems" + + 1. I use a NeXT. Is there anything I need to know? + + NeXTSTEP 3.0's Interface Builder uses "nib" directories, rather than + the files used in previous revisions. It removes files it doesn't + recognize, making it impossible to place such a directory under CVS -- + the CVS admin directory will be removed. + + Some time ago, <Bob_Vadnais@pdh.com> posted a palette named CVSPalette + that claimed to resolve this problem. It was intended to preserve the + CVS administrative directories within nib documents (directories) that + Interface Builder usually removes. + + CVSPalette is no longer in its announced place: + + ftp.cs.orst.edu:/pub/next/submissions + + though I did find two other interesting files on ftp.cs.orst.edu: + + /software/NeXT/sources/tools/cvs-next-2_1_1.tar.Z + + which is a port of CVS 1.3 (along with RCS and diff) and: + + /software/NeXT/sources/programming/cvs.postamble-2.4.gz + + which appears to be a set of wrappers for CVS commands that claim to + allow you to use CVS effectively (and without need for the "command + line") on a NeXT machine. + + [[Anyone know the truth about CVS and NeXT?]] + + Last modified: _6/13/1997_ + + 2. I use OS/2 and/or DOS and/or Windows. Is there anything I need to know? + + When using a local repository, be sure to specify the local access + method or CVS will interpret the drive letter as a remote host name + due to the : following it: + + WRONG: CVSROOT=C:\SRC\CVSROOT + + RIGHT: CVSROOT=:local:C:\SRC\CVSROOT + + (larry.jones@sdrc.com) + + You can share RCS files between Unix and DOS while avoiding the MS-DOS + file name limits by setting your RCSINIT environment variable to + '-x/,v'. New RCS files will be created without the standard ",v" + suffix, though files ending in ",v" will still be found if there is no + matching file in the same directory without the ",v". + + Erik van Linstee offers an OS/2 and a DOS port of CVS 1.3 in: + + ftp.informatik.tu-muenchen.de:/pub/comp/os/os2/gnu/devtools or + ftp.rrzn.uni-hannover.de:/pub/os2-local + + The files are named: + + cvs13p?[bs].zip + + Where the ? stands for the patch level (currently 8) and the b is for + the binaries, the s for the sources. + + There are three binaries. An OS/2 only one (32-bit), a DOS only one + (16-bit) and an EMX one that runs on both (32-bit). + + There are many differences between the Unix and the DOS versions of + CVS. Read the material that comes with the DOS version before using + it. + + [[Updates?]]. + + Last modified: _9/22/1997_ + + 3. I use SCO Unix. Is there anything I need to know? + + On SCO/UNIX 3.2 V2.0 POSIX signals don't work. Unfortunately the + configure program detects POSIXness and configures in the use of POSIX + signals. Workaround : Edit out the check for POSIXness in the + configure script. [[You could also remove all occurrences of + "-DPOSIX=1" from the Makefiles after configure is run. -dgg-]] + + SCO/UNIX doesn't understand #!/<some shell> syntax. This breaks the + use of log.pl as it gets invoked by /bin/sh instead of + !#/usr/local/bin/perl. WorkAround : edit log.pl and change it into a + shell script which invokes perl with log.perl (renamed from log.pl) as + input. + Contributed by Joe Drumgoole + + Last modified: _6/13/1997_ + + 4. I use AIX. Is there anything I need to know? + + The only report on AIX claims to have no trouble using it in concert + with SunOS and IRIX platforms. + + Last modified: _6/13/1997_ + + 5. I use IRIX. Is there anything I need to know? + + If you see "uid" numbers where you would expect user names, try adding + -lsun to the link line. Without it CVS is unable to retrieve "passwd" + data through NIS. + + Last modified: _6/13/1997_ + + 6. I use an HP system. Is there anything I need to know? + + HP distributes RCS version 3 (a circa 1983 release!) with HP-UX. CVS + does not work with RCS version 3; it requires RCS version 4 or later. + Your best bet is to find the latest version of RCS and install it + somewhere. + + HP-UX 8.07 has a serious bug with the mmap system call and NFS files; + the bug can crash the operating system. Make sure that you configure + RCS to avoid mmap by setting has_mmap to 0 in RCS's conf.h. This bug + is fixed in HP-UX 9. + + Contributed by Paul Eggert + + If using the setgid() trick described in 4D.13, you will have to + create an entry in the /etc/privgroup file to give the group assigned + to the cvs executable setgid permission (see setprivgrp(1m)). + Additionally, if you are restricting "read" access to the Repository + by limiting access to the executable (this requires yet another + group), then you will require that /etc/logingroup exists and is + configured correctly (usually it's just alink to /etc/group). + + Contributed by Dale Woolridge + + Last modified: _6/13/1997_ + + 7. I use AFS. Is there anything I need to know? + + There is a problem with the way CVS performs its locking when the + files are within AFS. When your current PTS id != your uid, the locks + are not deleted. The stat() system call returns the PTS id of the + owner. If that id != your uid, CVS assumes you did not lock it, and + leaves the lock files alone. The next time you try to use it, it + complains that someone has the repository locked. + + Contributed by Michael Ganzberger + + [[This was against CVS 1.3. Is it still in CVS 1.4?]] + + Last modified: _6/13/1997_ + + 8. I use A/UX. Is there anything I need to know? + + [[??]] + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/Related_Software/ + + " + Related Software" + + 1. How do I use CVS under Emacs? Is there an Emacs cvs-mode? + + The pcl-cvs package distributed with CVS is an emacs package that + helps with the update/commit process. When you are ready to update, + you use the 'cvs-update' command within emacs. This executes "update" + and fills a cvs-mode buffer with a line for each file that changed. + The most helpful features are: descriptive words for what happened + (i.e. Merged or Conflict rather than 'U' or 'C'), single keys bound to + diffs and commits, and the ability to mark arbitrary groups of files, + possibly from different directories, for commit as a whole. + + All the developers in my group that use emacs find pcl-cvs a much + friendlier and more helpful way to update/commit than raw cvs. One vi + user even converted to emacs just to use pcl-cvs. + + Contributed by Jeffrey M Loomis + + Last modified: _6/13/1997_ + + 2. What is GIC (Graphical Interface to CVS)? + + + + + GIC provides a graphical user interface to the Concurrent Version + System (CVS), a powerful revision control system. GIC is + implemented in the Tcl/Tk programming language and is intended to + augment the sometimes cumbersome CVS command line interface. + + Note that according to the official GIC page at + http://www.cpsc.ucalgary.ca/redirect/grouplab/projects/gic/ + GIC is no longer being maintained and tkCVS is recommended + instead. For more on tkCVS, see http://www.cyclic.com/tkcvs/ + + kingdon@cyclic.com + + Last modified: _9/6/1997_ + + 3. What is CAVEMAN? + + 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. + - Extra before and after program hooks. + - A layer of event logging. + - All sorts of error messages. + - Many changes to the semantics of commands. + + It is available via anonymous ftp on ftp.llnl.gov [128.115.54.18] in + gnu/caveman_vX.Y.Z.tar.gz (The numbers X, Y, & Z vary.) + + contact Kathleen Dyer kdyer@llnl.gov + (510)423-6803 + (510)423-5112 FAX + + [[Does someone want to elaborate?]] + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/Setting_up_and_Manag/ + + " + Setting up and Managing the Repository" + + 1. What do I do first? How do I create a Repository? + + 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. + + 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. + + 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 + module name. Here's a short list that could be used for storing a + small number of GNU and PD sources: + + local local + + gnu local/gnu + emacs local/gnu/emacs + cvs local/gnu/cvs + + public local/public + pdprog1 local/public/pdprog1 + pdprog2 local/public/pdprog2 + + 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. + + Last modified: _11/7/1997_ + + 2. What are those files in $CVSROOT/CVSROOT? + + There are eight Repository control (or "database") files of interest + in the CVSROOT directory: + + modules contains the "modules" database. See 1D.11, 2C.7, 4B.6 and + 4B.7 for more details. + + commitinfo contains two columns: 1. a regular expression to match + against pathnames within the Repository and + + a <command> to execute for matching pathnames. + + When you execute "commit", CVS passes the Repository pathname for each + directory (and the files to commit within that directory) to + <command>. If <command> exits with a non-zero status, the commit is + blocked. + + A <command> associated with a pathname of "DEFAULT" is executed if + nothing else matches. Every <command> associated with a pathname of + "ALL" is executed separately. + + rcsinfo contains the same first column as commitinfo, but the second + column is a template file for specifying the log entry you are + required to enter for each commit. + + "DEFAULT" and "ALL" work the same as in the commitinfo file. + + editinfo contains the same two columns as commitinfo, but the + <command> in the second column is intended to do some consistency + checking on the commit log. + + "DEFAULT" works as in commitinfo. + + loginfo contains the same two columns as commitinfo, but the + <command> is expected to read a log message from its standard input. + The <command> can do anything it wants with the log information, but + normally it is appended to a log file or sent to mailing lists. + + "DEFAULT" & "ALL" work the same as in commitinfo. + + cvsignore contains "ignore" patterns that are added to the built-in + ignore list. See 2D.10. + + checkoutlist contains a list of other files kept under RCS in + $CVSROOT/CVSROOT that should be checked out by mkmodules to provide a + readable copy. + + history contains a stream of text records, one for each event that + the "history" command is interested in. Though the contents of the + history file can be read, it is intended to be read and displayed by + the "history" command. This file is the only one in the above list + that is not under RCS. + + Last modified: _6/13/1997_ + + 3. Is there any other state stored in the Repository besides in the + $CVSROOT/CVSROOT directory? + + Only in the RCS files. The Repository holds exactly two things: the + tree of RCS files (each usually ending in ",v") and the CVSROOT + directory described above. + + Last modified: _6/13/1997_ + + 4. How do I put sources into the Repository? + + There are three main ways to put files in the Repository: + + Use the "import" command described in Section 3H. + + This method is the fastest way to put trees of new code into the + Repository and the *only* way to handle source releases from a 3rd + party software vendor. + + Use "add" followed by "commit". + + This is how to add new files and directories to the Repository, a few + at a time. Directories don't need to be committed. + + You can move RCS files directly into the Repository. + + You should create a directory hierarchy to hold them, but you can just + move arbitrary ",v" files into the Repository. The only "state" in the + Repository other than within ",v" files is in the required CVSROOT + directory at the top of the Repository. + + Last modified: _6/13/1997_ + + 5. What file permissions should I use on (and in) the Repository? + + 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 + filesystems, you might have to set the permissions to 2775.) + + 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> + + + - 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 + their "umask" to something reasonable, you might want to set the umask + for them: + + mv /usr/local/bin/cvs /usr/local/bin/cvs.real + cat > /usr/local/bin/cvs + #!/bin/sh + umask 2 # Or whatever your site standard is. + exec /usr/local/bin/cvs.real ${1+"$@"} + ^D + + Last modified: _6/13/1997_ + + 6. How do I structure my Repository? + + The Repository holds your software. It can be all interrelated or it + can be a bunch of separately managed directories. + + How you break a whole system down into its component parts, while + defining interfaces between them, is one aspect of "Software + Engineering", a discipline that requires the study of dozens of + strange and wonderful areas of the computer and management worlds. + + CVS provides a way to keep track of changes to individual files, a way + to "tag" collections of files, and a way to "name" collections of + files and directories. That's all. Everything else is in the way you + apply it. + + In other words, you should structure your Repository to match your + 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. + - check out multiple sections in a fixed relation to each other. + - check out large sections to match the assumptions built into your + build system. (Makefiles?) + + In my opinion, you should start small and keep everything in one tree, + placing each major sub-system into a separate directory. Later, when + you know what you are doing, you can make it more sophisticated. + + Last modified: _6/13/1997_ + + 7. Why would anyone use "modules"? They are too restrictive. I want to be + able to select just the files I want to edit. + + Any form of structure is restrictive. If you believe that total chaos + is a viable working paradigm, or if you believe you can keep track of + the interrelations between all portions of your Repository in your + head, then you can do what you please. + + If you believe that systems of files require management and structure, + then the "modules" idea is very useful. It is a way to impose a naming + scheme on a tree of files, a naming scheme that can be simpler than a + large list of relative pathnames. + + The "modules" file represents a published interface to the Repository + set up by your Repository Administrator. If s/he did a creditable job, + the modules offered will be internally consistent and will smoothly + interact with the rest of your environment. + + Last modified: _6/13/1997_ + + 8. How do I rename a file or directory? What are the consequences? + + In CVS there is no single "rename" command. + + See 2C.4 for the suggested way to rename a file or directory. + + The rest of this section covers some of the consequences of renaming. + + A "renaming database" has been proposed that would keep track of name + changes so that "update -r <tag>" would continue to work across the + renaming. But as it stands, you have to pick one of the following + options: + + Use the technique described in 2C.4. (For each file, duplicate the + file in the Repository, "remove" the old version so it winds up in the + Attic and strip all Tags off the new version.) + + - "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. + + This is not a good general solution, but if you plan never to look + back (someone may be gaining on you!), it is sometimes a useful + notion. + + If you are clever with Makefiles, you might be able to rework them to + handle either the new or old names, depending on which ones exist at + the time. Then you can move an old <tag> onto the new, more + 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 + file within each of the moved directories. + + The easiest way to move a lot of directories around is to tell + 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: + + cvs update: xyz.c is no longer in the repository + + and deletes the file. If the file was modified, "update" prints: + + cvs update: conflict: xyz.c is modified but no longer in the + repository C xyz.c + + and leaves the file alone. In the new directory, you see: + + U xyz.c + + as you would if someone else executed "add" and "commit". + + For each file, copy the working file to a new name in the working + directory and use the "cvs remove" to get rid of the old old file and + "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. + + Last modified: _6/13/1997_ + + 9. What are "Attic" directories? + + When you use the "remove" command on a file, CVS doesn't delete the + file, it only registers your desire to delete it. + + When you "commit" a removed file, CVS moves the Repository's matching + RCS file into a sub-directory named "Attic" within the Repository. + + Attic files are examined when the '-r' or '-D' option is used on + "checkout" or "update". If the specified revision, tag or date matches + one on a file in the Attic, that file is checked out with the others. + + You can think of the Attic as a sort of dead branch, which is only + looked at when you refer to a <tag> or <date>. + + Last modified: _6/13/1997_ + + 10. Is it OK to remove anything from the Repository? + + In general, removing anything from the Repository is a bad idea. The + information in a deleted object is lost forever. There are many ways + to skip over files, directories and revisions without deleting them. + + Here are some of the consequences of removing the following things + stored in the Repository: + + CVSROOT files (Repository control files) + + The Repository will work without any of them, but you should + understand what you are losing by deleting them. See 4B.2. + + Revisions + + The only way to remove revisions is to use the "admin -o" command (or + the equivalent RCS command "rcs -o"). + + They are lost forever. Any tags formerly attached to deleted revisions + are now pointing into the Phantom Zone. You'll need to contact Jor-el + to get them back. + + Files + + You should not remove a file unless you truly never want to see it + again. If you want to be able to check out an old revision of this + file, use "cvs remove" instead. + + Tags + + Tags take up little space and you can't recover from deleting them. If + you depend on tags for releases you will lose vital information. + + Directories + + There is no Attic for directories, so the only way to remove them is + to use "rm -r". They are gone forever. + + If you delete (or move) a directory, all checked-out versions of that + directory will cause CVS to halt. You'll have to visit each + checked-out directory and remove the matching working directory by + hand. + + Attic files + + The "remove" command sends files to the Attic. To really delete them, + you have to go into the Attic and use "rm". + + If a file in the Attic has a Tag on it that you might ever want to + check out again, you probably don't want to delete it. + + Lock files (named: "#cvs.[wr]fl.<pid>") + + These are lock files. If you are getting "lock" errors and the dates + on the lock files indicate that they are old, you can delete them. + + Deleting lock files still in use by a CVS process might produce + unusual errors. + + Last modified: _6/13/1997_ + + 11. Can I convert to CVS from RCS without losing my revision history? + + Yes, you can simply move (or copy) your RCS files into a directory + within the Repository, check out that directory and start working. + + Last modified: _6/13/1997_ + + 12. Can I move RCS files with branches in them into the Repository? + + Yes, but they may not work if you created branches in a way that + conflicts with CVS's assumptions: + + You can't use .0. branches. (They are reserved for "Magic" branch + tags.) + + If you use branch 1.1.1, you can't use the Vendor branch. + + You can use other RCS branches under CVS. There is no need to create + "magic" branch tags because the physical branch already exists. + + Last modified: _6/13/1997_ + + 13. Can I use raw RCS commands on the Repository? + + You can use raw rcs commands directly on the Repository if you take a + little care. The Repository itself contains no "CVS state" (as opposed + to RCS revision histories) outside the CVSROOT directory. + + But using raw RCS commands to change branches, tags or other things + that CVS depends on may render the files unusable. + + See 4D.7 on RCS/CVS sharing of the Repository and Section 3B on the + "admin" command. + + Last modified: _6/13/1997_ + + 14. How do I convert from SCCS to RCS? + + You'll have to execute something like "sccs2rcs" (in the CVS contrib + directory) on every file. Then you can move the resulting RCS files + into the Repository as described above. + + Last modified: _6/13/1997_ + + 15. How do I limit access to the Repository? + + There are all sorts of ways to restrict access to Repository files, + none of which are hooked directly into CVS. + + Techniques for limiting access include: + + Training, management and good backups. + + 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. + - Effective management of the boundaries and grey areas. + + In many cases, technical solutions to "security" problems are + inadequate. You should first try to avoid them. + + Personal Opinion: In an environment where "unknowns" are allowed to + touch important sources the "owner" of the CVS Repository must be a + large, loud, vigorous lout with a well-balanced truncheon and the + right to use it. Don't underestimate the effectiveness of letting + everyone know they will be strapped into the stocks on the Town Common + and pelted with vegetables if they break something they don't + understand without first asking the experts. + + Set Unix groups and permissions. See 4B.5. You can set different + owners, groups and permissions for each sub-directory within the + Repository if that helps. + + Catch invocations of "commit" by defining pre-commit programs in the + "commitinfo" file. This is fairly powerful, since it can block commits + based on anything you can program. Take a look at the programs in the + "contrib" directory of the CVS source tree. + + Use multiple Repositories, each with its own protection scheme. If + you use NFS (or AFS) you can even use "export" restrictions to various + groups of machines to keep (for example) the Engineering Repository + off the Customer Service machines. + + Try the "setgid" trick described in 4D.13. + + Try to use the RCS access control lists, though I don't think CVS + will handle them cleanly. + + Edit the source code to CVS to add your own access control. + + Last modified: _6/13/1997_ + + 16. What are the Repository Administrator's responsibilities? + + Generally, the Administrator should set "policy", create the + Repository and monitor its size and control files. + + Some specific responsibilities include: + + Examining the Repository once in a while to clean up: + + Trash files left by misguided developers who mistake the Repository + for a working directory. + + Non-RCS files. Other than the files CVS needs in the + $CVSROOT/CVSROOT directory, every file in the Repository should be an + RCS file. + + Lock files (both CVS '#*' and RCS ',*' files) left around after + crashes. + + Wrong permissions, groups and ownerships. + + Locked files. (RCS locks, that is.) + + Attic files that should never have been under CVS at all. Don't + blindly delete files from Attic directories -- they were mostly put + there (via the "cvs remove") for a reason. Files that should be + deleted are binary files (e.g. '*.o', 'core', executables) that were + mistakenly inserted by "import -I !". + + Maintaining the modules file. + + Storing site-specific ignore patterns in the + $CVSROOT/CVSROOT/cvsignore file. + + Storing the names of non-standard CVSROOT files (See 4B.2) in the + $CVSROOT/CVSROOT/checkoutlist + + Maintaining the other Repository control files: commitinfo, loginfo, + rcsinfo and editinfo. + + Pruning the history file every once in a while. (Try the + "cln_hist.pl" script in the "contrib" directory.) + + Staying aware of developments on the info-cvs mailing list and what + is available in the FTP and WWW archives. + + Running "ps ax" once in a while and kill off any "update" programs + not running as "root". It is too easy to leave the "cvs" off the front + of the "cvs update" command. + + Executing monitor programs to check the internal consistency of the + Repository files. Ideas: + + Files that have a default RCS branch that is not 1.1.1 (From an + abuse of "admin -b".) + + Files that have only Revisions 1.1 and 1.1.1.1, with a default + branch of "MAIN". (From an abuse of "admin -o".) + + Existing branch tags and various branch consistency checks. + + Last modified: _6/13/1997_ + + 17. How do I move the whole Repository? + + Copy or move the tree. (On Unix systems, a set of piped "tar" commands + works great. If the Repository does not contain any symlinks, which it + normally doesn't, you can also use "cp -r".) + + If you can avoid changing $CVSROOT (i.e. the "logical" pathname of the + Repository) by replacing the old location with a symbolic link to the + new location, you don't have to do anything else. + + (You could also mount the new location on top of the old location if + you are using NFS or some other filesystem that allows it.) + + If you must change $CVSROOT, you must also tell everyone to change the + CVSROOT environment variable in all running shells and in any personal + configuration files ('.' files on Unix) where it is set. + + The Repository itself contains no references to its own name, except + possibly in some of the files in the CVSROOT directory. If your + modules (or loginfo, commitinfo, etc.) file mentions helper programs + directly in the Repository, you'll have to change the pathnames to + point to the new Repository location. + + The main changes you'll have to make are to all the CVS administrative + files (./CVS/Repository and ./CVS/Root) in every working directory + ever checked out from the previous location of the Repository you just + moved. + + You have three choices: + + If all ./CVS/Repository files in all working directories contain + relative pathnames, you don't have to do anything else. + + Have everyone "release" or delete their working directories (after + committing, or just saving, their work) and check them all out again + from the new Repository after the move. + + Use "find . ( -name Repository -o -name Root )" and a PERL or shell + script to run through all the ./CVS/Repository and ./CVS/Root files + and edit the values in the files. + + Last modified: _6/13/1997_ + + 18. How do I change permissions on a file in the Repository by using a CVS + command? (i.e. without using "chmod 777 $CVSROOT/dir/file") + + When you first "import" or "add"/"commit" a file, the read and execute + bits on the Repository file are inherited from the original source + file, while the write bits on the Repository file are are turned off. + This is a standard RCS action. + + After that, there is no way to alter the permissions on a file in the + Repository using CVS (or RCS) commands. You have to change the + permissions on both your working file and on the Repository file from + which it was retrieved. + + Whenever you "checkout" the file or retrieve a new revision via + "update" (or after a "commit"), your working file is set to match the + permissions of the Repository file, minus any "umask" bits you have + set. + + Last modified: _6/13/1997_ + + Category: /Advanced_Topics_/Tricks_of_the_Trade/ + + " + Tricks of the Trade" + + 1. How can you even check in binary files, let alone allow CVS to do its + auto-merge trick on them? + + +First of all, if you want to use binary files, you should get RCS 5.7 +and CVS 1.9 or later (earlier versions had some support, but there have been +bug fixes). Secondly, follow the instructions for installing RCS very +carefully (it is easy to get it installed so it works for everything +except binary files). + +Then, specify 'cvs add -kb' instead of just 'cvs add' to add a binary +file. If you want to set an existing file to binary, run 'cvs admin +-kb' (and then check in a new copy of the file). Note that old +versions of CVS used -ko instead of -kb for binary files, so if you +see a reference to -ko in the context of binary files, you should +think -kb instead. + +Of course when 'cvs update' finds that a merge is needed, it can't +do this for binary files the same way as for text files. With the +latest versions (e.g. CVS 1.9.14), it should be able to give you both +versions and let you merge manually. Another approach is to +run 'cvs admin -l' to lock files, as described in +"How can I lock files while I'm working on them the way RCS does?" +elsewhere in this FAQ. See also +"Is there any way to import binary files?" and +"How do I "add" a binary file?" elsewhere in this FAQ. + +kingdon@cyclic.com + + Last modified: _9/6/1997_ + + 2. Can I edit the RCS (",v") files in the Repository? + + Yes, but be very careful. The RCS files are not free-form files, they + have a structure that is easily broken by hand-editing. The only time + I would suggest doing this is to recover from emergency failures that + are difficult to deal with using CVS commands, including the "admin" + command, which can talk directly to RCS. + + Though no one actively encourages the editing of RCS files, many + 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' + instead.) + - Unlocking a file by changing the "locker" from someone else to + yourself. (It's safer to use `cvs admin -u -l'.) + - Making global changes to past history. Example: Eradicating former + employees names from old documents and Author entries. (And someone + thought the "history" command was evidence of Big Brother! I never + realized how much help a wide-open revision control system could have + provided to The Ministry of Truth.) + + Last modified: _6/13/1997_ + + 3. Can I edit the ./CVS/{Entries,Repository,Tag} files? + + Yes, but with CVS 1.3 and later, there is almost no reason to edit any + of the CVS administrative files. + + If you move pieces of your Repository around it can be faster to edit + all the ./CVS/Repository files rather than checking out a large tree. + But that is nearly the only reason to do so. + + Last modified: _6/13/1997_ + + 4. Someone executed "admin -o" and removed revisions to which tags/symbols + were attached. How do I fix them? + + It depends on what you mean by "fix". I can think of three ways to fix + your predicament: + + Remove the tags. + + Assuming you really wanted to get rid of the revision and its + associated tags, you can remove them with the "admin" command. The + "tag -d" command will only remove tags attached to existing revisions. + You can remove a tag, even if it is attached to a non-existent + revision, by typing: + + cvs admin -N<tag> <file> + + Retrieve the outdated revision. + + You should first look in your backup system for recent versions of the + file. If you can't use them, you can carefully extract each revision + that followed the earliest outdated revision using RCS (or "cvs + admin") commands and reconstruct the file with all the right + revisions, branches and tags. This is a lot of work. + + You *can't* insert a revision into the current RCS file. + + Move the Tags to another revision in each file. + + If you want to move the tags to another valid revision, you have two + choices, both of which require that you find all the revision numbers + of the files you want to "tag" and execute the following command + sequences on each <file>. + + Use "update" to grab the revision you want, then execute a normal + "tag" command to Tag that revision: + + cvs update -r <rev> <file> + cvs tag <tag> <file> + + Use "admin" to set the tag to a specific revision: + + cvs admin -N<tag>:<rev> <file> + + Last modified: _6/13/1997_ + + 5. How do I move or rename a magic branch tag? + + (To rename a non-branch <tag> see 3O.9.) + + Before reading this, read 3M.3 and 3M.4 and understand exactly how tag + and rtag use '-r' and why it won't do the right job here. + + First, I have to explain exactly what a magic branch tag is. + + A magic <branch_tag> is an artificial tag attached to a non-existent + revision on a non-existent branch number zero. It looks like this: + + TAG1:<X>.0.Y + + <X> is the "branch point revision", a normal revision with an + odd number of '.'s in it. (e.g. 1.5, 1.3.1.6, etc) + + Y is an even number (e.g. 2, 4, 6, etc.) All CVS branches, + other than the Vendor branch, are even numbered. + + TAG1 is considered by CVS to be attached to revision <X>. The first + "update -r TAG1 <file>" after applying TAG1 will produce a copy of + revision <X> with a sticky tag of TAG1. The first "commit" to that + file will cause CVS to construct an RCS branch named <X>.Y and check + in revision <X>.Y.1 on the new branch. + + Note: TAG1 is *not* considered to be attached to <X> by RCS, which + explains why you can't refer directly to the branch point revision for + some CVS commands. + + Moving a magic <branch_tag> is the act of reapplying the same tag to + different revisions in the file: + + TAG1:<X>.0.Y + to + TAG1:<X>.0.Z or TAG1:<A>.0.B + + You can move a magic branch tag to the revisions of your choice by + using "update" to find the revisions you want to tag and reapplying + the tag to all the files with the '-F' option to force it to move the + existing <branch_tag>. + + cvs update -r <tag/rev> (or '-A' for the Main Branch) + cvs tag -F -b <branch_tag> + + If the earlier location of TAG1 refers to a physical branch within any + RCS file, moving it will make the existing branch in the file seem to + disappear from CVS's view. This is not a good idea unless you really + want to forget the existence of those RCS branches. + + If the "update" above retrieves the original branch point revision + (<X>), the "tag" command above will create the tag: + + TAG1:<X>.0.Z + + Where Z is 2 greater than the highest magic branch already on revision + <X>. The TAG1 branch will still have the same branch point (i.e. + revision <X>), but the first commit to the new TAG1 branch will create + a different RCS branch number (<X>.Z instead of <X>.Y). + + Renaming a magic <branch_tag> is the act of changing + + TAG1:<X>.0.Y + to + TAG2:<X>.0.Y + + There is no harm in changing a tag name as long as you forget that + TAG1 ever existed and you clean up any working directories with sticky + TAG1 tags on them by using "update -A", "update -r <other_tag>" or by + removing the working directories. + + On the other hand, actually changing the tag is not easy. + + See 3M.3 for why the seemingly obvious solution won't work: + + cvs tag -b -r <old_branch_tag> <new_branch_tag> + + The only direct way to rename a magic tag is to use the "admin" + command on each file: (You might want to use '-n'. Read "man rcs" and + look at the '-n' and '-N' options.) + + cvs admin -N<new_branch_tag>:<old_branch_tag> . + cvs tag -d <old_branch_tag> + + But you have to be careful because "admin" is different from other CVS + commands: + + "admin" can be used recursively, but only by specifying directory + names in its argument list (e.g. '.'), + + Where "rtag -r <old_branch_tag>" would interpret <old_branch_tag> as + a magic CVS branch tag, "admin" is a direct interface to RCS which + sees a magic branch tag as a simple (though non-existent) RCS revision + number. + + This is good for us in this particular case, but different from normal + CVS. + + "admin" also skips the Attic and produces different kinds of errors + than CVS usually does. (Because they are coming directly from RCS.) + + The other way to rename a magic <branch_tag> is to edit the Repository + files with a script of some kind. I've done it in the past, but I'll + leave it as an exercise for the reader. + + Last modified: _6/13/1997_ + + 6. Can I use RCS locally to record my changes without making them globally + visible by committing them? + + You can, but it will probably confuse CVS to have ",v" files in your + working directory. And you will lose all your log entries when you + finally commit it. + + Your best bet is to create your own CVS branch and work there. You can + commit as many revisions as you want, then merge it back into the main + line (or parent branch) when you are finished. + + Last modified: _6/13/1997_ + + 7. How can I allow access to the Repository by both CVS and RCS? + + The first step is to try not to. If some people are using CVS, there + is no reason for everyone not to. It is not hard to learn the basics + and CVS makes certain operations *easier* than a series of RCS + commands. Personal preference in what software tools can be applied to + a shared Repository has to take second place to system integration + needs. If you disagree, try writing some Lisp code for inclusion in + your Unix kernel and see what kind of reception you get. + + If you really must allow routine RCS access to the CVS Repository, you + can link an RCS sub-directory into a piece of the Repository: + + ln -s /Repository/some/directory/I/want RCS + + and RCS will work just fine. + + Those who are using RCS will have to keep the following in mind: + + If a file was originally added to the Repository by "import" and has + not been changed using CVS, the *RCS* default branch will remain + attached to the Vendor branch, causing revisions checked-in by "ci" to + wind up on the Vendor branch, instead of the main branch. Only CVS + moves the RCS default branch on first commit. + + The way around this is to checkin (using "ci") all the files first and + move them into the Repository. That way they won't have Vendor + branches. Then RCS will work OK. + + It is possible to use "rcs" and "ci" to make the files unusable by + CVS. The same is true of the CVS "admin" command. + + Normal RCS practice locks a file on checkout with "co -l". In such + an environment, RCS users should plan to keep survival gear and food + for at least 30 days near their desks. When faced with bizarre and + unexpected permission errors, howling mobs of slavering CVS users will + run the RCS users out of town with pitchforks and machetes. + + See 3C.8 for a way to avoid machetes aroused by lock collisions. + + Though files checked in by RCS users will correctly cause + "up-to-date" failures during CVS "commits" and they will be + auto-merged into CVS working directories during "update", the opposite + won't happen. + + RCS users will get no warning and will not be required to merge older + work into their code. They can easily checkin an old file on top of a + new revision added by CVS, discarding work committed earlier by CVS + users. + + See the howling mob scenario described above. + + RCS is great. I have used it for years. But I wouldn't mix it this + way. In a two-camp society, you are asking for real trouble, both in + technical hassles to clean up and in political hassles to soothe. + Branch merges will also be a major problem. + + Last modified: _6/13/1997_ + + 8. I "updated" a file my friend, "bubba", committed yesterday. Why doesn't + the file now have a modified date of yesterday? + + CVS restores dates from the RCS files only on first "checkout". After + that, it is more important to maintain a timestamp relative to the + other files in the working directory. + + Example: You committed a source file at 5PM. Bubba updated his copy of + the file, grabbing your changes, then changed and committed a new + revision of the file at 6PM. At 7PM, you compile your file. Then you + execute "update". If CVS sets the date to the one in the RCS file, the + file would be given a timestamp of 6PM and your Makefile wouldn't + rebuild anything that depended on it. Bad news. + + Note that the same logic applies to retrieving a revision out of the + Repository to replace a deleted file. If CVS changes your file in an + existing working directory, whether it was because a new revision was + committed by someone else or because you deleted your working file, + the timestamp on the retrieved working file *must* be set to the + current time. + + When you first retrieve a file, there is no reason to expect any + particular timestamp on the file within your working area. But later, + when dependency checking is performed during a build, it is more + important for the timestamps on the local files to be consistent with + each other than than it is for working files to match the timestamps + on the files in the Repository. See 4D.17 for some more about + timestamps. + + Last modified: _6/13/1997_ + + 9. While in the middle of a large "commit", how do I run other commands, + like "diff" or "stat" without seeing lock errors? + + Type: + cvs -n <command> + + The '-n' option to the main cvs command turns off lock checking, a + reasonable act for read-only commands given the promise offered by + '-n' not to alter anything. The "diff", "log" and "stat" commands + provide the same information (for files that are not being committed) + when used with and without the '-n' option. + + Warning: Ignoring locks can produce inconsistent information across a + collection of files if you are looking at the revisions affected by an + active commit. Be careful when creating "patches" from the output of + "cvs -n diff". If you are looking only at your working files, tagged + revisions, and BASE revisions (revisions whose numbers are read from + your ./CVS/Entries files), you should get consistent results. Of + course, if you catch a single file in the middle of RCS activity, you + might get some strange errors. + + Note that the suggested command is "cvs -n <command>". The visually + similar command "cvs <command> -n" has no relation to the suggested + usage and has an entirely different meaning for each command. + + "cvs -n update" also works in the middle of a commit, providing + slightly different information from a plain "cvs update". But, of + course, it also avoids modifying anything. + + You could also use the RCS functions, "rlog" and "rcsdiff" to display + some of the information by referring directly to the Repository files. + + You need RCS version 5 or later for the commands described above to + work reliably. + + Last modified: _6/13/1997_ + + 10. 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 + "update" command finds a file in the Repository that is not in the + ./CVS/Entries file, "update" copies the appropriate revision of the + "new" file out of the Repository and adds the filename to the Entries + file. This happens for files: + + Added to the Repository from another working directory. + + Dragged out of the Attic when switching branches with "update -A" or + "update -r". + + Whose names were deleted from the ./CVS/Entries file. + + If the ./CVS/Entries.Static file exists, CVS will only bring out + revisions of files that are contained in either ./CVS/Entries or + ./CVS/Entries.Static. If a Repository file is found in *neither* file, + it is ignored. + + The ./CVS/Entries.Static file is created when you check out an + individual file or a module that creates working directories that + don't contain all files in the corresponding Repository directory. In + those cases, without an ./CVS/Entries.Static file, a simple "update" + would bring more files out of the Repository than the original + "checkout" wanted. + + The ./CVS/Entries.Static file can be removed by hand. It is + automatically removed if you run "update -d" to create new directories + (even if no new directories are created). (Internally, since + "checkout" turns on the '-d' flag and calls the "update" routine, a + "checkout" of a module or directory that writes into an existing + directory will also remove the ./CVS/Entries.Static file.) + + Last modified: _6/13/1997_ + + 11. Why did I get the wrong Repository in the loginfo message? + + You probably: + + Use multiple Repositories. + + Configured CVS to use absolute pathnames in the ./CVS/Repository + file. + + Configured CVS not to use the ./CVS/Root file. + + Typed the "commit" command in one Repository with your $CVSROOT + pointing at another. + + "commit" and all other CVS commands will heed an absolute pathname in + the ./CVS/Repository file (or in the "-d CVSrootdir" override), but + the log function doesn't take arguments -- it just looks at $CVSROOT. + + If you avoid even one of the four steps above, you won't see this + problem. If you configure ./CVS/Root, you won't be allowed to execute + the program causing the error. + + Last modified: _6/13/1997_ + + 12. 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 + and is used by a widely distributed group of users is not a good + candidate for a setuid program. (The worst suggestion I've ever heard + was to make *Emacs* setuid to root.) + + Root access on Unix is too powerful. Also, it might not work in some + (secure?) environments. + + Running it setuid to some user other than root might work, if you add + this line to main.c near the beginning: + + setuid(geteuid()); + + Otherwise it uses *your* access rights, rather than the effective + uid's. + + Also, you have to invent a fake user whose name will show up in + various places. But many sites, especially those who might want a + setuid CVS for "security", want personal accountability -- no generic + accounts. I don't know whether accountability outweighs file security. + + And finally, unless you take action to limit the "admin" command, you + are leaving yourself unprotected anyway. + + Last modified: _6/13/1997_ + + 13. How about using groups and setgid() then? + + Here is a way to run CVS setgid in some environments: + + Stick this near the front of the main() in main.c: + + setgid(getegid()); + + This will allow "access" to work on systems where it only works on the + real gid. + + Create a group named "cvsg". (This example uses "cvsg". You can name + it as you wish.) + + Put *no* users in the "cvsg" group. You can put Repository + administrators in this group if you want to. + + Set the cvs executable to setgid (not setuid): + + cd /usr/local/bin; chown root.cvsg cvs; chmod 2755 cvs + + Make sure every file in the Repository is in group "cvsg": + + chown -R root.cvsg $CVSROOT + + Change all directory permissions to 770. This allows all access to + the files by the "cvsg" group (which has no members!) and no access at + all to anyone else. + + find $CVSROOT -type d -exec chmod 2770 {} \; + + On some systems you might have to type: + + find $CVSROOT -type d -exec chmod u=rwx,g=rwx,o=,g+s {} \; + + This should allow only the cvs program (or other "setgid to group + cvsg") programs to write into the area, but no one else. Yes the user + winds up owning the file, but s/he can't find it again later since + s/he can't traverse the tree. (If you enable the world execute bit + (mode 2771) on directories, users can traverse the tree and the user + who last wrote the file can still write to it.) + + If you want to allow read access, check out an entire tree somewhere. + You have to do this anyway to build it. + + Note: If you are using a stupid file system that can't inherit file + groups from the parent directory (even with the "setgid" (Octal 2000) + bit set), you might have to modify CVS (or RCS) to reset the group + every time you create a new file. I have not tested this. + + The setgid() method shares with the setuid() method the problem of + keeping "admin" from breaking things. + + Last modified: _6/13/1997_ + + 14. How do I use the "commitinfo" file? + + Go read 4B.2 first. + + The "commitinfo" file allows you to execute "sanity check" functions + before allowing a commit. If any function called from within the + commitinfo file exits with a non-zero status, the commit is denied. + + 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. + + If you want to serialize binary files, you might consider something + 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 + commitinfo: + + DEFAULT /absolute/path/to/program + + CVS executes the program once for each directory that "commit" + traverses, passing as arguments the directory and the files to be + committed within that directory. + + 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: + + regexp1 /absolute/path/to/program-for-regexp1 + 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: + + ALL /absolute/path/to/program + + It is executed independently of all the above. And it's repeatable -- + you can have as many ALL lines as you like. + + Last modified: _6/13/1997_ + + 15. How do I use the "loginfo" files? + + See 4B.2 and the "commitinfo" question above. + + The "loginfo" file has the same format as the "commitinfo" file, but + its function is different. Where the "commitinfo" information is used + before a commit, the "loginfo" file is used after a commit. + + All the commands in the "loginfo" file should read data from standard + input, then either append it to a file or send a message to a mailing + list. If you want to make it simple, you can put shell (the shell used + by "popen(3)") command lines directly in the "loginfo" (or + "commitinfo") file. These seem to work: + + ^special /usr/ucb/Mail -s %s special-mailing-list ^other /usr/ucb/Mail + -s %s other-mailing-list DEFAULT (echo '===='; echo %s; cat) > + /path/name/to/log/file + + Last modified: _6/13/1997_ + + 16. 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), + and commits it, the Repository will have a file in it that is + unreadable by everyone. The 0600 example would be unreadable by + *anyone* but root and the user who created it. + + There are 3 solutions to this: + + Let it happen. This is a valid way to protect things. If everyone is + working alone, a umask of 077 is OK. If everyone is working only in + small groups, a umask of 007 is OK. + + Train your users not to create such things if you expect to share + them. + + See 4B.5 for a small script that will reset the umask. + + I personally don't like the idea of a program automatically + *loosening* security. It would be better for you all to talk about the + issue and decide how to work together. + + 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 " + + Category: /Commands_/add_ad_new/ + + " + "add", "ad", "new"" + + 1. What is "add" for? + + To add a new directory to the Repository or to register the desire to + add a new file to the Repository. + + The directory is created immediately, while the desire to add the file + is recorded in the local ./CVS administrative directory. To really add + the file to the Repository, you must then "commit" it. + + Last modified: _6/13/1997_ + + 2. How do I add a new file to the branch I'm working on? + + The user actions for adding a file to any branch, including the Main + Branch, are exactly the same. + + You are in a directory checked out (or updated) with the '-A' option + (to place you on the Main Branch) or the "-r <branch_tag>" option (to + place you on a branch tagged with <branch_tag>). To add <file> to the + branch you are on, you type: + + cvs add <file> + cvs commit <file> + + If no ./CVS/Tag file exists (the '-A' option deletes it), the file + will be added to the Main Branch. If a ./CVS/Tag file exists (the "-r + <branch_tag>" option creates it), the file will be added to the branch + named (i.e. tagged with) <branch_tag>. + + Unless you took steps to first add the file to the Main Branch, your + new file ends up in the Attic. + + Last modified: _6/13/1997_ + + 3. Why did my new file end up in the Attic? + + The file is thrown into the Attic to keep it from being visible when + you check out the Main Branch, since it was never committed to the + Main Branch. + + Last modified: _6/13/1997_ + + 4. Now that it's in the Attic, how do I connect it to the Main branch? + + That can be considered a kind of "merge". See 4C.8 + + Last modified: _6/13/1997_ + + 5. How do I avoid the hassle of reconnecting an Attic-only file to the Main + Branch? + + You create it on the Main Branch first, then branch it. + + If you haven't yet added the file or if you decided to delete the new + Attic file and start over, then do the following: (If you added the + file (or worse, the 157 files) to the Attic and don't want to start + over, try the procedure in 4C.8.) + + Temporarily remove the sticky branch information. Either: + + Move the whole directory back to the Main Branch. [This might not be + a good idea if you have modified files, since it will require a merge + in each direction.] + + cvs update -A + + *or* + + Move the ./CVS/Tag file out of the way. + + mv ./CVS/Tag HOLD_Tag + + Add and branch the file "normally": + + cvs add <file> + cvs commit <file> + cvs tag -b <branch_tag> <file> + + [<branch_tag> is the same Branch Tag as you used on all the other + files. Look at ./CVS/Entries or the output from "cvs stat" for sticky + tags.] + + Clean up the temporary step. + + If you moved the ./CVS/Tag file, put it back. Then move the new file + onto the branch where you are working. + + mv HOLD_Tag ./CVS/Tag + cvs update -r <branch_tag> <file> + + If you ran "update -A" rather than moving the ./CVS/Tag file, move + the whole directory (including the new file) back onto the branch + where you were working: + + cvs update -r <branch_tag> + + Last modified: _6/13/1997_ + + 6. How do I cancel an "add"? + + If you want to remove the file entirely and cancel the "add" at the + same time, type: + + cvs remove -f <file> + + If you want to cancel the "add", but leave the file as it was before + you typed "cvs add", then you have to fake it: + + mv <file> <file>.hold + cvs remove <file> + mv <file>.hold <file> + + Last modified: _6/13/1997_ + + 7. What are the ./CVS/file,p and ./CVS/file,t files for? + + The ./CVS/file,p and ./CVS/file,t files are created by the "add" + command to hold command line options and message text between the time + of the "add" command and the expected "commit". + + The ./CVS/file,p file is always null, since its function was absorbed + by the "options" field in the ./CVS/Entries file. If you put something + in this file it will be used as arguments to the RCS "ci" command that + commit uses to check the file in, but CVS itself doesn't put anything + there. + + The ./CVS/file,t file is null unless you specify an initial message in + an "add -m 'message'" command. The text is handed to "rcs -i + -t./CVS/file,t" to create the initial RCS file container. + + Both files must exist to commit a newly added file. If the + ./CVS/file,p file doesn't exist, CVS prints an error and aborts the + commit. If the ./CVS/file,t file doesn't exist, RCS prints an error + and CVS gets confused, but does no harm. + + To recover from missing ,p and ,t files, just create two zero-length + files and rerun the "commit". + + Last modified: _6/13/1997_ + + 8. How do I "add" a binary file? + + If you configured CVS to use the GNU version of "diff" and "diff3", + you only need to turn off RCS keyword expansion. + + First you turn off RCS keyword expansion for the initial checkin by + using "add -ko". It works like "update -ko" in creating a "sticky" + option only for the copy of the file in the current working directory. + + cvs add -ko <file> + + Commit the file normally. The sticky -ko option will be used. + + cvs commit <file> + + Then mark the RCS file in the Repository so that keyword expansion is + turned off for all checked out versions of the file. + + cvs admin -ko <file> + + Since "admin -ko" records the keyword substitution value in the + Repository's RCS file, you no longer need the sticky option. You can + turn it off with the "update -A" command, but if you were on a branch, + you'll have to follow it "update -r <branch_tag>" to put yourself back + on the branch. + + Managing that binary file is another problem. See 4D.1. + + Last modified: _6/13/1997_ + + Category: /Commands_/admin_adm_rcs/ + + " + "admin", "adm", "rcs"" + + 1. What is "admin" for? + + To provide direct access to the underlying "rcs" command (which is not + documented in this FAQ) bypassing all safeguards and CVS assumptions. + + Last modified: _6/13/1997_ + + 2. Wow! Isn't that dangerous? + + Yes. + + Though you can't hurt the internal structure of an RCS file using its + own "rcs" command, you *can* change the underlying RCS files using + "admin" in ways that CVS can't handle. + + If you feel the need to use "admin", create some test files with the + RCS "ci" command and experiment on them with "rcs" before blasting any + CVS files. + + Last modified: _6/13/1997_ + + 3. What would I normally use "admin" for? + + Normally, you wouldn't use admin at all. In unusual circumstances, + experts can use it to set up or restore the internal RCS state that + CVS requires. + + You can use "admin -o" (for "outdate") to remove revisions you don't + care about. This has its own problems, such as leaving dangling Tags + and confusing the "update" command. + + There is some feeling among manipulators of binary files that "admin + -l" should be used to serialize access. See 3C.8. + + An interesting use for "admin" came up while maintaining CVS itself. I + import versions of CVS onto the Vendor branch of my copy of CVS, make + changes to some files and ship the diffs (created by "cvs diff -c -r + TO_BRIAN") off to Brian Berliner. After creating the diff, I retag + ("cvs tag -F TO_BRIAN") the working directory, which is then ready to + produce the next patch. + + I'll use "add.c" as an example (only because the name is short). + + When the next release came out, I discovered that the released "add.c" + (version 1.1.1.3 on the Vendor branch) was exactly the same as my + modified file (version 1.3). I didn't care about the changelog on + versions 1.2 and 1.3 (or the evidence of having done the work), so I + decided to revert the file to the state where it looked like I had not + touched the file -- where I was just using the latest on the vendor + branch after a sequence of imports. + + To do that, I removed all the revisions on the main branch, except for + the original 1.1 from which the Vendor branch sprouts: + + cvs admin -o1.2: add.c + + Then I set the RCS "default branch" back to the Vendor branch, the way + import would have created it: + + cvs admin -b1.1.1 add.c + + And I moved the "TO_BRIAN" Tag to the latest revision on the Vendor + branch, since that is the base from which further patches would be + created (if I made any): + + cvs admin -NTO_BRIAN:1.1.1.3 add.c + + Instead of 1.1.1.3, I could have used one of the "Release Tags" last + applied by "import" (3rd through Nth arguments). + + Suggestion: Practice on non-essential files. + + Last modified: _6/13/1997_ + + 4. What should I avoid when using "admin"? + + If you know exactly what you are doing, hack away. But under normal + circumstances: + + Never use "admin" to alter branches (using the '-b' option), which CVS + takes very seriously. If you change the default branch, CVS will not + work as expected. If you create new branches without using the "tag + -b" command, you may not be able to treat them as CVS branches. + + See 3C.8 for a short discussion of how to use "admin -l" for + serializing access to binary files. + + The "admin -o <file>" allows you to delete revisions, usually a bad + idea. You should commit a correction rather than back out a revision. + Outdating a revision is prone to all sorts of problems: + + Discarding data is always a bad idea. Unless something in the + revision you just committed is a threat to your job or your life, + (like naming a function "<boss's name>_is_a_dweeb", or including the + combination to the local Mafioso's safe in a C comment), just leave it + there. No one cares about simple mistakes -- just commit a corrected + revision. + + The time travel paradoxes you can cause by changing history are not + worth the trouble. Even if CVS can't interfere with your parents' + introduction, it *can* log commits in at least two ways (history and + loginfo). The reports now lie -- the revision referred to in the logs + no longer exists. + + If you used "import" to place <file> into CVS, outdating all the + revisions on the Main branch back to and including revision 1.2 (or + worse, 1.1), will produce an invalid CVS file. + + If the <file>,v file only contains revision 1.1 (and the connected + branch revision 1.1.1.1), then the default branch must be set to the + Vendor branch as it was when you first imported the file. Outdating + back through 1.2 doesn't restore the branch setting. Despite the above + admonition against it, "admin -b" is the only way to recover: + + cvs admin -b1.1.1 <file> + + Although you can't outdate a physical (RCS) branch point without + removing the whole branch, you *can* outdate a revision referred to by + a magic branch tag. If you do so, you will invalidate the branch. + + If you "outdate" a tagged revision, you will invalidate all uses of + the <tag>, not just the one on <file>. A tag is supposed to be + attached to a consistent set of files, usually a set built as a unit. + By discarding one of the files in the set, you have destroyed the + utility of the <tag>. And it leaves a dangling tag, which points to + nothing. + + And even worse, if you commit a revision already tagged, you will + alter what the <tag> pointed to without using the "tag" command. For + example, if revision 1.3 has <tag> attached to it and you "outdate" + the 1.3 revision, <tag> will point to a nonexistent revision. Although + this is annoying, it is nowhere near as much trouble as the problem + that will occur when you commit to this file again, recreating + revision 1.3. The old tag will point to the new revision, a file that + was not in existence when the <tag> was applied. And the discrepancy + is nearly undetectable. + + If you don't understand the above, you should not use the admin + command at all. + + Last modified: _6/13/1997_ + + 5. How do I restrict the "admin" command? The -i flag in the modules file + can restrict commits. What's the equivalent for "admin"? + + At this writing, to disable the "admin" command, you will have to + change the program source code, recompile and reinstall. + + Last modified: _6/13/1997_ + + 6. I backed out a revision with "admin -o" and committed a replacement. Why + doesn't "update" retrieve the new revision? + + CVS is confused because the revision in the ./CVS/Entries file matches + the latest revision in the Repository *and* the timestamp in the + ./CVS/Entries file matches your working file. CVS believes that your + file is "up-to-date" and doesn't need to be updated. + + You can cause CVS to notice the change by "touch"ing the file. + Unfortunately what CVS will tell you is that you have a "Modified" + file. If you then "commit" the file, you will bypass the normal CVS + check for "up-to-date" and will probably commit the revision that was + originally removed by "admin -o". + + Changing a file without changing the revision number confuses CVS no + matter whether you did it by replacing the revision (using "admin -o" + and "commit" or raw RCS commands) or by applying an editor directly to + a Repository (",v") file. Don't do it unless you are absolutely + certain no one has the latest revision of the file checked out. + + The best solution to this is to institute a program of deterrent + flogging of abusers of "admin -o". + + The "admin" command has other problems." See 3B.4 above. + + Last modified: _6/13/1997_ + + Category: /Commands_/checkout_co_get/ + + " + "checkout", "co", "get"" + + 1. What is "checkout" for? + + To acquire a copy of a module (or set of files) to work on. + + All work on files controlled by CVS starts with a "checkout". + + Last modified: _6/13/1997_ + + 2. What is the "module" that "checkout" takes on the command line? + + It is a name for a directory or a collection of files in the + Repository. It provides a compact name space and the ability to + execute before and after helper functions based on definitions in the + modules file. + + See 1D.11. + + Last modified: _6/13/1997_ + + 3. Isn't a CVS "checkout" just a bunch of RCS checkouts? + + Like much of CVS, a similar RCS concept is used to support a CVS + function. But a CVS checkout is *not* the same as an RCS checkout. + + Differences include: + + CVS does not lock the files. Others may access them at the same + time. + + CVS works best when you provide a name for a collection of files (a + module or a directory) rather than an explicit list of files to work + on. + + CVS remembers what revisions you checked out and what branch you are + on, simplifying later commands. + + Last modified: _6/13/1997_ + + 4. What's the difference between "update" and "checkout"? + + The "checkout" and "update" commands are nearly equivalent in how they + treat individual files. They differ in the following ways: + + The "checkout" command always creates a directory, moves into it, + then becomes equivalent to "update -d". + + The "update" command does not create directories unless you add the + '-d' option. + + "Update" is intended to be executed within a working directory + created by "checkout". It doesn't take a module or directory argument, + but figures out what Repository files to look at by reading the files + in the ./CVS administrative directory. + + The two commands generate completely different types of records in + the "history" file. + + Last modified: _6/13/1997_ + + 5. Why can't I check out a file from within my working directory? + + Though you *can* check out a file, you normally check out a module or + directory. And you normally do it only once at the beginning of a + project. + + After the initial "checkout", you can use the "update" command to + retrieve any file you want within the checked-out directory. There is + no need for further "checkout" commands. + + If you want to retrieve another module or directory to work on, you + must provide two pathnames: where to find it in the Repository and + where to put it on disk. The "modules" file and your current directory + supply two pieces of naming information. While inside a checked-out + working directory, the CVS administrative information provides most of + the rest. + + You should be careful not to confuse CVS with RCS and use "checkout" + in the RCS sense. An RCS "checkout" (which is performed by the RCS + "co" command) is closer to a "cvs update" than to a "cvs checkout". + + Last modified: _6/13/1997_ + + 6. How do I avoid dealing with those long relative pathnames? + + This question has also been phrased: + + How do I avoid all those layers of directories on checkout? or Why do + I have to go to the top of my working directory and checkout some long + pathname to get a file or two? + + This type of question occurs only among groups of people who decide + not to use "modules". The answer is to use "modules". + + When you hand the "checkout" command a relative pathname rather than a + module name, all directories in the path are created, maintaining the + same directory hierarchy as in the Repository. The same kind of + environment results if you specify a "module" that is really an alias + expanding into a list of relative pathnames rather than a list of + module names. + + If you use "module" names, "checkout" creates a single directory by + the name of the module in your current directory. This "module" + directory becomes your working directory. + + The "module" concept combines the ability to "name" a collection of + files with the ability to structure the Repository so that consistent + sets of files are checked out together. It is the responsibility of + the Repository Administrators to set up a modules file that describes + the software within the Repository. + + Last modified: _6/13/1997_ + + 7. Can I move a checked-out directory? Does CVS remember where it was + checked out? + + Yes and Yes. + + The ./CVS/Repository file in each working directory contains a + pathname pointing to the matching directory within the Repository. The + pathname is either absolute or relative to $CVSROOT, depending on how + you configured CVS. + + When you move a checked-out directory, the CVS administrative files + will move along with it. As long as you don't move the Repository + itself, or alter your $CVSROOT variable, the moved directory will + continue to be usable. + + CVS remembers where you checked out the directory in the "history" + file, which can be edited, or even ignored if you don't use the + "working directory" information displayed by the "history" command. + + Last modified: _6/13/1997_ + + 8. How can I lock files while I'm working on them the way RCS does? + + Until the day arrives of the all-powerful merge tool, there are still + files that must be accessed serially. For those instances, here's a + potential solution: + + Install a pre-commit program in the "commitinfo" file to check for + RCS locks. The program "rcslock.pl" performs this function. It can be + found in the contrib directory of the CVS source distribution. + + When you want to make a change to a file you know can't be merged, + first use "cvs admin -l" to lock the file. If you can't acquire the + lock, use the standard "locked out" protocol: go talk to the person + holding the lock. + + Make sure the pre-commit program prints a message and exits with a + non-zero status if someone besides the user running "commit" has the + file locked. This non-zero exist status will cause the "commit" to + fail cleanly. + + Make sure the pre-commit program exits with a zero status if the + file is either unlocked or locked by the user running "commit". The + "cvs commit" command that kicked off the pre-commit program will take + a zero exist status as an OK and checkin the file, which has the + side-effect of unlocking it. + + ===> The following is opinion and context. Don't read it if you are + looking for a quick fix. + + The topic of locking CVS files resurfaces on the network every so + often, producing the same results each time: + + The Big Endians: + + CVS was designed to avoid locks, using a copy-modify-merge model. + Locking is not necessary and you should take the time to learn the CVS + model which many people find workable. So why not get with the program + and learn how to think the CVS way? + + The Little Endians: + + The users determine how a tool is to be used, not the designers. We, + the users, have always used locking, our bosses demand locking, + locking is good, locking is God. I don't want to hear any more + lectures on the CVS model. Make locking work. + + Any organization making active changes to a source base will + eventually face the need to do parallel development. Parallel + development implies merges. (If you plan to keep separate copies of + everything and never merge, good luck. Tell me who you work for so I + can buy stock in your disk suppliers this year and sell your stock + short next year.) + + Merges will never go away. CVS chose to make "merges" stand front and + center as an important, common occurrence in development. It is one + way of looking at things. + + For free-format text, the merge paradigm gives you a considerable + amount of freedom. It does take a bit of management, but any project + should be ready to deal with it. + + On the other hand, there are many files that can't be merged using + text merge techniques. Straight text merge programs like "diff3" are + guaranteed to fail on executables (with relative branch statements), + files with self-referential counts stored in the file (such as TAGS + files), or files with relative motion statements in them (such as + Frame MIF files, many postscript files). They aren't all binary files. + + For these types of files, and many others, there are only two + solutions: + + Complex merge tools that are intimately aware of the contents of the + files to be merged. (ClearCase, and probably others, allow you to + define your own "files types" with associated "merge tools".) + + Serialization of access to the file. The only technical solution to + the problem of serialization is "locking". + + Since you can call a program that offers: + + "Which one do you want? A/B?" + + a "merge tool", more and more merge tools will appear which can be + hooked into a merge-intensive program like CVS. Think of a bitmap + "merge" tool that displays the bitmaps on the screen and offers a + "paint" interface to allow you to cut and paste, overlay, invert or + fuse the two images such that the result is a "merged" file. + + My conclusion is that the need for locking is temporary, awaiting + better technology. For large development groups, locking is not an + alternative to merging for text files. + + Last modified: _6/13/1997_ + + 9. What is "checkout -s"? How is it different from "checkout -c"? + + The '-c' and '-s' options to "checkout" both cause the modules file to + appear on standard output, but formatted differently. + + "checkout -c" lists the modules file alphabetized by the module name. + It also prints all data (including options like '-a' and "-o <prog>") + specified in the modules file. + + "checkout -s" lists the modules file sorted by "status" field, then by + module name. The status field was intended to allow you to mark + modules with strings of your choice to get a quick sorted report based + on the data you chose to put in the status fields. I have used it for + priority ("Showstopper", etc as tied into a bug database), for porting + status ("Ported", "Compiled", etc. when porting a large collection of + modules), for "assignee" (the person responsible for maintenance), and + for "test suite" (which automatic test procedure to run for a + particular module). + + Last modified: _6/13/1997_ + + Category: /Commands_/commit_ci_com/ + + " + "commit", "ci", "com"" + + 1. What is "commit" for? + + To store new revisions in the Repository, making them visible to other + users. + + Last modified: _6/13/1997_ + + 2. If I edit ten files, do I have to type "commit" ten times? + + No. The "commit" command will take multiple filenames, directory names + and relative pathnames on the command line and commit them all with + the same log message. If a file is unchanged, even if it is explicitly + listed on the command line, CVS will skip it. + + Like all CVS commands, "commit" will work on the whole directory by + default. Just type "cvs commit" to tell CVS to commit all modified + files (i.e. the files that "update" would display preceded by 'M') in + the current directory and in all sub-directories. + + Last modified: _6/13/1997_ + + 3. Explain: cvs commit: Up-to-date check failed for `<file>' + + You may not "commit" a file if your BASE revision (i.e. the revision + you last checked out, committed or retrieved via "update") doesn't + match the HEAD revision (i.e the latest revision on your branch, + usually the Main Branch). + + In other words, someone committed a revision since you last executed + "checkout", "update" or "commit". You must now execute "update" to + merge the other person's changes into your working file before + "commit" will work. You are thus protected (somewhat) from a common + form of race condition in source control systems, where a checkin of a + minor alteration of a second copy of the same base file obliterates + the changes made in the first. + + Normally, the "update" command's auto-merge should be followed by + another round of building and testing before the "commit". + + Last modified: _6/13/1997_ + + 4. What happens if two people try to "commit" conflicting changes? + + Conflicts can occur only when two developers check out the same + revision of the same file and make changes. The first developer to + commit the file has no chance of seeing the conflict. Only the second + developer runs into it, usually when faced with the "Up-to-date" error + explained in the previous question. + + There are two types of conflicts: + + When two developers make changes to the same section of code, the + auto-merge caused by "update" will print a 'C' on your terminal and + leave "overlap" markers in the file. + + You are expected to examine and clean them up before committing the + file. (That may be obvious to *some* of you, but . . .) + + A more difficult problem arises when two developers change different + sections of code, but make calls to, or somehow depend on, the old + version of each other's code. + + The auto-merge does the "right" thing, if you view the file as a + series of text lines. But as a program, the two developers have + created a problem for themselves. + + This is no different from making cross-referential changes in + *separate* files. CVS can't help you. In a perfect world, you would + each refer to the specification and resolve it independently. In the + real world you have to talk/argue, read code, test and debug until the + combined changes work again. + + Welcome to the world of parallel development. + + Last modified: _6/13/1997_ + + 5. I committed something and I don't like it. How do I remove it? + + Though you *can* use the "admin -o" (synonym: "rcs -o") command to + delete revisions, unless the file you committed is so embarrassing + that the need to eradicate it overrides the need to be careful, you + should just grab an old version of the file ("update -p -r + <previous-rev>" might help here) and commit it on top of the offending + revision. + + See Section 3B on "admin". + + Last modified: _6/13/1997_ + + 6. Explain: cvs commit: sticky tag `V3' for file `X' is not a branch + + The message implies two things: + + You created your working directory by using "checkout -r V3", or you + recently executed "update -r V3". + + The tag named V3 is not a branch tag. + + CVS records (i.e. makes "sticky") any "-r <tag/rev>" argument handed + to the "checkout" or "update" commands. The <tag/rev> is recorded as + the CVS working branch, which is the branch to which "commit" will add + a new revision. + + Branch tags are created when you use the -b switch on the "tag" or + "rtag" commands. Branch tags are magic tags that don't create a + physical branch, but merely mark the revision to branch from when the + branch is needed. The first commit to a magic branch creates a + physical branch in the RCS files. + + You can commit onto the end of the Main Trunk, if you have no sticky + tag at all, or onto the end of a branch, if you have a sticky branch + tag. But you can't commit a file that has a sticky tag not pointing to + a branch. CVS assumes a sticky Tag or Revision that does not refer to + a branch is attached to the middle of a series of revisions. You can't + squeeze a new revision between two others. Sticky dates also block + commits since they never refer to a branch. + + Scenario1: + + If you don't want a branch and were just looking at an old revision, + then you can move back to the Main Branch by typing: + + cvs update -A {files or dirs, default is '.'} + + or you can move to the branch named <branch_tag> by: + + cvs update -r <branch_tag> {files or dirs, default is '.'} + + Scenario2: + + If you really wanted to be on a branch and made an earlier mistake by + tagging your branch point with a non-branch tag, you can recover by + adding a new branch tag to the old non-branch tag: + + cvs rtag -b -r <oldtag> <newtag> <module> + + (It was not a big mistake. Branch-point tags can be useful. But the + <newtag> must have a different name.) + + If you don't know the <module> name or don't use "modules", you can + also use "tag" this way: + + cvs update -r <oldtag> + cvs tag -b <newtag> . + + Then, to put your working directory onto the branch, you type: + + cvs update -r <newtag> + + You can't delete <oldtag> before adding <newtag>, and I would not + advise deleting the <oldtag> at all, because it is useful in referring + to the branch point. If you must, you can delete the non-branch tag + by: + + cvs rtag -d <oldtag> <module> + or + cvs tag -d <oldtag> . + + Scenario3: + + If you made the same mistake as in Scenario2 (of placing a non-branch + tag where you wanted a branch tag), but really want <oldtag> to be the + name of your branch, you can execute a slightly different series of + commands to rename it and move your working directory onto the branch. + + Warning: This is not a way to rename a branch tag. It is a way to turn + a non-branch tag into a branch tag with the same name. + + cvs rtag -r <oldtag> <branch_point_tag> <module> + cvs rtag -d <oldtag> <module> + cvs rtag -b -r <branch_point_tag> <oldtag> <module> + + Then, if you really must, delete the <branch_point_tag>: + + cvs rtag -d <branch_point_tag> <module> + + Note: The unwieldy mixture of "tag" and "rtag" is mostly because you + can't specify a revision (-r <tag>) to the "tag" command. + + See 4C.3 for more info on creating a branch. + + Last modified: _6/13/1997_ + + 7. Why does "commit -r <tag/rev>" put newly added files in the Attic? + + If you specify "-r <rev>" (where <rev> is a dotted numeric number like + 2.4), it correctly sets the initial revision to <rev>, but it also + attaches the numeric <rev> as a sticky tag and throws the file into + the Attic. This is a bug. The obvious solution is to move the file out + of the Attic into the associated Repository directory and "update -A" + the file. There are no Tags to clean up. + + If you specify "-r <tag>" to commit a newly added file, the <tag> is + treated like a <branch_tag>, which becomes a symbolic RCS label + pointing to the string '1', which can be considered to be the "Main + branch number" when the main branch is still at revision 1.N. The file + is also thrown into the Attic. See 4C.8 for a way to recover from + this. + + In fact, a plain "commit" without the "-r" will throw a newly added + file into the Attic if you added it to a directory checked out on a + branch. See 3A.[2-5]. + + See Section 4C, on Branching, for many more details. + + Last modified: _6/13/1997_ + + 8. Why would a "commit" of a newly added file not produce rev 1.1? + + When committing a newly added file CVS looks for the highest main + branch major number in all files in the ./CVS/Entries file. Normally + it is '1', but if you have a file of revision 3.27 in your directory, + CVS will find the '3' and create revision 3.1 for the first rev of + <file>. Normally, the first revision is 1.1. + + Last modified: _6/13/1997_ + + Category: /Commands_/diff_di_dif/ + + " + "diff", "di", "dif"" + + 1. What is "diff" for? + + To display the difference between a working file and its BASE + revision (the revision last checked out, updated or committed): + + cvs diff <file> + + To display the difference between a working file and a committed + revision of the same file: + + cvs diff -r <tag/rev> <file> + + To display the difference between two committed revisions of the + same file: + + cvs diff -r <tag1/rev1> -r <tag2/rev2> <file> + + You can specify any number of <file> arguments. Without any <file> + arguments, it compares the whole directory. + + In the examples above, "-D <date>" may be substituted wherever "-r + <tag/rev>" appears. The revision a <date> refers to is the revision + that existed on that date. + + Last modified: _6/13/1997_ + + 2. Why did "diff" display nothing when I know there are later committed + revisions in the Repository? + + By default, "diff" displays the difference between your working file + and the BASE revision. If you haven't made any changes to the file + since your last "checkout", "update" or "commit" there is no + difference to display. + + To display the difference between your working file and the latest + revision committed to your current branch, type: + + cvs diff -r HEAD <file> + + Last modified: _6/13/1997_ + + 3. How do I display what changed in the Repository since I last executed + "checkout", "update" or "commit"? + + A special tag (interpreted by CVS -- it does not appear in the Tag + list) named "BASE" always refers to the revision you last checked out, + updated or committed. Another special tag named "HEAD" always refers + to the latest revision on your working branch. + + To compare BASE and HEAD, you type: + + cvs diff -r BASE -r HEAD <file> + + Last modified: _6/13/1997_ + + 4. How do I display the difference between my working file and what I + checked in last Thursday? + + cvs diff -D "last Thursday" <file> + + where "last Thursday" is a date string. To be more precise, the + argument to the '-D' option is a timestamp. Many formats are accepted. + See the man page under "-D date_spec" for details. + + Last modified: _6/13/1997_ + + 5. Why can't I pass long options, like --unified, to "diff"? + + CVS only handles single character '-X' arguments, not the FSF long + options. CVS also passes through only arguments it knows about, + because a few arguments are captured and interpreted by CVS. + + If you didn't configure RCS and CVS to use the GNU version of diff, + long options wouldn't work even if future versions of CVS acquire the + ability to pass them through. + + Most of the long options have equivalent single-character options, + which do work. The "--unified" option is equivalent to '-u' in + revisions of GNU diff since 1.15. + + Last modified: _6/13/1997_ + + Category: /Commands_/export_exp_ex/ + + " + "export", "exp", "ex"" + + 1. What is "export" for? + + "export" checks out a copy of a module in a form intended for export + outside the CVS environment. The "export" command produces the same + directory and file structure as the "checkout" command, but it doesn't + create "CVS" sub-directories and it removes all the RCS keywords from + the files. + + Last modified: _6/13/1997_ + + 2. Why does it remove the RCS keywords so I can't use the "ident" command + on the source files? + + It removes the RCS keywords, so that if the recipient of the exported + sources checks them into another set of RCS files (with or without + CVS), and then makes modifications through RCS or CVS commands, the + revision numbers that they had when you exported them will be + preserved. (That ident no longer works is just an unfortunate side + effect.) + + The theory is that you are exporting the sources to someone else who + will make independent changes, and at some point you or they will want + to know what revisions from your Repository they started with + (probably to merge changes, or to try to decide whether to merge + changes). + + A better way to handle this situation would be to give them their own + branch of your Repository. They would need to remember to checkin the + exported sources with RCS IDs intact (ci -k) so that their changes + would get revision numbers from the branch, rather than starting at + 1.1 again. Perhaps a future version of CVS will provide a way to + export sources this way. + + Contributed by Dan Franklin + + Last modified: _6/13/1997_ + + 3. Can I override the '-kv' flag CVS passes to RCS? + + Not as of CVS version 1.4. + + Last modified: _6/13/1997_ + + 4. Why doesn't "export" have a '-k' flag like "import" does? + + Export is intended for a specific purpose -- to remove all trace of + revision control on the way *out* of CVS. + + Last modified: _6/13/1997_ + + 5. Why does "export -D" check out every file in the Attic? + + See 5B.3 for an explanation of the same problem with "update". + + Last modified: _6/13/1997_ + + Category: /Commands_/history_hi_his/ + + " + "history", "hi", "his"" + + 1. What is "history" for? + + To provide information difficult or impossible to extract out of the + RCS files, such as a "tag" history or a summary of module activities. + + Last modified: _6/13/1997_ + + 2. Of what use is it? + + I have found it useful in a number of ways, including: + + 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?) + - Has anyone (and who) grabbed the revision of this file I committed + last week, or are they still working blind? + + Telling me how often a file/directory/module has been changed. + + Dumping a summary of work done on a particular module, including who + last worked on it and what changed. + + Displaying the checked-out modules and where they are being worked + on. + + To tell me what users "joe" and "malcolm" have done this week. + + Last modified: _6/13/1997_ + + 3. What is this, Big Brother? + + War is Peace. + Freedom is Slavery. + Ignorance is Strength. + + Normally manager types and those with the power to play Big Brother + don't care about this information. The Software Engineer responsible + for integration usually wants to know who is working on what and what + changed. Use your imagination. + + Last modified: _6/13/1997_ + + 4. I deleted my working directory and "history" still says I have it + checked out. How do I fix it? + + You can use "release -f" to forcibly add a "release" record to the + history file for a working directory associated with a "module". If + your version of "release" doesn't have the '-f' option, or you checked + out the directory using a relative path, you have to edit the + $CVSROOT/CVSROOT/history file. + + You can remove the last 'O' line in the history file referring to the + module in question or add an 'F' record. + + Last modified: _6/13/1997_ + + 5. So I *can* edit the History file? + + Yes, but if you are using history at all, you should take a little + care not to lose information. I normally use Emacs on the file, since + it can detect that a file has changed out from under it. You could + also copy and zero out the history file, edit the copy and append any + new records to the edited copy before replacing it. + + Last modified: _6/13/1997_ + + 6. Why does the history file grow so quickly? + + It stores 'U' records, which come in handy sometimes when you are + tracking whether people have updated each other's code before testing. + There should (and probably will sometime) be a way to choose what + kinds of events go into the history file. + + The contributed "cln_hist.pl" script will remove all the 'U' records, + plus matching pairs of 'O' and 'F' records during your normal clean up + of the history file. + + Last modified: _6/13/1997_ + + 7. What is the difference between "cvs history -r <tag/rev>" and "cvs + history -t <tag>"? + + The '-t' option looks for a Tag record stored by "rtag" in the history + file and limits the search to dates after the last <tag> of the given + name was added. + + The '-r' option was intended to search all files looking for the <tag> + in the RCS files. It takes forever and needs to be rewritten. + + Last modified: _6/13/1997_ + + 8. Why does "cvs history -c -t <tag>" fail to print anything? + + You have been using "tag" instead of "rtag". The "tag" command + currently doesn't store a history record. This is another remnant of + CVS's earlier firm belief in "modules". But it also has a basis in how + "rtag" and "tag" were originally used. + + "rtag" was intended for large-scale tagging of large chunks of the + Repository, an event work recording. "tag" was intended for adding and + updating tags on a few files or directories, though it could also be + used to tag the entire checked-out working tree when there is no + module defined to match the tree or when the working tree is the only + place where the right collection of revisions to tag can be found. + + Last modified: _6/13/1997_ + + 9. "cvs history -a -o" only printed one line for each checked-out module. + Shouldn't it print all the directories where the modules are checked out? + + Not as designed. + + Command Question it is supposed to answer. + ---------------- ------------------------------------------ + cvs history -o What modules do I have checked out? + cvs history -a -o <same for all users> + + cvs history -o -w What working directories have I created + and what modules are in them? + cvs history -a -o -w <same for every user> + + The -o option chooses the "checked out modules" report, which is the + default history report. + + Last modified: _6/13/1997_ + + 10. I can't figure out "history", can you give me concrete examples? + + Default output selects records only for the user who executes the + "history" command. To see records for other users, add one or more "-u + user" options or the '-a' option to select *all* users. + + 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 + * Modified files since last Friday: -c -D 'last Friday' + * Modified files since TAG was added: -c -t <tag> + * Modified files since TAG on files: -c -r <tag> + * Last modifier of file/Repository X? -c -l -[fp] X + * Modified files since string "str": -c -b str + * Tag history: (Actually "rtag".) -T + * History of file/Repository/module X: -[fpn] X + * Module report on "module": -m module + + Last modified: _6/13/1997_ + + 11. Can we merge history files when we merge Repositories? + + Assuming that the two Repositories have different sets of pathnames, + it should be possible to merge two history files by sorting them + together by the timestamp fields. + + You should be able to run: + + sort +0.1 ${dir1}/history ${dir2}/history > history + + If you "diff" a standard history file before and after such a sort, + you might see other differences caused by garbage (split lines, nulls, + etc) in the file. If your Repository is mounted through NFS onto + multiple machines you will also see a few differences caused by + different clocks on different machines. (Especially if you don't use + NTP to keep the clocks in sync.) + + Last modified: _6/13/1997_ + + Category: /Commands_/import_im_imp/ + + " + "import", "im", "imp"" + + 1. What is "import" for? + + The "import" command is a fast way to insert a whole tree of files + into CVS. + + The first "import" to a particular file within the Repository creates + an RCS file with a single revision on the "Vendor branch." Subsequent + "import"s of the same file within the Repository append a new revision + onto the Vendor branch. It does not, as some seem to believe, create a + new branch for each "import". All "imports" are appended to the single + Vendor branch. + + If the file hasn't changed, no new revision is created -- the new + "Release-Tag" is added to the previous revision. + + After the import is finished, files you have not changed locally are + considered to have changed in the "Main line of development". Files + you *have* changed locally must have the new Vendor code merged into + them before they are visible on the "Main line". + + See 4C.6 and 4C.15 + + Last modified: _6/13/1997_ + + 2. How am I supposed to use "import"? + + Create a source directory containing only the files you want to + import. Make sure you clean up any cruft left over from previous + builds or editing. You want to make sure that the directory contains + only what you want to call "source" from which everything else is + built. + + If this is not the first import from this "Vendor", you should also + compare the output of "find . ! -name CVS -print | sort" executed both + at the head of a checked out working directory and at the head of the + sources to be imported. If you find any deleted or renamed files, you + have to deal with them by hand. (See 4B.8 on renaming.) + + "cd" into your source directory and type: + + cvs import -m "Message" <repos> <Vendor-Tag> <Release-Tag> + + where <repos> is the relative directory pathname within the Repository + that corresponds to the sources you are importing. + + You might also consider using the "-I !" option to avoid ignoring + anything. It is easier to remove bogus files from the Repository than + to create a sparse tree of the ignored files and rerun "import". + + For example, if the FSF, CVS, Make and I are still active in the year + 2015, I'll import version 89.53 of GNU make this way: + + cvs import -m "GNUmake V89.53" gnu/make GNU GNUMAKE_89_53 + + See 3H.13 for more details. + + Last modified: _6/13/1997_ + + 3. Why does import put files on a branch? Why can't I work on the main + trunk instead of a Vendor branch? + + This was a Design choice. The Vendor branch is the way "import" deals + with a Vendor release. It is a solution to the Engineering problem of + how to merge multiple external releases of Vendor-supplied sources + into your ongoing work. The Vendor releases are kept on a separate, + special, "Vendor" branch and your work is kept on the RCS trunk. New + Vendor releases are imported onto the Vendor branch and then merged + into your work, if there is any, on the trunk. + + This way, you can use CVS to find out not only about your work, but + you can also find out what the Vendor changed by diffing between two + of the Release Tags you handed to "import". + + CVS was designed to work this way. If you use CVS in some other way, + you should think carefully about what you are doing. + + Note that the CVS "Main Branch" and the RCS Main Trunk are not the + same. Placing files on the Vendor Branch doesn't keep you from + creating a development branch to work on. + + See Section 4C, on Branching. + + If you are not working with 3rd party (i.e. Vendor) sources, you can + skip the "import" and avoid the Vendor branch entirely. It works just + as well to move pre-existing RCS files into Repository directories. + + You can create a whole Repository tree by copying a directory + hierarchy of normal source files directly into the Repository and + applying CVS to it. Here's an idea you should *test* before using: + + cd <your source tree> + set source = `pwd` + set module = xyzzy <<== Your choice of directory name + mkdir $CVSROOT/$module + cd $CVSROOT/$module + (cd $source; tar cf - .) | tar xvpBf - + find . -type f -exec ci -t-Original. {} \; + + The RCS "ci" command, without -u or -l options, will turn your source + file into an RCS (",v") and delete the original source. + + Last modified: _6/13/1997_ + + 4. Is there any way to import binary files? + + If you configured CVS to use the GNU version of "diff" and "diff3", + then you can import any kind of file. + + Binary files with RCS keywords in them are a problem, since you don't + want them to expand. + + If the tree you are about to "import" is entirely filled with binary + files, you can use the '-ko' option on "import". Otherwise, I would + run the import normally, then fix the binary files as described below + in 3H.5. + + See 4D.1 on Binary files. + + Last modified: _6/13/1997_ + + 5. Why does "import" corrupt some binary files? + + The RCS "co" command, when it is invoked by a CVS "checkout" or + "update" (or after a "commit") command, searches for and expands a + list of keywords within the file. They are documented in the RCS "co" + man page. Strings such as "$\Id$" (or "$\Id:"), or "$\Revision$" (or + "$\Revision:") are altered to the include the indicated information. + + [[Note: The keywords should appear in the text without the '\' + character I have inserted to *avoid* expansion here. The only real RCS + keywords in this document are at the top of the file, where I store + the Revision and Date.]] + + If RCS keyword strings show up in a binary file, they will be altered + unless you set the '-ko' option on the RCS files to tell RCS to keep + the original keyword values and not to expand new ones. After + "import", you can set the '-ko' option this way: + + cvs admin -ko <file> + rm <file> + cvs update <file> + + After an import that didn't use '-ko' (because the whole tree wasn't + of binary files) you should fix up the binary files as described above + before checking out any new copies of the files and before updating + any working directories you checked out earlier. + + See 4D.1 on Binary files. + + Last modified: _6/13/1997_ + + 6. How do I retain the original $\Revision$ strings in the sources? + + If you want to leave old RCS keywords as they are, you can use the + '-ko' tricks described above. + + Last modified: _6/13/1997_ + + 7. I imported some files for the Yarg compiler that compiles files with a + suffix of ".yarg" and whose comment prefix is "YARG> ". When I check them + out, they will no longer compile because they have this junk in them. Why? + + YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG> + YARG> $\Log: + # Revision 1.3 1998/03/03 00:16:16 bubba + # What is 2+2 anyway? + # + # Revision 1.2 1998/03/03 00:15:15 bubba + # Added scorekeeping. + YARG> + YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG> + + Well bubba, "Yarg" hasn't hit the big time yet. Neither RCS nor CVS + know about your suffix or your comment prefix. So you have two + choices: + + Check out the Yarg-less module, and tell all the files about your + comment prefix. Visit each directory and type: + + cvs admin -c"YARG> " *.yarg + + If *all* files in the whole directory tree are Yarg files, you can use + this instead: + + cvs admin -c"YARG> " . + + Then save any changes you made, remove all the "*.yarg" files and grab + new copies from the Repository: + + rm *.yarg (or: find . -name '*.yarg' -exec rm {} ';') (or: find . + -name '*.yarg' -print | xargs rm) (or: find . -name '*.yarg' -print0 | + xargs -0 rm if you have spaces in filenames and the GNU find/xargs.) + cvs update + + It might be faster to remove the whole directory and check it out + again. + + Change the import.c file in the CVS sources and add the .yarg + suffix, along with the "YARG> " comment prefix to the "comtable" + array. + + If you ever plan to add new files with $\Log in them, you should also + go into the RCS sources and make the same change in the table + contained in the "rcsfnms.c" file. + + Then delete the imported files from the Repository and re-"import" the + sources. + + Last modified: _6/13/1997_ + + 8. How do I make "import" save the timestamps on the original files? + + Use "import -d" to save the current timestamps on the files as the RCS + revision times. + + See 4D.8 for another aspect of file timestamps. + + Last modified: _6/13/1997_ + + 9. Why can't I "import" 3 releases on different branches? + + I'll bet you typed something like this: + + cd /src/blasto.v2 + cvs import -b 1.1.2 VENDOR2 Version2 + cd /src/blasto.v3 + cvs import -b 1.1.3 VENDOR3 Version3 + cd /src/blasto.v4 + cvs import -b 1.1.4 VENDOR4 Version4 + + This is wrong, or at least it won't help you much. You have created + three separate Vendor branches, which is probably not what you wanted. + + Earlier versions of CVS, as described in Brian Berliner's Usenix + paper, tried to support multiple Vendor branches on the theory that + you might receive source for the *same* program from multiple vendors. + It turns out that this is very rare, whereas the need to branch in + *your* development, for releases and for project branches, is much + greater. + + So the model now is to use a single vendor branch to contain a series + of releases from the same vendor. Your work moves along on the Main + Trunk, or on a CVS branch to support a real "branch in development". + + To set this up, you should type this instead of the above: + + cd /src/blasto.v2 + cvs import VENDOR Version2 + cd /src/blasto.v3 + cvs import VENDOR Version3 + cd /src/blasto.v4 + cvs import VENDOR Version4 + + Last modified: _6/13/1997_ + + 10. What do I do if the Vendor adds or deletes files between releases? + + Added files show up with no extra effort. To handle "removed" files, + you should always compare the tree structure of the new release + against the one you have in your Repository. If the Vendor has removed + files since the previous release, go into a working directory + containing your current version of the sources and "cvs remove" + (followed by "cvs commit" to make it really take effect) each file + that is no longer in the latest release. + + Using this scheme will allow you to "checkout" any version of the + vendor's code, with the correct revisions and files, by using + "checkout -r Version[234]". + + Renames are harder to find, since you have to compare file contents to + determine that one has occurred. If you notice one, see 4B.8 on + renaming files. + + Last modified: _6/13/1997_ + + 11. What about if the Vendor changes the names of files or directories, or + rearranges the whole structure between releases? + + Currently CVS can't handle this cleanly. It requires "renaming" a + bunch of files or directories. + + See 4B.8 on "renaming" for more details. + + What I generally do is to close the Repository for a while and make + changes in both the Repository and in a copy of the vendor release + until the structure matches, then execute the import. + + If you ever have to check out and build an old version, you may have + to use the new, or completely different Makefiles. + + Last modified: _6/13/1997_ + + 12. I thought "import" was for Vendor releases, why would I use it for code + of my own? Do I have to use import? + + For code you produce yourself, "import" is a convenience for fast + insertion of whole trees. It is not necessary. You can just as easily + create ",v" files using the RCS "ci" command and move them directly + into the Repository. + + Other than the CVSROOT directory, the Repository consists entirely of + directories of ",v" files. The Repository contains no other state + information. + + See Section 4B, on Setting up and Managing the Repository. + + Last modified: _6/13/1997_ + + 13. How do I import a large Vendor release? + + When the sum of the changes made by the Vendor and the changes made by + local developers is small, "import" is not a big problem. But when you + are managing a large Repository, any care taken up front will save you + time later. + + First read the following, then, before executing "import", see the + questions in Section 4C dealing with branch merges and Vendor branch + merges. + + If this is not the first import of this code, before starting, rtag + the whole directory you will be changing. + + The first step is to make sure the structure of the new files + matches the structure of the current Repository. + + Run "find . -print | sort" on both trees and "diff" the output. + + Alter the "source" tree until the "diff" (of the list of filenames, + not of the whole trees) shows that the directory structures are + equivalent. + + The "comm" command, if you have it, can help figure out what has been + added or deleted between releases. + + If they deleted any files, you can handle them cleanly with "cvs + remove". The command "comm -23 files.old files.new" will show you a + list of files that need to be removed. + + You should examine the list first to see if any have been renamed + rather than simply deleted. + + If they renamed any files, see 4B.8 on renaming files. + + Remember to *SAVE* the output from the import command. + + When you have dealt with removed and renamed files, then you can + execute the import: + + cd <new source> + cvs import -I ! -m "Message" <repos> <VendorTag> <ReleaseTag> + + Where + + "-I !" is an optional argument that keeps "import" from ignoring + files. The comparison of the "find" commands above will probably avoid + the need for this, but it is easier to remove files from the + Repository than to run a subset "import" to catch just the ignored + files. [You might have to quote or backwhack the '!'.] + + Message is the log message to be stored in the RCS files. + + <repos> is a relative path to a directory within the + Repository. The directory <new source> must be at + the same relative level within the new sources as + the <repos> you give is within the Repository. (I + realize this is not obvious. Experiment first.) + + <VendorTag> is a Tag used to identify the Vendor who sent you + the files you are importing. All "imports" into + the same <repos> *must* use the same VendorTag. + You can find it later by using the "log" command. + + <ReleaseTag> is a Tag used to identify the particular release of the + software you are importing. It must be unique and should be mnemonic + -- at least include the revision number in it. (Note: you can't use + '.' characters in a Tag. Substitute '_' or '-'.) + + There will be six categories of files to deal with. (Actually there + are eight, but you have already dealt with "removed" and "renamed" + files.) + + If this is the first "import" into a given <repos> directory, only the + first three of these ('I', 'L' and 'N') can occur. + + Ignored file. + + CVS prints: I filename + + You'll need to examine it to see if it *should* have been ignored. If + you use "-I !", nothing will be ignored. + + Symbolic link. + + CVS prints: L linkname + + Links are "ignored", but you'll probably want to create a "checkout + helper" function to regenerate them. + + New file. + + CVS prints: N filename + + CVS creates a new file in the Repository. You don't have to do + anything to the file, but you might have to change Makefiles to refer + to it if this is really a new file. + + A file unchanged by the Vendor since its last release. + + CVS prints: U filename + + CVS will notice this and simply add the new ReleaseTag to the latest + rev on the Vendor branch. + + No work will be needed by you, whether you have changed the file or + not. No one will notice anything. + + A file changed by the Vendor, but not by you. + + CVS prints: U filename + + CVS should add the file onto the vendor branch and attach the Release + Tag to it. + + When you next execute "update" in any working directory you'll get the + new revision. + + A file changed by both the Vendor and by you. + + CVS prints: C filename + + These are the trouble files. For each of these files (or in groups -- + I usually do one directory at a time), you must execute: + + cvs update -j <PreviousReleaseTag> -j <ReleaseTag> + or + cvs update -j <VendorTag:yesterday> -j <VendorTag> + + It will print either 'M' (if no overlaps) or 'C', if overlaps. If a + 'C' shows up, you'll need to edit the file by hand. + + Then, for every file, you'll need to execute "cvs commit". + + See the part of Section 4C dealing with branch merges. + + If you are truly performing a large import, you will most likely + need help. Managing those people is another problem area. + + Since the merge of the Vendor branch is just like any other merge, you + should read section 4C for more info about performing and cleaning up + merges. + + The larger the import, and the larger the group of people involved, + the more often you should use "tag" and "rtag" to record even trivial + milestones. See 4C.14, especially the "paranoid" section. + + Before starting the import, you should install and test a "commitinfo" + procedure to record all commits in a file or via Email to a mail + archive. Along with the tags you placed on the Repository before the + import, this archive will help to track what was changed, if problems + occur + + There are four stages to the recovery: + + Parcel out the work -- Effective Emacs Engineering. + + As input to the assignment process, you might want to examine the tree + and record the last person who changed the file. You can also + research, if you don't already know, who is expert in each area of the + software. + + Examine the import log (you saved the output, right?), estimate how + much work is involved in each area and assign groups of files to + individual developers. Unless some directory is immense, it is easier + to manage if you assign whole directories to one person. + + Keep a list. Suggest a completion date/time. Tell them to "commit" the + file when they are finished with the merge. If you tagged the + Repository before starting the import, you should have no trouble + figuring out what happened. + + If you can, find out (or tell them) which working directory to use. + You should verify that the working directory they use is on the Main + Branch ("update -A") and without modified files. + + If you trust your crew, have them notify you by Email. Have them send + you the output from "cvs update" in their working directory. You might + have to poll some people until you are certain they have finished, or + have given up. (This is not an invention. I've heard a false, "Yeah, + sure. I finished yesterday," more times that you'd believe.) + + When all reports are in, go on to the Source Verification stage. + + Source Verification -- CVS and other Tools. + + If you didn't dictate which ones to use, find all working directories + and run "cvs -n update" in all of them. The history command and the + "commitinfo" log you set up might help to find checked out working + directories. + + Sticky conflict flags will help, but they can't recover from + sloppiness or incompetence. You might want to check everything out + into a tree and grep for the parts of the merge conflict markers CVS + doesn't look for. CVS looks for the string '^>>>>>>> '. The merge + operation also puts '^<<<<<<< ' and '^======= ' markers in the file + that careless developers might leave there. + + If you find problems simply by looking at the source files and working + directories, start the flogging now. Resolving the textual conflicts + is the easy part. Weed the turkeys out before reaching the next part + of the cleanup -- the resolution of logical conflicts. + + Then apply a set of post-commit tags. + + Logical Verification -- Diff and powerful eyeballs. + + No source control system can solve the problem of resolving + distributed conflicts in program logic. If you change the argument + template for function A (defined in file A.c) and add new calls to + function A from within function B (defined in file B.c) using the old + argument format, you are outside the realm of CVS's competence. + + Assign someone to understand what the Vendor changed by running "cvs + diff -c -r <PreviousReleaseTag> <ReleaseTag>", where the tags were + those handed to the last two invocations of "import". + + Then have the same person compare that output (logically or you can + actually diff the diffs) to the output of the similar "cvs diff -c -r + <pre-import-tag> <post-commit-tag>". The two sets of differences + should be almost identical. They should both show only the work *you* + have performed. + + Product Verification -- Build and Test. + + Don't let your help off the hook until you verify that the merge + actually produced something that can compile and pass tests. Compiling + should really be part of the logical verification phase, but you + should test the output of the build system before declaring victory + and releasing the troops. + + After it is all built, apply another set of tags to mark the end of + the "import process". You can delete the intermediate tags you added + during source and logic testing, but keep the "pre-import" and + "post-import" tags forever. + + Of course, experience can tell you when to skip a step. But I'd start + out by considering each one as necessary unless you can prove + otherwise. + + Last modified: _6/13/1997_ + + 14. Explain: ERROR: cannot create link to <file>: Permission denied + + This error appears when you try to execute a second (or later) + "import" into the same module from a directory to which you don't have + write access. + + The "link error" is caused by a feature purposely added to speed up + the import. + + Though the error message is somewhat strange, it indicates that + "import" is supposed to be executed only in writable directories. + + Last modified: _6/13/1997_ + + 15. Where does the -m <message> go when the file doesn't change? + + The <message> handed to import is used as an RCS log message, but only + if the imported file changed since the last version on the Vendor + branch. If the imported file hasn't changed, then no new revision is + created. The <ReleaseTag> is still applied, but to the previous + revision. So the Tags are still correct, but the message is lost. + + Maybe it should be appended to the previous log message. But currently + it isn't. + + Last modified: _6/13/1997_ + + 16. How do I "import" just the files ignored by a previous "import"? + + A real answer follows, but first, an editorial: + + I am now convinced that you should always use the "-I !" option. + Removing a few extraneous files from the Repository is a lot easier + than the recovery step described below. + + Let's assume your original import procedure was: (We assume there is + enough disk space in /tmp.) + + cd <head-of-vendor-tree> + cvs import -m 'xyz 1.3' gnu/xyz GNU GNUXYZ_1_3 | tee /tmp/IMP + + To import just the files ignored by "import", I would do this: + + Create a list of the ignored files to import: + + cd <head-of-vendor-tree> awk '/^I / {print $2}' /tmp/IMP | sed + 's|^gnu/xyz/||' > /tmp/IG [Edit the IG file to contain just the files + you want.] + + Then create a sparse directory by handing your list to the GNU + version of "tar", installed in many places as "gtar": + + mkdir /tmp/FIXUP gtar -T /tmp/IG -c -f - . | (cd /tmp/FIXUP; gtar xvBf + -) + + Then rerun the import. Use the exact same command, but execute it in + the sparse directory tree you just created. And this time, tell it not + to ignore anything. + + cd /tmp/FIXUP + cvs import -I ! -m 'xyz 1.3' gnu/xyz GNU GNUXYZ_1_3 + + Last modified: _6/13/1997_ + + 17. Why did "import" ignore all the symlinks? + + This is another design choice. + + Like the Unix "tar" command, "import" could sprout an option to follow + symbolic links, but I don't think CVS will ever follow symbolic links + by default. + + Two possible future enhancements have been seriously discussed: + + Treat symbolic links as data in its parent directory (the way + ClearCase does) in some sort of per-directory control file. + + Treat symbolic links as version-controlled elements themselves, + whose data is the value of readlink(2). + + For now, they are simply ignored. + + If you want to save and reconstruct symlinks, you might want to define + a "checkout" or "update" program in the modules file which could + consult a file kept under CVS in your working directory and make sure + the specified links are in place. + + Last modified: _6/13/1997_ + + Category: /Commands_/log_lo_rlog/ + + " + "log", "lo", "rlog"" + + 1. What is "log" for? + + To provide an interface to the RCS "rlog" command, which displays + information about the underlying RCS files, including the revision + history and Tag (RCS calls it a "symbol") list. + + Last modified: _6/13/1997_ + + 2. How do I extract the log entries between two revisions? + + If both <rev1> and <rev2> are on the same branch, you can get what you + are looking for with: (If they aren't on the same branch you'll either + get an error or a display of the whole change log.) + + cvs log -r<rev1>:<rev2> <file> + + If you want all the revisions on the branch from <rev1> to the end of + the branch <rev1> is on, you can use: + + cvs log -r<rev1>: <file> + + (If <rev1> is a numeric RCS symbol attached to a branch revision with + an even number of '.'s in it, you get the whole branch.) + + If you want all the revisions on the branch from the beginning of the + branch <rev2> is on up to revision <rev2>, you can use: + + cvs log -r:<rev2> <file> + + Note: Depending on whether <rev1> and <rev2> are: + + - numeric or symbolic + - in the file or not + - on the same branch or not + + the RCS "rlog" (and therefore the "cvs log") command will + display some combination of: + + - error messages + - (intuitively correct) partial log listings + - a display of the entire change log. + + Last modified: _6/13/1997_ + + 3. How do I extract the log entries on a whole branch? + + cvs log -r<rev> <file> + + where <rev> must be a branch revision (one with an even number of + dots) or a *non-branch* tag on a branch revision. Non-branch tags on a + branch revision are not normally attached by CVS, to add one you will + have to explicitly tag a physical branch number within each file. + Since these branch numbers are almost never the same in different + files, this command is not all that useful. + + The intuitive command (at least from the CVS perspective): + + cvs log -r<branch_tag> <file> + + does not work. + + Last modified: _6/13/1997_ + + 4. How do I generate ChangeLogs from RCS logs? + + A program called rcs2log is distributed as part of GNU Emacs 19. A + (possibly older) version of this program appears in the contrib + directory of the cvs source tree. + + Last modified: _6/13/1997_ + + 5. Why does "log" tell me a file was committed exactly 5 hours later + + than I know it was? + + I can tell by this question that you were working in a time zone that + is 5 hours behind GMT (e.g. the U.S. East Coast in winter). + + RCS file dates are stored in GMT to allow users in different time + zones to agree on the meaning of a timestamp. At first glance this + doesn't seem necessary, but many companies use distributed file + systems, such as NFS or AFS, across multiple timezones. + + Some standard form must be used. GMT, as the "grid origin", is an + obvious candidate. The only other reasonable choice is to put the + timezone information in all the time stamps, but that changes the RCS + file format incompatibly, a step which has been avoided in the last + few RCS releases. + + Last modified: _6/13/1997_ + + Category: /Commands_/patch_pa_rdiff/ + + " + "patch", "pa", "rdiff"" + + 1. What is "patch" for? + + To produce a "diff" between tagged releases to be handed to the + "patch" command at other sites. This is the standard way that source + patches are distributed on the network. + + Last modified: _6/13/1997_ + + 2. Why does "patch" include files from the Attic when I use '-D'? + + See the explanation of the same problem with "update -D" contained in + section 5B. + + Last modified: _6/13/1997_ + + 3. How do I make "patch" produce a patch for one or two files? It seems to + work only with modules. + + Patch is intended for producing patches of whole modules between + releases to be distributed to remote sites. Instead of "patch", you + can use the "diff" command with the '-c' context option: + + cvs diff -c -r <rev/tag> -r <rev/tag> <file1> . . . + + The patch command will be able to merge such a "diff" into the remote + source files. + + If you configured CVS to use a version of "diff" that supports the + '-u' option, you can produce a more compact "patch" in "unidiff" + format. The latest revisions of the patch command can parse and apply + patches in "unidiff" format. + + Last modified: _6/13/1997_ + + Category: /Commands_/release_re_rel/ + + " + "release", "re", "rel"" + + 1. What is "release" for? + + To register that a module is no longer in use. It is intended to + reverse the effects of a "checkout" by adding a record to the history + file to balance the checkout record and by optionally allowing you to + delete the checked-out directory associated with the module name. + + Last modified: _6/13/1997_ + + 2. Why can't I reverse a "cvs checkout path/name/subdir" with a "cvs + release path/name/subdir" without an "unknown module name"? + + A simplistic implementation. (I can say this -- I wrote it.) + + The "release" function was written for CVS 1.2 under the assumption + that the "module name" is a first class, unavoidable interface to the + Repository, allowing no way to retrieve anything other than by module + name. Though it is easier to program that way, many users of CVS + believe the modules support to be too primitive to allow such a + limitation. + + Since "release" was written, other parts of CVS broke that assumption. + It needs to be revised. + + Last modified: _6/13/1997_ + + 3. Why can't I "release" portions of a checked out directory? I should be + able to "release" any file or sub-directory within my working directory. + + This isn't really a limitation in "release", per se. CVS doesn't try + to keep track of which files in which directories are "checked out" + and which are just lying there. You can delete directories and + "update" will not bring them back unless you add a special "-d" + option. + + In other words, CVS doesn't keep track of how you adjust the partition + between files you consider part of your working set and files that + were checked out because they are part of the same module or + directory. And neither does "release". + + In future CVS releases, "release" might become sophisticated enough to + handle both the reversal of a "checkout" and the deletion of random + portions of the working directory, but it isn't that way now. + + Last modified: _6/13/1997_ + + 4. I removed the tree that I was about to start working on. How do I tell + cvs that I want to release it if I don't have it anymore? + + See 3G.4. + + Last modified: _6/13/1997_ + + 5. Why doesn't "release -d module" reverse a "checkout module"? + + It does, if you are using "module" in a way that "release" expects: a + non-alias string in the left column of the "modules" database. + + If "module" is really an alias, or if you are using a relative path in + the place of "module", or if you renamed the directory with the -d + option in the modules file or on the "checkout" command line, then the + current version of "release" won't work. + + Future versions of "release" will probably fix most of these. + + Last modified: _6/13/1997_ + + 6. Why can't I release a module renamed with "cvs checkout -d"? + + The current version of "release" doesn't know how to track the + renaming option ('-d') of the "checkout" command. It will probably be + fixed in the future. + + Last modified: _6/13/1997_ + + Category: /Commands_/remove_rm_delete/ + + " + "remove", "rm", "delete"" + + 1. What is "remove" for? + + To remove a file from the working branch. It removes a file from the + main branch by placing it in an "Attic" directory. + + Last modified: _6/13/1997_ + + 2. Why doesn't "remove" work on directories when it appears to try? + + Oversight. It should be able to delete an empty directory, but you + still don't have a way to remember when it was there and when it + disappeared to allow the "-D " option to work. + + You'll have to remove the working directory and the matching directory + in the Repository. + + Note that you want to do a _cvs remove dir_ in the working directory, + do a cvs commit, and then do a _rmdir dir_ in the Repository. + (msusrtsp.mark at eds dot com) + + Last modified: _12/18/1997_ + + 3. I don't like removing files. Is there another way to ignore them? + + There's no reason to be hasty in using the "remove" command. + + If there is a way to ignore files in your build procedures, I'd just + do that. Later, when you decide that the files are really ancient, you + can execute a "remove" command to clean up. + + The CVS "ignore" concept can't ignore files already in CVS. + + Last modified: _6/13/1997_ + + 4. I just removed a file. How do I resurrect it? + + If you executed "remove", but haven't typed "commit" (you can tell + this by the 'R' notation that "update" prints next to the file), you + can execute "add" to reverse the "remove". + + If you followed the "remove" with a "commit", you'll have to move it + back out of the Attic by hand: + + I use something like this: (csh-like syntax) + + set repos = `cat ./CVS/Repository` + mv $repos/Attic/filename,v $repos/filename,v + + (If you use relative paths in your Repository files, that first line + becomes: set repos = $CVSROOT/`cat ./CVS/Repository`) + + While a file is in the Attic, you can't "add" another file by the same + name. To add such a file you either have to move it by hand as in the + above, or delete it from the Attic. + + The main reason for the Attic is to retain files with tags in them. If + you execute: "update -r <oldtag>", files with <oldtag> attached to + some revision will be taken from the normal Repository area and from + the Attic. That's why you can't "add" a file with the same name. + "remove" only moves a file off the main branch, it doesn't obliterate + it. + + Last modified: _6/13/1997_ + + 5. Why doesn't "remove" delete the file? Instead, it prints an error + message and tells me to remove the file by hand. + + Design choice. Unix software written within last decade, usually + requires an extra verification step, such as answering a question or + adding a flag on the command line. CVS currently requires that you + delete the file first unless you specify the '-f' (force) option, + which deletes the file before performing "cvs remove". + + Last modified: _6/13/1997_ + + Category: /Commands_/rtag_rt_rfreeze/ + + " + "rtag", "rt", "rfreeze"" + + 1. What is "rtag" for? + + To add a symbolic label (a "tag") to the last committed revisions of a + module directly in the Repository. + + Last modified: _6/13/1997_ + + 2. Why use "rtag"? It assumes no one is changing the Repository. + + Though the "tag" command is more useful in marking the revisions you + have in a particular working directory, "rtag" is much handier for + whole-Repository actions, which occur at major release boundaries. + + Last modified: _6/13/1997_ + + 3. What revision does "rtag -r <tag1> <tag2>" actually put the tag on? + + In short, the '-r' option is another way to select the revision to + tag. The revision is selected the same way for all commands that + accept a "-r <tag/rev>" option. + + Depending on whether <tag1> is a <branch_tag>, or a non-branch <tag> + and on whether you use the '-b' option to "rtag", you get four + different results: + + rtag -r <tag1> <tag2> + + Adds the non-branch tag <tag2> to the same revision that the + non-branch tag <tag1> is attached to. + + Example: + <tag1> --> TT1 + <tag2> --> TT2 + <file> --> Symbols: TT1:1.4 + After --> Symbols: TT1:1.4,TT2:1.4 + + rtag -r <branch_tag1> <tag2> + + Adds the non-branch tag <tag2> to the HEAD of (the highest revision + number on) the branch labelled with tag <branch_tag1>. + + Example: + <branch_tag1> --> BR1 + <tag2> --> TT2 + <file> --> Symbols: BR1:1.2.0.2 (1.2.2.5 is HEAD) + After --> Symbols: BR1:1.2.0.2,TT2:1.2.2.5 + + If the branch tagged by <branch_tag1> has not been created, then the + tag shows up on the branch point revision: + + Example: + <branch_tag1> --> BR1 + <tag2> --> TT2 + <file> --> Symbols: BR1:1.2.0.2 (No 1.2.X exists.) + After --> Symbols: BR1:1.2.0.2,TT2:1.2 + + rtag -b -r <tag1> <branch_tag2> + + Adds the magic branch tag <branch_tag2> to the revision that the + non-branch tag <tag1> is attached to, preparing it to be a branch + point. + + Example: + <tag1> --> TT1 + <branch_tag2> --> BR2 + <file> --> Symbol: TT1:1.4 + After --> Symbol: TT1:1.4, BR2:1.4.0.2 + + rtag -b -r <branch_tag1> <branch_tag2> + + Adds the magic branch tag <branch_tag2> to the revision at the HEAD of + (the highest revision number on) the branch labelled with + <branch_tag1>, preparing it to be a branch point. + + Example: + <branch_tag1> --> BR1 + <branch_tag2> --> BR2 + <file> --> Symbol: BR1:1.2.0.2 (1.2.2.5 is HEAD) + After --> Symbol: BR1:1.2.0.2,BR2:1.2.2.5.0.2 + + If the branch tagged by <branch_tag1> has not been created, then the + tag shows up as a second branch off the same branch point revision: + + Example: + <branch_tag1> --> BR1 + <tag2> --> TT2 + <file> --> Symbols: BR1:1.2.0.2 (No 1.2.X exists.) + After --> Symbols: BR1:1.2.0.2,TT2:1.2.0.4 + + In all four cases above, if <tag2> already exists on the file, you get + an error unless you specify the '-F' option. + + In all four cases, if <tag1> does not exist on the file, <tag2> is not + added unless you specify the '-f' option. + + Last modified: _6/13/1997_ + + 4. What happens if the tags are the same in "rtag -r <tag> <tag>"? + + Again, there are four cases depending on whether <tag> is a branch + tag, or a non-branch tag and on whether you use the '-b' option to + "rtag": + + rtag -r <tag> <tag> + + Is a no-op. It does nothing even with '-F' specified. + + If you add the '-f' option ("rtag -f -r <tag> <tag>"), then <tag> is + attached to the latest revision on the Main Branch if the file does + *not* already have <tag> on some revision. + + If the <tag> is already on the file, using "rtag -f" is still a no-op. + + rtag -r <branch_tag> <branch_tag> + + Produces an error, since the <branch_tag> is already on some revision + of the file. + + But, "rtag -F -r <branch_tag> <branch_tag>" turns the magic branch tag + into a non-branch tag. + + Symbols: BR1:1.4.0.2 becomes Symbols: BR1:1.4 + + rtag -b -r <tag> <tag> + + Produces an error, since the <tag> is already on the file. + + But, "rtag -F -b -r <tag> <tag>" turns the non-branch tag into a magic + branch tag. + + Symbols: BR1:1.4 becomes Symbols: BR1:1.4.0.2 + + rtag -b -r <branch_tag> <branch_tag> + + Produces an error, since the <branch_tag> is already on the file. + + But, "rtag -F -b -r <branch_tag> <branch_tag>" increments the branch + number. It essentially removes the branch and creates a new one by the + same name. + + Symbols: BR1:1.2.0.4 becomes Symbols: BR1:1.2.0.6 + + Last modified: _6/13/1997_ + + 5. Why doesn't "rtag -b -r <branch_tag1> <branch_tag2>" rename or duplicate + a magic branch tag? + + None of the "tag" or "rtag" options rename anything. They only apply + (or, with the '-F' option, move) tags to specific revisions in the + file. + + See 3M.[3-4] above for details of how it works. + + To rename a non-branch tag, see 3O.9. To rename a magic branch tag, + see 4D.5 + + Last modified: _6/13/1997_ + + Category: /Commands_/status_st_stat/ + + " + "status", "st", "stat"" + + 1. What is "status" for? + + To display the status of files, including the revision and branch you + are working on and the existence of "sticky" information. + + Last modified: _6/13/1997_ + + 2. Why does "status" limit the File: at the top to 17 characters? + + Designed that way to line up with other data. You can find the whole + filename in the line beginning with "RCS version:", which is not + limited in length. + + Last modified: _6/13/1997_ + + 3. Why does it print "Sticky" lines when the values are "(none)"? + + Oversight. It should probably elide lines without information. + + Last modified: _6/13/1997_ + + 4. Shouldn't the status "Needs Checkout" be "Needs Update"? + + Probably. + + [[Did this show up in CVS 1.4?]] + + Last modified: _6/13/1997_ + + Category: /Commands_/tag_ta_freeze/ + + " + "tag", "ta", "freeze"" + + 1. What is "tag" for? + + To add a symbolic label (a "tag") to the RCS files last checked out, + updated or committed in a working directory. + + Last modified: _6/13/1997_ + + 2. What is the difference between "tag" and "rtag"? + + The end result of both commands is that a <tag>, or symbolic name, is + attached to a single revision in each of a collection of files. + + The differences lie in: + + The collection of files they work on. + + "rtag" works on the collection of files referred to by a "module" name + as defined in the "modules" file, or a relative path within the + Repository. + + "tag" works on files and directories specified on the command line + within the user's working directory. (Default is '.') + + Both commands recursively follow directory hierarchies within the + named files and directories. + + The revisions they choose to tag. + + "rtag" places a tag on the latest committed revision of each file on + the branch specified by the '-r' option. By default it tags the Main + Branch. + + "tag" places a tag on the BASE (i.e. last checked out, updated or + committed) revision of each file found in the working directory. (The + BASE revision of a file is the one stored in the ./CVS/Entries file.) + + A different set of command line options. + + For example, "rtag" takes a "-r <oldtag>" option to retag an existing + tag. The "tag" command does not. + + How it is logged. + + Currently "rtag" records the <tag> and the module in the "history" + file, while "tag" does not. + + Last modified: _6/13/1997_ + + 3. Why does "tag -b" not put a tag on the Branch Point revision? How do I + refer to the Branch Point? + + This is probably an oversight, or a disbelief in the need for it. If + everything works perfectly, the "update -j" command will do the merge + you need and you don't need to check up on it by playing with the + branch point revision. + + The '-b' option attaches a magic branch tag to allow CVS later to + figure out the branch point. The actual revision that <tag> is + attached to does not exist. References to the branch tag are + equivalent to references to the latest revision on the branch. + + There is no way to refer to the branch point without adding a + non-branch tag. You might want to add non-branch tags as a habit and + add branch tags later, possibly immediate after adding the non-branch + tag. See 4C.3 on Creating a Branch. + + Last modified: _6/13/1997_ + + 4. So "{r}tag" labels a bunch of files. What do you use a Tag for? + + You use it to "checkout" the labeled collection of files as a single + object, referring to it by name. + + Anywhere a revision number can be used a Tag can be used. In fact tags + are more useful because they draw a line through a collection of + files, marking a development milestone. + + The way to think about a Tag is as a curve drawn through a matrix of + filename vs. revision number. Consider this: + + Say we have 5 files (in some arbitrary modules, some may be in 2 or + more modules by name, some may be in 2 or more modules because of the + Repository tree structure) 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. 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 draw a straight line + through the set of revisions you care about and shuffle the other + revisions accordingly. 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 + + I find that using these visual aids, it is much easier to understand + what a <tag> is and what it is useful for. + + Last modified: _6/13/1997_ + + 5. How do I get "tag" and "rtag" to send mail the way "commit" does? + + The "commit" command is supported by two files ("commitinfo" and + "loginfo") not used by other commands. To do logging the same way for + "tag" and "rtag" would require another file like loginfo, which + currently doesn't exist. + + The "rtag" command requires a "module" entry, which can specify a + "tag" program using the "-t programname" option on the module line. + + There is no equivalent support for "tag". + + Last modified: _6/13/1997_ + + 6. Why can't "tag" handle the '-r' option that "rtag" takes? + + Oversight. The answer is probably "Fixed in a Future Release." + + Last modified: _6/13/1997_ + + 7. After a "tag <tag>" in my working directory, why doesn't "checkout -r + <tag>" somewhere else produce copies of my current files? + + The only reason this would fail, other than misspelling the <tag> + string, is that you didn't "commit" your work before "tagging" it. + Only committed revisions may be tagged. Modified files are not marked + for later tagging. + + Last modified: _6/13/1997_ + + 8. Why doesn't "tag" write a history record the way "rtag" does? + + The "rtag" command was originally intended to place major "release" + tags onto modules. The "tag" functionality was developed to *move* the + more significant tag when slight changes to individual files sneaked + in after the release tag was stamped onto the Repository. + + The significant event was the "rtag", which was recorded in the + "history" file for the "history -T" option to work. + + It turns out that "tag" is generally more useful than "rtag", so the + model has changed. Future revisions of CVS will probably store both + kinds of tags in the history file. + + Last modified: _6/13/1997_ + + 9. How do I rename a <tag>? + + For a procedure to rename a branch tag, See section 4D.5 The following + covers only non-branch tags. + + First, pick a <newtag> that is not in use. You could reuse (i.e. move) + an existing tag to the new revisions using the '-F' option, but that + will confuse matters when both tags are not already on a file. (It + will probably confuse "rtag -f" too.) + + Use "rtag" to place <newtag> only on revisions attached to <oldtag> in + the whole Repository, then delete the old one. + + cvs rtag -r <oldtag> <newtag> world + cvs rtag -d <oldtag> world. + + You can also checkout or update your working directory to the <oldtag> + and "tag" rather than "rtag" the result. But that will take longer and + it has the chance of producing conflicts. + + cvs update -r <oldtag> + cvs tag <newtag> + cvs tag -d <oldtag> + cvs update -A (or cvs update -r <previous_tag>) + + Last modified: _6/13/1997_ + + Category: /Commands_/update_up_upd/ + + " + "update", "up", "upd"" + + 1. What is "update" for? + + The "update" command is by far the most important command and is + probably also the most used command. + + It has five purposes: (And many options.) + + To display the status of your working files. + + Though a plain "update" also displays the status, it does so after + possibly altering your working directory. To see the status of your + working files without changing anything, type: + + cvs -n update {optional list of files} + + To merge changes made by others to the branch you are working on + into your working files. + + Each working directory is attached to a branch, usually the Main + branch. To merge changes made on your working branch since your last + checkout, update or commit, type: + + cvs update {optional list of files} + + To merge changes made on another branch into the branch you are + working on (your "working branch"). + + If you want to grab a whole branch, from the branch point, which is + assumed to be on the Main Branch, to the end of the branch, you type: + + cvs update -j <branch_tag> {optional files} + + If you want to grab the changes made between two tags or revisions, + you type: + + cvs update -j <tag1> -j <tag2> {optional files} + + (If you are working with a single file, the Tags could also be + revisions numbers. Unless you take great care to match revision + numbers across different files (a waste of time given the way Tags + work), using revision numbers in place of the Tags for multiple files + would be meaningless.) + + To move your working directory to another branch. + + A working directory is presumed to be attached to (or working on) a + particular branch, usually the Main branch. To alter what CVS believes + to be your working branch, you "move" to that branch. + + To move to a tagged branch, type: + + cvs update -r <branch_tag> {optional files} + + To move to the Main Branch, type: + + cvs update -A {optional files} + + If you have modified files in your working directory, this is not a + clean move. CVS will attempt to merge the changes necessary to make it + look like you made the same changes to the new branch as you made in + the old one. But if you do this twice without resolving the merge + conflicts each time, you can lose work. + + To retrieve old revisions of files. + + This option is similar to 4 above but you are not restricted to using + a <branch_tag>. You may specify any revision or <tag> with '-r' and + get the specified revision or the tagged revision: + + cvs update -r <tag/rev> {optional files} + + Or you may specify any date with '-D': + + cvs update -D <date> {optional files} + + The '-p' option sends the revisions to standard output (normally your + terminal) rather than setting the "sticky" tag and changing the files. + + Last modified: _6/13/1997_ + + 2. What do 'U', 'M' and 'C' mean when I type "update"? Are they different + for "cvs -n update"? + + "cvs update" merges changes made to the Repository, since your last + "checkout", "update" or "commit", into your working files. You can + think of it as changing your BASE revision. + + "cvs update" prints lines beginning with: + + 'U' after replacing your unmodified file with a different + revision from the Repository. + + 'M' for two different reasons: + + for files you have modified that have not changed in the Repository. + + after a merge, if it detected no conflicts. + + 'C' after a merge, if it detected conflicts. See 2D.7 and 3P.6 for + more info on conflict resolution and "sticky conflicts." + + "cvs -n update" shows what it *would* do, rather than doing it. Or, + another way of looking at it, "cvs -n update" displays the + relationship between your current BASE revisions (identified in your + ./CVS/Entries file) and the HEAD revisions (the latest revisions in + the Repository). + + "cvs -n update" prints lines beginning with: + + 'U' for files you have not modified that have changed in the + Repository. + + 'M' for files you have modified that have not changed in the + Repository. + + 'C' for files you have modified that have also been changed in the + Repository. + + See 4C.6 for what the letters mean when merging in from another + branch. The output is almost the same for a normal update if you + consider the Repository as the branch and your working directory as + the "trunk". + + Last modified: _6/13/1997_ + + 3. What's the difference between "update" and "checkout"? + + See 3C.4 above. + + Last modified: _6/13/1997_ + + 4. Why don't I get new files when I execute "update"? + + There are six reasons for nothing to happen during an "update": + + Nothing on your branch changed in the Repository. + + If no one has committed anything to the branch you are working on + (normally the Main branch) since the last time you executed + "checkout", "update" or "commit", nothing will happen. + + It's like shouting "xyzzy" or "plugh" in the wrong room. + + You have a "sticky" non-branch <tag> or <date> attached to the + working files you are trying to "update". + + At some time in the past you checked out or updated your directory + with the "-r <tag>" or "-D <date>" option. Until you do it again with + a different tag or date, or go back to the Main Branch with "update + -A", you will never again see any updates. + + The ./CVS/Entries.Static file exists and you are expecting a new + file. + + If your ./CVS administrative directory contains a file named + Entries.Static, no files will be checked out that aren't already in + the Entries or Entries.Static file. + + You forgot to use the '-d' option and are looking for new + directories. + + If you execute "update" without the '-d' option, it will not create + new directories that have been added to the Repository. + + You typed "update" instead of "cvs update". + + On most Unix systems, your disk caches are now furiously being flushed + by multiple update daemons, destroying performance and proving to + management that you need more CPU power. :-) + + On HP systems you might be asked what package you want to install from + the "update server". + + Someone removed (using "admin -o") your BASE revision (the revision + CVS thought you had in your working directory), then committed a + "replacement". CVS is now confused because the revision in the + Repository matches your BASE revision when the files themselves don't + match. See 3B.6. + + Last modified: _6/13/1997_ + + 5. Why does "update" say 'M' both for plain modified files and for + successful (i.e. conflict-free) merges? Aren't they different? + + A design choice. Yes, they are different internally, but that + shouldn't matter. Your files are in the same condition after the + "update" as they were before -- a "diff" will display only your + modifications. And you are expected to continue onward with parts two + and three of the normal development cycle: "emacs" (a synonym for + "edit" in most of the civilized world) and "commit". + + Last modified: _6/13/1997_ + + 6. What's a "sticky conflict"? How does it know a conflict occurred? + + When a "cvs update" (or an "update -j") creates a conflict, it prints + a 'C' and stores the timestamp of the file after the merge in a + special field in the ./CVS/Entries file. + + This conflict indication implies that the merge command altered your + 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 + beginning of the file would look like this: + + <<<<<<< <file> The working <file> in question. + 7777 Change made to the working <file>. + ======= + 5555 Change made in the first commit (1.3) + >>>>>>> 1.3 The revision created by the first commit. + + The conflict is "sticky", which means that until the conflict is + cleared, the "update" command will continue to display the file's + status as 'C' and the "status" command will show the file's status as + "Unresolved Conflict". + + Until the conflict is cleared, "commit" is blocked for this file. + + The sticky conflict indicator can be cleared by: + + Resolving the conflict by editing the file. Two things must happen + before the conflict is considered resolved: + + The timestamp of the file must change. *and* The file must contain no + conflict markers. (The string searched for in the file is the regexp: + "^>>>>>>> ".) + + After clearing the sticky conflict indicator, you may then commit the + file normally. + + Removing the file and running "update". This throws away the local + changes and accepts the latest committed file on this branch. No + commit is needed. + + Forcing the commit to happen by using "commit -f". This is probably + a mistake since there are few lines of real text that begin with + ">>>>>>> ". + + Last modified: _6/13/1997_ + + 7. Is there a feature to tell me what I have changed, added and removed + without changing anything? + + The command "cvs -n update" will do exactly that. + + Last modified: _6/13/1997_ + + 8. Why were all my files deleted when I executed "update"? + + You probably executed "update -r <tag>" some time ago, then removed + <tag> from the Repository files. "update -r <tag>" will delete a file + that doesn't contain <tag>. + + A way to fix this is to "cd" into your working directory and type: + + cvs update -A + + If you don't want the latest revisions on the Main (or Vendor) Branch, + then decide what Tag (normal or branch) you want and type: + + cvs update -r <the_tag_you_want> + + Another way to make a file disappear is to execute "update -D <date>" + where <date> is before the date stamped onto the first revision in the + RCS file. + + Last modified: _6/13/1997_ + + Category: /Past__Future_/ + + " Past & Future " + + Category: /Past__Future_/Bugs_and_Patches/ + + " + Bugs and Patches" + + 1. Why can't CVS handle deletion of directories? + + An oversight, probably. [[Fixed in a future release?]] + + Last modified: _6/13/1997_ + + 2. Why can't CVS handle the moving of sources from one place in the + + directory hierarchy to another? + + A "renaming database" has been proposed to track the history of + pathname changes in the Repository. A general solution is a difficult + problem. See 4B.8. + + Last modified: _6/13/1997_ + + 3. When I typed "cvs update -D <date>", why did it check out all + + sorts of ancient files from the Attic? Shouldn't it just create the + set of files and revisions that existed at that date? + + This seems to be a bug, but is really the lack of any obvious place to + store the date when a file is "removed". + + There are four ranges of dates that CVS has to deal with when trying + to determine what revision was available on <date>: + + Dates before the earliest revision in the file. + + Dates between any two revisions in the file. + + Dates between the latest revision in the file and the date when the + file was moved to the Attic by "commit". + + Dates after moving the file to the Attic. + + Since the date when a file is moved to the Attic is not stored + anywhere, CVS can't tell the difference between #3 and #4. To avoid + not producing a file that should exist in case #3, it produces + extraneous files in case #4. + + For the above reason, if you have removed files in the Attic, it is + better to use "-r <tag>, or even "-r HEAD" than to use a date spec. + + If you must use "-D <date>", then you should either archive and delete + Attic files (losing some past history) or construct your Makefiles to + work with an explicit list of files and let the old source files stay + in the working directory. The contents of the revision-controlled + Makefile can then be considered to contain deletion "information". + + Last modified: _6/13/1997_ + + 4. When I typed "cvs update -D <date>" in my branch, why did it screw up + all my files? + + Currently, the internal routine ("version_ts") that looks up info + about a file, overrides both the tag and date if *either* the tag or + date is specified on the command line. If only the date is specified, + it should not override a branch tag, but it does. + + In CVS 1.3, the documented "-D <branch_tag>:<date>" syntax only works + with the Main Branch and the Vendor Branch. + + [[Is this fixed in CVS 1.4? This is one item I didn't check.]] + + Last modified: _6/13/1997_ + + 5. When I executed "checkout" into an existing directory I got "No such + file or directory" errors. Why? + + Though the man page says that "checkout" turns into an "update -d" in + directories that already exist, it is referring to directories that + already exist *and* were created by CVS. + + When you try to run "checkout" on top of an existing directory + structure, some of which wasn't created by CVS, it will handle + directories and non-CVS files within directories already under CVS, + but it will display the above error on non-CVS files within non-CVS + directories. + + Last modified: _6/13/1997_ + + 6. Why does "update" send all output to the terminal after 26 files have + been updated? + + CVS uses the "tmpnam()" function to generate temporary file names. The + ANSI standard for the "tmpnam()" function says: + + "The tmpnam function generates a different string each time it is + called, up to TMP_MAX times. If it is called more than TMP_MAX times, + the behavior is implementation defined." + + Later it says that the value of "TMP_MAX shall be at least 25." + + On some platforms, the above specification is taken literally by + turning "at least 25" into "exactly 26" and by doing something foolish + (i.e. "implementation defined") after that. Some systems return the + same name repeatedly, which causes one form of trouble. Others return + NULL or garbage, which causes a different form of trouble. + + The broken systems appear to be cycling a single character through the + alphabet. SunOS cycles 3 characters through the alphabet, so it won't + cause trouble until 26 cubed or 17576 calls to "tmpnam()". + + Since CVS doesn't depend on the exact format of the tmp files, the + workaround is to provide a "tmpnam()" that doesn't have a limit on the + number of calls to it. + + Last modified: _6/13/1997_ + + 7. Why does the merge occasionally resurrect lines of code? + + The diff3 program provided by GNU diff version 1.15 has a bug that + occasionally causes text to come back from the dead. + + This is an old problem which you can avoid by upgrading to the latest + GNU "diffutils" package. If you were using GNU diff version 1.15 and + plan to upgrade to the latest GNU diff program, see the next question. + + Last modified: _6/13/1997_ + + 8. Why does the merge fail when my "rcsmerge" program is configured to use + GNU diff version 2.1 or later? + + A change in the overlap format was introduced in GNU diff3 between + versions 2.0 and 2.1 that causes RCS versions before 5.6.0.1 to fail + during a merge. + + To get consistent rcsmerge behavior, you have four choices: + + Go back to using GNU diff 1.15 or 2.0 with RCS versions 5.5 or 5.6. + If you want to use GNU diff 2.1 or later, you'll have to pick one of + the other three choices in this list. + + Grab RCS version 5.6.0.1 from an FSF archive and set the DIFF3_A + macro to '1' as it tells you to in the Makefile: + + #define DIFF3_A 1 + + Patch the RCS 5.6 source. Change line 84 in "merger.c" from: + + DIFF3, "-am", "-L", label[0], "-L", label[1], to DIFF3, "-amE", "-L", + label[0], "-L", "", "-L", label[1], + + Wait both for RCS version 5.7 to be released and for a new version + of CVS that can deal with it. + + Last modified: _6/13/1997_ + + Category: /Past__Future_/Contributors/ + + " + Contributors" + + 1. Who wrote CVS? + + Brian Berliner <berliner@sun.com> converted a collection of scripts + written by Dick Grune <dick@cs.vu.nl> into a C program, then added all + sorts of features. He continues to maintain CVS. + + Jeff Polk <polk@bsdi.com> wrote much of the code added between + revisions 1.2 and 1.3. Many others were involved at some level. + + david d zuhn <zoo@armadillo.com> fixed a number of bugs, added some of + the new features, reworked the whole thing to be more portable, and + provided much of the energy to push CVS 1.4 out the door. + + Jim Kingdon implemented CVS 1.5's remote repository access features, + fixed many bugs, and managed the release of version 1.5. + + Take a look at the README and the ChangeLog files in the CVS sources + for more contributors. + + Last modified: _6/13/1997_ + + 2. You didn't write all of this FAQ, did you? + + In the original hunt for questions to answer (performed in Jan/Feb, + 1993), I polled hundreds of people and I rephrased all sorts of text + found on the net. Between 2/93 and 10/93, I released about 20 + versions, with corrections and additions from the info-cvs mailing + list and private correspondence. + + Between 10/93 and 10/94 I extracted frequently asked questions from + the 1200 mail messages to the info-cvs mailing list, turned them into + focused questions and tried to answer them. + + 93/02/?? ~4000 lines 93/06/?? ~5000 lines 93/10/23 7839 lines 278K + 94/10/29 9856 lines 360K 95/05/09 9981 lines 365K + + Because there are so many posers of questions, I will list only those + who contribute answers or help significantly with the content and + structure of this document. + + If I used someone else's text verbatim, I mentioned it in the given + answer. The people whose email postings have added to this document or + who have added to my understanding are: + + Brian Berliner <berliner@sun.com>, CVS maintainer. Paul Eggert + <eggert@twinsun.com>, RCS maintainer. + + Gray Watson <gray@antaire.com> Per Cederqvist <ceder@signum.se> Pete + Clark <pclark@is.com> + + all of whom have sent me copies of their tutorials and local CVS + documentation. + + Additional contributors, who have sent me ideas, text, corrections and + support include (in alphabetical order): + + Per Abrahamsen <amanda@iesd.auc.dk> Donald Amby + <amby@mixcom.mixcom.com> Mark D Baushke <mdb@cisco.com> Jim Blandy + <jimb@cyclic.com> Tom Cunningham <tomc@bouwsma,sps.mot.com> Graydon + Dodson <grdodson@lexmark.com> Joe Drumgoole + <joed@splatter.demon.co.uk> Don Dwiggins <dwig@markv.com> Bryant + Eastham <bryant@ced.utah.edu> Dan Franklin <dan@diamond.bbn.com> + Michael Ganzberger <ganzbergermd@ES.net> Steve Harris + <vsh%etnibsd@uunet.uu.net> Erik van Linstee + <linstee@dutecaj.et.tudelft.nl> Jeffrey M Loomis <jml@world.std.com> + Barry Margolin <barmar@near.net> Mark K. Mellis <mkm@ncd.com> Chris + Moore <Chris.Moore@src.bae.co.uk> Gary Oberbrunner <garyo@avs.com> + Steve Turner <stevet@carrier.sps.mot.com> Dave Wolfe + <dwolfe@pffft.sps.mot.com> Dale Woolridge <dwoolridge@cid.aes.doe.ca> + + Please send corrections. If I forgot you, remind me and I'll add your + name to the list. + + Last modified: _6/13/1997_ + + Category: /Past__Future_/Development/ + + " + Development" + + 1. Where do I send bug reports? + + First make sure it is a bug. Talk to your friends, coworkers and + anyone you know who uses CVS. Search this FAQ for related issues. Then + test it carefully. Try out variations to narrow down the problem. Make + sure it is repeatable. Look for workarounds so you can report them. + + If you are still sure it's a bug and you tried to fix it, skip to the + next question. Otherwise, send a message to the info-cvs mailing list + containing one of the following: + + If you have a good repeatable case and you think you know what is + going on, then describe the problem in detail. Include a workaround if + you have one. + + If you have no idea what is going on, go ahead and send a question + to the info-cvs mailing list. Include any information you have + describing the symptoms. + + Last modified: _6/13/1997_ + + 2. Where do I send fixes and patches? + + First make sure the "fix" does something useful. Have someone review + your fix. Spend a bit of one person's time in a detailed analysis of + your vast idea before displaying a half-vast idea to hundreds of + people. + + If you tried to fix it and the patch is small, include the patch in + your message. Make sure the patch is based on the latest released + version of CVS. + + If you tried to fix it and the patch is large, you should think about + why it is so large. Did you add a generally useful feature, or did it + grow out of hand? + + If you still believe it is solid, produce a patch file using the CVS + commands "patch" or "diff -c". [[You *are* keeping CVS under CVS, + right?]] The patch should be based on the latest released version of + CVS. Then use the "cvsbug" program (provided with the CVS sources) to + send it to the CVS maintainers. A self-contained patch that provides a + single useful feature or correction might show up independently in the + patches directory of the FTP archive. + + If careful testing reveals an RCS bug rather than a CVS bug, you can + send bug reports to: rcs-bugs@cs.purdue.edu + + Last modified: _6/13/1997_ + + 3. Where do I send ideas for future development? + + If you have a bright idea, discuss it on the info-cvs mailing list. If + you have the time to implement something you can test, send the diffs + along too as described above. + + Last modified: _6/13/1997_ + + 4. What plans are there for new features? + + + +A "rename" or "per-directory" database has been bandied about on +the net for years. Many of the goals of the rename database have +been achieved by the so-called "death support" in recent versions of +CVS (such as 1.9). For more information on what may remain to be +done, see item #189 in the TODO file of a development version of CVS. + +CVS version 1.5 supports remote repository access, but Paul +Kunz has produced another version +(rCVS) that also runs remotely. Note that as far as I know there +are no advantages to rCVS over the remote CVS in CVS 1.5 and later, +and the rCVS user community has migrated to remote CVS. +rCVS is *not* a multisite CVS (see item #186 in TODO for more on +multisite). For more on rCVS, see + +ftp://ftp.slac.stanford.edu/software/rcvs + +kingdon@cyclic.com + + Last modified: _9/6/1997_ + + 5. I have some time and I'd like to help. What can I do for you? + + + You can review this document, correct errors and fill in any of + the incomplete sections. + + You can write scripts or CVS add-ons and make them available by + web/FTP/etc. + + You could work on the regression test suite (src/sanity.sh in the + CVS source distribution). + + You can write specs for new features, fix bugs, review the + documentation or . . . + + For more information, see the files HACKING and DEVEL-CVS in the + CVS source distribution or + http://www.cyclic.com/cyclic-pages/cvsdev.html + + kingdon@cyclic.com + + Last modified: _9/6/1997_ + + Category: /Past__Future_/Professional_Support/ + + " + Professional Support" + + 1. Doesn't Cygnus support CVS? + + + + + Cygnus is a company that supports free software such as the GCC + compiler. They have never sold support for CVS, however. They + do use CVS internally and have contributed much code to CVS over + the years (for which CVS users should be grateful). + + kingdon@cyclic.com + + Last modified: _9/6/1997_ + + 2. What is Cyclic Software doing with CVS? + + +Cyclic Software exists to provide support for CVS. For details such +as prices and what this covers, see http://www.cyclic.com or ask +info@cyclic.com. + +kingdon@cyclic.com + + Last modified: _9/6/1997_ + + Category: /User_Tasks_/ + + " User Tasks " + + Category: /User_Tasks_/Common_User_Tasks/ + + " + Common User Tasks" + + 1. What is the absolute minimum I have to do to edit a file? + + Tell your Repository Administrator to create a module covering the + directory or files you care about. You will be told that your module + name is <module>. Then type: + + cvs checkout <module> + cd <module> + emacs <file> # Isn't Emacs a synonym for edit? + cvs commit <file> + + If you don't use modules (in my opinion, a mistake), you can check out + a directory by substituting its relative path within the Repository + for <module> in the example above. + + To work on a single file, you'll have to change "cd <module>" to "cd + `dirname <module>`". + + Last modified: _6/13/1997_ + + 2. If I edit multiple files, must I type "commit" for each one? + + No. You can commit a list of files and directories, including relative + paths into multiple directories. You can also commit every modified + file in the current directory or in all directories and subdirectories + from your current directory downward. See 3D.2. + + Last modified: _6/13/1997_ + + 3. How do I get rid of the <module> directory that "checkout" created? + + Change your directory to be the same as when you executed the + "checkout" command that created <module>. + + If you want to get rid of the CVS control information, but leave the + files and directories, type: + + cvs release <module> + + If you want to obliterate the entire directory, type: + + cvs release -d <module> + + ("release -d" searches through the output of "cvs -n update" and + refuses to continue if the "update" command finds any modified files + or non-ignored foreign files. Foreign directories too.) + + If you don't care about keeping "history", or checking for modified + and foreign files, you can just remove the whole directory. That's "rm + -rf <module>" under Unix. + + Last modified: _6/13/1997_ + + 4. How do I find out what has changed since my last update? + + There are many ways to answer this. + + To find out what you've changed in your current working directory + since your last checkout, update or commit, type: + + cvs diff + + To find out what other people have added (to your branch) since you + last checked out or updated, type: + + cvs diff -r BASE -r HEAD + + To look at a revision history containing the comments for all changes, + you can use the "log" command. + + You can also use "history" to trace a wide variety of events. + + Last modified: _6/13/1997_ + + 5. I just created a new file. How do I add it to the Repository? + + The "update" command will mark files CVS doesn't know about in your + working directory with a '?' indicator. + + ? <file> + + To add <file> to the Repository, type: + + cvs add <file> + cvs commit <file> + + See 3A.[2-5] and 4C.8 for branch and merge considerations. + + Last modified: _6/13/1997_ + + 6. How do I merge changes made by others into my working directory? + + If you are asking about other branches, see Section 4C on "Branching". + You will have to use the "update -j" command. + + Retrieving changes made to the Repository on the *same* branch you are + working on is the main purpose of the "update" command. The "update" + command tries to merge work committed to the Repository by others + since you last executed "checkout", "update" or "commit" into your + working files. + + For a single file, there are six possible results when you type the + "update" command: + + If the file is lying in your working directory, but is not under + CVS, it will do nothing but print: + + ? <file> + + If neither you nor anyone else has committed changes to <file>, + since your last "checkout", "update" or "commit", "update" will print + nothing and do nothing. + + If you have made no changes to a working file, but you or others + have committed changes to the Repository since your last "checkout", + "update" or "commit" of this working file, CVS will remove your + working file and replace it with a copy of the latest revision of that + file in the Repository. It will print: + + U <file> + + You might want to examine the changes (using the CVS "diff" command) + to see if they mesh with your own in related files. + + If you have made changes to a working file, but no one has changed + your BASE revision (the revision you retrieved from the Repository in + your last "checkout", "update" or "commit"), "update" will print: + + M <file> + + Nothing changes. You were told that you have a modified file in your + directory. + + If you have made changes to your working file and you or others have + committed changes to the Repository, but in different sections of the + file, CVS will merge the changes stored in the Repository since your + last "checkout", "update" or "commit" into your working file. "update" + will print: + + RCS file: /Repository/module/<file> retrieving revision 1.X retrieving + revision 1.Y Merging differences between 1.X and 1.Y into <file> M + <file> + + If you execute "diff" before and after this step, you should see the + same output, since both the base file and your working file changed in + parallel. This is one of the few times the otherwise nonsensical + phrase "same difference" means something. + + If both you and those who committed files (since your last checkout, + update or commit) have made changes to the same section of a file, CVS + will merge the changes into your file as in #5 above, but it will + leave conflict indicators in the file. "update" will print: + + RCS file: /Repository/module/<file> retrieving revision 1.X retrieving + revision 1.Y Merging differences between 1.X and 1.Y into <file> + rcsmerge warning: overlaps during merge + cvs update: conflicts found in <file> + C <file> + + This is a "conflict". The file will contain markers surrounding the + overlapping text. The 'C' conflict indicator is sticky -- subsequent + "update" commands will continue to show a 'C' until you edit the file. + + You must examine the overlaps with care and resolve the problem by + analyzing how to retain the features of both changes. See 2D.7 and + 3P.6 for more details on conflict resolution. + + Last modified: _6/13/1997_ + + 7. How do I label a set of revisions so I can retrieve them later? + + To "tag" the BASE revisions (the ones you last checked out, updated, + or committed) you should "cd" to the head of the working directory you + want to tag and type: + + cvs tag <tag> + + It recursively walks through your working directory tagging the BASE + revisions of all files. + + To "tag" the latest revision on the Main branch in the Repository, you + can use the following from anywhere: (No "cd" is required -- it works + directly on the Repository.) + + cvs rtag <tag> <module> + + Last modified: _6/13/1997_ + + 8. How do I checkout an old release of a module, directory or file? + + Module names and directories are simply ways to name sets of files. + Once the names are determined, there are 6 ways to specify which + revision of a particular file to check out: + + By tag or symbolic name, via the "-r <tag>" option. + + By date, via the "-D <date>" option. + + By branch tag (a type of tag with a magic format), via the "-r + <branch_tag>" option. + + By date within a branch, via the "-r <branch_tag>:<date>" option. + + By an explicit branch revision number ("-r <rev>"), which refers to + the latest revision on the branch. This isn't really an "old" + revision, from the branch's perspective, but from the user's + perspective the whole branch might have been abandoned in the past. + + An explicit revision number: "-r <rev>" Though this works, it is + almost useless for more than one file. + + You type: + + cvs checkout <option-specified-above> <module> + cd <module> + + Last modified: _6/13/1997_ + + 9. What do I have to remember to do periodically? + + You should execute "cvs -n update" fairly often to keep track of what + you and others have changed. It won't change anything -- it will just + give you a report. + + Unless you are purposely delaying the inclusion of others' work, you + should execute "update" once in a while and resolve the conflicts. It + is not good to get too far out of sync with the rest of the developers + working on your branch. + + It is assumed that your system administrators have arranged for editor + backup and Unix temp files (#* and .#*) to be deleted after a few + weeks. But you might want to look around for anything else that is + ignored or hidden. Try "cvs -n update -I !" to see all the ignored + files. + + If you are the Repository Administrator, see 4B.16 on Administrator + responsibilities. + + Last modified: _6/13/1997_ + + Category: /User_Tasks_/General_Questions/ + + " + General Questions" + + 1. How do I see what CVS is trying to do? + + The '-t' option on the main "cvs" command will display every external + command (mostly RCS commands and file deletions) it executes. When + combined with the '-n' option, which prevents the execution of any + command that might modify a file, you can see what it will do before + you let it fly. The '-t' option will *not* display every internal + action, only calls to external programs. + + To see a harmless example, try typing: + + cvs -nt update + + Some systems offer a "trace" or "truss" command that will display all + system calls as they happen. This is a *very* low-level interface that + does not normally follow the execution of external commands, but it + can be useful. + + The most complete answer is to read the source, compile it with the + '-g' option and step through it under a debugger. + + Last modified: _6/13/1997_ + + 2. If I work with multiple modules, should I check them all out and commit + them occasionally? Is it OK to leave modules checked out? + + The simple answers are "Yes." + + There is no reason to remove working directories, other than to save + disk space. As long as you have committed the files you choose to make + public, your working directory is just like any other directory. + + CVS doesn't care whether you leave modules checked out or not. The + advantage of leaving them checked out is that you can quickly visit + them to make and commit changes. + + Last modified: _6/13/1997_ + + 3. What is a "sticky" tag? What makes it sticky? How do I loosen it? + + When you execute "update -r <tag>", CVS remembers the <tag>. It has + become "sticky" in the sense that until you change it or remove it, + the tag is remembered and used in references to the file as if you had + typed "-r <tag>" on the command line. + + It is most useful for a <branch_tag>, which is a sticky tag indicating + what branch you are working on. + + A revision number ("-r <rev-number>") or date ("-D <date>") can also + become sticky when they are specified on the command line. + + A sticky tag, revision or date remains until you specify another tag, + revision or date the same way. The "update -A" command moves back to + the Main branch, which has the side-effect of clearing all sticky + items on the updated files. + + The "checkout" command creates sticky tags, revisions and dates the + same way "update" does. + + Also, the '-k' option records a "sticky" keyword option that is used + in further "updates until "update -A" is specified. + + Last modified: _6/13/1997_ + + 4. How do I get an old revision without updating the "sticky tag"? + + Use the '-p' option to "pipe" data to standard output. The command + "update -p -r <tag/rev>" sends the selected revision to your standard + output (usually the terminal, unless redirected). The '-p' affects no + disk files, leaving a "sticky tag" unaltered and avoiding all other + side-effects of a normal "update". + + If you want to save the result, you can redirect "stdout" to a file + using your shell's redirection capability. In most shells the + following command works: + + cvs update -p -r <tag/rev> filename > diskfile + + Last modified: _6/13/1997_ + + 5. What operations disregard sticky tags? + + The functions that routinely disregard sticky tags are: + + Those that work directly on the Repository or its administrative + files: + + admin rtag log status remove history + + Those that take Tags or revisions as arguments and ignore everything + else: (They also never *set* a sticky tag.) + + rdiff import export + + The "release" command itself ignores sticky tags, but it calls "cvs + -n update" (which *does* pay attention to a sticky tag) to figure out + what inconsistencies exist in the working directory. If no + discrepancies exist between the files you originally checked out + (possibly marked by a sticky tag) and what is there now, "release -d" + will delete them all. + + The "tag" command works on the revision lying in the working + directory however it got there. That the revision lying there might + happen to have a sticky tag attached to it is not the "tag" command's + concern. + + The main function that *does* read and write sticky tags is the + "update" command. You can avoid referring to or changing the sticky + tag by using the '-p' option, which sends files to your terminal, + touching nothing else. + + The "checkout" command sets sticky tags when checking out a new module + and it acts like "update" when checking out a module into an existing + directory. + + The "diff" and "commit" commands use the sticky tags, unless + overridden on the command line. They do not set sticky tags. Note that + you can only "commit" to a file checked out with a sticky tag, if the + tag identifies a branch. + + There are really two types of sticky tags, one attached to individual + files (in the ./CVS/Entries file) and one attached to each directory + (in the ./CVS/Tag file). They can differ. + + The "add" command registers the desire to add a new file. If the + "directory tag" (./CVS/Tag) file exists at the time of the "add", the + value stored in ./CVS/Tag becomes the "sticky tag" on the new file. + The file doesn't exist in the Repository until you "commit" it, but + the ./CVS/Entries file holds the sticky tag name from the time of the + "add" forward. + + Last modified: _6/13/1997_ + + 6. Is there a way to avoid reverting my Emacs buffer after committing a + file? Is there a "cvs-mode" for Emacs? + + See Section 4F.1 + + Last modified: _6/13/1997_ + + 7. How does conflict resolution work? What *really* happens if two of us + change the same file? + + While editing files, there is no conflict. You are working on separate + copies of the file stored in the virtual "branch" represented by your + working directories. After one of you commits a file, the other may + not commit the same file until "update" has merged the earlier + committed changes into the later working file. + + For example, say you both check out rev 1.2 of <file> and make change + to your working files. Your coworker commits revision 1.3. When you + try to commit your file, CVS says: + + cvs commit: Up-to-date check failed for `<file>' + + You must merge your coworker's changes into your working file by + typing: + + cvs update <file> + + which will produce the output described in 2B.6. + + If a conflict occurs, the filename will be shown with a status of 'C'. + After you resolve any overlaps caused by the merging process, you may + then commit the file. See 3P.6 for info on "sticky conflicts". + + Even if you get a simple 'M', you should examine the differences + before committing the file. A smooth, error-free text merge is still + no indication that the file is in proper shape. Compile and test it at + least. + + The answer to two obvious questions is "Yes". + + Yes, the first one who commits avoids the merge. Later developers have + to merge the earlier changes into their working files before + committing the merged result. Depending on how difficult the merge is + and how important the contending projects are, the order of commits + and updates might have to be carefully staged. + + And yes, between the time you execute "update" and "commit" (while you + are fixing conflicts and testing the results) someone else may commit + another revision of <file>. You will have to execute "update" again to + merge the new work before committing. Most organizations don't have + this problem. If you do, you might consider splitting the file. Or + hiring a manager. + + Last modified: _6/13/1997_ + + 8. How can I tell who has a module checked out? + + If you "checkout" module names (not relative pathnames) and you use + the release command, the "history" command will display active + checkouts, who has them and where they were checked out. It is + advisory only; it can be circumvented by using the '-l' option on the + main "cvs" command. + + Last modified: _6/13/1997_ + + 9. Where did the .#<file>.1.3 file in my working directory come from? + + It was created during an "update" when CVS merged changes from the + Repository into your modified working file. + + It serves the same purpose as any "backup" file: saving your bacon + often enough to be worth retaining. It is invaluable in recovering + when things go wrong. + + Say Developers A (you) and B check out rev 1.3 of file <file>. You + both make changes -- different changes. B commits first, so <file>,v + in the Repository contains revisions up through 1.4. + + At this point, there are 5 (yes, five) versions of the file of + interest to you: + + Revision 1.3 (What you originally checked out.) + + Revision 1.4 (What you need from developer B.) + + Your old working file. (Before the update.) + + Your new working file. (After the merge caused by "update".) + + Revision 1.5 (Which you will commit shortly.) + + In the case where your working file was not modified, #1 and #3 will + be the same, as will #2 and #4. In this degenerate case, there is no + need to create #5. The following assumes that your working file was + modified. + + If the merge executed by the "update" caused no overlaps, and you + commit the file immediately, #4 and #5 will be the same. But you can + make arbitrary changes before committing, so the difference between #4 + and #5 might be more than just the correction of overlaps. In general, + though, you don't need #4 after a commit. + + But #3 (which is the one saved as ".#<file>.1.3") holds all of your + work, independent of B's work. It could represent a major effort that + you couldn't afford to lose. If you don't save it somewhere, the merge + makes #3 *disappear* under a potential blizzard of conflicts caused by + overlapping changes. + + I have been saved a few times, and others I support have been saved + hundreds of times, by the ability to "diff <original file> <original + file with only my work added>", which can be done in the example above + by the Unix shell command: + + cvs update -p -r 1.3 <file> | diff - .#<file>.1.3 + + The assumption is that the ".#" files will be useful far beyond the + "commit" point, but not forever. You are expected to run the "normal" + Unix cleanup script from "cron", which removes "#*" and ".#*" files + older than a some period chosen by your sysadmin, usually ranging from + 7 to 30 days. + + A question was raised about the need for #3 after #5 has been + committed, under the assumption that you won't commit files until + everything is exactly as you like them. + + This assumes perfect humans, which violates one of the Cardinal rules + of Software Engineering: Never assume any form of discipline on the + part of the users of software. If restrictions are not bound into the + software, then you, the toolsmith, have to arrange a recovery path. + + In other words, I've seen every possible variety of screwup you can + imagine in #5. There is no way to make assumptions about what "should" + happen. I've seen #5 filled with zeros because of NFS failures, I've + seen emacs core dumps that leave #5 in an unreasonable state, I've + seen a foolish developer uppercase the whole file (with his "undo" + size set low so he couldn't undo it) and decide that it would be less + work to play with the uppercased file than to blow it away and start + over. I've even seen committed files with conflict markers still in + them, a sure sign of carelessness. + + There are all sorts of scenarios where having #3 is incredibly useful. + You can move it back into place and try again. + + Last modified: _6/13/1997_ + + 10. What is this "ignore" business? What is it ignoring? + + The "update" and "import" commands use collections of Unix wildcards + to skip over files and directories matching any of those patterns. + + You may add to the built-in ignore list by adding lines of + whitespace-separated wildcards to the following places: (They are read + in this order.) + + In a file named "cvsignore" in $CVSROOT/CVSROOT. + + A Repository Administrator uses this to add site-specific files and + patterns to the built-in ignore list. + + In a file named ".cvsignore" in your home directory. + + For user-specific files. For example, if you use "__" as your default + junk file prefix, you can put "__*" in your .cvsignore file. + + People who play around exclusively in directory trees where the + Makefiles are generated by "imake" or "configure" might want to put + "Makefile" in their ignore list, since they are all generated and + usually don't end up in the Repository. + + In the CVSIGNORE environment variable. + + For session-specific files. + + Via the '-I' option on "import" or "update" commands. + + For this-command-only files. + + In a file named ".cvsignore" within each directory. + + The contents of a ".cvsignore" file in each directory is temporarily + added to the ignore list. This way you can ignore files that are + peculiar to that directory, such as executables and other generated + files without known wildcard patterns. + + In any of the places listed above, a single '!' character nulls out + the ignore list. A Repository administrator can use this to override, + rather than enhance, the built-in ignore list. A user can choose to + override the system-wide ignore list. For example, if you place "! *.o + *.a" in your .cvsignore file, only *.o *.a files, plus any files a + local-directory .cvsignore file, are ignored. + + A variant of the ignore-file scheme is used internally during + checkout. "Module names" found in the modules file (or on the + "checkout" command line) that begin with a '!' are ignored during + checkout. This is useful to permanently ignore (if the '!' path is in + the modules file) or temporarily ignore (if the '!' path is on the + command line) a sub-directory within a Repository hierarchy. For + example: + + cvs checkout !gnu/emacs/tests gnu/emacs + + would checkout the module (or relative path within $CVSROOT) named + "gnu/emacs", but ignore the "tests" directory within it. + + Last modified: _6/13/1997_ + + 11. Is there a way to set user-specific configuration options? + + User-specific configuration is available through use of a ".cvsrc" + file in your home directory. + + CVS searches the first column of your ~/.cvsrc file for the cvs + command name you invoked. If the command is found, the rest of the + line is treated like a set of command line options, stuffed into the + command line before the arguments you actually typed. + + For example, if you always want to see context diffs and you never + want to have to delete a file before you run "cvs remove", then you + should create a .cvsrc file containing the following: + + diff -c + remove -f + + which will add the given options to every invocation of the given + commands. + + [[The rest of this will be removed someday, when CVS changes.]] + + I would like to stop here with a comment that the command name to use + is the full, canonical one. But the command that the cvsrc support + uses is the string you typed on the command line, not the proper + command. So to get the full effect of the above example, you should + also add all the alternate command names: + + di -c + dif -c + rm -f + delete -f + + There are two other limitations that will probably be fixed when CVS + sprouts long option names: + + It only affects options made available on the command line. + + There is a limited number of short options. With long option names, + there is no problem. You can have as many long options as you like, + affecting anything that looks malleable. + + The existing command line options do not come in on/off pairs, so + there is no easy way to override your ~/.cvsrc configuration for a + single invocation of a command. + + Choosing a good set of long option pairs would fix this. + + Last modified: _6/13/1997_ + + 12. Is it safe to interrupt CVS using Control-C? + + It depends on what you mean by "safe". ("Ah," said Arthur, "this is + obviously some strange usage of the word *safe* that I wasn't + previously aware of." -- Hitchhiker's Guide to the Galaxy) + + You won't hurt the underlying RCS files and if you are executing a + command that only *reads* data, you will have no cleanup to do. + + But you may have to hit Control-C repeatedly to stop it. CVS uses the + Unix "system" routine which blocks signals in the CVS parent process. + A single Control-C during "system" will only halt the child process, + usually some form of RCS command. + + If you don't hit another Control-C while the CVS process has control, + it is likely to continue onto the next task assuming that the earlier + one did its job. It is not enough to hit two Control-C's. You might + simply kill two child processes and not interrupt CVS at all. + Depending on the speed of your processor, your terminal and your + fingers, you might have to hit dozens of Control-C's to stop the damn + thing. + + Executing a CVS command, such as "commit" or "tag" that writes to the + files is a different matter. + + Since CVS is not a full-fledged database, with what database people + call "commit points", merely stopping the process will not back out + the "transaction" and place you back in the starting blocks. CVS has + no concept of an "atomic" transaction or of "backtracking", which + means that a command can be half-executed. + + Hitting Control-C will usually leave lock files that you have to go + clean up in the Repository. + + Example1: + + If you interrupt a multi-file "commit" in the middle of + an RCS checkin, RCS will leave the file either fully + checked-in or in its original state. But CVS might have + been half-way through the list of files to commit. The + directory or module will be inconsistent. + + To recover, you must remove the lock files, then decide + whether you want to back out or finish the job. + + To back out, you'll have to apply the "admin -o" + command, very carefully, to remove the newly committed + revisions. This is usually a bad idea, but is + occasionally necessary. + + To finish, you can simply retype the same commit command. + CVS will figure out what files are still modified and + commit them. It helps that RCS doesn't leave a file in an + intermediate state. + + Example2: + + If you interrupt a multi-file "tag" command, you have a + problem similar, but not equivalent, to interrupting a + "commit". The RCS file will still be consistent, but + unlike "commit", which only *adds* to the RCS file, "tag" + can *move* a tag and it doesn't keep a history of what + revision a tag used to be attached to. + + Normally, you have little choice but to re-execute the + command and allow it to tag everything consistently. + + You might be able to recover by carefully re-applying the + tags via the "cvs admin -N" command, but you'll still have + to dig up from outside sources the information you use to + determine what tag was on what revision in what file. + the Repository, or by using the equivalent: "cvs admin". + + Halting a new "checkout" should cause no harm. If you don't want it, + "release" (or rm -rf) it. If you do want it, re-execute the command. A + repeated "checkout" from above a directory acts like a repeated + "update -d" within it. + + Halting "update" half-way will give you an unpredictable collection of + files and revisions. To continue, you can rerun the update and it + should move you forward into in a known state. To back out, you'll + have to examine the output from the first "update" command, take a + look at each file that was modified and reconstruct the previous state + by editing the ./CVS/Entries file and by using "cvs admin". Good Luck. + + Last modified: _6/13/1997_ + + 13. How do I turn off the "admin" command? + + In the current revision, you'd have to edit the source code. + + Last modified: _6/13/1997_ + + 14. How do I turn off the ability to disable history via "cvs -l"? + + In the current revision, you'd have to edit the source code. + + Last modified: _6/13/1997_ + + 15. How do I keep certain people from accessing certain directories? + + If you don't try to run CVS set[ug]id, you can use Unix groups and + permissions to limit access to the Repository. + + If you only want to limit "commit" commands, you can write a program + to put in the "commitinfo" file. In the "contrib" directory, there are + a few scripts that might help you out. + + Last modified: _6/13/1997_ + + Category: /User_Tasks_/Getting_Started/ + + " + Getting Started" + + 1. What is the first thing I have to know? + + Your organization has most likely assigned one or more persons to + understand, baby-sit and administer the CVS programs and the data + Repository. I call these persons Repository Administrators. They + should have set up a Repository and "imported" files into it. + + If you don't believe anyone has this responsibility, or you are just + testing CVS, then *you* are the Repository Administrator. + + If you are a normal user of CVS ask your Repository Administrator what + module you should check out. + + Then you can work. + + If you *are* the Repository Administrator, you will want to read + everything you can get your hands on, including this FAQ. Source + control issues can be difficult, especially when you get to branches + and release planning. Expect to feel stupid for a few days/weeks. + + No tool in the universe avoids the need for intelligent organization. + In other words, there are all sorts of related issues you will + probably have to learn. Don't expect to dive in without any + preparation, stuff your 300 Megabytes of sources into CVS and expect + to start working. If you don't prepare first, you will probably spend + a few sleepless nights. + + Last modified: _6/13/1997_ + + 2. Where do I work? + + Wherever you have disk space. That's one of the advantages of CVS: you + use the "checkout" command to copy files from the Repository to your + working directory, which can be anywhere you have the space. + + Your local group might have conventions for where to work. Ask your + peers. + + Last modified: _6/13/1997_ + + 3. What does CVS use from my environment? + + You must set two environment variables. Some shells share these + variables with local shell variables using a different syntax. You'll + have to learn how your shell handles them. + + Variable Value (or action) + --------- --------------------- + CVSROOT Absolute pathname of the head of your Repository. + + PATH Normally set to a list of ':'-separated directory + pathnames searched to find executables. You must + make sure "cvs" is in one of the directories. + + If your CVS was built with the RCSBIN directory set + to null (""), and you don't set the RCSBIN + variable mentioned below, then the RCS commands + also must be somewhere in your PATH. + + Optional variables: (Used if set, but ignored otherwise.) + + Variable Value (or action) + --------- --------------------- + CVSEDITOR The name of your favorite fast-start editor + program. You'll be kicked into your editor to + supply revision comments if you don't specify them + via -m "Log message" on the command line. + + EDITOR Used if CVSEDITOR doesn't exist. If EDITOR + doesn't exist, CVS uses a configured constant, + usually, "vi". + + CVSREAD Sets files to read-only on "checkout". + + RCSBIN Changes where CVS finds the RCS commands. + + CVSIGNORE Adds to the ignore list. See Section 2D. + + Other variables used by CVS that are normally set upon login: + + Variable Value (or action) + --------- --------------------- + LOGNAME Used to find the real user name. + + USER Used to find the real user name if no LOGNAME. + + HOME Used to determine your home directory, if set. + Otherwise LOGNAME/USER/getuid() are used to find + your home directory from the passwd file. + + TMPDIR Used during import. It might also be used if your + platform's version of mktemp(3) is unusual, or + you have changed the source to use tmpnam(3). + + Last modified: _6/13/1997_ + + 4. OK, I've been told that CVS is set up, my module is named "ralph" and I + have to start editing. What do I type? + + cd <where you have some space to work> + cvs checkout ralph + cd ralph + + And hack away. + + Last modified: _6/13/1997_ + + 5. I have been using RCS for a while. Can I convert to CVS without losing + my revision history? How about converting from SCCS? + + If you are asking such questions, you are not a mere user of CVS, but + one of its Administrators! You should take a look at Section 4A, + "Installing CVS" and Section 4B, "Setting up and Managing the + Repository". + + Last modified: _6/13/1997_ + + Category: /User_Tasks_/Less_Common_User_Tas/ + + " + Less Common User Tasks" + + 1. Can I create non-CVS sub-directories in my working directory? + + Yes. Unless the directory exists in the Repository, "update" will skip + over them and print a '?' the way it does for files you forgot to add. + You can avoid seeing the '?' by adding the name of the foreign + directory to the ./.cvsignore file, just ask you can do with files. + + If you explicitly mention a foreign directory on the "update" command + line, it will traverse the directory and waste a bit of time, but if + any directory or sub-directory lacks the ./CVS administrative + directory, CVS will print an error and abort. + + Last modified: _6/13/1997_ + + 2. How do I add new sub-directories to the Repository? + + The "add" command will work on directories. You type: + + mkdir <dir> + cvs add <dir> + + It will respond: + + Directory /Repos/<dir> added to the repository + + and will create both a matching directory in the Repository and a + ./CVS administrative directory within the local <dir> directory. + + Last modified: _6/13/1997_ + + 3. How do I remove a file I don't need? + + (See the questions in Section 4B on removing files from the + Repository.) + + You type: + + rm <file> + cvs remove <file> + + CVS registers the file for removal. To complete the removal, you must + type: + + cvs commit <file> + + CVS moves the file to the Attic associated with your working + directory. Each directory in the Repository stores its deleted files + in an Attic sub-directory. A normal "checkout" doesn't look in the + Attic, but if you specify a tag, a date or a revision, the "checkout" + (or "update") command will retrieve files from the Attic with that + tag, date or revision. + + Last modified: _6/13/1997_ + + 4. How do I rename a file? + + CVS does not offer a way to rename a file in a way that CVS can track + later. See Section 4B for more information. + + Here is the best (to some, the only acceptable) way to get the effect + of renaming, while preserving the change log: + + Copy the RCS (",v") file directly in the Repository. + + cp $CVSROOT/<odir>/<ofile>,v $CVSROOT/<ndir>/<nfile>,v + + By duplicating the file, you will preserve the change history and the + ability to retrieve earlier revisions of the old file via the "-r + <tag/rev>" or "-D <date>" options to "checkout" and "update". + + Remove the old file using CVS. + + cd <working-dir>/<odir> rm <ofile> + cvs remove <ofile> + cvs commit <ofile> + + This will move the <ofile> to the Attic associated with <odir>. + + Retrieve <nfile> and remove all the Tags from it. + + By stripping off all the old Tags, "checkout -r" and "update -r" won't + retrieve revisions Tagged before the renaming. + + cd <working-dir>/<ndir> + cvs update <nfile> + cvs log <nfile> # Save the list of Tags + cvs tag -d <tag1> <nfile> + cvs tag -d <tag2> <nfile> + . . . + + This technique can be used to rename files within one directory or + across different directories. You can apply this idea to directories + too, as long as you apply the above to each file and don't delete the + old directory. + + Of course, you have to change your build system (e.g. Makefile) in + your <working-dir> to know about the name change. + + Warning: Stripping the old tags from the copied file will allow "-r + <tag>" to do the right thing, but you will still have problems with + "-D <date>" because there is no place to store the "deletion time". + See 5B.3 for more details. + + Last modified: _6/13/1997_ + + 5. How do I make sure that all the files and directories in my working + directory are really in the Repository? + + A "cvs update", or "cvs -n update" (which won't modify your working + directory) will display foreign elements, which have no counterpart in + the Repository, preceded by a '?'. To register foreign directories, + you can use "cvs add". To register foreign files, you can use "cvs + add" followed by "cvs commit". + + You could also checkout your module, or the Repository directory + associated with your working directory, a second time into another + work area and compare it to your working directory using the (non-CVS) + "diff -r" command. + + By default many patterns of files are ignored. If you create a file + named "core" or a file ending in ".o", it is usually ignored. If you + really want to see all the files that aren't in the Repository, you + can use a special "ignore" pattern to say "ignore no files". Try + executing: (You may have to quote or backwhack (i.e. precede by '\') + the '!' in your shell.) + + cvs -n update -I ! + + The above command will display not only the normal modified, update + and conflict indicators ('M', 'U', and 'C' respectively) on files + within the Repository, but it will also display each file not in the + Repository preceded by a '?' character. + + The '-n' option will not allow "update" to alter your working + directory. + + Last modified: _6/13/1997_ + + 6. How do I create a branch? + + Type this in your working directory: + + cvs tag -b <branch_tag> + + and you will create a branch. No files have real branches in them yet, + but if you move onto the branch by typing: + + cvs update -r <branch_tag> + + and commit a file in the normal way: + + cvs commit <file> + + then a branch will be created in the underlying <file>,v file and the + new revision of <file> will appear only on that branch. + + See Section 4C, on Branching. + + Last modified: _6/13/1997_ + + 7. How do I modify the modules file? How about the other files in the + CVSROOT administrative area? + + A module named "modules" has been provided in the default modules + file, so you can type: + + cvs checkout modules + cd modules + + Another module named CVSROOT has been provided in the default modules + file, covering all the administrative files. Type: + + cvs checkout CVSROOT + cd CVSROOT + + Then you can edit your files, followed by: + + cvs commit + + If you start with the provided template for the "modules" file, the + CVSROOT and the "modules" module will have the "mkmodules" program as + a "commit helper". After a file is committed to such a module, + "mkmodules" will convert a number of standard files (See 4B.2) in the + CVSROOT directory inside the Repository into a form that is usable by + CVS. + + Last modified: _6/13/1997_ + + 8. How do I split a file into pieces, retaining revision histories? + + If you and a coworker find yourselves repeatedly committing the same + file, but never for changes in the same area of the file, you might + want to split the file into two or more pieces. If you are both + changing the same section of code, splitting the file is of no use. + You should talk to each other instead. + + 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>. + + 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> + + Then remove all the <tags> from the new files by using: + + cvs log <fileB> <fileC> # Save the list of <tag?> + cvs tag -d <tag1> <fileB> <fileC> + cvs tag -d <tag2> <fileB> <fileC> + . . . + + 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. + + [From experience, I'd suggest making sure that only one copy of each + line of code exists among the three files, except for "include" + statements, which must be duplicated. And make sure the code + compiles.] + + emacs <fileA> <fileB> <fileC> + cvs commit <fileA> <fileB> <fileC> + + As in the "rename" case, by duplicating the files, you'll preserve the + change history and the ability to retrieve earlier revisions. + + 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_ + + Category: /What_is_CVS_/ + + " What is CVS? " + + Category: /What_is_CVS_/How_does_CVS_differ_/ + + " + How does CVS differ from other, similar software?" + + 1. How does CVS differ from RCS? + + CVS uses RCS to do much of its work and absolutely all the work of + changing the underlying RCS files in the Repository. + + RCS comprises a set of programs designed to keep track of changes to + individual files. Of course, it also allows you to refer to multiple + files on the command line, but they are handled by iterating over + individual files. There is no pretense of coordinated interaction + among groups of files. + + CVS's main intent is to provide a set of grouping functions that allow + you to treat a collection of RCS files as a single object. Of course, + CVS also has to do a lot of iteration, but it tries its best to hide + that it is doing so. In addition, CVS has some truly group-oriented + facets, such as the modules file and the CVS administrative files that + refer to a whole directory or module. + + One group aspect that can be a bit confusing is that a CVS branch is + not the same as an RCS branch. To support a CVS branch, CVS uses + "tags" (what RCS calls "symbols") and some local state, in addition to + RCS branches. + + Other features offered by CVS that are not supported directly by RCS + are + + Automatic determination of the state of a file, (e.g. modified, + up-to-date with the Repository, already tagged with the same string, + etc.) which helps in limiting the amount of displayed text you have to + wade through to figure out what changed and what to do next. + + A copy-modify-merge scheme that avoids locking the files and allows + simultaneous development on a single file. + + Serialization of commits. CVS requires you to merge all changes + committed (via "update") since you checked out your working copy of + the file. Although it is still possible to commit a file filled with + old data, it is less likely than when using raw RCS. + + Relatively easy merging of releases from external Vendors. + + Last modified: _6/13/1997_ + + 2. How does CVS differ from SCCS? + + SCCS is much closer to RCS than to CVS, so some of the previous entry + applies. + + You might want to take a look at Walter Tichy's papers on RCS, which + are referred to in the RCS man pages. + + [[More info here?]] + + Last modified: _6/13/1997_ + + 3. How does CVS differ from ClearCase? + + ClearCase is a distributed client-server version control system. + ClearCase is a variant DSEE tools, formerly available on Apollo + platforms. The ClearCase tool set includes a few X-based interface + tools, a command-line interface, and C programmer API. It is currently + available on Sun, HP, SGI and OSF/1 platforms. + + ClearCase uses a special Unix filesystem type, called "mvfs" for + "multi-version file system". Conceptually, mvfs adds another dimension + to a regular Unix filesystem. The new axis is used to store the + different versions of files and to provide a tree-hierarchical view of + a collection of objects that might be scattered across any number of + separate hosts on your local network. + + Each user acquires a "view" into the file database by creating a + special mvfs mount point on their machine. Each view has a + "configuration spec" containing a set of selection rules that specify + the particular version of each file to make visible in that view. You + can think of a "view" as a work area in CVS, except that the files + don't really exist on your local disk until you modify them. This + technique conserves disk space because it doesn't keep private copies + of read-only files. + + Another advantage is that a view is "transparent" in the sense that + all of the files in a "view" appear to be regular Unix files to other + tools and Unix system calls. An extended naming convention allows + access to particular versions of a file directly: + "test.cc@@/main/bugfix/3" identifies the third version of test.c on + the bugfix branch. + + ClearCase supports both the copy-modify-merge model of CVS (by using + what are called "unreserved checkouts" and the checkin/checkout + development model with file locking. Directories are + version-controlled objects as well as files. A graphical merge tool is + provided. Like RCS, ClearCase supports branches, symbolic tags, and + delta compression. ASCII as well as binary files are supported, and + converters from RCS, SCCS, DSEE formats are also included. + + A make-compatible build facility is provided that can identify common + object code and share it among developers. A build auditing feature + automatically records file dependencies by tracking every file that is + opened when producing a derived object, thus making explicit + dependency lists unnecessary. Pre- and post-event triggers are + available for most ClearCase operations to invoke user programs or + shell scripts. User-defined attributes can be assigned to any version + or object. Hyper-links between version controlled objects can record + their relationship. + + For more information, contact: + + Atria Software, Inc. 24 Prime Park Way Natick, MA 01760 info@atria.com + + (508) 650-1193 (phone) (508) 650-1196 (fax) + + Originally contributed by Steve Turner + Edited by the author of this FAQ. + + Last modified: _6/13/1997_ + + 4. How does CVS differ from TeamWare/SparcWorks? + + TeamWare is a configuration management tool from Sun Microsystems, a + part of SparcWorks. It uses the same copy and merge model as CVS. The + central abstraction is a workspace, which corresponds to either a CVS + branch or a checked out module. TeamWare allows you to manipulate + workspaces directly, including moving and merging code between + workspaces. You can put your workspace on tape and continue to work + with it at home, just like you can with CVS. TeamWare is built upon + and compatible with SCCS. + + TeamWare provides both a command line interface and a graphical + interface. The CodeManager tool will display the project as a tree of + workspaces, and allows you to manipulate them with drag and drop. The + other tools are VersionTool that displays and manipulates a dag with a + version history of a single file, CheckPoint that will create symbolic + tags, MakeTool, a make compatible tool with a GUI, and FileMerge which + will interactively merge files when needed (like emerge for emacs). If + you have a sun, you can try /usr/old/mergetool for an old SunView + version of FileMerge. + + Email: sunprosig@sun.com + + Originally extracted from TeamWare + Marketing literature by Per Abrahamsen. + Edited by the author of this FAQ. + + For more information, contact: + + SunExpress, Inc. P.O. Box 4426 Bridgeton, MO 63044-9863 (800)873-7869 + + Last modified: _6/13/1997_ + + 5. How does CVS differ from Aegis? + + Aegis appears to be a policy-setting tool that allows you to use other + sub-programs (make, RCS, etc.) to implement pieces of the imposed + policy. + + The initial document seems to say that most Unix tools are inadequate + for use under Aegis. + + It is not really similar to CVS and requires a different mindset. + + [[Need more info here.]] + + Last modified: _6/13/1997_ + + 6. How does CVS differ from Shapetools? + + Shapetools includes a build mechanism (called Shape, not surprisingly) + that is aware of the version mechanism, and some dependency tracking. + It is based on a file system extension called Attributed File System, + which allows arbitrary-sized "attributes" to be associated with a + file. Files are version controlled in a manner similar to RCS. + Configurations are managed through the Shapefile, an extension of the + Makefile syntax and functionality. Shape includes version selection + rules to allow sophisticated selection of component versions in a + build. + + Shapetools' concurrency control is pessimistic, in contrast to that of + CVS. Also, there's very limited support for branching and merging. It + has a built-in policy for transitioning a system from initial + development to production. + + Contributed by Don Dwiggins + + Last modified: _6/13/1997_ + + 7. How does CVS differ from TeamNet? + + TeamNet is a configuration management tool from TeamOne. + + For more information, contact: + + TeamOne 710 Lakeway Drive, Ste 100 Sunnyvale, CA 94086 (800) 442-6650 + + Contributed by Steve Turner + + Last modified: _6/13/1997_ + + 8. How does CVS differ from ProFrame? + + ProFrame is a new system integration framework from IBM. ProFrame is + compliant with the CFI (CAD Framework Initiative) industry standards, + including the Scheme extension language. + + ProFrame consists of three major components: (1) the Process Manager + that automates your local design methodology (2) the Design Data + Manager handles configuration management, and (3) Inter-tool + Communication to provide a communication path among tools running on + heterogeneous servers. + + The Design Data Manager(2) is probably the appropriate component to + compare to CVS. The Design Data Manager provides version control with + checkin/checkout capability, configuration management, and data + dependency tracking. A graphical data selection interface is provided. + Using this interface, you may create and manipulate objects and + hierarchy structures, view the revision history for an object, and + view and assign attributes to a design object. + + The ProFrame server currently runs only on RS6000, but clients may be + a wide variety of Unix platforms. Contact IBM for the latest platform + information. + + For more information, contact: + + IBM EDA Marketing and Sales P.O. Box 950, M/S P121 Poughkeepsie, NY + 12602 (800) 332-0066 + + Contributed by Steve Turner + [extracted from the ProFrame 1.1.0 datasheet] + + Last modified: _6/13/1997_ + + 9. How does CVS differ from CaseWare/CM? + + CaseWare/CM is a software configuration management product from + CaseWare, Inc. CaseWare/CM may be customized to support a wide variety + of methodologies, including various phases of the software lifecycle, + and different access rights for users. + + A GUI is provided to view version histories and configurations. A + merge tools is also included. CaseWare supports type-specific + lifecycles, which allows different types of files to move through + different lifecycles. Also provided is a build facility to support + automatic dependency analysis, parallel, distributed, and remote + builds, and variant releases. + + CaseWare/CM has been integrated with other CASE tools, including + FrameMaker, ALSYS Ada, CodeCenter/Object Center, HP SoftBench, and + Software Through Pictures. CaseWare also offers CaseWare/PT, a problem + tracking system to integrate change requests with configuration + management. + + Multiple vendors and operating systems are supported. + + For more information, contact: + + CaseWare, Inc. 108 Pacifica, 2nd Floor Irvine, CA 92718-3332 (714) + 453-2200 (phone) (714) 453-2276 (fax) + + Contributed by Steve Turner + [extracted from the CaseWare/CM data sheet] + + Last modified: _6/13/1997_ + + 10. How does CVS differ from Sublime? + + Produced by AT&T. Sablime uses SCCS as the underlying source code + control system. It uses some other control system (called sbcs I + think) for managing binary files. It uses lock, edit, comit, unlock + mechanism. It has a motif based GUI and curses based GUI (that works + only with ksh, not tcsh, or bash) to do more common tasks. It has even + a command line interface. + + Changing source happens as a result of MR. A testing person or a + developer assigns an MR (modification request) to a group of people. + They are allowed to take out files under that MR and change them and + check them back in. You can set up dependencies between and MR and do + release management to say "I want the sources to include these MRs" + etc. It is a reasonably good maintanance system. It is bit heavy + 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_ + + 11. How does CVS differ from PVCS? + + PVCS works on single files like RCS and SCCS, CVS works on complete + subsystems. PVCS has a make utility (called a configuration builder), + CVS does not. PVCS has a GUI interface for Unix, DOS, OS/2, and MS + Windows. + + Intersolv, Inc. + 1700 NW 167th Place + OR 97006 + + Contributed by Per Abrahamsen + [Extracted from Intersolv Marketing literature.] + + Last modified: _6/13/1997_ + + 12. How does CVS differ from CMVC? + + CMVC is an IBM Configuration Management and Version Control system. + (Though I'm not certain that's the right acronym expansion.) It runs + on Suns, HPs, RS6000s, OS/2 and Windows. + + Other than revision control, it apparently has features to manage + releases, bug tracking and the connection between alterations and + reported bugs and feature requests. It is a client/server system, + based on a choice of commercial Relational Database systems, and it + provides a Motif or command line interface. + + Unlike CVS, it uses a strict locking protocol to serialize source code + alterations. + + Last modified: _6/13/1997_ + + Category: /What_is_CVS_/What_do_you_mean_by_/ + + " + What do you mean by . . .? (Definitions)" + + 1. What are "The Repository", "$CVSROOT" and "CVSROOT"? + + The Repository is a directory tree containing the CVS administrative + files and all the RCS files that constitute "imported" or "committed" + work. The Repository is kept in a shared area, separate from the + working areas of all developers. + + Users of CVS must set their "CVSROOT" environment variable to the + absolute pathname of the head of the Repository. Most command line + interpreters replace an instance of "$CVSROOT" with the value of the + "CVSROOT" environment variable. By analogy, in this document + "$CVSROOT" is used as shorthand for "the absolute pathname of the + directory at the head of the Repository". + + One of the things found in $CVSROOT is a directory named CVSROOT. It + contains all the "state", the administrative files, that CVS needs + during execution. The "modules", "history", "commitinfo", "loginfo" + and other files can be found there. See 4B.2 for more information + about CVSROOT files. + + Last modified: _6/13/1997_ + + 2. What is an RCS file? + + An RCS file is a text file containing the source text and the revision + history for all committed revisions of a source file. It is stored + separately from the working files, in a directory hierarchy, called + the Repository. + + RCS is the "Revision Control System" that CVS uses to manage + individual files. RCS file names normally end in ",v", but that can be + altered (via the RCS -x option) to conform to file naming standards on + platforms with unusual filename limitations. + + Last modified: _6/13/1997_ + + 3. What is a working file? + + A working file is a disk file containing a checked-out copy of a + source file that earlier had been placed under CVS. If the working + file has been edited, the changes since the last committed revision + are invisible to other users of CVS. + + Last modified: _6/13/1997_ + + 4. What is a working directory (or working area)? + + A working directory is the place where you work and the place from + which you "commit" files. + + The "checkout" command creates a tree of working directories, filling + them with working files. Each working directory contains a + sub-directory named ./CVS containing three administrative files, which + are created by "checkout" and are always present: + + ./CVS/Entries + contains information about working files. + + ./CVS/Repository + contains the location of the directory within the + Repository that was used to create the working directory. + + ./CVS/Root + contains the value of $CVSROOT at the time you created + the working directory. + + Other files may also appear in ./CVS depending on the state of your + working directory: + + ./CVS/Tag + contains the "sticky tag" associated with the whole + directory. See 3A.2 for its main purpose. + [Created by "checkout" or "update" when using "-r <tag>".] + [Deleted by "checkout" or "update" when using '-A'.] + + ./CVS/Entries.Static + contains a fixed list of working files. If this file + exists, an "update" doesn't automatically bring newly + added files out of the Repository. + [Created and maintained by hand.] + + ./CVS/Checkin.prog + contains a program to run whenever anything in the + working directory is committed. + [Created by checkout if "-i <prog>" appears in the + modules file for the checked-out module.] + + ./CVS/Update.prog + contains a program to run whenever anything in the + working directory is updated. + [Created by checkout if "-u <prog>" appears in the + modules file for the checked-out module.] + + ./CVS/<file>,p ./CVS/<file>,t + contain (possibly zero-length) state information about an + "add" that has not been committed. + [Created by "add".] + [Deleted by "commit" or "remove".] + + Last modified: _6/13/1997_ + + 5. What is "checking out"? + + "Checking out" is the act of using the "checkout" command to copy a + particular revision from a set of RCS files into your working area. + You normally execute "checkout" only once per working directory (or + tree of working directories), maintaining them thereafter with the + "update" command. + + See section 3C on the "checkout" command. + + Last modified: _6/13/1997_ + + 6. What is a revision? + + A "revision" is a version of a file that was "committed" ("checked + in", in RCS terms) some time in the past. CVS (and RCS) can retrieve + any file that was committed by specifying its revision number or its + "tag" ("symbolic name", in RCS terms). + + In CVS, a "tag" is more useful than a revision number. It usually + marks a milestone in development represented by different revision + numbers in different files, all available as one "tagged" collection. + + Sometimes the word "revision" is used as shorthand for "the file you + get if you retrieve (via "checkout" or "update") the given revision + from the Repository." + + Last modified: _6/13/1997_ + + 7. What is a "Tag"? + + A "Tag" is a symbolic name, a synonym or alias for a particular + revision number in a file. The CVS "tag" command places the same "Tag" + on all files in a working directory, allowing you to retrieve those + files by name in the future. + + The CVS "Tag" is implemented by applying RCS "symbols" to each + individual file. The Tags on a file (or collection of files) may be + displayed using the "log" command. + + Last modified: _6/13/1997_ + + 8. What are "HEAD" and "BASE"? + + HEAD and BASE are built-in tags that don't show up in the "log" or + "status" listings. They are interpreted directly by CVS. + + "HEAD" refers to the latest revision on the current branch in the + Repository. The current branch is either the main line of development, + or a branch in development created by placing a branch tag on a set of + files and checking out that branch. + + "BASE" refers to the revision on the current branch you last checked + out, updated, or committed. If you have not modified your working + file, "BASE" is the committed revision matching it. + + Most of the time BASE and HEAD refer to the same revision. They can + become different in two ways: + + Someone else changed HEAD by committing a new revision of your file + to the Repository. You can pull BASE up to equal HEAD by executing + "update". + + You moved BASE backward by executing "checkout" or "update" with the + option "-r <rev/tag>" or "-D <date>". CVS records a sticky tag and + moves your files to the specified earlier revision. You can clear the + sticky tag and pull BASE up to equal HEAD again by executing "update + -A". + + Last modified: _6/13/1997_ + + 9. What is a Branch? + + In general, a branch is any mechanism that allows one or more + developers to modify a file without affecting anyone other than those + working on the same branch. + + There are four kinds of "branch" CVS can manage: + + The Vendor Branch. + + A single vendor branch is supported. The "import" command takes a + sequence of releases from a source code vendor (called a "vendor" even + if no money is involved), placing them on a special "Vendor" branch. + The Vendor branch is considered part of the "Main line" of + development, though it must be merged into locally modified files on + the RCS Main branch before the "import" is complete. + + See Section 3H ("import"). + + Your Working directory. + + A checked-out working directory, can be treated like a private branch. + No one but you can touch your files. You have complete control over + when you include work committed by others. However, you can't commit + or tag intermediate versions of your work. + + A Development branch. + + A group of developers can share changes among the group, without + affecting the Main line of development, by creating a branch. Only + those who have checked-out the branch see the changes committed to + that branch. This kind of branch is usually temporary, collapsing + (i.e. merge and forget) into the Main line when the project requiring + the branch is completed. + + You can also create a private branch of this type, allowing an + individual to commit (and tag) intermediate revisions without changing + the Main line. It should be managed exactly like a Development Branch + -- collapsed into the Main line (or its parent branch, if that is not + the Main Branch) and forgotten when the work is done. + + A Release branch. + + At release time, a branch should be created marking what was released. + Later, small changes (sometimes called "patches") can be made to the + release without including everything else on the Main line of + development. You avoid forcing the customer to accept new, possibly + untested, features added since the release. This is also the way to + correct bugs found during testing in an environment where other + developers have continued to commit to the Main line while you are + testing and packaging the release. + + Although the internal format of this type of branch (branch tag and + RCS branches) is the same as in a development branch, its purpose and + the way it is managed are different. The major difference is that a + Release branch is normally Permanent. Once you let a release out the + door to customers, or to the next stage of whatever process you are + using, you should retain forever the branch marking that release. + + Since the branch is permanent, you cannot incorporate the branch fixes + into the Main line by "collapsing" (merging and forgetting) the + release branch. For large changes to many files on the release branch, + you will have to perform a branch merge using "update -j <rev> -j + <rev>". (See 4C.7) + + The most common way to merge small changes back into Main line + development is to make the change in both places simultaneously. This + is faster than trying to perform a selective merge. + + See 1D.12 (merges) and Section 4C, on Branching for more info. + + Last modified: _6/13/1997_ + + 10. What is "the trunk"? + + Another name for the RCS Main Branch. The RCS Main Branch is related, + but not equivalent, to both the CVS Main branch and what developers + consider to be the Main line of development. See 3H.3 and Section 4C + on Branching. + + Last modified: _6/13/1997_ + + 11. What is a module? + + In essence, a module is a name you hand to the "checkout" command to + retrieve one or more files to work on. It was originally intended to + be a simple, unique name in the "modules" file attached to a directory + or a subset of files within a directory. + + The module idea is now a somewhat slippery concept that can be defined + in two different ways: + * A module is an argument to "checkout". There are three types: + 1. An entry in the modules file. A "module" name as described in + 'B.' below. + 2. A relative path to a directory or file in the Repository. + 3. A mixed-mode string of "modulename/relative-path". Everything + up to the first slash ('/') is looked up as a module. The + relative path is appended to the directory associated with + the module name and the resulting path is checked out as in + #2 above. + * A module is a unique (within the file) character string in the + first column of the modules file. There are five types: + 1. A name for a directory within the Repository that allows you + to ignore the parent directories above it. + Example: + emacs gnu/emacs + 2. A name for a subset of the files within such a directory. + Example: + ls unix/bin Makefile ls.c + The 2nd through Nth strings in the above can be files, + directories or module substitutions. No relative paths. + A module substitution occurs when you use a '&module-name' + reference. The module-name referred to is logically + substituted for the '&module-name' string. + 3. A relative pathname to a directory within the Repository + which, when checked out, creates an image of part of the + Repository structure in your current directory. + Example: + gnu/emacs -o /bin/emacs.helper gnu/emacs + The files checked out are exactly the same as the files + "checkout" would retrieve if the path weren't even in the + modules file. The only reason to put this kind of relative + pathname into the modules file is to hook one of the helper + functions onto it. + 4. A relative pathname to a single file within the Repository + which, when checked out, creates something you probably don't + want: It creates a directory by the name of the file and puts + the file in it. + Example: + gnu/emacs/Makefile -o /bin/emacs.helper gnu/emacs Makefile + The file checked out is the same as what you would get if you + handed the relative pathname to the "checkout" command. But + it puts it in a strange place. The only reason to do this is + to hook a helper function onto a specific file name. + 5. An alias consisting of a list of any of the above, including + other aliases, plus exceptions. + Example: + my_work -a emacs !emacs/tests gnu/bison unix/bin/ls.c + The exception "!emacs/test" above is functionally equivalent + to specifying "!emacs/tests" on the "checkout" command line. + + Another way to look at it is that the modules file is simply another + way to "name" files. The hierarchical directory structure provides + another. You should use whatever turns out to be simplest for your + development group. + + See 4G.2 for some specific ideas about how to use the modules file. + + Last modified: _11/12/1997_ + + 12. What does "merge" mean? + + A merge is a way of combining changes made in two independent copies + of a common starting file. Checking out an RCS revision produces a + file, so for the purposes of a merge "file" and "revision" are + equivalent. So, we can say there are always three "files" involved in + a merge: + + The original, starting, "base" or "branch point" file. + + A copy of the base file modified in one way. + + Another copy of the base file modified in a different way. + + Humans aren't very good at handling three things at once, so the + terminology dealing with merges can become strained. One way to think + about it is that all merges are performed by inserting the difference + between a base revision and a later revision (committed by someone + else) into your working file. Both the "later" revision and your + working file are presumed to have started life as a copy of the "base" + revision. + + In CVS, there are three main types of "merge": + + The "update" command automatically merges revisions committed by + others into your working file. In this case, the three files involved + in the merge are: + + Base: The revision you originally checked out. Later: A revision + committed onto the current branch after you checked out the Base + revision. Working: Your working file. The one lying in the working + directory containing changes you have made. + + The "update -j <branch_tag> {optional files}" command merges changes + made on the given branch into your working files, which is presumed to + be on the Main line of development. + + See 4C.6 + + The "update -j <rev> -j <rev> {optional files}" command merges the + difference between two specified revisions into files in your working + directory. The two revisions <rev> are usually on the same branch and, + when updating multiple files, they are most useful when they are Tag + names rather than numeric revisions. + + See 4C.7 + + Last modified: _6/13/1997_ + + Category: /What_is_CVS_/What_is_CVS_Whats_it/ + + " + What is CVS? What's it for? Why CVS?" + + 1. What does CVS stand for? Can you describe it in one sentence? + + "CVS" is an acronym for the "Concurrent Versions System". + + CVS is a "Source Control" or "Revision Control" tool designed to keep + track of source changes made by groups of developers working on the + same files, allowing them to stay in sync with each other as each + individual chooses. + + Last modified: _6/13/1997_ + + 2. What is CVS for? What does it do for me? + + CVS is used to keep track of collections of files in a shared + directory called "The Repository". Each collection of files can be + given a "module" name, which is used to "checkout" that collection. + + After checkout, files can be modified (using your favorite editor), + "committed" back into the Repository and compared against earlier + revisions. Collections of files can be "tagged" with a symbolic name + for later retrieval. + + You can add new files, remove files you no longer want, ask for + information about sets of files in three different ways, produce patch + "diffs" from a base revision and merge the committed changes of other + developers into your working files. + + Last modified: _6/13/1997_ + + 3. How does CVS work? + + CVS saves its version-control information in RCS files stored in a + directory hierarchy, called the Repository, which is separate from the + user's working directory. + + Files in the Repository are stored in a format dictated by the RCS + commands CVS uses to do much of its real work. RCS files are standard + byte-stream files with an internal format described by keywords stored + in the files themselves. + + To begin work, you execute a "checkout" command, handing it a module + name or directory path (relative to the $CVSROOT variable) you want to + work on. CVS copies the latest revision of each file in the specified + module or directory out of the Repository and into a directory tree + created in your current directory. You may specify a particular branch + to work on by symbolic name if you don't want to work on the default + (main or trunk) branch. + + You may then modify files in the new directory tree, build them into + output files and test the results. When you want to make your changes + available to other developers, you "commit" them back into the + Repository. + + Other developers can check out the same files at the same time. To + merge the committed work of others into your working files you use the + "update" command. When your merged files build and test correctly, you + may commit the merged result. This method is referred to as + "copy-modify-merge", which does not require locks on the source files. + + At any time, usually at some milestone, you can "tag" the committed + files, producing a symbolic name that can be handed to a future + "checkout" command. A special form of "tag" produces a branch in + development, as usually happens at "release" time. + + When you no longer plan to modify or refer to your local copy of the + files, they can be removed. + + Last modified: _6/13/1997_ + + 4. What is CVS useful for? + + CVS is intended to handle source control for files in three major + situations: + + Multiple developers working on the same files. + + The major advantage of using CVS over the simpler tools like RCS or + SCCS is that it allows multiple developers to work on the same sources + at the same time. + + The shared Repository provides a rendezvous for committed sources that + allows developers a fair amount of flexibility in how often to publish + (via the "commit" command) changes or include work committed by others + (via the "update" command). + + Tracking a stream of releases from a source vendor. + + If you are making changes to sources distributed by someone else, the + CVS feature, called the Vendor Branch, allows you to combine local + modifications with repeated vendor releases. + + I have found this most useful when dealing with sources from three + major classes of source vendor: + + Large companies who send you tapes full of the latest release (e.g. + Unix OS vendors, database companies). + + Public Domain software which *always* requires work. + + Pseudo-Public sources which may require work. (e.g. GNU programs, X, + CVS itself, etc.) + + Branching development. + + Aside from the "Vendor Branch", there are three kinds of "branches in + development" that CVS can support: + + Your working directory can be treated as a private branch. + + A Development branch can be shared by one or more developers. + + At release time, a branch is usually created for bug fixes. + + (See 1D.9 and Section 4C for more info on branches.) + + CVS's branch support is a bit primitive, but it was designed to allow + you to create branches, work on them for while and merge them back + into the main line of development. You should also be able to merge + work performed on the main branch into the branch you are working on. + Arbitrary sharing and merging between branches is not currently + supported. + + Last modified: _6/13/1997_ + + 5. What is CVS *not* useful for? + + CVS is not a build system. + + Though the structure of your Repository and modules file interact with + your build system (e.g. a tree of Makefiles), they are essentially + independent. + + CVS does not dictate how you build anything. It merely stores files + for retrieval in a tree structure you devise. + + CVS does not dictate how to use disk space in the checked out working + directories. If you require your Makefiles or build procedures to know + the relative positions of everything else, you wind up requiring the + entire Repository to be checked out. That's simply bad planning. + + If you modularize your work, and construct a build system that will + share files (via links, mounts, VPATH in Makefiles, etc.), you can + arrange your disk usage however you like. + + But you have to remember that *any* such system is a lot of work to + construct and maintain. CVS does not address the issues involved. You + must use your brain and a collection of other tools to provide a build + scheme to match your plans. + + Of course, you should use CVS to maintain the tools created to support + such a build system (scripts, Makefiles, etc). + + CVS is not a substitute for management. + + You and your project leaders are expected to plan what you are doing. + Everyone involved must be aware of schedules, merge points, branch + names, release dates and the range of procedures needed to build + products. (If you produce it and someone else uses it, it is a + product.) CVS can't cover for a failure to manage your project. + + CVS is an instrument for making sources dance to your tune. But you + are the piper and the composer. No instrument plays itself or writes + its own music. + + CVS is not a substitute for developer communication. + + When faced with conflicts within a single file, most developers manage + to resolve them without too much effort. But a more general definition + of "conflict" includes problems too difficult to solve without + communication between developers. + + CVS cannot determine when simultaneous changes within a single file, + or across a whole collection of files, will logically conflict with + one another. Its concept of a "conflict" is purely textual, arising + when two changes to the same base file are near enough to spook the + merge command into dropping conflict markers into the merged file. + + CVS is not capable of figuring out distributed conflicts in program + logic. For example, if you change the arguments to function X defined + in file A and, at the same time, edit file B, adding new calls to + function X using the old arguments. You are outside the realm of CVS's + competence. + + Acquire the habit of reading specs and talking to your peers. + + CVS is not a configuration management system. + + CVS is a source control system. The phrase "configuration management" + is a marketing term, not an industry-recognized set of functions. + + A true "configuration management system" would contain elements of the + following: + + * Source control. + * Dependency tracking. + * Build systems (i.e. What to build and how to find + things during a build. What is shared? What is local?) + * Bug tracking. + * Automated Testing procedures. + * Release Engineering documentation and procedures. + * Tape Construction. + * Customer Installation. + * A way for users to run different versions of the same + software on the same host at the same time. + + CVS provides only the first. + + Last modified: _6/13/1997_ + + Category: /What_is_CVS_/Where_do_I_find_CVS_/ + + " + Where do I find CVS? Where can I find Help?" + + 1. How do I get more information about CVS? + + The first thing I would do is to read the Info file that comes with + the CVS sources under "doc". You can format and read the cvs.texinfo + file in two ways: 1. Use TeX to format it and a "dvips" command to + print it and 2. Install the cvs.info files that are created by the + Makefile and read them online using the Emacs "info-mode" or a + stand-alone "info" reader. + + Then I'd run "cvsinit" to set up a Repository and read the man page + while trying out the commands. + + Type "cvs -H" for general help or "cvs -H command" for + command-specific help. + + For background, you can read the original CVS paper (in the source + tree, under "doc"). It describes the purpose of CVS and some of how it + was designed. Note that the emphasis of the document (especially on + multiple vendors providing the same sources) is somewhat out of date. + + For more detailed information about "internals", read the man pages + for RCS. If you are a programmer, you can also read the source code to + CVS. + + Other information and tutorials may be available in the "doc" + directory of the FTP archive described below. + + For current information, and a fair amount of detail, join the + info-cvs mailing list described below. + + Last modified: _6/13/1997_ + + 2. Is there an archive of CVS material? + + An anonymous FTP area has been set up. It contains many of the CVS + files you might want, including extra documentation, patches and a + copy of the latest release. + + ftp ftp.delos.com + >>> User: anonymous + >>> Passwd: <Your Internet address> + cd /pub/cvs + get README + get Index + + The README has more (and more up-to-date) information. The Index + contains a terse list of what is in the archive. + + A WWW home page is also available at http://www.delos.com/cvs. + + Last modified: _6/13/1997_ + + 3. How do I get files out of the archive if I don't have FTP? + + Use one of the FTP<->Email servers. These are the ones I've been told + about: + + FTPMAIL service is available from the same host as the FTP server + described above. Send mail to "ftpmail@delos.com" containing "help" in + the body of the message. For example, on most Unix systems, you can + type: + + echo help | Mail ftpmail@delos.com + + The FTPMAIL server will respond with a document describing how to use + the server. If the "Mail" command doesn't exist on your system, try + "mailx", "/usr/ucb/mail" or "/bin/mail". + + If you are on BITNET, use Princeton's BITFTP server. Type + + echo 'send help' | Mail bitftp@pucc.princeton.edu + + (It is likely that only BITNET addresses can use this one.) + + Other possibilities I've heard of from the net: (Try the one closest + to you.) + + ftpmail@decwrl.dec.com ftpmail@sunsite.unc.edu ftpmail@cs.arizona.edu + ftpmail@cs.uow.edu.au ftpmail@doc.ic.ac.uk + + Last modified: _6/13/1997_ + + 4. How do I get a copy of the latest version of CVS? + + The latest released version of CVS and all the programs it depends on + should be available through anonymous FTP on any FSF archive. The main + FSF archive is at "prep.ai.mit.edu". There are mirrors of the FSF + archive on UUNET and other large Internet sites. + + Program(s) Suggested revision + ----------- ----------------------- + CVS 1.5 + RCS 5.7 (latest version available today) + GNU diff 2.7 (or later) [contained in diffutils-2.7] + GDBM 1.5 (or later) [optional] + + The GNU version of diff is suggested by both the RCS and CVS + configuration instructions because it works better than the standard + version. + + It is a good idea not to accept the versions of CVS, RCS or diff you + find lying on your system unless you have checked out their + provenance. Using inconsistent collections of tools can cause you more + trouble than you can probably afford. + + The FTP archive mentioned above should contain the latest official + release of CVS, some official and unofficial patches and possibly + complete patched versions of CVS in use somewhere. + + Last modified: _6/13/1997_ + + 5. Is there a mailing list devoted to CVS? How do I find it? + + An Internet mailing list named "info-cvs" grew out of the private + mailing list used by the CVS 1.3 alpha testers in early 1992. + Throughout 1994, the list received an average of 100 messages per + month. + + You can add yourself to the mailing list by sending an Email message + to: + + info-cvs-request@prep.ai.mit.edu + + (Don't forget the "-request" or you'll send a message to the whole + list, some of whom are capable of remote execution.) + + Mail to the whole list should be sent to: + + info-cvs@prep.ai.mit.edu + + An archive of the mailing list is maintained in the FTP archive + mentioned above. + + Last modified: _6/13/1997_ + + 6. What happened to the CVS Usenet newsgroup I heard about? + + + A Usenet newsgroup named "gnu.cvs.info" was announced in April + 1993, with an expected creation date of August, 1993. However, + nothing came of this. + + If you want to discuss CVS on usenet, the correct group is + comp.software.config-mgmt (which also covers other configuration + management systems). Someday it might be possible to create a + comp.software.config-mgmt.cvs, but only if there is sufficient + CVS traffic on comp.software.config-mgmt. + + kingdon@cyclic.com + + Last modified: _9/6/1997_ + _________________________________________________________________ + + [Add an answer to this category] + + [Category /] + _________________________________________________________________ + + _Search the FAQ-O-Matic:_ ____________________ ______ + [matching all words] + Or look for questions modified in the last: [7.] ____ + _________________________________________________________________ + + 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. |