<div id="Multiple-developers"></div>
<div class="header">
<p>
Next: [[cvs: Revision management#Revision management|Revision management]], Previous: [[cvs: Handling binary files#Handling binary files|Binary files]], Up: [[cvs#Top|Top]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Multiple-developers-1"></div>
== Multiple developers ==
<div id="index-Multiple-developers"></div>
<div id="index-Team-of-developers"></div>
<div id="index-File-locking"></div>
<div id="index-Locking-files"></div>
<div id="index-Working-copy"></div>
<div id="index-Reserved-checkouts"></div>
<div id="index-Unreserved-checkouts"></div>
<div id="index-RCS_002dstyle-locking"></div>

When more than one person works on a software project
things often get complicated.  Often, two people try to
edit the same file simultaneously.  One solution, known
as <em>file locking</em> or <em>reserved checkouts</em>, is
to allow only one person to edit each file at a time.
This is the only solution with some version control
systems, including <small>RCS</small> and <small>SCCS</small>.  Currently
the usual way to get reserved checkouts with <small>CVS</small>
is the <code>cvs admin -l</code> command (see [[cvs: Guide to CVS commands#admin options|admin options]]).  This is not as nicely integrated into
<small>CVS</small> as the watch features, described below, but it
seems that most people with a need for reserved
checkouts find it adequate.
It also may be possible to use the watches
features described below, together with suitable
procedures (not enforced by software), to avoid having
two people edit at the same time.

The default model with <small>CVS</small> is known as
<em>unreserved checkouts</em>.  In this model, developers
can edit their own <em>working copy</em> of a file
simultaneously.  The first person that commits his
changes has no automatic way of knowing that another
has started to edit it.  Others will get an error
message when they try to commit the file.  They must
then use <small>CVS</small> commands to bring their working copy
up to date with the repository revision.  This process
is almost automatic.

<small>CVS</small> also supports mechanisms which facilitate
various kinds of communication, without actually
enforcing rules like reserved checkouts do.

The rest of this chapter describes how these various
models work, and some of the issues involved in
choosing between them.


<div class="menu-preformatted" style="font-family: serif">
 [[#File status|&bull; File status]]::                 A file can be in several states
 [[#Bringing a file up to date|&bull; Updating a file]]::             Bringing a file up-to-date
 [[#Conflicts example|&bull; Conflicts example]]::           An informative example
 [[#Informing others about commits|&bull; Informing others]]::            To cooperate you must inform
 [[#Several developers simultaneously attempting to run CVS|&bull; Concurrency]]::                 Simultaneous repository access
 [[#Mechanisms to track who is editing files|&bull; Watches]]::                     Mechanisms to track who is editing files
 [[#Choosing between reserved or unreserved checkouts|&bull; Choosing a model]]::            Reserved or unreserved checkouts?
</div>


----

<div id="File-status"></div>
<div class="header">
<p>
Next: [[#Bringing a file up to date|Updating a file]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="File-status-1"></div>
=== File status ===
<div id="index-File-status"></div>
<div id="index-Status-of-a-file"></div>

Based on what operations you have performed on a
checked out file, and what operations others have
performed to that file in the repository, one can
classify a file in a number of states.  The states, as
reported by the <code>status</code> command, are:

<div id="index-Up_002dto_002ddate"></div>
;Up-to-date
: The file is identical with the latest revision in the repository for the branch in use.

;Locally Modified
<div id="index-Locally-Modified"></div>
: You have edited the file, and not yet committed your changes.

;Locally Added
<div id="index-Locally-Added"></div>
: You have added the file with <code>add</code>, and not yet committed your changes.

;Locally Removed
<div id="index-Locally-Removed"></div>
: You have removed the file with <code>remove</code>, and not yet committed your changes.

;Needs Checkout
<div id="index-Needs-Checkout"></div>
: Someone else has committed a newer revision to the repository.  The name is slightly misleading; you will ordinarily use <code>update</code> rather than <code>checkout</code> to get that newer revision.

;Needs Patch
<div id="index-Needs-Patch"></div>
: Like Needs Checkout, but the <small>CVS</small> server will send a patch rather than the entire file.  Sending a patch or sending an entire file accomplishes the same thing.

;Needs Merge
<div id="index-Needs-Merge"></div>
: Someone else has committed a newer revision to the repository, and you have also made modifications to the file.

;Unresolved Conflict
<div id="index-Unresolved-Conflict"></div>
: A file with the same name as this new file has been added to the repository from a second workspace.  This file will need to be moved out of the way to allow an <code>update</code> to complete.

;File had conflicts on merge
<div id="index-File-had-conflicts-on-merge"></div>
: This is like Locally Modified, except that a previous <code>update</code> command gave a conflict.  If you have not already done so, you need to resolve the conflict as described in [[#Conflicts example|Conflicts example]].

;Unknown
<div id="index-Unknown"></div>
: <small>CVS</small> doesn&rsquo;t know anything about this file.  For example, you have created a new file and have not run <code>add</code>.


To help clarify the file status, <code>status</code> also
reports the <code>Working revision</code> which is the
revision that the file in the working directory derives
from, and the <code>Repository revision</code> which is the
latest revision in the repository for the branch in
use.

The options to <code>status</code> are listed in
[[cvs: Quick reference to CVS commands#Quick reference to CVS commands|Invoking CVS]].  For information on its <code>Sticky tag</code>
and <code>Sticky date</code> output, see [[cvs: Revisions#Sticky tags|Sticky tags]].
For information on its <code>Sticky options</code> output,
see the &lsquo;<code>-k</code>&rsquo; option in [[cvs: Guide to CVS commands#update options|update options]].

You can think of the <code>status</code> and <code>update</code>
commands as somewhat complementary.  You use
<code>update</code> to bring your files up to date, and you
can use <code>status</code> to give you some idea of what an
<code>update</code> would do (of course, the state of the
repository might change before you actually run
<code>update</code>).  In fact, if you want a command to
display file status in a more brief format than is
displayed by the <code>status</code> command, you can invoke

<div id="index-update_002c-to-display-file-status"></div>
<div class="example" style="margin-left: 3.2em">
 $ cvs -n -q update
</div>

The &lsquo;<code>-n</code>&rsquo; option means to not actually do the
update, but merely to display statuses; the &lsquo;<code>-q</code>&rsquo;
option avoids printing the name of each directory.  For
more information on the <code>update</code> command, and
these options, see [[cvs: Quick reference to CVS commands#Quick reference to CVS commands|Invoking CVS]].


----

<div id="Updating-a-file"></div>
<div class="header">
<p>
Next: [[#Conflicts example|Conflicts example]], Previous: [[#File status|File status]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Bringing-a-file-up-to-date"></div>
=== Bringing a file up to date ===
<div id="index-Bringing-a-file-up-to-date"></div>
<div id="index-Updating-a-file"></div>
<div id="index-Merging-a-file"></div>
<div id="index-Update_002c-introduction"></div>

When you want to update or merge a file, use the <code>update</code>
command.  For files that are not up to date this is roughly equivalent
to a <code>checkout</code> command: the newest revision of the file is
extracted from the repository and put in your working directory.

Your modifications to a file are never lost when you
use <code>update</code>.  If no newer revision exists,
running <code>update</code> has no effect.  If you have
edited the file, and a newer revision is available,
<small>CVS</small> will merge all changes into your working copy.

For instance, imagine that you checked out revision 1.4 and started
editing it.  In the meantime someone else committed revision 1.5, and
shortly after that revision 1.6.  If you run <code>update</code> on the file
now, <small>CVS</small> will incorporate all changes between revision 1.4 and 1.6 into
your file.

<div id="index-Overlap"></div>
If any of the changes between 1.4 and 1.6 were made too
close to any of the changes you have made, an
<em>overlap</em> occurs.  In such cases a warning is
printed, and the resulting file includes both
versions of the lines that overlap, delimited by
special markers.
See [[cvs: Guide to CVS commands#update&mdash;Bring work tree in sync with repository|update]], for a complete description of the
<code>update</code> command.


----

<div id="Conflicts-example"></div>
<div class="header">
<p>
Next: [[#Informing others about commits|Informing others]], Previous: [[#Bringing a file up to date|Updating a file]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Conflicts-example-1"></div>
=== Conflicts example ===
<div id="index-Merge_002c-an-example"></div>
<div id="index-Example-of-merge"></div>
<div id="index-driver_002ec-_0028merge-example_0029"></div>

Suppose revision 1.4 of &lsquo;<tt>driver.c</tt>&rsquo; contains this:

<div class="example" style="margin-left: 3.2em">
 #include &lt;stdio.h&gt;
 
 void main()
 <nowiki>{</nowiki>
     parse();
     if (nerr == 0)
         gencode();
     else
         fprintf(stderr, &quot;No code generated.\n&quot;);
     exit(nerr == 0 ? 0 : 1);
 <nowiki>}</nowiki>
</div>

Revision 1.6 of &lsquo;<tt>driver.c</tt>&rsquo; contains this:

<div class="example" style="margin-left: 3.2em">
 #include &lt;stdio.h&gt;
 
 int main(int argc,
          char **argv)
 <nowiki>{</nowiki>
     parse();
     if (argc != 1)
     <nowiki>{</nowiki>
         fprintf(stderr, &quot;tc: No args expected.\n&quot;);
         exit(1);
     <nowiki>}</nowiki>
     if (nerr == 0)
         gencode();
     else
         fprintf(stderr, &quot;No code generated.\n&quot;);
     exit(!!nerr);
 <nowiki>}</nowiki>
</div>

Your working copy of &lsquo;<tt>driver.c</tt>&rsquo;, based on revision
1.4, contains this before you run &lsquo;<code>cvs update</code>&rsquo;:

<div class="example" style="margin-left: 3.2em">
 #include &lt;stdlib.h&gt;
 #include &lt;stdio.h&gt;
 
 void main()
 <nowiki>{</nowiki>
     init_scanner();
     parse();
     if (nerr == 0)
         gencode();
     else
         fprintf(stderr, &quot;No code generated.\n&quot;);
     exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 <nowiki>}</nowiki>
</div>

You run &lsquo;<code>cvs update</code>&rsquo;:

<div class="example" style="margin-left: 3.2em">
 $ cvs update driver.c
 RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v
 retrieving revision 1.4
 retrieving revision 1.6
 Merging differences between 1.4 and 1.6 into driver.c
 rcsmerge warning: overlaps during merge
 cvs update: conflicts found in driver.c
 C driver.c
</div>

<div id="index-Conflicts-_0028merge-example_0029"></div>
<small>CVS</small> tells you that there were some conflicts.
Your original working file is saved unmodified in
&lsquo;<tt>.#driver.c.1.4</tt>&rsquo;.  The new version of
&lsquo;<tt>driver.c</tt>&rsquo; contains this:

<div class="example" style="margin-left: 3.2em">
 #include &lt;stdlib.h&gt;
 #include &lt;stdio.h&gt;
 
 int main(int argc,
          char **argv)
 <nowiki>{</nowiki>
     init_scanner();
     parse();
     if (argc != 1)
     <nowiki>{</nowiki>
         fprintf(stderr, &quot;tc: No args expected.\n&quot;);
         exit(1);
     <nowiki>}</nowiki>
     if (nerr == 0)
         gencode();
     else
         fprintf(stderr, &quot;No code generated.\n&quot;);
 &lt;&lt;&lt;&lt;&lt;&lt;&lt; driver.c
     exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 =======
     exit(!!nerr);
 &gt;&gt;&gt;&gt;&gt;&gt;&gt; 1.6
 <nowiki>}</nowiki>
</div>

<div id="index-Markers_002c-conflict"></div>
<div id="index-Conflict-markers"></div>
<div id="index-_003c_003c_003c_003c_003c_003c_003c"></div>
<div id="index-_003e_003e_003e_003e_003e_003e_003e"></div>
<div id="index-_003d_003d_003d_003d_003d_003d_003d"></div>

Note how all non-overlapping modifications are incorporated in your working
copy, and that the overlapping section is clearly marked with
&lsquo;<code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code>&rsquo;, &lsquo;<code>=======</code>&rsquo; and &lsquo;<code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code>&rsquo;.

<div id="index-Resolving-a-conflict"></div>
<div id="index-Conflict-resolution"></div>
You resolve the conflict by editing the file, removing the markers and
the erroneous line.  Suppose you end up with this file:
<div class="example" style="margin-left: 3.2em">
 #include &lt;stdlib.h&gt;
 #include &lt;stdio.h&gt;
 
 int main(int argc,
          char **argv)
 <nowiki>{</nowiki>
     init_scanner();
     parse();
     if (argc != 1)
     <nowiki>{</nowiki>
         fprintf(stderr, &quot;tc: No args expected.\n&quot;);
         exit(1);
     <nowiki>}</nowiki>
     if (nerr == 0)
         gencode();
     else
         fprintf(stderr, &quot;No code generated.\n&quot;);
     exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 <nowiki>}</nowiki>
</div>

You can now go ahead and commit this as revision 1.7.

<div class="example" style="margin-left: 3.2em">
 $ cvs commit -m &quot;Initialize scanner. Use symbolic exit values.&quot; driver.c
 Checking in driver.c;
 /usr/local/cvsroot/yoyodyne/tc/driver.c,v  &lt;--  driver.c
 new revision: 1.7; previous revision: 1.6
 done
</div>

For your protection, <small>CVS</small> will refuse to check in a
file if a conflict occurred and you have not resolved
the conflict.  Currently to resolve a conflict, you
must change the timestamp on the file.  In previous
versions of <small>CVS</small>, you also needed to
insure that the file contains no conflict markers.
Because
your file may legitimately contain conflict markers (that
is, occurrences of &lsquo;<code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; </code>&rsquo; at the start of a
line that don&rsquo;t mark a conflict), the current
version of <small>CVS</small> will print a warning and proceed to
check in the file.

<div id="index-emerge"></div>
If you use release 1.04 or later of pcl-cvs (a <small>GNU</small>
Emacs front-end for <small>CVS</small>) you can use an Emacs
package called emerge to help you resolve conflicts.
See the documentation for pcl-cvs.


----

<div id="Informing-others"></div>
<div class="header">
<p>
Next: [[#Several developers simultaneously attempting to run CVS|Concurrency]], Previous: [[#Conflicts example|Conflicts example]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Informing-others-about-commits"></div>
=== Informing others about commits ===
<div id="index-Informing-others"></div>
<div id="index-Spreading-information"></div>
<div id="index-Mail_002c-automatic-mail-on-commit"></div>

It is often useful to inform others when you commit a
new revision of a file.  The &lsquo;<code>-i</code>&rsquo; option of the
&lsquo;<tt>modules</tt>&rsquo; file, or the &lsquo;<tt>loginfo</tt>&rsquo; file, can be
used to automate this process.  See [[cvs: Reference manual for Administrative files#The modules file|modules]].
See [[cvs: Reference manual for Administrative files#Loginfo|loginfo]].  You can use these features of <small>CVS</small>
to, for instance, instruct <small>CVS</small> to mail a
message to all developers, or post a message to a local
newsgroup.


----

<div id="Concurrency"></div>
<div class="header">
<p>
Next: [[#Mechanisms to track who is editing files|Watches]], Previous: [[#Informing others about commits|Informing others]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Several-developers-simultaneously-attempting-to-run-CVS"></div>
=== Several developers simultaneously attempting to run CVS ===

<div id="index-Locks_002c-cvs_002c-introduction"></div>
If several developers try to run <small>CVS</small> at the same
time, one may get the following message:

<div class="example" style="margin-left: 3.2em">
 <nowiki>[</nowiki>11:43:23<nowiki>]</nowiki> waiting for bach's lock in /usr/local/cvsroot/foo
</div>

<div id="index-_0023cvs_002erfl_002c-removing"></div>
<div id="index-_0023cvs_002ewfl_002c-removing"></div>
<div id="index-_0023cvs_002elock_002c-removing"></div>
<small>CVS</small> will try again every 30 seconds, and either
continue with the operation or print the message again,
if it still needs to wait.  If a lock seems to stick
around for an undue amount of time, find the person
holding the lock and ask them about the cvs command
they are running.  If they aren&rsquo;t running a cvs
command, look in the repository directory mentioned in
the message and remove files which they own whose names
start with &lsquo;<tt>#cvs.rfl</tt>&rsquo;,
&lsquo;<tt>#cvs.wfl</tt>&rsquo;, or &lsquo;<tt>#cvs.lock</tt>&rsquo;.

Note that these locks are to protect <small>CVS</small>&rsquo;s
internal data structures and have no relationship to
the word <em>lock</em> in the sense used by
<small>RCS</small>&mdash;which refers to reserved checkouts
(see [[#Multiple developers|Multiple developers]]).

Any number of people can be reading from a given
repository at a time; only when someone is writing do
the locks prevent other people from reading or writing.

<div id="index-Atomic-transactions_002c-lack-of"></div>
<div id="index-Transactions_002c-atomic_002c-lack-of"></div>
One might hope for the following property:

<blockquote>
If someone commits some changes in one cvs command,
then an update by someone else will either get all the
changes, or none of them.
</blockquote>

but <small>CVS</small> does ''not'' have this property.  For
example, given the files

<div class="example" style="margin-left: 3.2em">
 a/one.c
 a/two.c
 b/three.c
 b/four.c
</div>

if someone runs

<div class="example" style="margin-left: 3.2em">
 cvs ci a/two.c b/three.c
</div>

and someone else runs <code>cvs update</code> at the same
time, the person running <code>update</code> might get only
the change to &lsquo;<tt>b/three.c</tt>&rsquo; and not the change to
&lsquo;<tt>a/two.c</tt>&rsquo;.


----

<div id="Watches"></div>
<div class="header">
<p>
Next: [[#Choosing between reserved or unreserved checkouts|Choosing a model]], Previous: [[#Several developers simultaneously attempting to run CVS|Concurrency]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Mechanisms-to-track-who-is-editing-files"></div>
=== Mechanisms to track who is editing files ===
<div id="index-Watches"></div>

For many groups, use of <small>CVS</small> in its default mode is
perfectly satisfactory.  Users may sometimes go to
check in a modification only to find that another
modification has intervened, but they deal with it and
proceed with their check in.  Other groups prefer to be
able to know who is editing what files, so that if two
people try to edit the same file they can choose to
talk about who is doing what when rather than be
surprised at check in time.  The features in this
section allow such coordination, while retaining the
ability of two developers to edit the same file at the
same time.

For maximum benefit developers should use <code>cvs
edit</code> (not <code>chmod</code>) to make files read-write to
edit them, and <code>cvs release</code> (not <code>rm</code>) to
discard a working directory which is no longer in use,
but <small>CVS</small> is not able to enforce this behavior.


<div class="menu-preformatted" style="font-family: serif">
 [[#Telling CVS to watch certain files|&bull; Setting a watch]]::             Telling CVS to watch certain files
 [[#Telling CVS to notify you|&bull; Getting Notified]]::            Telling CVS to notify you
 [[#How to edit a file which is being watched|&bull; Editing files]]::               How to edit a file which is being watched
 [[#Information about who is watching and editing|&bull; Watch information]]::           Information about who is watching and editing
 [[#Using watches with old versions of CVS|&bull; Watches Compatibility]]::       Watches interact poorly with CVS 1.6 or earlier
</div>


----

<div id="Setting-a-watch"></div>
<div class="header">
<p>
Next: [[#Telling CVS to notify you|Getting Notified]], Up: [[#Mechanisms to track who is editing files|Watches]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Telling-CVS-to-watch-certain-files"></div>
==== Telling CVS to watch certain files ====

To enable the watch features, you first specify that
certain files are to be watched.

<div id="index-watch-on-_0028subcommand_0029"></div>
;<div id="index-cvs-watch-on"></div>Command<nowiki>:</nowiki> <strong>cvs watch on</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

<div id="index-Read_002donly-files_002c-and-watches"></div>
: Specify that developers should run <code>cvs edit</code> before editing <var>files</var>.  <small>CVS</small> will create working copies of <var>files</var> read-only, to remind developers to run the <code>cvs edit</code> command before working on them.

: If <var>files</var> includes the name of a directory, <small>CVS</small> arranges to watch all files added to the corresponding repository directory, and sets a default for files added in the future; this allows the user to set notification policies on a per-directory basis.  The contents of the directory are processed recursively, unless the <code>-l</code> option is given. The <code>-R</code> option can be used to force recursion if the <code>-l</code> option is set in &lsquo;<tt>~/.cvsrc</tt>&rsquo; (see [[cvs: Guide to CVS commands#Default options and the ~/.cvsrc file|~/.cvsrc]]).

: If <var>files</var> is omitted, it defaults to the current directory.

<div id="index-watch-off-_0028subcommand_0029"></div>

;<div id="index-cvs-watch-off"></div>Command<nowiki>:</nowiki> <strong>cvs watch off</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

: Do not create <var>files</var> read-only on checkout; thus, developers will not be reminded to use <code>cvs edit</code> and <code>cvs unedit</code>.

: The <var>files</var> and options are processed as for <code>cvs watch on</code>.



----

<div id="Getting-Notified"></div>
<div class="header">
<p>
Next: [[#How to edit a file which is being watched|Editing files]], Previous: [[#Telling CVS to watch certain files|Setting a watch]], Up: [[#Mechanisms to track who is editing files|Watches]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Telling-CVS-to-notify-you"></div>
==== Telling CVS to notify you ====

You can tell <small>CVS</small> that you want to receive
notifications about various actions taken on a file.
You can do this without using <code>cvs watch on</code> for
the file, but generally you will want to use <code>cvs
watch on</code>, to remind developers to use the <code>cvs edit</code>
command.

<div id="index-watch-add-_0028subcommand_0029"></div>
;<div id="index-cvs-watch-add"></div>Command<nowiki>:</nowiki> <strong>cvs watch add</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><code>-a</code> <var>action</var><nowiki>]</nowiki>&hellip; <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

: Add the current user to the list of people to receive notification of work done on <var>files</var>.

: The <code>-a</code> option specifies what kinds of events <small>CVS</small> should notify the user about.  <var>action</var> is one of the following:

:;<code>edit</code>
:: Another user has applied the <code>cvs edit</code> command (described below) to a watched file.

:;<code>commit</code>
:: Another user has committed changes to one of the named <var>files</var>.

:;<code>unedit</code>
:: Another user has abandoned editing a file (other than by committing changes). They can do this in several ways, by:


::* applying the <code>cvs unedit</code> command (described below) to the file


::* applying the <code>cvs release</code> command (see [[cvs: Guide to CVS commands#release&mdash;Indicate that a Module is no longer in use|release]]) to the file&rsquo;s parent directory (or recursively to a directory more than one level up)


::* deleting the file and allowing <code>cvs update</code> to recreate it


:;<code>all</code>
:: All of the above.

:;<code>none</code>
:: None of the above.  (This is useful with <code>cvs edit</code>, described below.)


: The <code>-a</code> option may appear more than once, or not at all.  If omitted, the action defaults to <code>all</code>.

: The <var>files</var> and options are processed as for <code>cvs watch on</code>.



<div id="index-watch-remove-_0028subcommand_0029"></div>
;<div id="index-cvs-watch-remove"></div>Command<nowiki>:</nowiki> <strong>cvs watch remove</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><code>-a</code> <var>action</var><nowiki>]</nowiki>&hellip; <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

: Remove a notification request established using <code>cvs watch add</code>; the arguments are the same.  If the <code>-a</code> option is present, only watches for the specified actions are removed.


<div id="index-notify-_0028admin-file_0029"></div>
When the conditions exist for notification, <small>CVS</small>
calls the &lsquo;<tt>notify</tt>&rsquo; administrative file.  Edit
&lsquo;<tt>notify</tt>&rsquo; as one edits the other administrative
files (see [[cvs: The Repository#The administrative files|Intro administrative files]]).  This
file follows the usual conventions for administrative
files (see [[cvs: Reference manual for Administrative files#The common syntax|syntax]]), where each line is a regular
expression followed by a command to execute.  The
command should contain a single occurrence of &lsquo;<code>%s</code>&rsquo;
which will be replaced by the user to notify; the rest
of the information regarding the notification will be
supplied to the command on standard input.  The
standard thing to put in the <code>notify</code> file is the
single line:

<div class="example" style="margin-left: 3.2em">
 ALL mail %s -s &quot;CVS notification&quot;
</div>

This causes users to be notified by electronic mail.

<div id="index-users-_0028admin-file_0029"></div>
Note that if you set this up in the straightforward
way, users receive notifications on the server machine.
One could of course write a &lsquo;<tt>notify</tt>&rsquo; script which
directed notifications elsewhere, but to make this
easy, <small>CVS</small> allows you to associate a notification
address for each user.  To do so create a file
&lsquo;<tt>users</tt>&rsquo; in &lsquo;<tt>CVSROOT</tt>&rsquo; with a line for each
user in the format <var>user</var>:<var>value</var>.  Then
instead of passing the name of the user to be notified
to &lsquo;<tt>notify</tt>&rsquo;, <small>CVS</small> will pass the <var>value</var>
(normally an email address on some other machine).

<small>CVS</small> does not notify you for your own changes.
Currently this check is done based on whether the user
name of the person taking the action which triggers
notification matches the user name of the person
getting notification.  In fact, in general, the watches
features only track one edit by each user.  It probably
would be more useful if watches tracked each working
directory separately, so this behavior might be worth
changing.


----

<div id="Editing-files"></div>
<div class="header">
<p>
Next: [[#Information about who is watching and editing|Watch information]], Previous: [[#Telling CVS to notify you|Getting Notified]], Up: [[#Mechanisms to track who is editing files|Watches]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="How-to-edit-a-file-which-is-being-watched"></div>
==== How to edit a file which is being watched ====

<div id="index-Checkout_002c-as-term-for-getting-ready-to-edit"></div>
Since a file which is being watched is checked out
read-only, you cannot simply edit it.  To make it
read-write, and inform others that you are planning to
edit it, use the <code>cvs edit</code> command.  Some systems
call this a <em>checkout</em>, but <small>CVS</small> uses that term
for obtaining a copy of the sources (see [[cvs: Overview#Getting the source|Getting the source]]), an operation which those systems call a
<em>get</em> or a <em>fetch</em>.

<div id="index-edit-_0028subcommand_0029"></div>
;<div id="index-cvs-edit"></div>Command<nowiki>:</nowiki> <strong>cvs edit</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><code>-a</code> <var>action</var><nowiki>]</nowiki>&hellip; <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

: Prepare to edit the working files <var>files</var>.  <small>CVS</small> makes the <var>files</var> read-write, and notifies users who have requested <code>edit</code> notification for any of <var>files</var>.

: The <code>cvs edit</code> command accepts the same options as the <code>cvs watch add</code> command, and establishes a temporary watch for the user on <var>files</var>; <small>CVS</small> will remove the watch when <var>files</var> are <code>unedit</code>ed or <code>commit</code>ted.  If the user does not wish to receive notifications, she should specify <code>-a none</code>.

: The <var>files</var> and the options are processed as for the <code>cvs watch</code> commands.



Normally when you are done with a set of changes, you
use the <code>cvs commit</code> command, which checks in your
changes and returns the watched files to their usual
read-only state.  But if you instead decide to abandon
your changes, or not to make any changes, you can use
the <code>cvs unedit</code> command.

<div id="index-unedit-_0028subcommand_0029"></div>
<div id="index-Abandoning-work"></div>
<div id="index-Reverting-to-repository-version"></div>
;<div id="index-cvs-unedit"></div>Command<nowiki>:</nowiki> <strong>cvs unedit</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

: Abandon work on the working files <var>files</var>, and revert them to the repository versions on which they are based.  <small>CVS</small> makes those <var>files</var> read-only for which users have requested notification using <code>cvs watch on</code>.  <small>CVS</small> notifies users who have requested <code>unedit</code> notification for any of <var>files</var>.

: The <var>files</var> and options are processed as for the <code>cvs watch</code> commands.

: If watches are not in use, the <code>unedit</code> command probably does not work, and the way to revert to the repository version is with the command <code>cvs update -C file</code> (see [[cvs: Guide to CVS commands#update&mdash;Bring work tree in sync with repository|update]]). The meaning is not precisely the same; the latter may also bring in some changes which have been made in the repository since the last time you updated.

When using client/server <small>CVS</small>, you can use the
<code>cvs edit</code> and <code>cvs unedit</code> commands even if
<small>CVS</small> is unable to successfully communicate with the
server; the notifications will be sent upon the next
successful <small>CVS</small> command.


----

<div id="Watch-information"></div>
<div class="header">
<p>
Next: [[#Using watches with old versions of CVS|Watches Compatibility]], Previous: [[#How to edit a file which is being watched|Editing files]], Up: [[#Mechanisms to track who is editing files|Watches]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Information-about-who-is-watching-and-editing"></div>
==== Information about who is watching and editing ====

<div id="index-watchers-_0028subcommand_0029"></div>
;<div id="index-cvs-watchers"></div>Command<nowiki>:</nowiki> <strong>cvs watchers</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

: List the users currently watching changes to <var>files</var>.  The report includes the files being watched, and the mail address of each watcher.

: The <var>files</var> and options are processed as for the <code>cvs watch</code> commands.



<div id="index-editors-_0028subcommand_0029"></div>
;<div id="index-cvs-editors"></div>Command<nowiki>:</nowiki> <strong>cvs editors</strong><em> <nowiki>[</nowiki><code>-lR</code><nowiki>]</nowiki> <nowiki>[</nowiki><var>files</var><nowiki>]</nowiki>&hellip;</em>

: List the users currently working on <var>files</var>.  The report includes the mail address of each user, the time when the user began working with the file, and the host and path of the working directory containing the file.

: The <var>files</var> and options are processed as for the <code>cvs watch</code> commands.



----

<div id="Watches-Compatibility"></div>
<div class="header">
<p>
Previous: [[#Information about who is watching and editing|Watch information]], Up: [[#Mechanisms to track who is editing files|Watches]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Using-watches-with-old-versions-of-CVS"></div>
==== Using watches with old versions of CVS ====

<div id="index-CVS-1_002e6_002c-and-watches"></div>
If you use the watch features on a repository, it
creates &lsquo;<tt>CVS</tt>&rsquo; directories in the repository and
stores the information about watches in that directory.
If you attempt to use <small>CVS</small> 1.6 or earlier with the
repository, you get an error message such as the
following (all on one line):

<div class="example" style="margin-left: 3.2em">
 cvs update: cannot open CVS/Entries for reading:
 No such file or directory
</div>

and your operation will likely be aborted.  To use the
watch features, you must upgrade all copies of <small>CVS</small>
which use that repository in local or server mode.  If
you cannot upgrade, use the <code>watch off</code> and
<code>watch remove</code> commands to remove all watches, and
that will restore the repository to a state which
<small>CVS</small> 1.6 can cope with.


----

<div id="Choosing-a-model"></div>
<div class="header">
<p>
Previous: [[#Mechanisms to track who is editing files|Watches]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
<div id="Choosing-between-reserved-or-unreserved-checkouts"></div>
=== Choosing between reserved or unreserved checkouts ===
<div id="index-Choosing_002c-reserved-or-unreserved-checkouts"></div>

Reserved and unreserved checkouts each have pros and
cons.  Let it be said that a lot of this is a matter of
opinion or what works given different groups&rsquo; working
styles, but here is a brief description of some of the
issues.  There are many ways to organize a team of
developers.  <small>CVS</small> does not try to enforce a certain
organization.  It is a tool that can be used in several
ways.

Reserved checkouts can be very counter-productive.  If
two persons want to edit different parts of a file,
there may be no reason to prevent either of them from
doing so.  Also, it is common for someone to take out a
lock on a file, because they are planning to edit it,
but then forget to release the lock.

People, especially people who are familiar with
reserved checkouts, often wonder how often conflicts
occur if unreserved checkouts are used, and how
difficult they are to resolve.  The experience with
many groups is that they occur rarely and usually are
relatively straightforward to resolve.

The rarity of serious conflicts may be surprising, until one realizes
that they occur only when two developers disagree on the proper design
for a given section of code; such a disagreement suggests that the
team has not been communicating properly in the first place.  In order
to collaborate under ''any'' source management regimen, developers
must agree on the general design of the system; given this agreement,
overlapping changes are usually straightforward to merge.

In some cases unreserved checkouts are clearly
inappropriate.  If no merge tool exists for the kind of
file you are managing (for example word processor files
or files edited by Computer Aided Design programs), and
it is not desirable to change to a program which uses a
mergeable data format, then resolving conflicts is
going to be unpleasant enough that you generally will
be better off to simply avoid the conflicts instead, by
using reserved checkouts.

The watches features described above in [[#Mechanisms to track who is editing files|Watches]]
can be considered to be an intermediate model between
reserved checkouts and unreserved checkouts.  When you
go to edit a file, it is possible to find out who else
is editing it.  And rather than having the system
simply forbid both people editing the file, it can tell
you what the situation is and let you figure out
whether it is a problem in that particular case or not.
Therefore, for some groups it can be considered the
best of both the reserved checkout and unreserved
checkout worlds.


----

<div class="header">
<p>
Previous: [[#Mechanisms to track who is editing files|Watches]], Up: [[#Multiple developers|Multiple developers]] &nbsp; |[[cvs: Index#SEC_Contents|Contents]]||[[cvs: Index#Index|Index]]|</p>
</div>
This document was generated on <i>a sunny day</i> using [http://www.nongnu.org/texi2html/ <i>texi2html</i>].
