## 39.8. More CVS

Here's a slightly more complex example of how to use CVS. I'm working on this book, via CVS, with my two main coauthors (who are on the east and west coasts of the United States). The repository, which has almost 1,000 files, is on a computer in the O'Reilly office in Massachusetts.

1. From the command line or in a shell setup file (Section 3.3), I need to set an environment variable (Section 35.3) named CVSROOT that tells CVS where the repository is and what my username is on that machine. In the C shell, for instance, I'd execute a command that sets my username to jpeek, the server hostname to bserver.east.oreilly.com, and the repository to /books/cvs. I'm also using ssh for secure access to the server, so I need to set the CVS_RSH environment variable and tell CVS to use the "ext" connection method:

   >     setenv CVSROOT :ext:jpeek@bserver.east.oreilly.com:/books/cvs
   >     setenv CVS_RSH ssh

2. I have a directory where I keep my local copies of the book files. To start, I check out my copy of the ulpt3 repository from the server:

   `!$` Section 30.3

   >     % cd books
   >     % cvs checkout ulpt3
   >     cvs checkout: updating ulpt3
   >     U ulpt3/0001.sgm
   >     U ulpt3/0007.sgm
   >     U ulpt3/0023.sgm
   >        ...more...
   >     % cd !$
   >     cd ulpt3

3. Now my ulpt3 subdirectory has the same files that the repository does. I can edit any of them, just as I'd edit files that aren't in CVS -- but my changes don't make it back to the repository until I use the CVS command to do that.

   Let's say I edit the file 0123.sgm. I'd like to write it back to the repository, where the other authors can grab it in case they're printing that part of the book. First I should update my workspace. This brings in any changes by other authors. If another author has updated 0123.sgm and put it in the archive before I do, CVS will merge the two files and expect me to resolve the differences:

   >     % vi 0123.sgm
   >        ...edit the file...
   >     % cvs update
   >     cvs update: updating .
   >     U ulpt/0075.sgm
   >     RCS file: /books/cvs/ulpt3/0123.sgm,v
   >     retrieving revision 3.6
   >     retrieving revision 3.7
   >     Merging differences between 3.6 and 3.7 into 0123.sgm
   >     rcsmerge: warning: conflicts during merge
   >     cvs update: conflicts found in 0123.sgm
   >     C 0123.sgm
   >     %

   The `U` line shows that another author changed file 0075.sgm; CVS is updating my copy of it. As it happens, another author edited 0123.sgm while I did -- and committed his changes to the repository before I got there. CVS sees that the copy in the repository is newer than the one I fetched a while ago, so it merges the two versions. If the changes had been to different parts of the file, CVS wouldn't have complained, just warned me that 0123.sgm had been merged. As luck would have it (something to do with this being an example, I think `;-)`) both changes were in the same place and CVS warned me that the merge failed; there was a conflict.

4. This step only applies if there was a conflict during the update. Edit the file and search for a string of less-than signs (`<<<<`). You'll see something like this:

   >       <para>
   >       <indexterm><primary>serial line modes</primary></indexterm>
   >     <<<<<<< 0123.sgm
   >       But there is some overlap. For example, a terminal can be unusable
   >       because a program has left either the serial line modes or the
   >       terminal itself in an unexpected state. For this reason,
   >       <link linkend="UPT-ART-0079">terminal initialization</link>,
   >       as performed by the <command>tset</command> and
   >     =======
   >       But there is some overlap. For example, a terminal can be unusable
   >       because a program has left the terminal in an "wedged"
   >       or unexpected state. The serial modes may be wrong too. This is why
   >       <link linkend="UPT-ART-0079">terminal initialization</link>,
   >       as performed by the <command>tset</command> and
   >     >>>>>>> 3.7
   >       <command>tput</command> programs,
   >       initializes both the terminal and the serial line interface.

   The text from your working file is at the top, after the `<<<<` characters. The conflicting text is after the `====` characters. You decide that your text is better written, so you simply delete the markers and the second chunk of text. [In a slightly less contrived example, there would probably be a process for this. You might use cvs log to look at the log message on the conflicting change, talk to the author of the conflicting change or both. Sometimes you might have to look at cvs log to figure out who checked in the conflicting change, because there may have been several changes. -- DJPH]

5. Things look good. Now tell CVS to put all your changes from your local workspace into the repository by committing. You should give a message that describes the changes you made. You can give the message either as an argument to the -m option or by typing it into your text editor, like this:

   >     % cvs commit
   >     cvs commit: Examining .
   >       ...your text editor runs...
   >     Checking in 0123.sgm;
   >     /books/cvs/ulpt3/0123.sgm,v <-- 0123.sgm
   >     new revision: 3.8; previous revision: 3.7
   >     done

--JP and DJPH

Copyright © 2003 O'Reilly & Associates. All rights reserved.